aboutsummaryrefslogtreecommitdiff
path: root/sys/fs
diff options
context:
space:
mode:
authorJordan K. Hubbard <jkh@FreeBSD.org>1995-08-06 16:14:21 +0000
committerJordan K. Hubbard <jkh@FreeBSD.org>1995-08-06 16:14:21 +0000
commit78f1a844fbd79cb8d12bfb1454db7559b86c2216 (patch)
treea3ab31bfe1f41cfcc09385107443010e78ad5c8e /sys/fs
parent59eab4883608277730b3edc1e362d58fac256a1d (diff)
downloadsrc-78f1a844fbd79cb8d12bfb1454db7559b86c2216.tar.gz
src-78f1a844fbd79cb8d12bfb1454db7559b86c2216.zip
Allow a pipe to be opened read/write at one end, as is allowed in
SunOS and SCO. You can then even use the pipe as a cheap fifo stack (yuck!). A semantic change also important (but not limited) to iBCS2 compatibility. Submitted by: swallace
Notes
Notes: svn path=/head/; revision=9973
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/fifofs/fifo_vnops.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
index 106ac89661ca..0f4f34b895c8 100644
--- a/sys/fs/fifofs/fifo_vnops.c
+++ b/sys/fs/fifofs/fifo_vnops.c
@@ -149,8 +149,6 @@ fifo_open(ap)
int error;
static char openstr[] = "fifo";
- if ((ap->a_mode & (FREAD|FWRITE)) == (FREAD|FWRITE))
- return (EINVAL);
if ((fip = vp->v_fifoinfo) == NULL) {
MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
vp->v_fifoinfo = fip;
@@ -182,24 +180,38 @@ fifo_open(ap)
rso->so_state |= SS_CANTSENDMORE;
}
error = 0;
- if (ap->a_mode & FREAD) {
+ if ((ap->a_mode & (FREAD|FWRITE)) == (FREAD|FWRITE)) {
+ if (fip->fi_readers == 0) {
+ fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
+ if (fip->fi_writers > 0)
+ wakeup((caddr_t)&fip->fi_writers);
+ }
+ if (fip->fi_writers == 0) {
+ fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
+ if (fip->fi_readers > 0)
+ wakeup((caddr_t)&fip->fi_readers);
+ }
+ fip->fi_readers++;
+ fip->fi_writers++;
+ }
+ else if (ap->a_mode & FREAD) {
fip->fi_readers++;
if (fip->fi_readers == 1) {
fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
if (fip->fi_writers > 0)
wakeup((caddr_t)&fip->fi_writers);
}
- if (ap->a_mode & O_NONBLOCK)
- return (0);
- while (fip->fi_writers == 0) {
- VOP_UNLOCK(vp);
- error = tsleep((caddr_t)&fip->fi_readers,
- PCATCH | PSOCK, openstr, 0);
- VOP_LOCK(vp);
- if (error)
- break;
- }
- } else {
+ if (!(ap->a_mode & O_NONBLOCK))
+ while (fip->fi_writers == 0) {
+ VOP_UNLOCK(vp);
+ error = tsleep((caddr_t)&fip->fi_readers,
+ PCATCH | PSOCK, openstr, 0);
+ VOP_LOCK(vp);
+ if (error)
+ break;
+ }
+ }
+ else {
fip->fi_writers++;
if (fip->fi_readers == 0 && (ap->a_mode & O_NONBLOCK)) {
error = ENXIO;
@@ -408,7 +420,8 @@ fifo_close(ap)
fip->fi_writers--;
if (fip->fi_writers == 0)
socantrcvmore(fip->fi_readsock);
- } else {
+ }
+ if (ap->a_fflag & FREAD) {
fip->fi_readers--;
if (fip->fi_readers == 0)
socantsendmore(fip->fi_writesock);