Socket blocking by default on musl target


#1

Hi

I have a binary compiled with Rust nightly and musl, which is running some SSH commands on remote hosts using ssh2 library. After a rustup yesterday, the SSH connection is always hanging. When compiled for x86_64-unknown-linux-gnu it works fine.

Doing an strace I can see that the one compiled for x86_64-unknown-linux-musl does not set the socket to non-blocking but the native one does:

x86_64-unknown-linux-musl:

socket(PF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("10.94.5.16")}, 16) = 0
sendto(3, "SSH-2.0-libssh2_1.7.0_DEV\r\n", 27, MSG_NOSIGNAL, NULL, 0) = 27

x86_64-unknown-linux-gnu:

connect(3, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("10.94.5.16")}, 16) = 0
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
sendto(3, "SSH-2.0-libssh2_1.7.0_DEV\r\n", 27, MSG_NOSIGNAL, NULL, 0) = 27

I did an strace on a binary using an older Rust nightly version and musl target and there I can see the socket is also created as non-blocking by default using fcntl, so there seem to have been a change in one of the recent night-lies affecting musl target.

The fix is easy, I just need to force the socket to be non-blocking:

        let tcp_socket = try!(TcpStream::connect(host));
        try!(tcp_socket.set_nonblocking(true));

However, after this change I can see that on musl target the socket is set as non-blocking using ioctl instead of fcntl:

ioctl(3, FIONBIO, [1]) 

Any clues why there is a change in default behaviour between x86_64-unknown-linux-musl and x86_64-unknown-linux-gnu?

Also, why sometimes ioctl is used and some other times fcntl to configure the socket?

Thank you