coreutils
[Top][All Lists]
Advanced

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

Re: [PATCH] tee: Add --pipe-check to allow instantly detecting closed ou


From: Carl Edquist
Subject: Re: [PATCH] tee: Add --pipe-check to allow instantly detecting closed outputs
Date: Fri, 9 Dec 2022 10:13:00 -0600 (CST)

Hi Pádraig,

Getting back to this portability question:

On Fri, 2 Dec 2022, Pádraig Brady wrote:

 Anyway if it's possible just to use poll(2) (the system one, not the
 gnulib replacement), that might simplify the portability logic.

Yes it would be better to use poll() if possible,
and that's what I attempted with tail(1) recently.
From the gnulib docs on poll():

"
 Portability problems fixed by Gnulib:

  This function is missing on some platforms:
  mingw, MSVC 14, HP NonStop.

  This function doesn't work on special files like @file{/dev/null} and ttys
  like
  @file{/dev/tty} on some platforms:
  AIX 5.3, Mac OS X 10.4.0

Portability problems not fixed by Gnulib:

  Under Windows, when passing a pipe, Gnulib's @code{poll} replacement might
  return 0 even before the timeout has passed.  Programs using it with pipes
  can
  thus busy wait.

  On some platforms, file descriptors other than sockets do not support
  POLLHUP; they will return a "readable" or "writable" status instead:
  AIX 7.2, HP NonStop.
"

So to use poll() everywhere we'd need the gnulib module.
But empirically the replacement didn't work on macos at least
for this use case, and we know the select emulation wouldn't work on AIX.

So portable use of poll() will be awkward.

Don't remember if i said so already or not, but thanks for the summary!

In my last patch i made a first attempt to define a HAVE_POLL_PIPE_CLOSE_DETECTION in configure.ac using AC_RUN_IFELSE to test poll() functionality. Arsen pointed out that this does not work for cross-compiling. (That's too bad, but, i think i understand now why it's a problem.)

We could still do just an AC_COMPILE_IFELSE to test whether native poll() is available, though if i understand your summary right there are a number of platforms where native poll() is available but won't work correctly here.

So, if we need to separate out the poll() vs select() implementations using a list of platforms, do we have a good idea what list of platforms are "ok for native poll pipe detection", or alternatively a list of platforms that are not ok?

So tail.c uses:

        #if defined _AIX || defined __sun || defined __APPLE__ || HAVE_INOTIFY

but as far as i can tell HAVE_INOTIFY relates to the use of inotify in tail, which is specific to "tail -f" mode, and perhaps not relevant to the logic in tee (or other filters).

The section you quoted "From the gnulib docs on poll()" makes it sound like there might be problems with: Windows, mingw, MSVC 14, HP NonStop, AIX 5.3 & 7.2, and Mac OS X 10.4.0. (Already that makes me wonder about _AIX and __APPLE__ being in the list of platforms to use poll().)

Anyway, just trying to get a handle on what might be a good way to do the preprocessor macro logic to decide between the poll() and select() implementations.

I guess in worst case, it sounds like select() could be used everywhere. And there is some appeal to having a single implementation. But select() does seem less efficient if poll() is available; for instance with select(), two fd_sets need to be zeroed out (128 bytes each) before every call to read(), compared to the poll() version that only needs to initialize two struct pollfds (8 bytes each). So i still see some value in doing poll() where possible.


Any thoughts on how to put together preprocessor logic that gets at the heart of the issue?

Thanks,
Carl


reply via email to

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