Re: HP/UX 11 test_socket failure

Anders Qvist <[email protected]> Sat, 19 Oct 2002 08:10:30 +0200
Newsgroups gmane.comp.python.snake-farm.user
Message-ID <[email protected]>
On Fri, Oct 18, 2002 at 08:06:34PM -0400, Guido van Rossum wrote:
> > Does this mean that some underlying system call returns something
> > unexpected on HP/UX?
> 
> Sounds like it does, yes.  How annoying. :-(
> 
> > Find out in the next installment of the
> > mystery of the non-blocking socket; part 2: HP/UX socket API. (I gotta
> > go away for a day and will be back sunday).

I've never been good at ifdefs, but I parse internal_setblocking in
socketmodule.c as executing:

  #else /* !PYOS_OS2 */
      delay_flag = fcntl(s->sock_fd, F_GETFL, 0);
      if (block)
          delay_flag &= (~O_NDELAY);
      else
          delay_flag |= O_NDELAY;
      fcntl(s->sock_fd, F_SETFL, delay_flag);
  #endif /* !PYOS_OS2 */

for HP/UX. However, man recv says:

  If the O_NDELAY flag is set using fcntl() (defined in <sys/fcntl.h>
  and explained in fcntl(2) and fcntl(5)), nonblocking I/O is enabled.

  In this case, the recv() request completes in one of three ways:

    ·  If there is enough data available to satisfy the entire request,
       recv() completes successfully, having read all the data, and
       returns the number of bytes read.

    ·  If there is not enough data available to satisfy the entire
       request, recv() completes successfully, having read as much data
       as possible, and returns the number of bytes it was able to read.

    ·  If there is no data available, recv() completes successfully,
       having read no data, and returns 0.

whereas it says:

  If the O_NONBLOCK flag is set using fcntl() (defined in <sys/fcntl.h>
  and explained in fcntl(2) and fcntl(5)), POSIX-style nonblocking I/O
  is enabled.  In this case, the recv() request completes in one of
  three ways:

    ·  If there is enough data available to satisfy the entire request,
       recv() completes successfully, having read all the data, and
       returns the number of bytes read.

    ·  If there is not enough data available to satisfy the entire
       request, recv() completes successfully, having read as much data
       as possible, and returns the number of bytes it was able to read.

    ·  If there is no data available, recv() completes, having read no
       data, and returns -1 with errno set to [EAGAIN].

... which seems to be what recv expects (function sock_recv):

    n = recv(s->sock_fd, PyString_AS_STRING(buf), len, flags);
    Py_END_ALLOW_THREADS

    if (n < 0) {
            Py_DECREF(buf);
            return s->errorhandler();
    }

I'll patch and try this tomorrow, unless someone else does it before
me.
-- 
Anders "Quest" Qvist

"We've all heard that a million monkeys banging on a million typewriters
will eventually reproduce the entire works of Shakespeare. Now, thanks 
to the Internet, we know this is not true." -- Robert Wilensky