123386Smckusick /* 229106Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 333921Sbostic * All rights reserved. 423386Smckusick * 533921Sbostic * Redistribution and use in source and binary forms are permitted 6*34858Sbostic * provided that the above copyright notice and this paragraph are 7*34858Sbostic * duplicated in all such forms and that any documentation, 8*34858Sbostic * advertising materials, and other materials related to such 9*34858Sbostic * distribution and use acknowledge that the software was developed 10*34858Sbostic * by the University of California, Berkeley. The name of the 11*34858Sbostic * University may not be used to endorse or promote products derived 12*34858Sbostic * from this software without specific prior written permission. 13*34858Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*34858Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*34858Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1633921Sbostic * 17*34858Sbostic * @(#)sys_socket.c 7.3 (Berkeley) 06/29/88 1823386Smckusick */ 1912794Ssam 2017095Sbloom #include "param.h" 2117095Sbloom #include "systm.h" 2217095Sbloom #include "dir.h" 2317095Sbloom #include "user.h" 2417095Sbloom #include "file.h" 2517095Sbloom #include "mbuf.h" 2617095Sbloom #include "protosw.h" 2717095Sbloom #include "socket.h" 2817095Sbloom #include "socketvar.h" 2917095Sbloom #include "ioctl.h" 3017095Sbloom #include "uio.h" 3117095Sbloom #include "stat.h" 3212794Ssam 3312794Ssam #include "../net/if.h" 3412794Ssam #include "../net/route.h" 3512794Ssam 3613045Ssam int soo_rw(), soo_ioctl(), soo_select(), soo_close(); 3712794Ssam struct fileops socketops = 3813045Ssam { soo_rw, soo_ioctl, soo_select, soo_close }; 3912794Ssam 4012794Ssam soo_rw(fp, rw, uio) 4112794Ssam struct file *fp; 4212794Ssam enum uio_rw rw; 4312794Ssam struct uio *uio; 4412794Ssam { 4512794Ssam int soreceive(), sosend(); 4612794Ssam 4712794Ssam return ( 4812794Ssam (*(rw==UIO_READ?soreceive:sosend)) 4912794Ssam ((struct socket *)fp->f_data, 0, uio, 0, 0)); 5012794Ssam } 5112794Ssam 5212794Ssam soo_ioctl(fp, cmd, data) 5312794Ssam struct file *fp; 5412794Ssam int cmd; 5512794Ssam register caddr_t data; 5612794Ssam { 5712794Ssam register struct socket *so = (struct socket *)fp->f_data; 5812794Ssam 5912794Ssam switch (cmd) { 6012794Ssam 6112794Ssam case FIONBIO: 6212794Ssam if (*(int *)data) 6312794Ssam so->so_state |= SS_NBIO; 6412794Ssam else 6512794Ssam so->so_state &= ~SS_NBIO; 6613050Ssam return (0); 6712794Ssam 6812794Ssam case FIOASYNC: 6912794Ssam if (*(int *)data) 7012794Ssam so->so_state |= SS_ASYNC; 7112794Ssam else 7212794Ssam so->so_state &= ~SS_ASYNC; 7313050Ssam return (0); 7412794Ssam 7513001Ssam case FIONREAD: 7613001Ssam *(int *)data = so->so_rcv.sb_cc; 7713050Ssam return (0); 7813001Ssam 7912794Ssam case SIOCSPGRP: 8012794Ssam so->so_pgrp = *(int *)data; 8113050Ssam return (0); 8212794Ssam 8312794Ssam case SIOCGPGRP: 8412794Ssam *(int *)data = so->so_pgrp; 8513050Ssam return (0); 8612794Ssam 8712794Ssam case SIOCATMARK: 8812794Ssam *(int *)data = (so->so_state&SS_RCVATMARK) != 0; 8913050Ssam return (0); 9012794Ssam } 9113050Ssam /* 9213050Ssam * Interface/routing/protocol specific ioctls: 9313050Ssam * interface and routing ioctls should have a 9413050Ssam * different entry since a socket's unnecessary 9513050Ssam */ 9613050Ssam #define cmdbyte(x) (((x) >> 8) & 0xff) 9713050Ssam if (cmdbyte(cmd) == 'i') 9818366Skarels return (ifioctl(so, cmd, data)); 9913050Ssam if (cmdbyte(cmd) == 'r') 10013050Ssam return (rtioctl(cmd, data)); 10113050Ssam return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 10213050Ssam (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0)); 10312794Ssam } 10412794Ssam 10512794Ssam soo_select(fp, which) 10612794Ssam struct file *fp; 10712794Ssam int which; 10812794Ssam { 10912794Ssam register struct socket *so = (struct socket *)fp->f_data; 11012794Ssam register int s = splnet(); 11112794Ssam 11212794Ssam switch (which) { 11312794Ssam 11412794Ssam case FREAD: 11512794Ssam if (soreadable(so)) { 11612794Ssam splx(s); 11712794Ssam return (1); 11812794Ssam } 11912794Ssam sbselqueue(&so->so_rcv); 12012794Ssam break; 12112794Ssam 12212794Ssam case FWRITE: 12312794Ssam if (sowriteable(so)) { 12412794Ssam splx(s); 12512794Ssam return (1); 12612794Ssam } 12712794Ssam sbselqueue(&so->so_snd); 12812794Ssam break; 12924768Skarels 13024768Skarels case 0: 13124768Skarels if (so->so_oobmark || 13224768Skarels (so->so_state & SS_RCVATMARK)) { 13324768Skarels splx(s); 13424768Skarels return (1); 13524768Skarels } 13624768Skarels sbselqueue(&so->so_rcv); 13724768Skarels break; 13812794Ssam } 13912794Ssam splx(s); 14012794Ssam return (0); 14112794Ssam } 14212794Ssam 14313099Ssam /*ARGSUSED*/ 14413045Ssam soo_stat(so, ub) 14513045Ssam register struct socket *so; 14612794Ssam register struct stat *ub; 14712794Ssam { 14812794Ssam 14912794Ssam bzero((caddr_t)ub, sizeof (*ub)); 15012794Ssam return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE, 15112794Ssam (struct mbuf *)ub, (struct mbuf *)0, 15212794Ssam (struct mbuf *)0)); 15312794Ssam } 15412794Ssam 15512794Ssam soo_close(fp) 15612794Ssam struct file *fp; 15712794Ssam { 15814032Ssam int error = 0; 15933921Sbostic 16014032Ssam if (fp->f_data) 16114032Ssam error = soclose((struct socket *)fp->f_data); 16212794Ssam fp->f_data = 0; 16312794Ssam return (error); 16412794Ssam } 165