1 /* 2 * Copyright (c) 1982, 1986 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * @(#)sys_socket.c 7.3 (Berkeley) 06/29/88 18 */ 19 20 #include "param.h" 21 #include "systm.h" 22 #include "dir.h" 23 #include "user.h" 24 #include "file.h" 25 #include "mbuf.h" 26 #include "protosw.h" 27 #include "socket.h" 28 #include "socketvar.h" 29 #include "ioctl.h" 30 #include "uio.h" 31 #include "stat.h" 32 33 #include "../net/if.h" 34 #include "../net/route.h" 35 36 int soo_rw(), soo_ioctl(), soo_select(), soo_close(); 37 struct fileops socketops = 38 { soo_rw, soo_ioctl, soo_select, soo_close }; 39 40 soo_rw(fp, rw, uio) 41 struct file *fp; 42 enum uio_rw rw; 43 struct uio *uio; 44 { 45 int soreceive(), sosend(); 46 47 return ( 48 (*(rw==UIO_READ?soreceive:sosend)) 49 ((struct socket *)fp->f_data, 0, uio, 0, 0)); 50 } 51 52 soo_ioctl(fp, cmd, data) 53 struct file *fp; 54 int cmd; 55 register caddr_t data; 56 { 57 register struct socket *so = (struct socket *)fp->f_data; 58 59 switch (cmd) { 60 61 case FIONBIO: 62 if (*(int *)data) 63 so->so_state |= SS_NBIO; 64 else 65 so->so_state &= ~SS_NBIO; 66 return (0); 67 68 case FIOASYNC: 69 if (*(int *)data) 70 so->so_state |= SS_ASYNC; 71 else 72 so->so_state &= ~SS_ASYNC; 73 return (0); 74 75 case FIONREAD: 76 *(int *)data = so->so_rcv.sb_cc; 77 return (0); 78 79 case SIOCSPGRP: 80 so->so_pgrp = *(int *)data; 81 return (0); 82 83 case SIOCGPGRP: 84 *(int *)data = so->so_pgrp; 85 return (0); 86 87 case SIOCATMARK: 88 *(int *)data = (so->so_state&SS_RCVATMARK) != 0; 89 return (0); 90 } 91 /* 92 * Interface/routing/protocol specific ioctls: 93 * interface and routing ioctls should have a 94 * different entry since a socket's unnecessary 95 */ 96 #define cmdbyte(x) (((x) >> 8) & 0xff) 97 if (cmdbyte(cmd) == 'i') 98 return (ifioctl(so, cmd, data)); 99 if (cmdbyte(cmd) == 'r') 100 return (rtioctl(cmd, data)); 101 return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 102 (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0)); 103 } 104 105 soo_select(fp, which) 106 struct file *fp; 107 int which; 108 { 109 register struct socket *so = (struct socket *)fp->f_data; 110 register int s = splnet(); 111 112 switch (which) { 113 114 case FREAD: 115 if (soreadable(so)) { 116 splx(s); 117 return (1); 118 } 119 sbselqueue(&so->so_rcv); 120 break; 121 122 case FWRITE: 123 if (sowriteable(so)) { 124 splx(s); 125 return (1); 126 } 127 sbselqueue(&so->so_snd); 128 break; 129 130 case 0: 131 if (so->so_oobmark || 132 (so->so_state & SS_RCVATMARK)) { 133 splx(s); 134 return (1); 135 } 136 sbselqueue(&so->so_rcv); 137 break; 138 } 139 splx(s); 140 return (0); 141 } 142 143 /*ARGSUSED*/ 144 soo_stat(so, ub) 145 register struct socket *so; 146 register struct stat *ub; 147 { 148 149 bzero((caddr_t)ub, sizeof (*ub)); 150 return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE, 151 (struct mbuf *)ub, (struct mbuf *)0, 152 (struct mbuf *)0)); 153 } 154 155 soo_close(fp) 156 struct file *fp; 157 { 158 int error = 0; 159 160 if (fp->f_data) 161 error = soclose((struct socket *)fp->f_data); 162 fp->f_data = 0; 163 return (error); 164 } 165