diff options
author | Keith M Wesolowski <wesolows@foobazco.org> | 2013-05-08 18:18:49 +0000 |
---|---|---|
committer | Keith M Wesolowski <wesolows@foobazco.org> | 2013-05-08 18:18:49 +0000 |
commit | 43840e901cacf50a9bb41148069e34ca307524e8 (patch) | |
tree | 2836162f69bba2534e8b9acf9797e5892f103258 /usr/src/uts/common/syscall/pipe.c | |
parent | abd43b3991c3becf4fd3cc1a370aeafdc8749a30 (diff) | |
parent | 5dbfd19ad5fcc2b779f40f80fa05c1bd28fd0b4e (diff) | |
download | illumos-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.c | 74 |
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)); } |