This is rated to discussion from dotnet/corefx#23115
Consider following C code:
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <sys/select.h>
int
main(int argc, char ** argv) {
int ret, fd;
struct sockaddr_in sa;
socklen_t salen;
int newfd;
int flags;
fd_set fs;
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
sa.sin_port = htons(6600);
fd=socket(PF_INET,SOCK_STREAM, 0);
if (argc > 1) {
printf("setting accepting fd to non-block\n");
ret=fcntl(fd, F_SETFL, O_NONBLOCK);
fprintf(stderr, "Flags set on %d with %d\n", fd, ret);
}
if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) != 0) {
fprintf(stderr, "Bind failed %s\n",strerror(errno));
return -1;
}
if (listen(fd, 100) != 0) {
fprintf(stderr, "Listen failed: %s\n", strerror(errno));
return(1);
}
flags = fcntl(fd, F_GETFL);
printf("Accepting fd %d flags=0x%x NONBLOCK=%d\n", fd, flags, flags & O_NONBLOCK );
FD_ZERO(&fs);
FD_SET(fd, &fs);
select(fd+1, &fs, NULL, NULL, NULL);
newfd = accept(fd, (struct sockaddr *)&sa, &salen);
printf("newfd=%d\n", newfd);
flags = fcntl(newfd, F_GETFL);
printf("newfd flags=0x%x NONBLOCK=%d\n", flags, flags & O_NONBLOCK);
}
This will listen on port 6600 and accept new connection. It will printf socket flags after new socket is accepted. (nc 127.0.0.1 6600) When argument is passed to executable it will accept using non-blocking socket.
furt@Ubuntu:/tmp$ ./socket
Accepting fd 3 flags=0x2 NONBLOCK=0
newfd=4
newfd flags=0x2 NONBLOCK=0
furt@Ubuntu:/tmp$ ./socket -b
setting accepting fd to non-block
Accepting fd 3 flags=0x802 NONBLOCK=2048
newfd=4
newfd flags=0x2 NONBLOCK=0
however on macOS 10.12.6
Accepting fd 3 flags=0x2 NONBLOCK=0
newfd=4
newfd flags=0x2 NONBLOCK=0
macik:~ furt$ ./socket -b
setting accepting fd to non-block
Flags set on 3 with 0
Accepting fd 3 flags=0x6 NONBLOCK=4
newfd=4
newfd flags=0x6 NONBLOCK=4
I got same result on macOS 10.13 (High Sierra)
For comparison on FreeBSD 11.0:
[furt@toweinfu-d11 /tmp]$ ./socket -b
setting accepting fd to non-block
Flags set on 3 with 0
Accepting fd 3 flags=0x6 NONBLOCK=4
newfd=4
newfd flags=0x6 NONBLOCK=4
It seems like on macOS and BSD new socket inherits flags from accepting socket.
This is rated to discussion from dotnet/corefx#23115
Consider following C code:
This will listen on port 6600 and accept new connection. It will printf socket flags after new socket is accepted. (nc 127.0.0.1 6600) When argument is passed to executable it will accept using non-blocking socket.
however on macOS 10.12.6
I got same result on macOS 10.13 (High Sierra)
For comparison on FreeBSD 11.0:
It seems like on macOS and BSD new socket inherits flags from accepting socket.