Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
linux: fix accept4() ENOSYS detection on i386
Browse files Browse the repository at this point in the history
accept4() piggybacks on the socketcall() on i386. socketcall() has the flaw
that it returns EINVAL instead of ENOSYS when the operation is not supported.

The problem is that accept4() also returns EINVAL when its flag argument is
invalid.

Try to discern between the two failure cases to the best of our abilities.
  • Loading branch information
bnoordhuis committed Jun 29, 2012
1 parent 4a88b3b commit 27cd5f0
Showing 1 changed file with 19 additions and 7 deletions.
26 changes: 19 additions & 7 deletions src/unix/linux/syscalls.c
Expand Up @@ -152,13 +152,25 @@

int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
#if __i386__
unsigned long args[] = {
(unsigned long) fd,
(unsigned long) addr,
(unsigned long) addrlen,
(unsigned long) flags
};
return syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args);
unsigned long args[4];
int r;

args[0] = (unsigned long) fd;
args[1] = (unsigned long) addr;
args[2] = (unsigned long) addrlen;
args[3] = (unsigned long) flags;

r = syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args);

/* socketcall() raises EINVAL when SYS_ACCEPT4 is not supported but so does
* a bad flags argument. Try to distinguish between the two cases.
*/
if (r == -1)
if (errno == EINVAL)
if ((flags & ~(UV__SOCK_CLOEXEC|UV__SOCK_NONBLOCK)) == 0)
errno = ENOSYS;

return r;
#elif __NR_accept4
return syscall(__NR_accept4, fd, addr, addrlen, flags);
#else
Expand Down

0 comments on commit 27cd5f0

Please sign in to comment.