On 04/11/2012 05:55 PM, Zulfiqar Malik wrote:
I am trying to write a very small shell client for some automation
related things and am running into problems with libssh2_channel_read.
Here are the two scenarios (application has to be single threaded.):
1. Blocking mode: libssh2_channel_read blocks if there's no data and
never returns. Its impossible to use this function reliably.
2. Non-blocking mode: libssh2_channel_read doesn't block but keeps on
returning -37 (LIBSSH2_ERROR_EAGAIN) and I end up with essentially the
same problem i.e. stuck in an infinite loop. To top it off
libssh2_channel_eof doesn't work and always returns 0.

You don't say what's happening at the other end. Can we assuming it's something like:

libssh2_channel_exec(channel, "cat foo");

and that you want to exit when the contents of foo have been returned? Is is possible, for example, that your channel is not returning eof because it isn't eof?

I don't know what's wrong or what needs to be done but I cannot seem to
find a way through this problem. I have tried libssh2 v 1.3.1 and the
latest one 1.4.1 with the same result. Given below is my readOutput
method which reads the output:
     for (;;count++)
     {
         /* loop until we block */
         int rc;
         do {
             char buffer[1024];
             rc = libssh2_channel_read(channel, buffer, sizeof(buffer));
             if (rc > 0) {
                 bytecount += rc;
                 buffer[rc] = '\0';

Probably not related, but ^^^ corrupts the stack if libssh2_channel_read returns a full buffer. If you're going to explicitly null terminate the buffer, you need:

rc = libssh2_channel_read(channel, buffer, sizeof(buffer) - 1);

                 fprintf(stderr, "%s", buffer);
                 count = 0;
             }
             else {
                 if (rc != LIBSSH2_ERROR_EAGAIN)
                     fprintf(stderr, "libssh2_channel_read returned
%d\n", rc);
             }
             if (libssh2_channel_eof(channel)) {
                 rc = 0;
                 break;
             }
         }
         while(rc > 0);
         //::Sleep(3);
         /* this is due to blocking that would occur otherwise so we loop on
            this condition */
         if(rc == LIBSSH2_ERROR_EAGAIN)
         {
             ::Sleep(5);
             //waitsocket(sock, sshSession);

I'm assuming this references something like the waitsocket() example at http://www.libssh2.org/examples/ssh2_exec.html. Why the sleep instead?

         }
         else
             break;
     }

Matt
--
Matthew Booth, RHCA, RHCSS
Red Hat Engineering, Virtualisation Team

GPG ID:  D33C3490
GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490
_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel

Reply via email to