Mercurial > illumos > illumos-gate
comparison usr/src/uts/common/syscall/pipe.c @ 14022:19e11862653b
3713 Implement accept4()
3714 Implement pipe2()
3715 Implement dup3()
3716 Implement mkostemp() and mkostemps()
3719 so_socketpair syscall should preserve FD_CLOEXEC flag
Reviewed by: Dan McDonald <danmcd@nexenta.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Approved by: Garrett D'Amore <garrett@damore.org>
author | Theo Schlossnagle <jesus@omniti.com> |
---|---|
date | Thu, 11 Apr 2013 04:50:36 +0000 |
parents | 6bec9720e054 |
children | c50199ce44c8 |
comparison
equal
deleted
inserted
replaced
14021:1faa5bdf272f | 14022:19e11862653b |
---|---|
17 * information: Portions Copyright [yyyy] [name of copyright owner] | 17 * information: Portions Copyright [yyyy] [name of copyright owner] |
18 * | 18 * |
19 * CDDL HEADER END | 19 * CDDL HEADER END |
20 */ | 20 */ |
21 /* | 21 /* |
22 * Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved. | |
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. |
23 * Use is subject to license terms. | 24 * Use is subject to license terms. |
24 * Copyright (c) 2011 Bayard G. Bell. All rights reserved. | 25 * Copyright (c) 2011 Bayard G. Bell. All rights reserved. |
25 */ | 26 */ |
26 | 27 |
39 #include <sys/stream.h> | 40 #include <sys/stream.h> |
40 #include <sys/strsubr.h> | 41 #include <sys/strsubr.h> |
41 #include <sys/errno.h> | 42 #include <sys/errno.h> |
42 #include <sys/debug.h> | 43 #include <sys/debug.h> |
43 #include <sys/fs/fifonode.h> | 44 #include <sys/fs/fifonode.h> |
45 #include <sys/fcntl.h> | |
44 | 46 |
45 /* | 47 /* |
46 * This is the loadable module wrapper. | 48 * This is the loadable module wrapper. |
47 */ | 49 */ |
48 #include <sys/modctl.h> | 50 #include <sys/modctl.h> |
49 #include <sys/syscall.h> | 51 #include <sys/syscall.h> |
50 | 52 |
51 longlong_t pipe(); | 53 int pipe(intptr_t fds, int); |
52 | 54 |
53 static struct sysent pipe_sysent = { | 55 static struct sysent pipe_sysent = { |
54 0, | 56 2, |
55 SE_32RVAL1 | SE_32RVAL2 | SE_NOUNLOAD | SE_ARGC, | 57 SE_ARGC | SE_32RVAL1 | SE_NOUNLOAD, |
56 (int (*)())pipe | 58 (int (*)())pipe |
57 }; | 59 }; |
58 | 60 |
59 /* | 61 /* |
60 * Module linkage information for the kernel. | 62 * Module linkage information for the kernel. |
100 * pipe(2) system call. | 102 * pipe(2) system call. |
101 * Create a pipe by connecting two streams together. Associate | 103 * Create a pipe by connecting two streams together. Associate |
102 * each end of the pipe with a vnode, a file descriptor and | 104 * each end of the pipe with a vnode, a file descriptor and |
103 * one of the streams. | 105 * one of the streams. |
104 */ | 106 */ |
105 longlong_t | 107 int |
106 pipe() | 108 pipe(intptr_t arg, int flags) |
107 { | 109 { |
108 vnode_t *vp1, *vp2; | 110 vnode_t *vp1, *vp2; |
109 struct file *fp1, *fp2; | 111 struct file *fp1, *fp2; |
110 int error = 0; | 112 int error = 0; |
113 int flag1, flag2, iflags; | |
111 int fd1, fd2; | 114 int fd1, fd2; |
112 rval_t r; | 115 |
113 | 116 /* |
117 * Validate allowed flags. | |
118 */ | |
119 if (flags & ~(FCLOEXEC|FNONBLOCK) != 0) { | |
120 return (set_errno(EINVAL)); | |
121 } | |
114 /* | 122 /* |
115 * Allocate and initialize two vnodes. | 123 * Allocate and initialize two vnodes. |
116 */ | 124 */ |
117 makepipe(&vp1, &vp2); | 125 makepipe(&vp1, &vp2); |
118 | 126 |
122 * write. | 130 * write. |
123 */ | 131 */ |
124 if (error = falloc(vp1, FWRITE|FREAD, &fp1, &fd1)) { | 132 if (error = falloc(vp1, FWRITE|FREAD, &fp1, &fd1)) { |
125 VN_RELE(vp1); | 133 VN_RELE(vp1); |
126 VN_RELE(vp2); | 134 VN_RELE(vp2); |
127 return ((longlong_t)set_errno(error)); | 135 return (set_errno(error)); |
128 } | 136 } |
129 | 137 |
130 if (error = falloc(vp2, FWRITE|FREAD, &fp2, &fd2)) | 138 if (error = falloc(vp2, FWRITE|FREAD, &fp2, &fd2)) |
131 goto out2; | 139 goto out2; |
132 | 140 |
145 strmate(vp1, vp2); | 153 strmate(vp1, vp2); |
146 | 154 |
147 VTOF(vp1)->fn_ino = VTOF(vp2)->fn_ino = fifogetid(); | 155 VTOF(vp1)->fn_ino = VTOF(vp2)->fn_ino = fifogetid(); |
148 | 156 |
149 /* | 157 /* |
158 * Set the O_NONBLOCK flag if requested. | |
159 */ | |
160 if (flags & FNONBLOCK) { | |
161 flag1 = fp1->f_flag; | |
162 flag2 = fp2->f_flag; | |
163 iflags = flags & FNONBLOCK; | |
164 | |
165 if (error = VOP_SETFL(vp1, flag1, iflags, fp1->f_cred, NULL)) { | |
166 goto out_vop_close; | |
167 } | |
168 fp1->f_flag |= iflags; | |
169 | |
170 if (error = VOP_SETFL(vp2, flag2, iflags, fp2->f_cred, NULL)) { | |
171 goto out_vop_close; | |
172 } | |
173 fp2->f_flag |= iflags; | |
174 } | |
175 | |
176 /* | |
177 * Return the file descriptors to the user. They now | |
178 * point to two different vnodes which have different | |
179 * stream heads. | |
180 */ | |
181 if (copyout(&fd1, &((int *)arg)[0], sizeof (int)) || | |
182 copyout(&fd2, &((int *)arg)[1], sizeof (int))) { | |
183 error = EFAULT; | |
184 goto out_vop_close; | |
185 } | |
186 | |
187 /* | |
150 * Now fill in the entries that falloc reserved | 188 * Now fill in the entries that falloc reserved |
151 */ | 189 */ |
152 mutex_exit(&fp1->f_tlock); | 190 mutex_exit(&fp1->f_tlock); |
153 mutex_exit(&fp2->f_tlock); | 191 mutex_exit(&fp2->f_tlock); |
154 setf(fd1, fp1); | 192 setf(fd1, fp1); |
155 setf(fd2, fp2); | 193 setf(fd2, fp2); |
156 | 194 |
157 /* | 195 /* |
158 * Return the file descriptors to the user. They now | 196 * Optionally set the FCLOEXEC flag |
159 * point to two different vnodes which have different | 197 */ |
160 * stream heads. | 198 if ((flags & FCLOEXEC) != 0) { |
161 */ | 199 f_setfd(fd1, FD_CLOEXEC); |
162 r.r_val1 = fd1; | 200 f_setfd(fd2, FD_CLOEXEC); |
163 r.r_val2 = fd2; | 201 } |
164 return (r.r_vals); | 202 |
203 return (0); | |
204 out_vop_close: | |
205 (void) VOP_CLOSE(vp1, FWRITE|FREAD, 1, (offset_t)0, fp1->f_cred, NULL); | |
206 (void) VOP_CLOSE(vp2, FWRITE|FREAD, 1, (offset_t)0, fp2->f_cred, NULL); | |
165 out: | 207 out: |
208 setf(fd2, NULL); | |
166 unfalloc(fp2); | 209 unfalloc(fp2); |
167 setf(fd2, NULL); | |
168 out2: | 210 out2: |
211 setf(fd1, NULL); | |
169 unfalloc(fp1); | 212 unfalloc(fp1); |
170 setf(fd1, NULL); | |
171 VN_RELE(vp1); | 213 VN_RELE(vp1); |
172 VN_RELE(vp2); | 214 VN_RELE(vp2); |
173 return ((longlong_t)set_errno(error)); | 215 return (set_errno(error)); |
174 } | 216 } |