class fifo_shmem_t
{
LONG _nreaders, _nwriters;
+ /* Set to 1 the first time a writer opens. */
+ LONG _writer_opened;
fifo_reader_id_t _owner, _prev_owner, _pending_owner;
af_unix_spinlock_t _owner_lock, _reading_lock, _nreaders_lock, _nwriters_lock;
int inc_nwriters () { return (int) InterlockedIncrement (&_nwriters); }
int dec_nwriters () { return (int) InterlockedDecrement (&_nwriters); }
+ bool writer_opened () const { return (bool) _writer_opened; }
+ void set_writer_opened () { InterlockedExchange (&_writer_opened, 1); }
+
fifo_reader_id_t get_owner () const { return _owner; }
void set_owner (fifo_reader_id_t fr_id) { _owner = fr_id; }
fifo_reader_id_t get_prev_owner () const { return _prev_owner; }
int nwriters () const { return shmem->nwriters (); }
int inc_nwriters () { return shmem->inc_nwriters (); }
int dec_nwriters () { return shmem->dec_nwriters (); }
+ bool writer_opened () const { return shmem->writer_opened (); }
+ void set_writer_opened () { shmem->set_writer_opened (); }
void nreaders_lock () { shmem->nreaders_lock (); }
void nreaders_unlock () { shmem->nreaders_unlock (); }
void nwriters_lock () { shmem->nwriters_lock (); }
/* Called if we appear to be at EOF after polling fc_handlers. */
bool hit_eof () const
{ return !nwriters () && !IsEventSignalled (writer_opening); }
+ /* Special EOF test needed by select.cc:peek_fifo(). */
+ bool select_hit_eof () const { return hit_eof () && writer_opened (); }
int get_nhandlers () const { return nhandlers; }
fifo_client_handler &get_fc_handler (int i) { return fc_handler[i]; }
PUNICODE_STRING get_pipe_name ();
- Fix a permission problem when writing DOS attributes on Samba.
Addresses: https://cygwin.com/pipermail/cygwin/2022-January/250629.html
+- For Linux compatibility, select(2) no longer reports read ready on a
+ FIFO that has never been opened for writing.
+ Addresses: https://cygwin.com/pipermail/cygwin/2022-September/252223.html
}
}
fh->fifo_client_unlock ();
- if (!nconnected && fh->hit_eof ())
+ /* According to POSIX and the Linux man page, we're supposed to
+ report read ready if the FIFO is at EOF, i.e., if the pipe is
+ empty and there are no writers. But there seems to be an
+ undocumented exception, observed on Linux and other platforms
+ (https://cygwin.com/pipermail/cygwin/2022-September/252223.html):
+ If no writer has ever been opened, then we do not report read
+ ready. This can happen if a reader is opened with O_NONBLOCK
+ before any writers have opened. To be consistent with other
+ platforms, we use a special EOF test that returns false if
+ there's never been a writer opened. */
+ if (!nconnected && fh->select_hit_eof ())
{
select_printf ("read: %s, saw EOF", fh->get_name ());
gotone += s->read_ready = true;