summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2012-12-17 00:05:04 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2012-12-17 00:14:36 +0100
commitcbe6f88b5ee7fa3394e916a8a7fe893066923b73 (patch)
tree218060794f87c0fbaa0a9b2f34ca322acf3598a8
parent23c9bbee12b08bcbc82188dabe3bf8135756c183 (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.c17
-rw-r--r--trans/fifo.c27
-rw-r--r--trans/new-fifo.c27
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)