为什么当O_NONBLOCK被设置时这个读取被阻塞?

Strace摘录(请忽略发送xml到ssh):

dup(12) = 13 getsockname(13, {sa_family=AF_INET, sin_port=htons(46811), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0 getsockopt(13, SOL_SOCKET, SO_TYPE, [1], [4]) = 0 fstat(13, {st_mode=S_IFSOCK|0777, st_size=0, ...}) = 0 getsockname(13, {sa_family=AF_INET, sin_port=htons(46811), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0 getsockopt(13, SOL_SOCKET, SO_TYPE, [1], [4]) = 0 fcntl(13, F_SETFD, FD_CLOEXEC) = 0 fcntl(13, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK) fcntl(13, F_SETFL, O_RDWR|O_NONBLOCK) = 0 setsockopt(13, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 setsockopt(13, SOL_SOCKET, SO_REUSEPORT, [0], 4) = 0 setsockopt(13, SOL_TCP, TCP_NODELAY, [0], 4) = 0 setsockopt(13, SOL_TCP, TCP_CORK, [0], 4) = 0 fcntl(12, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK) fcntl(12, F_SETFL, O_RDWR) = 0 close(12) = 0 getpeername(13, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0 sendto(13, "<stream:stream xmlns:stream='htt"..., 133, MSG_NOSIGNAL, NULL, 0) = 133 read(13, "SSH-2.0-OpenSSH_6.6.1\r\n", 4096) = 23 read(13, <unfinished ...> 

(最后我杀了它。)

read()在最后被阻塞; 尽pipe通过fcntl()设置了O_NONBLOCK

这怎么可能?


版本信息:

 $ uname -r 3.16.4-1-ARCH 

由于FD 13是FD 12的dup() ,因此该行将删除您的O_NONBLOCK

 fcntl(12, F_SETFL, O_RDWR) = 0