This commit was generated by cvs2svn to track changes on a CVS vendor
[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 *
600f7f07 33 * from: @(#)fifo_vnops.c 7.7 (Berkeley) 4/15/91
4c45483e 34 * $Id: fifo_vnops.c,v 1.4 1993/10/16 15:24:02 rgrimes Exp $
15637ed4
RG
35 */
36
cfdfcf49 37#ifdef FIFO
15637ed4
RG
38#include "param.h"
39#include "time.h"
40#include "namei.h"
41#include "vnode.h"
42#include "socket.h"
43#include "socketvar.h"
44#include "stat.h"
45#include "systm.h"
46#include "ioctl.h"
47#include "file.h"
48#include "fifo.h"
49#include "errno.h"
50#include "malloc.h"
51
52/*
53 * This structure is associated with the FIFO vnode and stores
54 * the state associated with the FIFO.
55 */
56struct fifoinfo {
57 struct socket *fi_readsock;
58 struct socket *fi_writesock;
59 long fi_readers;
60 long fi_writers;
61};
62
63struct vnodeops fifo_vnodeops = {
64 fifo_lookup, /* lookup */
65 fifo_create, /* create */
66 fifo_mknod, /* mknod */
67 fifo_open, /* open */
68 fifo_close, /* close */
69 fifo_access, /* access */
70 fifo_getattr, /* getattr */
71 fifo_setattr, /* setattr */
72 fifo_read, /* read */
73 fifo_write, /* write */
74 fifo_ioctl, /* ioctl */
75 fifo_select, /* select */
76 fifo_mmap, /* mmap */
77 fifo_fsync, /* fsync */
78 fifo_seek, /* seek */
79 fifo_remove, /* remove */
80 fifo_link, /* link */
81 fifo_rename, /* rename */
82 fifo_mkdir, /* mkdir */
83 fifo_rmdir, /* rmdir */
84 fifo_symlink, /* symlink */
85 fifo_readdir, /* readdir */
86 fifo_readlink, /* readlink */
87 fifo_abortop, /* abortop */
88 fifo_inactive, /* inactive */
89 fifo_reclaim, /* reclaim */
90 fifo_lock, /* lock */
91 fifo_unlock, /* unlock */
92 fifo_bmap, /* bmap */
93 fifo_strategy, /* strategy */
94 fifo_print, /* print */
95 fifo_islocked, /* islocked */
96 fifo_advlock, /* advlock */
97};
98
99/*
100 * Trivial lookup routine that always fails.
101 */
102/* ARGSUSED */
4c45483e 103int
15637ed4
RG
104fifo_lookup(vp, ndp, p)
105 struct vnode *vp;
106 struct nameidata *ndp;
107 struct proc *p;
108{
109
110 ndp->ni_dvp = vp;
111 ndp->ni_vp = NULL;
112 return (ENOTDIR);
113}
114
115/*
116 * Open called to set up a new instance of a fifo or
117 * to find an active instance of a fifo.
118 */
119/* ARGSUSED */
4c45483e 120int
15637ed4
RG
121fifo_open(vp, mode, cred, p)
122 register struct vnode *vp;
123 int mode;
124 struct ucred *cred;
125 struct proc *p;
126{
127 register struct fifoinfo *fip;
128 struct socket *rso, *wso;
129 int error;
130 static char openstr[] = "fifo";
131
132 if ((mode & (FREAD|FWRITE)) == (FREAD|FWRITE))
133 return (EINVAL);
134 if ((fip = vp->v_fifoinfo) == NULL) {
135 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
136 vp->v_fifoinfo = fip;
137 fip->fi_readers = fip->fi_writers = 0;
138 if (error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0)) {
139 free(fip, M_VNODE);
140 vp->v_fifoinfo = NULL;
141 return (error);
142 }
143 fip->fi_readsock = rso;
144 if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0)) {
145 (void)soclose(rso);
146 free(fip, M_VNODE);
147 vp->v_fifoinfo = NULL;
148 return (error);
149 }
150 fip->fi_writesock = wso;
151 if (error = unp_connect2(wso, rso)) {
152 (void)soclose(wso);
153 (void)soclose(rso);
154 free(fip, M_VNODE);
155 vp->v_fifoinfo = NULL;
156 return (error);
157 }
158 wso->so_state |= SS_CANTRCVMORE;
159 rso->so_state |= SS_CANTSENDMORE;
160 }
161 error = 0;
162 if (mode & FREAD) {
163 fip->fi_readers++;
164 if (fip->fi_readers == 1) {
165 fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
166 if (fip->fi_writers > 0)
167 wakeup((caddr_t)&fip->fi_writers);
168 }
169 if (mode & O_NONBLOCK)
170 return (0);
171 while (fip->fi_writers == 0) {
172 VOP_UNLOCK(vp);
173 error = tsleep((caddr_t)&fip->fi_readers, PSOCK | PCATCH,
174 openstr, 0);
175 VOP_LOCK(vp);
176 if (error)
177 break;
178 }
179 } else {
180 fip->fi_writers++;
181 if (fip->fi_readers == 0 && (mode & O_NONBLOCK)) {
182 error = ENXIO;
183 } else {
184 if (fip->fi_writers == 1) {
185 fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
186 if (fip->fi_readers > 0)
187 wakeup((caddr_t)&fip->fi_readers);
188 }
189 while (fip->fi_readers == 0) {
190 VOP_UNLOCK(vp);
191 error = tsleep((caddr_t)&fip->fi_writers,
192 PSOCK | PCATCH, openstr, 0);
193 VOP_LOCK(vp);
194 if (error)
195 break;
196 }
197 }
198 }
199 if (error)
200 fifo_close(vp, mode, cred, p);
201 return (error);
202}
203
204/*
205 * Vnode op for read
206 */
207/* ARGSUSED */
4c45483e 208int
15637ed4
RG
209fifo_read(vp, uio, ioflag, cred)
210 struct vnode *vp;
211 register struct uio *uio;
212 int ioflag;
213 struct ucred *cred;
214{
215 register struct socket *rso = vp->v_fifoinfo->fi_readsock;
216 int error, startresid;
217
218#ifdef DIAGNOSTIC
219 if (uio->uio_rw != UIO_READ)
220 panic("fifo_read mode");
221#endif
222 if (uio->uio_resid == 0)
223 return (0);
224 if (ioflag & IO_NDELAY)
225 rso->so_state |= SS_NBIO;
226 startresid = uio->uio_resid;
227 VOP_UNLOCK(vp);
4c45483e
GW
228 error = soreceive(rso, (struct mbuf **)0, uio,
229 (struct mbuf **)0, (struct mbuf **)0, (int *)0);
15637ed4
RG
230 VOP_LOCK(vp);
231 /*
232 * Clear EOF indication after first such return.
233 */
234 if (uio->uio_resid == startresid)
235 rso->so_state &= ~SS_CANTRCVMORE;
236 if (ioflag & IO_NDELAY)
237 rso->so_state &= ~SS_NBIO;
238 return (error);
239}
240
241/*
242 * Vnode op for write
243 */
244/* ARGSUSED */
4c45483e 245int
15637ed4
RG
246fifo_write(vp, uio, ioflag, cred)
247 struct vnode *vp;
248 register struct uio *uio;
249 int ioflag;
250 struct ucred *cred;
251{
252 struct socket *wso = vp->v_fifoinfo->fi_writesock;
253 int error;
254
255#ifdef DIAGNOSTIC
256 if (uio->uio_rw != UIO_WRITE)
257 panic("fifo_write mode");
258#endif
259 if (ioflag & IO_NDELAY)
260 wso->so_state |= SS_NBIO;
261 VOP_UNLOCK(vp);
8604ac85 262 error = sosend(wso, (struct mbuf *)0, uio, 0, (struct mbuf *)0, 0);
15637ed4
RG
263 VOP_LOCK(vp);
264 if (ioflag & IO_NDELAY)
265 wso->so_state &= ~SS_NBIO;
266 return (error);
267}
268
269/*
270 * Device ioctl operation.
271 */
272/* ARGSUSED */
4c45483e 273int
15637ed4
RG
274fifo_ioctl(vp, com, data, fflag, cred, p)
275 struct vnode *vp;
276 int com;
277 caddr_t data;
278 int fflag;
279 struct ucred *cred;
280 struct proc *p;
281{
282 struct file filetmp;
283 int error;
284
285 if (com == FIONBIO)
286 return (0);
287 if (fflag & FREAD)
288 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
289 else
290 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
291 return (soo_ioctl(&filetmp, com, data, p));
292}
293
294/* ARGSUSED */
4c45483e 295int
15637ed4
RG
296fifo_select(vp, which, fflag, cred, p)
297 struct vnode *vp;
298 int which, fflag;
299 struct ucred *cred;
300 struct proc *p;
301{
302 struct file filetmp;
303 int error;
304
305 if (fflag & FREAD)
306 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
307 else
308 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
309 return (soo_select(&filetmp, which, p));
310}
311
312/*
313 * This is a noop, simply returning what one has been given.
314 */
4c45483e 315int
15637ed4
RG
316fifo_bmap(vp, bn, vpp, bnp)
317 struct vnode *vp;
318 daddr_t bn;
319 struct vnode **vpp;
320 daddr_t *bnp;
321{
322
323 if (vpp != NULL)
324 *vpp = vp;
325 if (bnp != NULL)
326 *bnp = bn;
327 return (0);
328}
329
330/*
331 * At the moment we do not do any locking.
332 */
333/* ARGSUSED */
4c45483e 334int
15637ed4
RG
335fifo_lock(vp)
336 struct vnode *vp;
337{
338
339 return (0);
340}
341
342/* ARGSUSED */
4c45483e 343int
15637ed4
RG
344fifo_unlock(vp)
345 struct vnode *vp;
346{
347
348 return (0);
349}
350
351/*
352 * Device close routine
353 */
354/* ARGSUSED */
4c45483e 355int
15637ed4
RG
356fifo_close(vp, fflag, cred, p)
357 register struct vnode *vp;
358 int fflag;
359 struct ucred *cred;
360 struct proc *p;
361{
362 register struct fifoinfo *fip = vp->v_fifoinfo;
363 int error1, error2;
364
365 if (fflag & FWRITE) {
366 fip->fi_writers--;
367 if (fip->fi_writers == 0)
368 socantrcvmore(fip->fi_readsock);
369 } else {
370 fip->fi_readers--;
371 if (fip->fi_readers == 0)
372 socantsendmore(fip->fi_writesock);
373 }
374 if (vp->v_usecount > 1)
375 return (0);
376 error1 = soclose(fip->fi_readsock);
377 error2 = soclose(fip->fi_writesock);
378 FREE(fip, M_VNODE);
379 vp->v_fifoinfo = NULL;
380 if (error1)
381 return (error1);
382 return (error2);
383}
384
385/*
386 * Print out the contents of a fifo vnode.
387 */
4c45483e 388void
15637ed4
RG
389fifo_print(vp)
390 struct vnode *vp;
391{
392
393 printf("tag VT_NON");
394 fifo_printinfo(vp);
395 printf("\n");
396}
397
398/*
399 * Print out internal contents of a fifo vnode.
400 */
4c45483e 401void
15637ed4
RG
402fifo_printinfo(vp)
403 struct vnode *vp;
404{
405 register struct fifoinfo *fip = vp->v_fifoinfo;
406
407 printf(", fifo with %d readers and %d writers",
408 fip->fi_readers, fip->fi_writers);
409}
410
411/*
412 * Fifo failed operation
413 */
4c45483e 414int
15637ed4
RG
415fifo_ebadf()
416{
417
418 return (EBADF);
419}
420
421/*
422 * Fifo advisory byte-level locks.
423 */
424/* ARGSUSED */
4c45483e 425int
15637ed4
RG
426fifo_advlock(vp, id, op, fl, flags)
427 struct vnode *vp;
428 caddr_t id;
429 int op;
430 struct flock *fl;
431 int flags;
432{
433
434 return (EOPNOTSUPP);
435}
436
437/*
438 * Fifo bad operation
439 */
4c45483e 440int
15637ed4
RG
441fifo_badop()
442{
443
444 panic("fifo_badop called");
445 /* NOTREACHED */
446}
cfdfcf49 447#endif /*FIFO*/