1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

Assume that accept4 is always available and works

Simplify the Linux accept4 implementation based on the assumption
that it is available in some way.  __ASSUME_ACCEPT4_SOCKETCALL was
previously unused, so remove it.

For ia64, the accept4 system call (and socket call) were backported
in kernel version 3.2.18.  Reflect this in the installation
instructions.
This commit is contained in:
Florian Weimer
2017-04-19 07:44:48 +02:00
parent 62f71aad7e
commit e92030239a
16 changed files with 230 additions and 138 deletions

View File

@ -22,75 +22,20 @@
#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <socketcall.h>
#include <kernel-features.h>
int
accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags)
{
/* Do not use the accept4 syscall on socketcall architectures unless
it was added at the same time as the socketcall support or can be
assumed to be present. */
#if defined __ASSUME_SOCKETCALL \
&& !defined __ASSUME_ACCEPT4_SYSCALL_WITH_SOCKETCALL \
&& !defined __ASSUME_ACCEPT4_SYSCALL
# undef __NR_accept4
#endif
#ifdef __NR_accept4
int
accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags)
{
return SYSCALL_CANCEL (accept4, fd, addr.__sockaddr__, addr_len, flags);
}
#elif defined __NR_socketcall
# include <socketcall.h>
# ifdef __ASSUME_ACCEPT4_SOCKETCALL
int
accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags)
{
return SOCKETCALL_CANCEL (accept4, fd, addr.__sockaddr__, addr_len, flags);
}
# else
static int have_accept4;
int
accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags)
{
if (__glibc_likely (have_accept4 >= 0))
{
int ret = SOCKETCALL_CANCEL (accept4, fd, addr.__sockaddr__, addr_len,
flags);
/* The kernel returns -EINVAL for unknown socket operations.
We need to convert that error to an ENOSYS error. */
if (__builtin_expect (ret < 0, 0)
&& have_accept4 == 0
&& errno == EINVAL)
{
/* Try another call, this time with the FLAGS parameter
cleared and an invalid file descriptor. This call will not
cause any harm and it will return immediately. */
ret = SOCKETCALL_CANCEL (invalid, -1);
if (errno == EINVAL)
{
have_accept4 = -1;
__set_errno (ENOSYS);
}
else
{
have_accept4 = 1;
__set_errno (EINVAL);
}
return -1;
}
return ret;
}
__set_errno (ENOSYS);
return -1;
}
# endif /* __ASSUME_ACCEPT4_SOCKETCALL */
#else /* __NR_socketcall */
int
accept4 (int fd, __SOCKADDR_ARG addr, socklen_t *addr_len, int flags)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (accept4)
#else
return SYSCALL_CANCEL (accept4, fd, addr.__sockaddr__, addr_len, flags);
#endif
}