"Why fcntl() flag values are defined in Octal format"
As many of the users have suggested, it's purely because of historical reasons. Apparently Octal format was more popular than Hex format.
"Is this answer the correct way to make non-blocking to blocking socket?"
Yes. The answer is correct, as it serves the purpose of setting the flags with keeping various scenario in consideration. However, error checking would have been more helpful, which is trivial.
"Is there a difference between fcntl(socket, F_GETFL, 0)
and fcntl(socket, F_GETFL)
?"
No difference. The man page for fcntl(2) suggest the same.
F_GETFL (void) -- Get the file access mode and the file status flags; arg is ignored.
SSL connection with non-blocking socket
This is a little tricky part, where I was facing problem. A typical blocking call on SSL will look like this:
int result = ::SSL_connect(pSSL); // <0: failed, 0: disconnected, 0<: pass
Now, the natural non-blocking alternative, we may assume as:
::fcntl(socketfd, F_SETFL, m_fcntl);
::connect(socketfd, ...);
int result == ::SSL_connect(pSSL);
// put the FD_SET() etc.
result = select(...);
if(result == 0) ... // SSL timed out
else if(result < 0) ... // SSL error
else ... // success
However, it doesn't work as simple as that. SSL is a bit complicated process, where messages are exchanged back and forth. Hence, we have to run ::SSL_Connect()
in a loop to capture SSL_want_read, SSL_want_write
. In a simplistic manner, the code may look like this:
::fcntl(socketfd, F_SETFL, m_fcntl);
::connect(socketfd, ...);
int result; // looping for various handshakes & to/from messages
while((result = ::SSL_connect(pSSL)) < 0) {
// put the FD_SET() etc.
if(select(...) <= 0)
break;
}
if(result == 0) ... // SSL timed out
else if(result < 0) ... // SSL error
else ... // success
I was able to fix my SSL issue with above (pseudo) code.
This answer is based on useful comments & my findings.