This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.0'.
[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 *
78ed81a3 33 * from: @(#)fifo_vnops.c 7.7 (Berkeley) 4/15/91
34 * $Id$
15637ed4
RG
35 */
36
78ed81a3 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 */
103fifo_lookup(vp, ndp, p)
104 struct vnode *vp;
105 struct nameidata *ndp;
106 struct proc *p;
107{
108
109 ndp->ni_dvp = vp;
110 ndp->ni_vp = NULL;
111 return (ENOTDIR);
112}
113
114/*
115 * Open called to set up a new instance of a fifo or
116 * to find an active instance of a fifo.
117 */
118/* ARGSUSED */
119fifo_open(vp, mode, cred, p)
120 register struct vnode *vp;
121 int mode;
122 struct ucred *cred;
123 struct proc *p;
124{
125 register struct fifoinfo *fip;
126 struct socket *rso, *wso;
127 int error;
128 static char openstr[] = "fifo";
129
130 if ((mode & (FREAD|FWRITE)) == (FREAD|FWRITE))
131 return (EINVAL);
132 if ((fip = vp->v_fifoinfo) == NULL) {
133 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
134 vp->v_fifoinfo = fip;
135 fip->fi_readers = fip->fi_writers = 0;
136 if (error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0)) {
137 free(fip, M_VNODE);
138 vp->v_fifoinfo = NULL;
139 return (error);
140 }
141 fip->fi_readsock = rso;
142 if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0)) {
143 (void)soclose(rso);
144 free(fip, M_VNODE);
145 vp->v_fifoinfo = NULL;
146 return (error);
147 }
148 fip->fi_writesock = wso;
149 if (error = unp_connect2(wso, rso)) {
150 (void)soclose(wso);
151 (void)soclose(rso);
152 free(fip, M_VNODE);
153 vp->v_fifoinfo = NULL;
154 return (error);
155 }
156 wso->so_state |= SS_CANTRCVMORE;
157 rso->so_state |= SS_CANTSENDMORE;
158 }
159 error = 0;
160 if (mode & FREAD) {
161 fip->fi_readers++;
162 if (fip->fi_readers == 1) {
163 fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
164 if (fip->fi_writers > 0)
165 wakeup((caddr_t)&fip->fi_writers);
166 }
167 if (mode & O_NONBLOCK)
168 return (0);
169 while (fip->fi_writers == 0) {
170 VOP_UNLOCK(vp);
171 error = tsleep((caddr_t)&fip->fi_readers, PSOCK | PCATCH,
172 openstr, 0);
173 VOP_LOCK(vp);
174 if (error)
175 break;
176 }
177 } else {
178 fip->fi_writers++;
179 if (fip->fi_readers == 0 && (mode & O_NONBLOCK)) {
180 error = ENXIO;
181 } else {
182 if (fip->fi_writers == 1) {
183 fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
184 if (fip->fi_readers > 0)
185 wakeup((caddr_t)&fip->fi_readers);
186 }
187 while (fip->fi_readers == 0) {
188 VOP_UNLOCK(vp);
189 error = tsleep((caddr_t)&fip->fi_writers,
190 PSOCK | PCATCH, openstr, 0);
191 VOP_LOCK(vp);
192 if (error)
193 break;
194 }
195 }
196 }
197 if (error)
198 fifo_close(vp, mode, cred, p);
199 return (error);
200}
201
202/*
203 * Vnode op for read
204 */
205/* ARGSUSED */
206fifo_read(vp, uio, ioflag, cred)
207 struct vnode *vp;
208 register struct uio *uio;
209 int ioflag;
210 struct ucred *cred;
211{
212 register struct socket *rso = vp->v_fifoinfo->fi_readsock;
213 int error, startresid;
214
215#ifdef DIAGNOSTIC
216 if (uio->uio_rw != UIO_READ)
217 panic("fifo_read mode");
218#endif
219 if (uio->uio_resid == 0)
220 return (0);
221 if (ioflag & IO_NDELAY)
222 rso->so_state |= SS_NBIO;
223 startresid = uio->uio_resid;
224 VOP_UNLOCK(vp);
225 error = soreceive(rso, (struct mbuf **)0, uio, (int *)0,
226 (struct mbuf **)0, (struct mbuf **)0);
227 VOP_LOCK(vp);
228 /*
229 * Clear EOF indication after first such return.
230 */
231 if (uio->uio_resid == startresid)
232 rso->so_state &= ~SS_CANTRCVMORE;
233 if (ioflag & IO_NDELAY)
234 rso->so_state &= ~SS_NBIO;
235 return (error);
236}
237
238/*
239 * Vnode op for write
240 */
241/* ARGSUSED */
242fifo_write(vp, uio, ioflag, cred)
243 struct vnode *vp;
244 register struct uio *uio;
245 int ioflag;
246 struct ucred *cred;
247{
248 struct socket *wso = vp->v_fifoinfo->fi_writesock;
249 int error;
250
251#ifdef DIAGNOSTIC
252 if (uio->uio_rw != UIO_WRITE)
253 panic("fifo_write mode");
254#endif
255 if (ioflag & IO_NDELAY)
256 wso->so_state |= SS_NBIO;
257 VOP_UNLOCK(vp);
78ed81a3 258 error = sosend(wso, (struct mbuf *)0, uio, 0, (struct mbuf *)0, 0);
15637ed4
RG
259 VOP_LOCK(vp);
260 if (ioflag & IO_NDELAY)
261 wso->so_state &= ~SS_NBIO;
262 return (error);
263}
264
265/*
266 * Device ioctl operation.
267 */
268/* ARGSUSED */
269fifo_ioctl(vp, com, data, fflag, cred, p)
270 struct vnode *vp;
271 int com;
272 caddr_t data;
273 int fflag;
274 struct ucred *cred;
275 struct proc *p;
276{
277 struct file filetmp;
278 int error;
279
280 if (com == FIONBIO)
281 return (0);
282 if (fflag & FREAD)
283 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
284 else
285 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
286 return (soo_ioctl(&filetmp, com, data, p));
287}
288
289/* ARGSUSED */
290fifo_select(vp, which, fflag, cred, p)
291 struct vnode *vp;
292 int which, fflag;
293 struct ucred *cred;
294 struct proc *p;
295{
296 struct file filetmp;
297 int error;
298
299 if (fflag & FREAD)
300 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_readsock;
301 else
302 filetmp.f_data = (caddr_t)vp->v_fifoinfo->fi_writesock;
303 return (soo_select(&filetmp, which, p));
304}
305
306/*
307 * This is a noop, simply returning what one has been given.
308 */
309fifo_bmap(vp, bn, vpp, bnp)
310 struct vnode *vp;
311 daddr_t bn;
312 struct vnode **vpp;
313 daddr_t *bnp;
314{
315
316 if (vpp != NULL)
317 *vpp = vp;
318 if (bnp != NULL)
319 *bnp = bn;
320 return (0);
321}
322
323/*
324 * At the moment we do not do any locking.
325 */
326/* ARGSUSED */
327fifo_lock(vp)
328 struct vnode *vp;
329{
330
331 return (0);
332}
333
334/* ARGSUSED */
335fifo_unlock(vp)
336 struct vnode *vp;
337{
338
339 return (0);
340}
341
342/*
343 * Device close routine
344 */
345/* ARGSUSED */
346fifo_close(vp, fflag, cred, p)
347 register struct vnode *vp;
348 int fflag;
349 struct ucred *cred;
350 struct proc *p;
351{
352 register struct fifoinfo *fip = vp->v_fifoinfo;
353 int error1, error2;
354
355 if (fflag & FWRITE) {
356 fip->fi_writers--;
357 if (fip->fi_writers == 0)
358 socantrcvmore(fip->fi_readsock);
359 } else {
360 fip->fi_readers--;
361 if (fip->fi_readers == 0)
362 socantsendmore(fip->fi_writesock);
363 }
364 if (vp->v_usecount > 1)
365 return (0);
366 error1 = soclose(fip->fi_readsock);
367 error2 = soclose(fip->fi_writesock);
368 FREE(fip, M_VNODE);
369 vp->v_fifoinfo = NULL;
370 if (error1)
371 return (error1);
372 return (error2);
373}
374
375/*
376 * Print out the contents of a fifo vnode.
377 */
378fifo_print(vp)
379 struct vnode *vp;
380{
381
382 printf("tag VT_NON");
383 fifo_printinfo(vp);
384 printf("\n");
385}
386
387/*
388 * Print out internal contents of a fifo vnode.
389 */
390fifo_printinfo(vp)
391 struct vnode *vp;
392{
393 register struct fifoinfo *fip = vp->v_fifoinfo;
394
395 printf(", fifo with %d readers and %d writers",
396 fip->fi_readers, fip->fi_writers);
397}
398
399/*
400 * Fifo failed operation
401 */
402fifo_ebadf()
403{
404
405 return (EBADF);
406}
407
408/*
409 * Fifo advisory byte-level locks.
410 */
411/* ARGSUSED */
412fifo_advlock(vp, id, op, fl, flags)
413 struct vnode *vp;
414 caddr_t id;
415 int op;
416 struct flock *fl;
417 int flags;
418{
419
420 return (EOPNOTSUPP);
421}
422
423/*
424 * Fifo bad operation
425 */
426fifo_badop()
427{
428
429 panic("fifo_badop called");
430 /* NOTREACHED */
431}
78ed81a3 432#endif /*FIFO*/