1 /* 2 * Copyright (c) 1982, 1986, 1988 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.4 (Berkeley) 04/22/89 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 ((*(rw == UIO_READ ? soreceive : sosend)) 48 ((struct socket *)fp->f_data, 0, uio, 0, 0, 0)); 49 } 50 51 soo_ioctl(fp, cmd, data) 52 struct file *fp; 53 int cmd; 54 register caddr_t data; 55 { 56 register struct socket *so = (struct socket *)fp->f_data; 57 58 switch (cmd) { 59 60 case FIONBIO: 61 if (*(int *)data) 62 so->so_state |= SS_NBIO; 63 else 64 so->so_state &= ~SS_NBIO; 65 return (0); 66 67 case FIOASYNC: 68 if (*(int *)data) 69 so->so_state |= SS_ASYNC; 70 else 71 so->so_state &= ~SS_ASYNC; 72 return (0); 73 74 case FIONREAD: 75 *(int *)data = so->so_rcv.sb_cc; 76 return (0); 77 78 case SIOCSPGRP: 79 so->so_pgid = *(int *)data; 80 return (0); 81 82 case SIOCGPGRP: 83 *(int *)data = so->so_pgid; 84 return (0); 85 86 case SIOCATMARK: 87 *(int *)data = (so->so_state&SS_RCVATMARK) != 0; 88 return (0); 89 } 90 /* 91 * Interface/routing/protocol specific ioctls: 92 * interface and routing ioctls should have a 93 * different entry since a socket's unnecessary 94 */ 95 #define cmdbyte(x) (((x) >> 8) & 0xff) 96 if (cmdbyte(cmd) == 'i') 97 return (ifioctl(so, cmd, data)); 98 if (cmdbyte(cmd) == 'r') 99 return (rtioctl(cmd, data)); 100 return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 101 (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0)); 102 } 103 104 soo_select(fp, which) 105 struct file *fp; 106 int which; 107 { 108 register struct socket *so = (struct socket *)fp->f_data; 109 register int s = splnet(); 110 111 switch (which) { 112 113 case FREAD: 114 if (soreadable(so)) { 115 splx(s); 116 return (1); 117 } 118 sbselqueue(&so->so_rcv); 119 break; 120 121 case FWRITE: 122 if (sowriteable(so)) { 123 splx(s); 124 return (1); 125 } 126 sbselqueue(&so->so_snd); 127 break; 128 129 case 0: 130 if (so->so_oobmark || 131 (so->so_state & SS_RCVATMARK)) { 132 splx(s); 133 return (1); 134 } 135 sbselqueue(&so->so_rcv); 136 break; 137 } 138 splx(s); 139 return (0); 140 } 141 142 /*ARGSUSED*/ 143 soo_stat(so, ub) 144 register struct socket *so; 145 register struct stat *ub; 146 { 147 148 bzero((caddr_t)ub, sizeof (*ub)); 149 return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE, 150 (struct mbuf *)ub, (struct mbuf *)0, 151 (struct mbuf *)0)); 152 } 153 154 soo_close(fp) 155 struct file *fp; 156 { 157 int error = 0; 158 159 if (fp->f_data) 160 error = soclose((struct socket *)fp->f_data); 161 fp->f_data = 0; 162 return (error); 163 } 164