From e8a0b27a7101f5b9939de83df3d6d8b606c5678b Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Mon, 5 Nov 2012 14:30:15 -0500 Subject: improve SOCK_NONBLOCK/SOCK_CLOEXEC fallback code checking for EINVAL should be sufficient, but qemu user emulation returns EPROTONOSUPPORT in some of the failure cases, and it seems conceivable that other kernels doing linux-emulation could make the same mistake. since DNS lookups and other important code might break if the fallback does not get invoked, be extra careful and check for either error. note that it's important NOT to perform the fallback code on other errors such as resource-exhaustion cases, since the fallback is not atomic and will lead to file-descriptor leaks in multi-threaded programs that use exec. the fallback code is only "safe" to run when the initial failure is caused by the application's choice of arguments, not the system state. --- src/network/socket.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/socket.c b/src/network/socket.c index ba8d45b1..51be30ee 100644 --- a/src/network/socket.c +++ b/src/network/socket.c @@ -6,7 +6,8 @@ int socket(int domain, int type, int protocol) { int s = socketcall(socket, domain, type, protocol, 0, 0, 0); - if (s<0 && errno==EINVAL && (type&(SOCK_CLOEXEC|SOCK_NONBLOCK))) { + if (s<0 && (errno==EINVAL || errno==EPROTONOSUPPORT) + && (type&(SOCK_CLOEXEC|SOCK_NONBLOCK))) { s = socketcall(socket, domain, type & ~(SOCK_CLOEXEC|SOCK_NONBLOCK), protocol, 0, 0, 0); -- cgit v1.2.1