Missing header file from Net/2 tape.
[unix-history] / sys / kern / fifo_vnops.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)fifo_vnops.c 7.7 (Berkeley) 4/15/91
34 *
35 * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
36 * -------------------- ----- ----------------------
37 * CURRENT PATCH LEVEL: 1 00141
38 * -------------------- ----- ----------------------
39 *
40 * 20 Apr 93 Jay Fenlason 1. fi_{readers|fi_writers} of fifoinfo init to 0
41 * 2. fifo_open() was calling tsleep() without
42 * unlocking the inode of the fifo
43 */
44
cfdfcf49 45#ifdef FIFO
15637ed4
RG
46#include "param.h"
47#include "time.h"
48#include "namei.h"
49#include "vnode.h"
50#include "socket.h"
51#include "socketvar.h"
52#include "stat.h"
53#include "systm.h"
54#include "ioctl.h"
55#include "file.h"
56#include "fifo.h"
57#include "errno.h"
58#include "malloc.h"
59
60/*
61 * This structure is associated with the FIFO vnode and stores
62 * the state associated with the FIFO.
63 */
64struct fifoinfo {
65 struct socket *fi_readsock;
66 struct socket *fi_writesock;
67 long fi_readers;
68 long fi_writers;
69};
70
71struct vnodeops fifo_vnodeops = {
72 fifo_lookup, /* lookup */
73 fifo_create, /* create */
74 fifo_mknod, /* mknod */
75 fifo_open, /* open */
76 fifo_close, /* close */
77 fifo_access, /* access */
78 fifo_getattr, /* getattr */
79 fifo_setattr, /* setattr */
80 fifo_read, /* read */
81 fifo_write, /* write */
82 fifo_ioctl, /* ioctl */
83 fifo_select, /* select */
84 fifo_mmap, /* mmap */
85 fifo_fsync, /* fsync */
86 fifo_seek, /* seek */
87 fifo_remove, /* remove */
88 fifo_link, /* link */
89 fifo_rename, /* rename */
90 fifo_mkdir, /* mkdir */
91 fifo_rmdir, /* rmdir */
92 fifo_symlink, /* symlink */
93 fifo_readdir, /* readdir */
94 fifo_readlink, /* readlink */
95 fifo_abortop, /* abortop */
96 fifo_inactive, /* inactive */
97 fifo_reclaim, /* reclaim */
98 fifo_lock, /* lock */
99 fifo_unlock, /* unlock */
100 fifo_bmap, /* bmap */
101 fifo_strategy, /* strategy */
102 fifo_print, /* print */
103 fifo_islocked, /* islocked */
104 fifo_advlock, /* advlock */
105};
106
107/*
108 * Trivial lookup routine that always fails.
109 */
110/* ARGSUSED */
111fifo_lookup(vp, ndp, p)
112 struct vnode *vp;
113 struct nameidata *ndp;
114 struct proc *p;
115{
116
117 ndp->ni_dvp = vp;
118 ndp->ni_vp = NULL;
119 return (ENOTDIR);
120}
121
122/*
123 * Open called to set up a new instance of a fifo or
124 * to find an active instance of a fifo.
125 */
126/* ARGSUSED */
127fifo_open(vp, mode, cred, p)
128 register struct vnode *vp;
129 int mode;
130 struct ucred *cred;
131 struct proc *p;
132{
133 register struct fifoinfo *fip;
134 struct socket *rso, *wso;
135 int error;
136 static char openstr[] = "fifo";
137
138 if ((mode & (FREAD|FWRITE)) == (FREAD|FWRITE))
139 return (EINVAL);
140 if ((fip = vp->v_fifoinfo) == NULL) {
141 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
142 vp->v_fifoinfo = fip;
143 fip->fi_readers = fip->fi_writers = 0;
144 if (error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0)) {
145 free(fip, M_VNODE);
146 vp->v_fifoinfo = NULL;
147 return (error);
148 }
149 fip->fi_readsock = rso;
150 if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0)) {
151 (void)soclose(rso);
152 free(fip, M_VNODE);
153 vp->v_fifoinfo = NULL;
154 return (error);
155 }
156 fip->fi_writesock = wso;
157 if (error = unp_connect2(wso, rso)) {
158 (void)soclose(wso);
159 (void)soclose(rso);
160 free(fip, M_VNODE);
161 vp->v_fifoinfo = NULL;
162 return (error);
163 }
164 wso->so_state |= SS_CANTRCVMORE;
165 rso->so_state |= SS_CANTSENDMORE;
166 }
167 error = 0;
168 if (mode & FREAD) {
169 fip->fi_readers++;
170 if (fip->fi_readers == 1) {
171 fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
172 if (fip->fi_writers > 0)
173 wakeup((caddr_t)&fip->fi_writers);
174 }
175 if (mode & O_NONBLOCK)
176 return (0);
177 while (fip->fi_writers == 0) {
178 VOP_UNLOCK(vp);
179 error = tsleep((caddr_t)&fip->fi_readers, PSOCK | PCATCH,
180 openstr, 0);
181 VOP_LOCK(vp);
182 if (error)
183 break;
184 }
185 } else {
186 fip->fi_writers++;
187 if (fip->fi_readers == 0 && (mode & O_NONBLOCK)) {
188 error = ENXIO;
189 } else {
190 if (fip->fi_writers == 1) {
191 fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
192 if (fip->fi_readers > 0)
193 wakeup((caddr_t)&fip->fi_readers);
194 }
195 while (fip->fi_readers == 0) {
196 VOP_UNLOCK(vp);
197 error = tsleep((caddr_t)&fip->fi_writers,
198 PSOCK | PCATCH, openstr, 0);
199 VOP_LOCK(vp);
200 if (error)
201 break;
202 }
203 }
204 }
205 if (error)
206 fifo_close(vp, mode, cred, p);
207 return (error);
208}
209
210/*
211 * Vnode op for read
212 */
213/* ARGSUSED */
214fifo_read(vp, uio, ioflag, cred)
215 struct vnode *vp;
216 register struct uio *uio;
217 int ioflag;
218 struct ucred *cred;
219{
220 register struct socket *rso = vp->v_fifoinfo->fi_readsock;
221 int error, startresid;
222
223#ifdef DIAGNOSTIC
224 if (uio->uio_rw != UIO_READ)
225 panic("fifo_read mode");
226#endif
227 if (uio->uio_resid == 0)
228 return (0);
229 if (ioflag & IO_NDELAY)
230 rso->so_state |= SS_NBIO;
231 startresid = uio->uio_resid;
232 VOP_UNLOCK(vp);
233 error = soreceive(rso, (struct mbuf **)0, uio, (int *)0,
234 (struct mbuf **)0, (struct mbuf **)0);
235 VOP_LOCK(vp);
236 /*
237 * Clear EOF indication after first such return.
238 */
239 if (uio->uio_resid == startresid)
240 rso->so_state &= ~SS_CANTRCVMORE;
241 if (ioflag & IO_NDELAY)
242 rso->so_state &= ~SS_NBIO;
243 return (error);
244}
245
246/*
247 * Vnode op for write
248 */
249/* ARGSUSED */
250fifo_write(vp, uio, ioflag, cred)
251 struct vnode *vp;
252 register struct uio *uio;
253 int ioflag;
254 struct ucred *cred;
255{
256 struct socket *wso = vp->v_fifoinfo->fi_writesock;
257 int error;
258
259#ifdef DIAGNOSTIC
260 if (uio->uio_rw != UIO_WRITE)
261 panic("fifo_write mode");
262#endif
263 if (ioflag & IO_NDELAY)
264 wso->so_state |= SS_NBIO;
265 VOP_UNLOCK(vp);
8604ac85 266 error = sosend(wso, (struct mbuf *)0, uio, 0, (struct mbuf *)0, 0);
15637ed4
RG
267 VOP_LOCK(vp);
268 if (ioflag & IO_NDELAY)
269 wso->so_state &= ~SS_NBIO;
270 return (error);
271}
272
273/*
274 * Device ioctl operation.
275 */
276/* ARGSUSED */
277fifo_ioctl(vp, com, data, fflag, cred, p)
278 struct vnode *vp;
279 int com;
280 caddr_t data;
281 int fflag;
282 struct ucred *cred;
283 struct proc *p;
284{
285 struct file filetmp;
286 int error;
287
288 if (com == FIONBIO)
289 return (0);
290 if (fflag & FREAD)
291 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
292 else
293 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
294 return (soo_ioctl(&filetmp, com, data, p));
295}
296
297/* ARGSUSED */
298fifo_select(vp, which, fflag, cred, p)
299 struct vnode *vp;
300 int which, fflag;
301 struct ucred *cred;
302 struct proc *p;
303{
304 struct file filetmp;
305 int error;
306
307 if (fflag & FREAD)
308 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
309 else
310 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
311 return (soo_select(&filetmp, which, p));
312}
313
314/*
315 * This is a noop, simply returning what one has been given.
316 */
317fifo_bmap(vp, bn, vpp, bnp)
318 struct vnode *vp;
319 daddr_t bn;
320 struct vnode **vpp;
321 daddr_t *bnp;
322{
323
324 if (vpp != NULL)
325 *vpp = vp;
326 if (bnp != NULL)
327 *bnp = bn;
328 return (0);
329}
330
331/*
332 * At the moment we do not do any locking.
333 */
334/* ARGSUSED */
335fifo_lock(vp)
336 struct vnode *vp;
337{
338
339 return (0);
340}
341
342/* ARGSUSED */
343fifo_unlock(vp)
344 struct vnode *vp;
345{
346
347 return (0);
348}
349
350/*
351 * Device close routine
352 */
353/* ARGSUSED */
354fifo_close(vp, fflag, cred, p)
355 register struct vnode *vp;
356 int fflag;
357 struct ucred *cred;
358 struct proc *p;
359{
360 register struct fifoinfo *fip = vp->v_fifoinfo;
361 int error1, error2;
362
363 if (fflag & FWRITE) {
364 fip->fi_writers--;
365 if (fip->fi_writers == 0)
366 socantrcvmore(fip->fi_readsock);
367 } else {
368 fip->fi_readers--;
369 if (fip->fi_readers == 0)
370 socantsendmore(fip->fi_writesock);
371 }
372 if (vp->v_usecount > 1)
373 return (0);
374 error1 = soclose(fip->fi_readsock);
375 error2 = soclose(fip->fi_writesock);
376 FREE(fip, M_VNODE);
377 vp->v_fifoinfo = NULL;
378 if (error1)
379 return (error1);
380 return (error2);
381}
382
383/*
384 * Print out the contents of a fifo vnode.
385 */
386fifo_print(vp)
387 struct vnode *vp;
388{
389
390 printf("tag VT_NON");
391 fifo_printinfo(vp);
392 printf("\n");
393}
394
395/*
396 * Print out internal contents of a fifo vnode.
397 */
398fifo_printinfo(vp)
399 struct vnode *vp;
400{
401 register struct fifoinfo *fip = vp->v_fifoinfo;
402
403 printf(", fifo with %d readers and %d writers",
404 fip->fi_readers, fip->fi_writers);
405}
406
407/*
408 * Fifo failed operation
409 */
410fifo_ebadf()
411{
412
413 return (EBADF);
414}
415
416/*
417 * Fifo advisory byte-level locks.
418 */
419/* ARGSUSED */
420fifo_advlock(vp, id, op, fl, flags)
421 struct vnode *vp;
422 caddr_t id;
423 int op;
424 struct flock *fl;
425 int flags;
426{
427
428 return (EOPNOTSUPP);
429}
430
431/*
432 * Fifo bad operation
433 */
434fifo_badop()
435{
436
437 panic("fifo_badop called");
438 /* NOTREACHED */
439}
cfdfcf49 440#endif /*FIFO*/