Subject: libssh2_channel_read hangs when no data to read

libssh2_channel_read hangs when no data to read

From: Phillip Wu <Phillip.Wu_at_lpma.nsw.gov.au>
Date: Tue, 8 Mar 2011 12:38:52 +1100

Hi,

I having a problem with libssh2_channel_read hanging when there is no data to read.

I am using visual c++ 2010 Express and the libssh2 1.2.7 compiled using mingw.

This is what I have done:
1. Created a socket to the host (socket is blocked I/O)
2. Start a session
3. Authenticate user
4. Start a channel
5. Request pty (vanilla)
6. libssh2_channel_exec("passwd")
Read from the channel(after changing to non-block) as follows (I got most of the code from ssh2_exec example):

static int waitsocket(int socket_fd, LIBSSH2_SESSION *sessioni, int timetowait)
{
    struct timeval timeout;
    int rc;
    fd_set fd;
    fd_set *writefd = NULL;
    fd_set *readfd = NULL;
    int dir;
    timeout.tv_sec = timetowait;
    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(socket_fd + 1, readfd, writefd, NULL, &timeout);
    return rc;
}

int ssh2_read(SOCKET sock, LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, char *buffer, int bufsize, int timeout) {
  int rc;
  char *p;
  u_long mode = 1;
  int status;
  int size;

  /* non blocking */
  status=ioctlsocket (sock, FIONBIO, &mode);
  if (status!=0) return -1;
  p=buffer;
  size=bufsize;
  *p=0;
  for( ;; )
  {

   do
   {
     rc = libssh2_channel_read( channel, p, size);
     if( rc > 0 )
     {
       p+=rc;
       size-=rc;
     }
     else {
       fprintf(stderr, "libssh2_channel_read returned %d\n", rc);
       if (rc!=0) return -2;
     }
   }
   while( rc > 0 );

   if( rc == LIBSSH2_ERROR_EAGAIN ) rc=waitsocket(sock, session, timeout);
   else break;
  }
  /* non blocking */
  mode=0;
  status=ioctlsocket (sock, FIONBIO, &mode);
  if (status!=0) return -1;
  *p=0;
  return 0;
}

Using trace code I found out that I have got from the remote host a prompt to key in the
exisiting password. The code is hanging at libssh2_channel_read(). I am expecting that the read
should come back with 0 bytes read. The waitsocket() code never gets run.

Can someone please help me and tell me how I can fix this problem?
ps. I did try to turn on debugging:
      ./configure -enable_debugging
     and make a call to libssh2_trace(session,~0);
    but nothing came out on stderr

***************************************************************
This message is intended for the addressee named and may contain confidential information. If you are not the intended recipient, please delete it and notify the sender. Views expressed in this message are those of the individual sender, and are not necessarily the views of the Land and Property Management Authority. This email message has been swept by MIMEsweeper for the presence of computer viruses.
***************************************************************
Please consider the environment before printing this email.

_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
Received on 2011-03-08