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.
This commit is contained in:
parent
4a88b3b4b7
commit
27cd5f03ef
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user