123386Smckusick /* 240935Skarels * Copyright (c) 1982, 1986, 1990 Regents of the University of California. 333921Sbostic * All rights reserved. 423386Smckusick * 544445Sbostic * %sccs.include.redist.c% 633921Sbostic * 7*50429Skarels * @(#)sys_socket.c 7.12 (Berkeley) 07/17/91 823386Smckusick */ 912794Ssam 1017095Sbloom #include "param.h" 1117095Sbloom #include "systm.h" 1217095Sbloom #include "file.h" 1317095Sbloom #include "mbuf.h" 1417095Sbloom #include "protosw.h" 1517095Sbloom #include "socket.h" 1617095Sbloom #include "socketvar.h" 1717095Sbloom #include "ioctl.h" 1817095Sbloom #include "stat.h" 1912794Ssam 2047975Skarels #include "net/if.h" 2147975Skarels #include "net/route.h" 2212794Ssam 2312794Ssam struct fileops socketops = 2437728Smckusick { soo_read, soo_write, soo_ioctl, soo_select, soo_close }; 2512794Ssam 2637728Smckusick /* ARGSUSED */ 2737728Smckusick soo_read(fp, uio, cred) 2812794Ssam struct file *fp; 2912794Ssam struct uio *uio; 3037728Smckusick struct ucred *cred; 3112794Ssam { 3212794Ssam 3337728Smckusick return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0, 3440935Skarels uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0)); 3512794Ssam } 3612794Ssam 3737728Smckusick /* ARGSUSED */ 3837728Smckusick soo_write(fp, uio, cred) 3937728Smckusick struct file *fp; 4037728Smckusick struct uio *uio; 4137728Smckusick struct ucred *cred; 4237728Smckusick { 4337728Smckusick 4437728Smckusick return (sosend((struct socket *)fp->f_data, (struct mbuf *)0, 4540935Skarels uio, (struct mbuf *)0, (struct mbuf *)0, 0)); 4637728Smckusick } 4737728Smckusick 4847540Skarels soo_ioctl(fp, cmd, data, p) 4912794Ssam struct file *fp; 5012794Ssam int cmd; 5112794Ssam register caddr_t data; 5247540Skarels struct proc *p; 5312794Ssam { 5412794Ssam register struct socket *so = (struct socket *)fp->f_data; 5512794Ssam 5612794Ssam switch (cmd) { 5712794Ssam 5812794Ssam case FIONBIO: 5912794Ssam if (*(int *)data) 6012794Ssam so->so_state |= SS_NBIO; 6112794Ssam else 6212794Ssam so->so_state &= ~SS_NBIO; 6313050Ssam return (0); 6412794Ssam 6512794Ssam case FIOASYNC: 6643897Skarels if (*(int *)data) { 6712794Ssam so->so_state |= SS_ASYNC; 6843897Skarels so->so_rcv.sb_flags |= SB_ASYNC; 6943897Skarels so->so_snd.sb_flags |= SB_ASYNC; 7043897Skarels } else { 7112794Ssam so->so_state &= ~SS_ASYNC; 7243897Skarels so->so_rcv.sb_flags &= ~SB_ASYNC; 7343897Skarels so->so_snd.sb_flags &= ~SB_ASYNC; 7443897Skarels } 7513050Ssam return (0); 7612794Ssam 7713001Ssam case FIONREAD: 7813001Ssam *(int *)data = so->so_rcv.sb_cc; 7913050Ssam return (0); 8013001Ssam 8112794Ssam case SIOCSPGRP: 8237478Ssklower so->so_pgid = *(int *)data; 8313050Ssam return (0); 8412794Ssam 8512794Ssam case SIOCGPGRP: 8637478Ssklower *(int *)data = so->so_pgid; 8713050Ssam return (0); 8812794Ssam 8912794Ssam case SIOCATMARK: 9012794Ssam *(int *)data = (so->so_state&SS_RCVATMARK) != 0; 9113050Ssam return (0); 9212794Ssam } 9313050Ssam /* 9413050Ssam * Interface/routing/protocol specific ioctls: 9513050Ssam * interface and routing ioctls should have a 9613050Ssam * different entry since a socket's unnecessary 9713050Ssam */ 9840935Skarels if (IOCGROUP(cmd) == 'i') 9947540Skarels return (ifioctl(so, cmd, data, p)); 10040935Skarels if (IOCGROUP(cmd) == 'r') 10147540Skarels return (rtioctl(cmd, data, p)); 10213050Ssam return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 10313050Ssam (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0)); 10412794Ssam } 10512794Ssam 10647540Skarels soo_select(fp, which, p) 10712794Ssam struct file *fp; 10812794Ssam int which; 10947540Skarels struct proc *p; 11012794Ssam { 11112794Ssam register struct socket *so = (struct socket *)fp->f_data; 11212794Ssam register int s = splnet(); 11312794Ssam 11412794Ssam switch (which) { 11512794Ssam 11612794Ssam case FREAD: 11712794Ssam if (soreadable(so)) { 11812794Ssam splx(s); 11912794Ssam return (1); 12012794Ssam } 12147540Skarels sbselqueue(&so->so_rcv, p); 12212794Ssam break; 12312794Ssam 12412794Ssam case FWRITE: 12512794Ssam if (sowriteable(so)) { 12612794Ssam splx(s); 12712794Ssam return (1); 12812794Ssam } 12947540Skarels sbselqueue(&so->so_snd, p); 13012794Ssam break; 13124768Skarels 13224768Skarels case 0: 13324768Skarels if (so->so_oobmark || 13424768Skarels (so->so_state & SS_RCVATMARK)) { 13524768Skarels splx(s); 13624768Skarels return (1); 13724768Skarels } 13847540Skarels sbselqueue(&so->so_rcv, p); 13924768Skarels break; 14012794Ssam } 14112794Ssam splx(s); 14212794Ssam return (0); 14312794Ssam } 14412794Ssam 14513045Ssam soo_stat(so, ub) 14613045Ssam register struct socket *so; 14712794Ssam register struct stat *ub; 14812794Ssam { 14912794Ssam 15012794Ssam bzero((caddr_t)ub, sizeof (*ub)); 151*50429Skarels ub->st_mode = S_IFSOCK; 15212794Ssam return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE, 15312794Ssam (struct mbuf *)ub, (struct mbuf *)0, 15412794Ssam (struct mbuf *)0)); 15512794Ssam } 15612794Ssam 15748028Smckusick /* ARGSUSED */ 15848028Smckusick soo_close(fp, p) 15912794Ssam struct file *fp; 16048028Smckusick struct proc *p; 16112794Ssam { 16214032Ssam int error = 0; 16333921Sbostic 16414032Ssam if (fp->f_data) 16514032Ssam error = soclose((struct socket *)fp->f_data); 16612794Ssam fp->f_data = 0; 16712794Ssam return (error); 16812794Ssam } 169