summaryrefslogtreecommitdiff
path: root/term
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 /term
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.
Diffstat (limited to 'term')
-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;
}
}