bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-gnulib] work around poll() bug in MacOS X 10.4


From: Bruno Haible
Subject: [bug-gnulib] work around poll() bug in MacOS X 10.4
Date: Wed, 1 Jun 2005 13:48:06 +0200
User-agent: KMail/1.5

Hi,

It has been reported that MacOS X 10.4 has the poll() system call, but it
is completely broken: it does not work any files in /dev/*. This includes
/dev/tty, normal stdin and stdout, and even /dev/null. See
http://lists.apple.com/archives/darwin-dev/2005/May/msg00220.html
http://comments.gmane.org/gmane.os.apple.fink.gnome/1193
http://cvs.sourceforge.net/viewcvs.py/fink/dists/10.4-transitional/unstable/main/finkinfo/gnome/glib2.info?r1=1.3&r2=1.4

This test program
=============================== polltest.c ===============================
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>

int main () {
  struct pollfd ufd;
  int result;
  {
    ufd.fd = 0;
    ufd.events = POLLIN;
    ufd.revents = 0;
    errno = 0;
    result = poll(&ufd,1,0);
    printf("fd = %d: %d/%d %d -> %d\n", ufd.fd, result, errno, ufd.events, 
ufd.revents);
  }
  {
    ufd.fd = 1;
    ufd.events = POLLOUT;
    ufd.revents = 0;
    errno = 0;
    result = poll(&ufd,1,0);
    printf("fd = %d: %d/%d %d -> %d\n", ufd.fd, result, errno, ufd.events, 
ufd.revents);
  }
  {
    ufd.fd = open("/dev/tty", O_RDONLY);
    ufd.events = POLLIN;
    ufd.revents = 0;
    errno = 0;
    result = poll(&ufd,1,0);
    printf("fd = %d: %d/%d %d -> %d\n", ufd.fd, result, errno, ufd.events, 
ufd.revents);
  }
  {
    ufd.fd = open("/dev/tty", O_WRONLY);
    ufd.events = POLLOUT;
    ufd.revents = 0;
    errno = 0;
    result = poll(&ufd,1,0);
    printf("fd = %d: %d/%d %d -> %d\n", ufd.fd, result, errno, ufd.events, 
ufd.revents);
  }
  {
    ufd.fd = open("/dev/null", O_RDONLY);
    ufd.events = POLLIN;
    ufd.revents = 0;
    errno = 0;
    result = poll(&ufd,1,0);
    printf("fd = %d: %d/%d %d -> %d\n", ufd.fd, result, errno, ufd.events, 
ufd.revents);
  }
  {
    ufd.fd = open("/dev/null", O_WRONLY);
    ufd.events = POLLOUT;
    ufd.revents = 0;
    errno = 0;
    result = poll(&ufd,1,0);
    printf("fd = %d: %d/%d %d -> %d\n", ufd.fd, result, errno, ufd.events, 
ufd.revents);
  }
  return 0;
}
==========================================================================

yields this on Linux and Solaris:

fd = 0: 0/0 1 -> 0
fd = 1: 1/0 4 -> 4
fd = 3: 0/0 1 -> 0
fd = 4: 1/0 4 -> 4
fd = 5: 1/0 1 -> 1
fd = 6: 1/0 4 -> 4

but this on MacOS X 10.4.0:

fd = 0: 1/0 1 -> 32
fd = 1: 1/0 4 -> 32
fd = 3: 1/0 1 -> 32
fd = 4: 1/0 4 -> 32
fd = 5: 1/0 1 -> 32
fd = 6: 1/0 4 -> 32

Here is a proposed patch for gnulib.

2005-06-01  Bruno Haible  <address@hidden>

        * poll.m4 (gl_FUNC_POLL): Check against MacOS X 10.4 poll() bug.
        When using lib/poll.c, define poll as rpl_poll.

diff -c -3 -r1.3 poll.m4
*** m4/poll.m4  23 Jan 2005 08:06:57 -0000      1.3
--- m4/poll.m4  1 Jun 2005 11:44:30 -0000
***************
*** 1,5 ****
! # poll.m4 serial 3
! dnl Copyright (c) 2003 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
  dnl with or without modifications, as long as this notice is preserved.
--- 1,5 ----
! # poll.m4 serial 4
! dnl Copyright (c) 2003, 2005 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
  dnl with or without modifications, as long as this notice is preserved.
***************
*** 14,21 ****
    fi
    AC_SUBST([POLL_H])
  
!   AC_REPLACE_FUNCS(poll)
!   if test $ac_cv_func_poll = no; then
      gl_PREREQ_POLL
    fi
  ])
--- 14,65 ----
    fi
    AC_SUBST([POLL_H])
  
!   AC_CHECK_FUNC(poll,
!     [# Check whether poll() works on special files (like /dev/null) and
!      # and ttys (like /dev/tty). On MacOS X 10.4.0, it doesn't.
!      AC_TRY_RUN([
! #include <fcntl.h>
! #include <poll.h>
!        int main()
!        {
!          struct pollfd ufd;
!          /* Try /dev/null for reading.  */
!          ufd.fd = open ("/dev/null", O_RDONLY);
!          if (ufd.fd < 0) /* If /dev/null does not exist, it's not MacOS X. */
!            return 0;
!          ufd.events = POLLIN;
!          ufd.revents = 0;
!          if (!(poll (&ufd, 1, 0) == 1 && ufd.revents == POLLIN))
!            return 1;
!          /* Try /dev/null for writing.  */
!          ufd.fd = open ("/dev/null", O_WRONLY);
!          if (ufd.fd < 0) /* If /dev/null does not exist, it's not MacOS X. */
!            return 0;
!          ufd.events = POLLOUT;
!          ufd.revents = 0;
!          if (!(poll (&ufd, 1, 0) == 1 && ufd.revents == POLLOUT))
!            return 1;
!          /* Trying /dev/tty may be too environment dependent.  */
!          return 0;
!        }],
!        [gl_cv_func_poll=yes],
!        [gl_cv_func_poll=no],
!        [# When cross-compiling, assume that poll() works everywhere except on
!         # MacOS X, regardless of its version.
!         AC_EGREP_CPP([MacOSX], [
! #if defined(__APPLE__) && defined(__MACH__)
! This is MacOSX
! #endif
! ], [gl_cv_func_poll=no], [gl_cv_func_poll=yes])])])
!   if test $gl_cv_func_poll = yes; then
!     AC_DEFINE([HAVE_POLL], 1,
!       [Define to 1 if you have the 'poll' function and it works.])
!   fi
! 
!   if test $gl_cv_func_poll = no; then
!     AC_LIBOBJ(poll)
!     AC_DEFINE(poll, rpl_poll,
!       [Define to poll if the replacement function should be used.])
      gl_PREREQ_POLL
    fi
  ])





reply via email to

[Prev in Thread] Current Thread [Next in Thread]