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