So I studied libssh2 example about how to implement a non-blocking sftp write operation (https://libssh2.org/examples/sftp_write_nonblock.html), and I noticed the following difference when checking the return value of a non-blocking function call:
waitsocket() is not called in case of libssh2_session_handshake(), libssh2_userauth_password(), libssh2_userauth_publickey_fromfile(), libssh2_sftp_init(), libssh2_sftp_open(). For example:
while((rc = libssh2_session_handshake(session, sock)) == LIBSSH2_ERROR_EAGAIN);
if(rc)
{
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
goto shutdown;
}
but it is called in case of libssh2_sftp_write():
while((nwritten = libssh2_sftp_write(sftp_handle, ptr, nread)) == LIBSSH2_ERROR_EAGAIN)
{
waitsocket(sock, session);
}
I add the implementation of waitsocket() below:
static int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION *session)
{
struct timeval timeout;
int rc;
fd_set fd;
fd_set *writefd = NULL;
fd_set *readfd = NULL;
int dir;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(socket_fd, &fd);
/* now make sure we wait in the correct direction */
dir = libssh2_session_block_directions(session);
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
readfd = &fd;
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
writefd = &fd;
rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);
return rc;
}
Why waitsocket() is not called in every case? For example: for a successful handshake to happen, doesn't it make sense to wait for the socket to be readable and/or writeable?