123386Smckusick /* 2*29106Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323386Smckusick * All rights reserved. The Berkeley software License Agreement 423386Smckusick * specifies the terms and conditions for redistribution. 523386Smckusick * 6*29106Smckusick * @(#)sys_socket.c 7.1 (Berkeley) 06/05/86 723386Smckusick */ 812794Ssam 917095Sbloom #include "param.h" 1017095Sbloom #include "systm.h" 1117095Sbloom #include "dir.h" 1217095Sbloom #include "user.h" 1317095Sbloom #include "file.h" 1417095Sbloom #include "mbuf.h" 1517095Sbloom #include "protosw.h" 1617095Sbloom #include "socket.h" 1717095Sbloom #include "socketvar.h" 1817095Sbloom #include "ioctl.h" 1917095Sbloom #include "uio.h" 2017095Sbloom #include "stat.h" 2112794Ssam 2212794Ssam #include "../net/if.h" 2312794Ssam #include "../net/route.h" 2412794Ssam 2513045Ssam int soo_rw(), soo_ioctl(), soo_select(), soo_close(); 2612794Ssam struct fileops socketops = 2713045Ssam { soo_rw, soo_ioctl, soo_select, soo_close }; 2812794Ssam 2912794Ssam soo_rw(fp, rw, uio) 3012794Ssam struct file *fp; 3112794Ssam enum uio_rw rw; 3212794Ssam struct uio *uio; 3312794Ssam { 3412794Ssam int soreceive(), sosend(); 3512794Ssam 3612794Ssam return ( 3712794Ssam (*(rw==UIO_READ?soreceive:sosend)) 3812794Ssam ((struct socket *)fp->f_data, 0, uio, 0, 0)); 3912794Ssam } 4012794Ssam 4112794Ssam soo_ioctl(fp, cmd, data) 4212794Ssam struct file *fp; 4312794Ssam int cmd; 4412794Ssam register caddr_t data; 4512794Ssam { 4612794Ssam register struct socket *so = (struct socket *)fp->f_data; 4712794Ssam 4812794Ssam switch (cmd) { 4912794Ssam 5012794Ssam case FIONBIO: 5112794Ssam if (*(int *)data) 5212794Ssam so->so_state |= SS_NBIO; 5312794Ssam else 5412794Ssam so->so_state &= ~SS_NBIO; 5513050Ssam return (0); 5612794Ssam 5712794Ssam case FIOASYNC: 5812794Ssam if (*(int *)data) 5912794Ssam so->so_state |= SS_ASYNC; 6012794Ssam else 6112794Ssam so->so_state &= ~SS_ASYNC; 6213050Ssam return (0); 6312794Ssam 6413001Ssam case FIONREAD: 6513001Ssam *(int *)data = so->so_rcv.sb_cc; 6613050Ssam return (0); 6713001Ssam 6812794Ssam case SIOCSPGRP: 6912794Ssam so->so_pgrp = *(int *)data; 7013050Ssam return (0); 7112794Ssam 7212794Ssam case SIOCGPGRP: 7312794Ssam *(int *)data = so->so_pgrp; 7413050Ssam return (0); 7512794Ssam 7612794Ssam case SIOCATMARK: 7712794Ssam *(int *)data = (so->so_state&SS_RCVATMARK) != 0; 7813050Ssam return (0); 7912794Ssam } 8013050Ssam /* 8113050Ssam * Interface/routing/protocol specific ioctls: 8213050Ssam * interface and routing ioctls should have a 8313050Ssam * different entry since a socket's unnecessary 8413050Ssam */ 8513050Ssam #define cmdbyte(x) (((x) >> 8) & 0xff) 8613050Ssam if (cmdbyte(cmd) == 'i') 8718366Skarels return (ifioctl(so, cmd, data)); 8813050Ssam if (cmdbyte(cmd) == 'r') 8913050Ssam return (rtioctl(cmd, data)); 9013050Ssam return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 9113050Ssam (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0)); 9212794Ssam } 9312794Ssam 9412794Ssam soo_select(fp, which) 9512794Ssam struct file *fp; 9612794Ssam int which; 9712794Ssam { 9812794Ssam register struct socket *so = (struct socket *)fp->f_data; 9912794Ssam register int s = splnet(); 10012794Ssam 10112794Ssam switch (which) { 10212794Ssam 10312794Ssam case FREAD: 10412794Ssam if (soreadable(so)) { 10512794Ssam splx(s); 10612794Ssam return (1); 10712794Ssam } 10812794Ssam sbselqueue(&so->so_rcv); 10912794Ssam break; 11012794Ssam 11112794Ssam case FWRITE: 11212794Ssam if (sowriteable(so)) { 11312794Ssam splx(s); 11412794Ssam return (1); 11512794Ssam } 11612794Ssam sbselqueue(&so->so_snd); 11712794Ssam break; 11824768Skarels 11924768Skarels case 0: 12024768Skarels if (so->so_oobmark || 12124768Skarels (so->so_state & SS_RCVATMARK)) { 12224768Skarels splx(s); 12324768Skarels return (1); 12424768Skarels } 12524768Skarels sbselqueue(&so->so_rcv); 12624768Skarels break; 12712794Ssam } 12812794Ssam splx(s); 12912794Ssam return (0); 13012794Ssam } 13112794Ssam 13213099Ssam /*ARGSUSED*/ 13313045Ssam soo_stat(so, ub) 13413045Ssam register struct socket *so; 13512794Ssam register struct stat *ub; 13612794Ssam { 13712794Ssam 13812794Ssam bzero((caddr_t)ub, sizeof (*ub)); 13912794Ssam return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE, 14012794Ssam (struct mbuf *)ub, (struct mbuf *)0, 14112794Ssam (struct mbuf *)0)); 14212794Ssam } 14312794Ssam 14412794Ssam soo_close(fp) 14512794Ssam struct file *fp; 14612794Ssam { 14714032Ssam int error = 0; 14814032Ssam 14914032Ssam if (fp->f_data) 15014032Ssam error = soclose((struct socket *)fp->f_data); 15112794Ssam fp->f_data = 0; 15212794Ssam return (error); 15312794Ssam } 154