summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2001-05-31 04:55:36 +0000
committerRoland McGrath <roland@gnu.org>2001-05-31 04:55:36 +0000
commit33e55d9f63f0ba84b892e145f226c16b8f1733e7 (patch)
tree892a5ddae3b63156abde64c8c34a582b2057f7f3
parent450bd9625dd2d9c7ba33e584cfbfbfac326032f0 (diff)
2001-05-30 Roland McGrath <roland@frob.com>
* users.c (trivfs_S_io_select): Mask out SELECT_READ and/or SELECT_WRITE if those accesses are not allowed by the peropen. Don't keep old bits in AVAILABLE across waits, return only what is true at the moment we return.
-rw-r--r--term/users.c31
1 files changed, 12 insertions, 19 deletions
diff --git a/term/users.c b/term/users.c
index 9d103013..a987454d 100644
--- a/term/users.c
+++ b/term/users.c
@@ -2000,44 +2000,37 @@ trivfs_S_io_select (struct trivfs_protid *cred,
int *type,
int *idtag)
{
- int available;
-
if (!cred)
return EOPNOTSUPP;
if (cred->pi.class == pty_class)
return pty_io_select (cred, reply, type, idtag);
- /* We don't deal with SELECT_URG here. */
- *type &= (SELECT_READ | SELECT_WRITE);
-
- available = 0;
- if (*type == 0)
- return 0;
+ if ((cred->po->openmodes & O_READ) == 0)
+ *type &= ~SELECT_READ;
+ if ((cred->po->openmodes & O_WRITE) == 0)
+ *type &= ~SELECT_WRITE;
mutex_lock (&global_lock);
while (1)
{
+ int available = 0;
if ((*type & SELECT_READ) && qsize (inputq))
available |= SELECT_READ;
if ((*type & SELECT_WRITE) && qavail (outputq))
available |= SELECT_WRITE;
- if (available)
+ if (available == 0)
{
- *type = available;
- mutex_unlock (&global_lock);
- return 0;
+ ports_interrupt_self_on_port_death (cred, reply);
+ if (hurd_condition_wait (&select_alert, &global_lock) == 0)
+ continue;
}
- ports_interrupt_self_on_port_death (cred, reply);
- if (hurd_condition_wait (&select_alert, &global_lock))
- {
- *type = 0;
- mutex_unlock (&global_lock);
- return EINTR;
- }
+ *type = available;
+ mutex_unlock (&global_lock);
+ return available ? 0 EINTR;
}
}