diff --git a/include/errno.h b/include/errno.h index bb79502d2..54ca0b373 100755 --- a/include/errno.h +++ b/include/errno.h @@ -102,6 +102,7 @@ extern int errno; /* place where the error numbers go */ #define EMSGSIZE (_SIGN 73) /* Message too long */ #define ENOTSOCK (_SIGN 74) /* Socket operation on non-socket */ #define ENOPROTOOPT (_SIGN 75) /* Protocol not available */ +#define EOPNOTSUPP (_SIGN 76) /* Operation not supported */ /* The following are not POSIX errors, but they can still happen. * All of these are generated by the kernel and relate to message passing. diff --git a/lib/ansi/errlist.c b/lib/ansi/errlist.c index 962bf2111..f6caa0dcd 100755 --- a/lib/ansi/errlist.c +++ b/lib/ansi/errlist.c @@ -85,6 +85,7 @@ const char *_sys_errlist[] = { "Message too long", /* EMSGSIZE */ "Socket operation on non-socket", /* ENOTSOCK */ "Protocol not available", /* ENOPROTOOPT */ + "Operation not supported", /* EOPNOTSUPP */ }; const int _sys_nerr = sizeof(_sys_errlist) / sizeof(_sys_errlist[0]); diff --git a/lib/ip/accept.c b/lib/ip/accept.c index 28a543b7b..c6fe2ee06 100644 --- a/lib/ip/accept.c +++ b/lib/ip/accept.c @@ -23,15 +23,30 @@ int accept(int socket, struct sockaddr *_RESTRICT address, socklen_t *_RESTRICT address_len) { int r; + nwio_udpopt_t udpopt; r= _tcp_accept(socket, address, address_len); - return r; + if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL)) + return r; -#if DEBUG - fprintf(stderr, "accept: not implemented for fd %d\n", socket); -#endif - errno= ENOSYS; - return -1; + /* Unfortunately, we have to return EOPNOTSUPP for a socket that + * does not support accept (such as a UDP socket) and ENOTSOCK for + * filedescriptors that do not refer to a socket. + */ + r= ioctl(socket, NWIOGUDPOPT, &udpopt); + if (r == 0) + { + /* UDP socket */ + errno= EOPNOTSUPP; + return -1; + } + if ((errno == ENOTTY || errno == EBADIOCTL)) + { + errno= ENOTSOCK; + return -1; + } + + return r; } static int _tcp_accept(int socket, struct sockaddr *_RESTRICT address,