Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

linux: fix accept4() ENOSYS detection on i386

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...
commit 27cd5f03ef26b32b0043ae67bb2dae9dabda60bf 1 parent 4a88b3b
@bnoordhuis bnoordhuis authored
Showing with 19 additions and 7 deletions.
  1. +19 −7 src/unix/linux/syscalls.c
View
26 src/unix/linux/syscalls.c
@@ -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
Please sign in to comment.
Something went wrong with that request. Please try again.