123386Smckusick /* 2*40935Skarels * Copyright (c) 1982, 1986, 1990 Regents of the University of California. 333921Sbostic * All rights reserved. 423386Smckusick * 533921Sbostic * Redistribution and use in source and binary forms are permitted 634858Sbostic * provided that the above copyright notice and this paragraph are 734858Sbostic * duplicated in all such forms and that any documentation, 834858Sbostic * advertising materials, and other materials related to such 934858Sbostic * distribution and use acknowledge that the software was developed 1034858Sbostic * by the University of California, Berkeley. The name of the 1134858Sbostic * University may not be used to endorse or promote products derived 1234858Sbostic * from this software without specific prior written permission. 1334858Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434858Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534858Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1633921Sbostic * 17*40935Skarels * @(#)sys_socket.c 7.6 (Berkeley) 04/16/90 1823386Smckusick */ 1912794Ssam 2017095Sbloom #include "param.h" 2117095Sbloom #include "systm.h" 2217095Sbloom #include "user.h" 2317095Sbloom #include "file.h" 2417095Sbloom #include "mbuf.h" 2517095Sbloom #include "protosw.h" 2617095Sbloom #include "socket.h" 2717095Sbloom #include "socketvar.h" 2817095Sbloom #include "ioctl.h" 2917095Sbloom #include "uio.h" 3017095Sbloom #include "stat.h" 3112794Ssam 3212794Ssam #include "../net/if.h" 3312794Ssam #include "../net/route.h" 3412794Ssam 3537728Smckusick int soo_read(), soo_write(), soo_ioctl(), soo_select(), soo_close(); 3612794Ssam struct fileops socketops = 3737728Smckusick { soo_read, soo_write, soo_ioctl, soo_select, soo_close }; 3812794Ssam 3937728Smckusick /* ARGSUSED */ 4037728Smckusick soo_read(fp, uio, cred) 4112794Ssam struct file *fp; 4212794Ssam struct uio *uio; 4337728Smckusick struct ucred *cred; 4412794Ssam { 4512794Ssam 4637728Smckusick return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0, 47*40935Skarels uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0)); 4812794Ssam } 4912794Ssam 5037728Smckusick /* ARGSUSED */ 5137728Smckusick soo_write(fp, uio, cred) 5237728Smckusick struct file *fp; 5337728Smckusick struct uio *uio; 5437728Smckusick struct ucred *cred; 5537728Smckusick { 5637728Smckusick 5737728Smckusick return (sosend((struct socket *)fp->f_data, (struct mbuf *)0, 58*40935Skarels uio, (struct mbuf *)0, (struct mbuf *)0, 0)); 5937728Smckusick } 6037728Smckusick 6112794Ssam soo_ioctl(fp, cmd, data) 6212794Ssam struct file *fp; 6312794Ssam int cmd; 6412794Ssam register caddr_t data; 6512794Ssam { 6612794Ssam register struct socket *so = (struct socket *)fp->f_data; 6712794Ssam 6812794Ssam switch (cmd) { 6912794Ssam 7012794Ssam case FIONBIO: 7112794Ssam if (*(int *)data) 7212794Ssam so->so_state |= SS_NBIO; 7312794Ssam else 7412794Ssam so->so_state &= ~SS_NBIO; 7513050Ssam return (0); 7612794Ssam 7712794Ssam case FIOASYNC: 7812794Ssam if (*(int *)data) 7912794Ssam so->so_state |= SS_ASYNC; 8012794Ssam else 8112794Ssam so->so_state &= ~SS_ASYNC; 8213050Ssam return (0); 8312794Ssam 8413001Ssam case FIONREAD: 8513001Ssam *(int *)data = so->so_rcv.sb_cc; 8613050Ssam return (0); 8713001Ssam 8812794Ssam case SIOCSPGRP: 8937478Ssklower so->so_pgid = *(int *)data; 9013050Ssam return (0); 9112794Ssam 9212794Ssam case SIOCGPGRP: 9337478Ssklower *(int *)data = so->so_pgid; 9413050Ssam return (0); 9512794Ssam 9612794Ssam case SIOCATMARK: 9712794Ssam *(int *)data = (so->so_state&SS_RCVATMARK) != 0; 9813050Ssam return (0); 9912794Ssam } 10013050Ssam /* 10113050Ssam * Interface/routing/protocol specific ioctls: 10213050Ssam * interface and routing ioctls should have a 10313050Ssam * different entry since a socket's unnecessary 10413050Ssam */ 105*40935Skarels if (IOCGROUP(cmd) == 'i') 10618366Skarels return (ifioctl(so, cmd, data)); 107*40935Skarels if (IOCGROUP(cmd) == 'r') 10813050Ssam return (rtioctl(cmd, data)); 10913050Ssam return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 11013050Ssam (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0)); 11112794Ssam } 11212794Ssam 11312794Ssam soo_select(fp, which) 11412794Ssam struct file *fp; 11512794Ssam int which; 11612794Ssam { 11712794Ssam register struct socket *so = (struct socket *)fp->f_data; 11812794Ssam register int s = splnet(); 11912794Ssam 12012794Ssam switch (which) { 12112794Ssam 12212794Ssam case FREAD: 12312794Ssam if (soreadable(so)) { 12412794Ssam splx(s); 12512794Ssam return (1); 12612794Ssam } 12712794Ssam sbselqueue(&so->so_rcv); 12812794Ssam break; 12912794Ssam 13012794Ssam case FWRITE: 13112794Ssam if (sowriteable(so)) { 13212794Ssam splx(s); 13312794Ssam return (1); 13412794Ssam } 13512794Ssam sbselqueue(&so->so_snd); 13612794Ssam break; 13724768Skarels 13824768Skarels case 0: 13924768Skarels if (so->so_oobmark || 14024768Skarels (so->so_state & SS_RCVATMARK)) { 14124768Skarels splx(s); 14224768Skarels return (1); 14324768Skarels } 14424768Skarels sbselqueue(&so->so_rcv); 14524768Skarels break; 14612794Ssam } 14712794Ssam splx(s); 14812794Ssam return (0); 14912794Ssam } 15012794Ssam 15113099Ssam /*ARGSUSED*/ 15213045Ssam soo_stat(so, ub) 15313045Ssam register struct socket *so; 15412794Ssam register struct stat *ub; 15512794Ssam { 15612794Ssam 15712794Ssam bzero((caddr_t)ub, sizeof (*ub)); 15812794Ssam return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE, 15912794Ssam (struct mbuf *)ub, (struct mbuf *)0, 16012794Ssam (struct mbuf *)0)); 16112794Ssam } 16212794Ssam 16312794Ssam soo_close(fp) 16412794Ssam struct file *fp; 16512794Ssam { 16614032Ssam int error = 0; 16733921Sbostic 16814032Ssam if (fp->f_data) 16914032Ssam error = soclose((struct socket *)fp->f_data); 17012794Ssam fp->f_data = 0; 17112794Ssam return (error); 17212794Ssam } 173