summaryrefslogtreecommitdiffstats
path: root/sys/miscfs/fifofs
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1995-08-06 16:14:21 +0000
committerjkh <jkh@FreeBSD.org>1995-08-06 16:14:21 +0000
commitc4d12492fbf418f2581c171abfc398a89f17b1f2 (patch)
treea3ab31bfe1f41cfcc09385107443010e78ad5c8e /sys/miscfs/fifofs
parent93469a89048da9777b19d441d18e4ee926ed62dd (diff)
downloadFreeBSD-src-c4d12492fbf418f2581c171abfc398a89f17b1f2.zip
FreeBSD-src-c4d12492fbf418f2581c171abfc398a89f17b1f2.tar.gz
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
Diffstat (limited to 'sys/miscfs/fifofs')
-rw-r--r--sys/miscfs/fifofs/fifo_vnops.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/sys/miscfs/fifofs/fifo_vnops.c b/sys/miscfs/fifofs/fifo_vnops.c
index 106ac89..0f4f34b 100644
--- a/sys/miscfs/fifofs/fifo_vnops.c
+++ b/sys/miscfs/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);
OpenPOWER on IntegriCloud