diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2012-12-17 00:05:04 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2012-12-17 00:14:36 +0100 |
commit | cbe6f88b5ee7fa3394e916a8a7fe893066923b73 (patch) | |
tree | 218060794f87c0fbaa0a9b2f34ca322acf3598a8 | |
parent | 23c9bbee12b08bcbc82188dabe3bf8135756c183 (diff) |
Make io_select return errors
instead of returning 0 and make clients have to actually read the error.
This makes implementing "poll" much easier.
Based on Svante Signell's patch.
* pflocal/io.c (S_io_select): Return error returned by pipe_wait_readable or
pipe_wait_writable.
* trans/fifo.c (trivfs_S_io_select): Return error returned by
pipe_wait_readable or pipe_wait_writable. Return EBADF on bogus access mode.
* trans/new-fifo.c (trivfs_S_io_select): Likewise.
-rw-r--r-- | pflocal/io.c | 17 | ||||
-rw-r--r-- | trans/fifo.c | 27 | ||||
-rw-r--r-- | trans/new-fifo.c | 27 |
3 files changed, 55 insertions, 16 deletions
diff --git a/pflocal/io.c b/pflocal/io.c index f67052f3..2301611e 100644 --- a/pflocal/io.c +++ b/pflocal/io.c @@ -231,15 +231,24 @@ S_io_select (struct sock_user *user, if (valid & SELECT_READ) { pipe_acquire_reader (read_pipe); - if (pipe_wait_readable (read_pipe, 1, 1) != EWOULDBLOCK) - ready |= SELECT_READ; /* Data immediately readable (or error). */ + err = pipe_wait_readable (read_pipe, 1, 1); + if (err == EWOULDBLOCK) + err = 0; /* Not readable, actually not an error. */ + else + ready |= SELECT_READ; /* Data immediately readable (or error). */ pthread_mutex_unlock (&read_pipe->lock); + if (err) + /* Prevent write test from overwriting err. */ + valid &= ~SELECT_WRITE; } if (valid & SELECT_WRITE) { pipe_acquire_writer (write_pipe); - if (pipe_wait_writable (write_pipe, 1) != EWOULDBLOCK) - ready |= SELECT_WRITE; /* Data immediately writable (or error). */ + err = pipe_wait_writable (write_pipe, 1); + if (err == EWOULDBLOCK) + err = 0; /* Not writable, actually not an error. */ + else + ready |= SELECT_WRITE; /* Data immediately writable (or error). */ pthread_mutex_unlock (&write_pipe->lock); } diff --git a/trans/fifo.c b/trans/fifo.c index 4fe999dd..b40a50d1 100644 --- a/trans/fifo.c +++ b/trans/fifo.c @@ -424,12 +424,21 @@ trivfs_S_io_select (struct trivfs_protid *cred, if (cred->po->openmodes & O_READ) { pthread_mutex_lock (&pipe->lock); - if (pipe_wait_readable (pipe, 1, 1) != EWOULDBLOCK) - ready |= SELECT_READ; /* Data immediately readable (or error). */ + err = pipe_wait_readable (pipe, 1, 1); + if (err == EWOULDBLOCK) + err = 0; /* Not readable, actually not an error. */ + else + ready |= SELECT_READ; /* Data immediately readable (or error). */ pthread_mutex_unlock (&pipe->lock); } else - ready |= SELECT_READ; /* Error immediately available... */ + { + err = EBADF; + ready |= SELECT_READ; /* Error immediately available... */ + } + if (err) + /* Prevent write test from overwriting err. */ + *select_type &= ~SELECT_WRITE; } if (*select_type & SELECT_WRITE) @@ -437,12 +446,18 @@ trivfs_S_io_select (struct trivfs_protid *cred, if (cred->po->openmodes & O_WRITE) { pthread_mutex_lock (&pipe->lock); - if (pipe_wait_writable (pipe, 1) != EWOULDBLOCK) - ready |= SELECT_WRITE; /* Data immediately writable (or error). */ + err = pipe_wait_writable (pipe, 1); + if (err == EWOULDBLOCK) + err = 0; /* Not writable, actually not an error. */ + else + ready |= SELECT_WRITE; /* Data immediately writable (or error). */ pthread_mutex_unlock (&pipe->lock); } else - ready |= SELECT_WRITE; /* Error immediately available... */ + { + err = EBADF; + ready |= SELECT_WRITE; /* Error immediately available... */ + } } if (ready) diff --git a/trans/new-fifo.c b/trans/new-fifo.c index cc16b988..5cc44b58 100644 --- a/trans/new-fifo.c +++ b/trans/new-fifo.c @@ -610,12 +610,21 @@ trivfs_S_io_select (struct trivfs_protid *cred, if (cred->po->openmodes & O_READ) { pthread_mutex_lock (&pipe->lock); - if (pipe_wait_readable (pipe, 1, 1) != EWOULDBLOCK) - ready |= SELECT_READ; /* Data immediately readable (or error). */ + err = pipe_wait_readable (pipe, 1, 1); + if (err == EWOULDBLOCK) + err = 0; /* Not readable, actually not an error. */ + else + ready |= SELECT_READ; /* Data immediately readable (or error). */ pthread_mutex_unlock (&pipe->lock); } else - ready |= SELECT_READ; /* Error immediately available... */ + { + err = EBADF; + ready |= SELECT_READ; /* Error immediately available... */ + } + if (err) + /* Prevent write test from overwriting err. */ + *select_type &= ~SELECT_WRITE; } if (*select_type & SELECT_WRITE) @@ -623,12 +632,18 @@ trivfs_S_io_select (struct trivfs_protid *cred, if (cred->po->openmodes & O_WRITE) { pthread_mutex_lock (&pipe->lock); - if (pipe_wait_writable (pipe, 1) != EWOULDBLOCK) - ready |= SELECT_WRITE; /* Data immediately writable (or error). */ + err = pipe_wait_writable (pipe, 1); + if (err == EWOULDBLOCK) + err = 0; /* Not writable, actually not an error. */ + else + ready |= SELECT_WRITE; /* Data immediately writable (or error). */ pthread_mutex_unlock (&pipe->lock); } else - ready |= SELECT_WRITE; /* Error immediately available... */ + { + err = EBADF; + ready |= SELECT_WRITE; /* Error immediately available... */ + } } if (ready) |