blob: 8981b92e3bb0c0a6d629e6572b5f063a2f8c842e [file] [log] [blame]
Willy Tarreau1bc4aab2012-10-08 20:11:03 +02001/*
2 * include/common/accept4.h
3 * Definition of the accept4 system call for older Linux libc.
4 *
5 * Copyright 2000-2012 Willy Tarreau <w@1wt.eu>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation, version 2.1
10 * exclusively.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 *
21 */
22
23#ifndef _COMMON_ACCEPT4_H
24#define _COMMON_ACCEPT4_H
25
26#if defined (__linux__) && defined(USE_ACCEPT4)
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <sys/syscall.h>
31#include <errno.h>
32#include <fcntl.h>
33#include <unistd.h>
34#include <common/syscall.h>
35
36/* On recent Linux kernels, the accept4() syscall may be used to avoid an fcntl()
37 * call to set O_NONBLOCK on the resulting socket. It was introduced in Linux
38 * 2.6.28 and is not present in older libcs.
39 */
40#ifndef SOCK_NONBLOCK
41#define SOCK_NONBLOCK O_NONBLOCK
42#endif
43
Willy Tarreau23179762014-01-15 16:45:17 +010044#if defined(USE_MY_ACCEPT4) || (!defined(SYS_ACCEPT4) && !defined(__NR_accept4))
Willy Tarreau1bc4aab2012-10-08 20:11:03 +020045#if defined(CONFIG_HAP_LINUX_VSYSCALL) && defined(__linux__) && defined(__i386__)
46/* The syscall is redefined somewhere else */
47extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
48#elif ACCEPT4_USE_SOCKETCALL
Willy Tarreau7fca87f2012-10-10 08:26:12 +020049static inline _syscall2(int, socketcall, int, call, unsigned long *, args);
Willy Tarreau1bc4aab2012-10-08 20:11:03 +020050static int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
51{
52 unsigned long args[4];
Willy Tarreau1bc4aab2012-10-08 20:11:03 +020053
54 args[0] = (unsigned long)sockfd;
55 args[1] = (unsigned long)addr;
56 args[2] = (unsigned long)addrlen;
57 args[3] = (unsigned long)flags;
58 return socketcall(SYS_ACCEPT4, args);
59}
60#else
Willy Tarreaucefad672014-05-08 22:36:29 +020061static inline _syscall4(int, accept4, int, sockfd, struct sockaddr *, addr, socklen_t *, addrlen, int, flags);
Willy Tarreau1bc4aab2012-10-08 20:11:03 +020062#endif /* VSYSCALL etc... */
63#endif /* USE_MY_ACCEPT4 */
64#endif /* __linux__ && USE_ACCEPT4 */
65#endif /* _COMMON_ACCEPT4_H */
66
67/*
68 * Local variables:
69 * c-indent-level: 8
70 * c-basic-offset: 8
71 * End:
72 */