1 /* 2 * Copyright (c) 1982 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)sys_socket.c 6.6 (Berkeley) 09/16/85 7 */ 8 9 #include "param.h" 10 #include "systm.h" 11 #include "dir.h" 12 #include "user.h" 13 #include "file.h" 14 #include "mbuf.h" 15 #include "protosw.h" 16 #include "socket.h" 17 #include "socketvar.h" 18 #include "ioctl.h" 19 #include "uio.h" 20 #include "stat.h" 21 22 #include "../net/if.h" 23 #include "../net/route.h" 24 25 int soo_rw(), soo_ioctl(), soo_select(), soo_close(); 26 struct fileops socketops = 27 { soo_rw, soo_ioctl, soo_select, soo_close }; 28 29 soo_rw(fp, rw, uio) 30 struct file *fp; 31 enum uio_rw rw; 32 struct uio *uio; 33 { 34 int soreceive(), sosend(); 35 36 return ( 37 (*(rw==UIO_READ?soreceive:sosend)) 38 ((struct socket *)fp->f_data, 0, uio, 0, 0)); 39 } 40 41 soo_ioctl(fp, cmd, data) 42 struct file *fp; 43 int cmd; 44 register caddr_t data; 45 { 46 register struct socket *so = (struct socket *)fp->f_data; 47 48 switch (cmd) { 49 50 case FIONBIO: 51 if (*(int *)data) 52 so->so_state |= SS_NBIO; 53 else 54 so->so_state &= ~SS_NBIO; 55 return (0); 56 57 case FIOASYNC: 58 if (*(int *)data) 59 so->so_state |= SS_ASYNC; 60 else 61 so->so_state &= ~SS_ASYNC; 62 return (0); 63 64 case FIONREAD: 65 *(int *)data = so->so_rcv.sb_cc; 66 return (0); 67 68 case SIOCSPGRP: 69 so->so_pgrp = *(int *)data; 70 return (0); 71 72 case SIOCGPGRP: 73 *(int *)data = so->so_pgrp; 74 return (0); 75 76 case SIOCATMARK: 77 *(int *)data = (so->so_state&SS_RCVATMARK) != 0; 78 return (0); 79 } 80 /* 81 * Interface/routing/protocol specific ioctls: 82 * interface and routing ioctls should have a 83 * different entry since a socket's unnecessary 84 */ 85 #define cmdbyte(x) (((x) >> 8) & 0xff) 86 if (cmdbyte(cmd) == 'i') 87 return (ifioctl(so, cmd, data)); 88 if (cmdbyte(cmd) == 'r') 89 return (rtioctl(cmd, data)); 90 return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 91 (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0)); 92 } 93 94 soo_select(fp, which) 95 struct file *fp; 96 int which; 97 { 98 register struct socket *so = (struct socket *)fp->f_data; 99 register int s = splnet(); 100 101 switch (which) { 102 103 case FREAD: 104 if (soreadable(so)) { 105 splx(s); 106 return (1); 107 } 108 sbselqueue(&so->so_rcv); 109 break; 110 111 case FWRITE: 112 if (sowriteable(so)) { 113 splx(s); 114 return (1); 115 } 116 sbselqueue(&so->so_snd); 117 break; 118 119 case 0: 120 if (so->so_oobmark || 121 (so->so_state & SS_RCVATMARK)) { 122 splx(s); 123 return (1); 124 } 125 sbselqueue(&so->so_rcv); 126 break; 127 } 128 splx(s); 129 return (0); 130 } 131 132 /*ARGSUSED*/ 133 soo_stat(so, ub) 134 register struct socket *so; 135 register struct stat *ub; 136 { 137 138 bzero((caddr_t)ub, sizeof (*ub)); 139 return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE, 140 (struct mbuf *)ub, (struct mbuf *)0, 141 (struct mbuf *)0)); 142 } 143 144 soo_close(fp) 145 struct file *fp; 146 { 147 int error = 0; 148 149 if (fp->f_data) 150 error = soclose((struct socket *)fp->f_data); 151 fp->f_data = 0; 152 return (error); 153 } 154