Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!news-1.dfn.de!news.dfn.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Rainer Weikusat Newsgroups: comp.os.linux.development.apps Subject: Re: Linux O_NONBLOCK bug/ quirk Date: Fri, 28 Mar 2014 20:12:31 +0000 Lines: 72 Message-ID: <87siq23wwg.fsf@sable.mobileactivedefense.com> References: <878urvu0gx.fsf@sable.mobileactivedefense.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: individual.net SxCQYGpQoyN6baFP0ewYjw6UL0jtbAQCzI2mKL4eAQ31VELqQ= Cancel-Lock: sha1:XGXQjKitBTw1ECY2WOH0+jmApA0= sha1:YW6LbSWQGXN+GRf3t3XshVhhmnU= User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) Xref: csiph.com comp.os.linux.development.apps:669 Rainer Weikusat writes: [...] > a receive operation on a socket in > non-blocking mode can actually be blocked forever on Linux, example > code: > > --------- > #include > #include > #include > #include > > int main(void) > { > struct sockaddr_un sun; > int fd; > > fd = socket(AF_UNIX, SOCK_DGRAM, 0); > sun.sun_family = AF_UNIX; > strncpy(sun.sun_path, "/tmp/bla", sizeof(sun.sun_path)); > bind(fd, (struct sockaddr *)&sun, sizeof(sun)); > > if (fork() == 0) read(fd, &fd, sizeof(fd)); > > sleep(1); > > fcntl(fd, F_SETFL, O_NONBLOCK); > read(fd, &fd, sizeof(fd)); > > return 0; > } > -------- This is more serious than I thought. Considering newer APIs, the can also be ------------ #include #include #include #include int main(void) { struct sockaddr_un sun; int fd; fd = socket(AF_UNIX, SOCK_DGRAM, 0); sun.sun_family = AF_UNIX; strncpy(sun.sun_path, "/tmp/bla", sizeof(sun.sun_path)); bind(fd, (struct sockaddr *)&sun, sizeof(sun)); if (fork() == 0) recv(fd, &fd, sizeof(fd), 0); sleep(1); recv(fd, &fd, sizeof(fd), MSG_DONTWAIT); return 0; } ------------- What happens here is that the 2nd recv stops on a mutex held by the first and thus, effectively blocks until a message is received on this socket, IOW, the implementation of MSG_DONTWAIT is completely broken for datagram sockets (certainly AF_UNIX, likely, AF_INET, too). Further, it is not going to be fixed because the so-called 'networking maintainer' 'completely disagrees' with the idea that 'non-blocking operation' actually means 'the call will not block' (that's the state of 2 days ago).