1 /* 2 * Copyright (c) 1982, 1986, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)sys_socket.c 8.3 (Berkeley) 02/14/95 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/proc.h> 13 #include <sys/file.h> 14 #include <sys/mbuf.h> 15 #include <sys/protosw.h> 16 #include <sys/socket.h> 17 #include <sys/socketvar.h> 18 #include <sys/ioctl.h> 19 #include <sys/stat.h> 20 21 #include <net/if.h> 22 #include <net/route.h> 23 24 struct fileops socketops = 25 { soo_read, soo_write, soo_ioctl, soo_select, soo_close }; 26 27 /* ARGSUSED */ 28 int 29 soo_read(fp, uio, cred) 30 struct file *fp; 31 struct uio *uio; 32 struct ucred *cred; 33 { 34 35 return (soreceive((struct socket *)fp->f_data, (struct mbuf **)0, 36 uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0)); 37 } 38 39 /* ARGSUSED */ 40 int 41 soo_write(fp, uio, cred) 42 struct file *fp; 43 struct uio *uio; 44 struct ucred *cred; 45 { 46 47 return (sosend((struct socket *)fp->f_data, (struct mbuf *)0, 48 uio, (struct mbuf *)0, (struct mbuf *)0, 0)); 49 } 50 51 int 52 soo_ioctl(fp, cmd, data, p) 53 struct file *fp; 54 u_long cmd; 55 register caddr_t data; 56 struct proc *p; 57 { 58 register struct socket *so = (struct socket *)fp->f_data; 59 60 switch (cmd) { 61 62 case FIONBIO: 63 if (*(int *)data) 64 so->so_state |= SS_NBIO; 65 else 66 so->so_state &= ~SS_NBIO; 67 return (0); 68 69 case FIOASYNC: 70 if (*(int *)data) { 71 so->so_state |= SS_ASYNC; 72 so->so_rcv.sb_flags |= SB_ASYNC; 73 so->so_snd.sb_flags |= SB_ASYNC; 74 } else { 75 so->so_state &= ~SS_ASYNC; 76 so->so_rcv.sb_flags &= ~SB_ASYNC; 77 so->so_snd.sb_flags &= ~SB_ASYNC; 78 } 79 return (0); 80 81 case FIONREAD: 82 *(int *)data = so->so_rcv.sb_cc; 83 return (0); 84 85 case SIOCSPGRP: 86 so->so_pgid = *(int *)data; 87 return (0); 88 89 case SIOCGPGRP: 90 *(int *)data = so->so_pgid; 91 return (0); 92 93 case SIOCATMARK: 94 *(int *)data = (so->so_state&SS_RCVATMARK) != 0; 95 return (0); 96 } 97 /* 98 * Interface/routing/protocol specific ioctls: 99 * interface and routing ioctls should have a 100 * different entry since a socket's unnecessary 101 */ 102 if (IOCGROUP(cmd) == 'i') 103 return (ifioctl(so, cmd, data, p)); 104 if (IOCGROUP(cmd) == 'r') 105 return (rtioctl(cmd, data, p)); 106 return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 107 (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0)); 108 } 109 110 int 111 soo_select(fp, which, p) 112 struct file *fp; 113 int which; 114 struct proc *p; 115 { 116 register struct socket *so = (struct socket *)fp->f_data; 117 register int s = splnet(); 118 119 switch (which) { 120 121 case FREAD: 122 if (soreadable(so)) { 123 splx(s); 124 return (1); 125 } 126 selrecord(p, &so->so_rcv.sb_sel); 127 so->so_rcv.sb_flags |= SB_SEL; 128 break; 129 130 case FWRITE: 131 if (sowriteable(so)) { 132 splx(s); 133 return (1); 134 } 135 selrecord(p, &so->so_snd.sb_sel); 136 so->so_snd.sb_flags |= SB_SEL; 137 break; 138 139 case 0: 140 if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) { 141 splx(s); 142 return (1); 143 } 144 selrecord(p, &so->so_rcv.sb_sel); 145 so->so_rcv.sb_flags |= SB_SEL; 146 break; 147 } 148 splx(s); 149 return (0); 150 } 151 152 int 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 ub->st_mode = S_IFSOCK; 160 return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE, 161 (struct mbuf *)ub, (struct mbuf *)0, 162 (struct mbuf *)0)); 163 } 164 165 /* ARGSUSED */ 166 int 167 soo_close(fp, p) 168 struct file *fp; 169 struct proc *p; 170 { 171 int error = 0; 172 173 if (fp->f_data) 174 error = soclose((struct socket *)fp->f_data); 175 fp->f_data = 0; 176 return (error); 177 } 178