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.5 (Berkeley) 05/09/89 18 */ 19 20 #include "param.h" 21 #include "systm.h" 22 #include "user.h" 23 #include "file.h" 24 #include "mbuf.h" 25 #include "protosw.h" 26 #include "socket.h" 27 #include "socketvar.h" 28 #include "ioctl.h" 29 #include "uio.h" 30 #include "stat.h" 31 32 #include "../net/if.h" 33 #include "../net/route.h" 34 35 int soo_read(), soo_write(), soo_ioctl(), soo_select(), soo_close(); 36 struct fileops socketops = 37 { soo_read, soo_write, soo_ioctl, soo_select, soo_close }; 38 39 /* ARGSUSED */ 40 soo_read(fp, uio, cred) 41 struct file *fp; 42 struct uio *uio; 43 struct ucred *cred; 44 { 45 46 return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0, 47 uio, (int *)0, (struct mbuf **)0, (struct mbuf **)0)); 48 } 49 50 /* ARGSUSED */ 51 soo_write(fp, uio, cred) 52 struct file *fp; 53 struct uio *uio; 54 struct ucred *cred; 55 { 56 57 return (sosend((struct socket *)fp->f_data, (struct mbuf *)0, 58 uio, 0, (struct mbuf *)0, (struct mbuf *)0)); 59 } 60 61 soo_ioctl(fp, cmd, data) 62 struct file *fp; 63 int cmd; 64 register caddr_t data; 65 { 66 register struct socket *so = (struct socket *)fp->f_data; 67 68 switch (cmd) { 69 70 case FIONBIO: 71 if (*(int *)data) 72 so->so_state |= SS_NBIO; 73 else 74 so->so_state &= ~SS_NBIO; 75 return (0); 76 77 case FIOASYNC: 78 if (*(int *)data) 79 so->so_state |= SS_ASYNC; 80 else 81 so->so_state &= ~SS_ASYNC; 82 return (0); 83 84 case FIONREAD: 85 *(int *)data = so->so_rcv.sb_cc; 86 return (0); 87 88 case SIOCSPGRP: 89 so->so_pgid = *(int *)data; 90 return (0); 91 92 case SIOCGPGRP: 93 *(int *)data = so->so_pgid; 94 return (0); 95 96 case SIOCATMARK: 97 *(int *)data = (so->so_state&SS_RCVATMARK) != 0; 98 return (0); 99 } 100 /* 101 * Interface/routing/protocol specific ioctls: 102 * interface and routing ioctls should have a 103 * different entry since a socket's unnecessary 104 */ 105 #define cmdbyte(x) (((x) >> 8) & 0xff) 106 if (cmdbyte(cmd) == 'i') 107 return (ifioctl(so, cmd, data)); 108 if (cmdbyte(cmd) == 'r') 109 return (rtioctl(cmd, data)); 110 return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 111 (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0)); 112 } 113 114 soo_select(fp, which) 115 struct file *fp; 116 int which; 117 { 118 register struct socket *so = (struct socket *)fp->f_data; 119 register int s = splnet(); 120 121 switch (which) { 122 123 case FREAD: 124 if (soreadable(so)) { 125 splx(s); 126 return (1); 127 } 128 sbselqueue(&so->so_rcv); 129 break; 130 131 case FWRITE: 132 if (sowriteable(so)) { 133 splx(s); 134 return (1); 135 } 136 sbselqueue(&so->so_snd); 137 break; 138 139 case 0: 140 if (so->so_oobmark || 141 (so->so_state & SS_RCVATMARK)) { 142 splx(s); 143 return (1); 144 } 145 sbselqueue(&so->so_rcv); 146 break; 147 } 148 splx(s); 149 return (0); 150 } 151 152 /*ARGSUSED*/ 153 soo_stat(so, ub) 154 register struct socket *so; 155 register struct stat *ub; 156 { 157 158 bzero((caddr_t)ub, sizeof (*ub)); 159 return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE, 160 (struct mbuf *)ub, (struct mbuf *)0, 161 (struct mbuf *)0)); 162 } 163 164 soo_close(fp) 165 struct file *fp; 166 { 167 int error = 0; 168 169 if (fp->f_data) 170 error = soclose((struct socket *)fp->f_data); 171 fp->f_data = 0; 172 return (error); 173 } 174