summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/syscall/pipe.c
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2013-05-08 18:18:49 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2013-05-08 18:18:49 +0000
commit43840e901cacf50a9bb41148069e34ca307524e8 (patch)
tree2836162f69bba2534e8b9acf9797e5892f103258 /usr/src/uts/common/syscall/pipe.c
parentabd43b3991c3becf4fd3cc1a370aeafdc8749a30 (diff)
parent5dbfd19ad5fcc2b779f40f80fa05c1bd28fd0b4e (diff)
downloadillumos-joyent-43840e901cacf50a9bb41148069e34ca307524e8.tar.gz
[illumos-gate merge]
commit 5dbfd19ad5fcc2b779f40f80fa05c1bd28fd0b4e 3713 Implement accept4() 3714 Implement pipe2() 3715 Implement dup3() 3716 Implement mkostemp() and mkostemps() 3719 so_socketpair syscall should preserve FD_CLOEXEC flag commit 6136c589445a3ea081bd34ab72db1060875b6bcc 3722 link-editor is over restrictive of R_AMD64_32 addends Conflicts: usr/src/lib/libc/sparcv9/Makefile.com [copyright] usr/src/lib/libc/sparc/Makefile.com [copyright] usr/src/lib/libc/i386/Makefile.com [copyright]
Diffstat (limited to 'usr/src/uts/common/syscall/pipe.c')
-rw-r--r--usr/src/uts/common/syscall/pipe.c74
1 files changed, 58 insertions, 16 deletions
diff --git a/usr/src/uts/common/syscall/pipe.c b/usr/src/uts/common/syscall/pipe.c
index a626b2364a..1b9ea4f6db 100644
--- a/usr/src/uts/common/syscall/pipe.c
+++ b/usr/src/uts/common/syscall/pipe.c
@@ -19,6 +19,7 @@
* CDDL HEADER END
*/
/*
+ * Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright (c) 2011 Bayard G. Bell. All rights reserved.
@@ -41,6 +42,7 @@
#include <sys/errno.h>
#include <sys/debug.h>
#include <sys/fs/fifonode.h>
+#include <sys/fcntl.h>
/*
* This is the loadable module wrapper.
@@ -48,11 +50,11 @@
#include <sys/modctl.h>
#include <sys/syscall.h>
-longlong_t pipe();
+int pipe(intptr_t fds, int);
static struct sysent pipe_sysent = {
- 0,
- SE_32RVAL1 | SE_32RVAL2 | SE_NOUNLOAD | SE_ARGC,
+ 2,
+ SE_ARGC | SE_32RVAL1 | SE_NOUNLOAD,
(int (*)())pipe
};
@@ -102,16 +104,22 @@ _info(struct modinfo *modinfop)
* each end of the pipe with a vnode, a file descriptor and
* one of the streams.
*/
-longlong_t
-pipe()
+int
+pipe(intptr_t arg, int flags)
{
vnode_t *vp1, *vp2;
struct file *fp1, *fp2;
int error = 0;
+ int flag1, flag2, iflags;
int fd1, fd2;
- rval_t r;
/*
+ * Validate allowed flags.
+ */
+ if (flags & ~(FCLOEXEC|FNONBLOCK) != 0) {
+ return (set_errno(EINVAL));
+ }
+ /*
* Allocate and initialize two vnodes.
*/
makepipe(&vp1, &vp2);
@@ -124,7 +132,7 @@ pipe()
if (error = falloc(vp1, FWRITE|FREAD, &fp1, &fd1)) {
VN_RELE(vp1);
VN_RELE(vp2);
- return ((longlong_t)set_errno(error));
+ return (set_errno(error));
}
if (error = falloc(vp2, FWRITE|FREAD, &fp2, &fd2))
@@ -147,6 +155,36 @@ pipe()
VTOF(vp1)->fn_ino = VTOF(vp2)->fn_ino = fifogetid();
/*
+ * Set the O_NONBLOCK flag if requested.
+ */
+ if (flags & FNONBLOCK) {
+ flag1 = fp1->f_flag;
+ flag2 = fp2->f_flag;
+ iflags = flags & FNONBLOCK;
+
+ if (error = VOP_SETFL(vp1, flag1, iflags, fp1->f_cred, NULL)) {
+ goto out_vop_close;
+ }
+ fp1->f_flag |= iflags;
+
+ if (error = VOP_SETFL(vp2, flag2, iflags, fp2->f_cred, NULL)) {
+ goto out_vop_close;
+ }
+ fp2->f_flag |= iflags;
+ }
+
+ /*
+ * Return the file descriptors to the user. They now
+ * point to two different vnodes which have different
+ * stream heads.
+ */
+ if (copyout(&fd1, &((int *)arg)[0], sizeof (int)) ||
+ copyout(&fd2, &((int *)arg)[1], sizeof (int))) {
+ error = EFAULT;
+ goto out_vop_close;
+ }
+
+ /*
* Now fill in the entries that falloc reserved
*/
mutex_exit(&fp1->f_tlock);
@@ -155,20 +193,24 @@ pipe()
setf(fd2, fp2);
/*
- * Return the file descriptors to the user. They now
- * point to two different vnodes which have different
- * stream heads.
+ * Optionally set the FCLOEXEC flag
*/
- r.r_val1 = fd1;
- r.r_val2 = fd2;
- return (r.r_vals);
+ if ((flags & FCLOEXEC) != 0) {
+ f_setfd(fd1, FD_CLOEXEC);
+ f_setfd(fd2, FD_CLOEXEC);
+ }
+
+ return (0);
+out_vop_close:
+ (void) VOP_CLOSE(vp1, FWRITE|FREAD, 1, (offset_t)0, fp1->f_cred, NULL);
+ (void) VOP_CLOSE(vp2, FWRITE|FREAD, 1, (offset_t)0, fp2->f_cred, NULL);
out:
- unfalloc(fp2);
setf(fd2, NULL);
+ unfalloc(fp2);
out2:
- unfalloc(fp1);
setf(fd1, NULL);
+ unfalloc(fp1);
VN_RELE(vp1);
VN_RELE(vp2);
- return ((longlong_t)set_errno(error));
+ return (set_errno(error));
}