|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Copyright (c) 1982, 1986, 1990, 1993 ! 24: * The Regents of the University of California. All rights reserved. ! 25: * ! 26: * Redistribution and use in source and binary forms, with or without ! 27: * modification, are permitted provided that the following conditions ! 28: * are met: ! 29: * 1. Redistributions of source code must retain the above copyright ! 30: * notice, this list of conditions and the following disclaimer. ! 31: * 2. Redistributions in binary form must reproduce the above copyright ! 32: * notice, this list of conditions and the following disclaimer in the ! 33: * documentation and/or other materials provided with the distribution. ! 34: * 3. All advertising materials mentioning features or use of this software ! 35: * must display the following acknowledgement: ! 36: * This product includes software developed by the University of ! 37: * California, Berkeley and its contributors. ! 38: * 4. Neither the name of the University nor the names of its contributors ! 39: * may be used to endorse or promote products derived from this software ! 40: * without specific prior written permission. ! 41: * ! 42: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 43: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 44: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 45: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 46: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 47: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 48: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 49: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 50: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 51: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 52: * SUCH DAMAGE. ! 53: * ! 54: * @(#)sys_socket.c 8.1 (Berkeley) 6/10/93 ! 55: */ ! 56: ! 57: #include <sys/param.h> ! 58: #include <sys/systm.h> ! 59: #include <sys/file.h> ! 60: #include <sys/protosw.h> ! 61: #include <sys/socket.h> ! 62: #include <sys/socketvar.h> ! 63: #include <sys/filio.h> /* XXX */ ! 64: #include <sys/sockio.h> ! 65: #include <sys/stat.h> ! 66: #include <sys/uio.h> ! 67: #include <sys/filedesc.h> ! 68: ! 69: #include <net/if.h> ! 70: #include <net/route.h> ! 71: ! 72: int soo_read __P((struct file *fp, struct uio *uio, ! 73: struct ucred *cred)); ! 74: int soo_write __P((struct file *fp, struct uio *uio, ! 75: struct ucred *cred)); ! 76: int soo_close __P((struct file *fp, struct proc *p)); ! 77: ! 78: int soo_select __P((struct file *fp, int which, struct proc *p)); ! 79: ! 80: struct fileops socketops = ! 81: { soo_read, soo_write, soo_ioctl, soo_select, soo_close }; ! 82: ! 83: /* ARGSUSED */ ! 84: int ! 85: soo_read(fp, uio, cred) ! 86: struct file *fp; ! 87: struct uio *uio; ! 88: struct ucred *cred; ! 89: { ! 90: struct socket *so = (struct socket *)fp->f_data; ! 91: struct kextcb *kp; ! 92: int (*fsoreceive) __P((struct socket *so, ! 93: struct sockaddr **paddr, ! 94: struct uio *uio, struct mbuf **mp0, ! 95: struct mbuf **controlp, int *flagsp)); ! 96: ! 97: fsoreceive = so->so_proto->pr_usrreqs->pru_soreceive; ! 98: if (fsoreceive != soreceive) ! 99: { kp = sotokextcb(so); ! 100: while (kp) ! 101: { if (kp->e_soif && kp->e_soif->sf_soreceive) ! 102: (*kp->e_soif->sf_soreceive)(so, 0, &uio, ! 103: 0, 0, 0, kp); ! 104: kp = kp->e_next; ! 105: } ! 106: ! 107: } ! 108: return (*fsoreceive)(so, 0, uio, 0, 0, 0); ! 109: } ! 110: ! 111: /* ARGSUSED */ ! 112: int ! 113: soo_write(fp, uio, cred) ! 114: struct file *fp; ! 115: struct uio *uio; ! 116: struct ucred *cred; ! 117: { ! 118: struct socket *so = (struct socket *)fp->f_data; ! 119: int (*fsosend) __P((struct socket *so, struct sockaddr *addr, ! 120: struct uio *uio, struct mbuf *top, ! 121: struct mbuf *control, int flags)); ! 122: struct kextcb *kp; ! 123: ! 124: fsosend = so->so_proto->pr_usrreqs->pru_sosend; ! 125: if (fsosend != sosend) ! 126: { kp = sotokextcb(so); ! 127: while (kp) ! 128: { if (kp->e_soif && kp->e_soif->sf_sosend) ! 129: (*kp->e_soif->sf_sosend)(so, 0, &uio, ! 130: 0, 0, 0, kp); ! 131: kp = kp->e_next; ! 132: } ! 133: } ! 134: ! 135: return (*fsosend)(so, 0, uio, 0, 0, 0); ! 136: } ! 137: ! 138: int ! 139: soo_ioctl(fp, cmd, data, p) ! 140: struct file *fp; ! 141: u_long cmd; ! 142: register caddr_t data; ! 143: struct proc *p; ! 144: { ! 145: register struct socket *so = (struct socket *)fp->f_data; ! 146: ! 147: struct sockopt sopt; ! 148: struct kextcb *kp; ! 149: ! 150: kp = sotokextcb(so); ! 151: sopt.sopt_level = cmd; ! 152: sopt.sopt_name = (int)data; ! 153: sopt.sopt_p = p; ! 154: while (kp) ! 155: { if (kp->e_soif && kp->e_soif->sf_socontrol) ! 156: (*kp->e_soif->sf_socontrol)(so, &sopt, kp); ! 157: kp = kp->e_next; ! 158: } ! 159: ! 160: switch (cmd) { ! 161: ! 162: case FIONBIO: ! 163: if (*(int *)data) ! 164: so->so_state |= SS_NBIO; ! 165: else ! 166: so->so_state &= ~SS_NBIO; ! 167: return (0); ! 168: ! 169: case FIOASYNC: ! 170: if (*(int *)data) { ! 171: so->so_state |= SS_ASYNC; ! 172: so->so_rcv.sb_flags |= SB_ASYNC; ! 173: so->so_snd.sb_flags |= SB_ASYNC; ! 174: } else { ! 175: so->so_state &= ~SS_ASYNC; ! 176: so->so_rcv.sb_flags &= ~SB_ASYNC; ! 177: so->so_snd.sb_flags &= ~SB_ASYNC; ! 178: } ! 179: return (0); ! 180: ! 181: case FIONREAD: ! 182: *(int *)data = so->so_rcv.sb_cc; ! 183: return (0); ! 184: ! 185: case SIOCSPGRP: ! 186: so->so_pgid = *(int *)data; ! 187: return (0); ! 188: ! 189: case SIOCGPGRP: ! 190: *(int *)data = so->so_pgid; ! 191: return (0); ! 192: ! 193: case SIOCATMARK: ! 194: *(int *)data = (so->so_state&SS_RCVATMARK) != 0; ! 195: return (0); ! 196: case SIOCSETOT: { ! 197: /* ! 198: * Set socket level options here and then call protocol ! 199: * specific routine. ! 200: */ ! 201: struct socket *cloned_so = NULL; ! 202: int cloned_fd = *(int *)data; ! 203: int error = 0; ! 204: ! 205: /* let's make sure it's either -1 or a valid file descriptor */ ! 206: if (cloned_fd != -1) { ! 207: struct file *cloned_fp; ! 208: error = getsock(p->p_fd, cloned_fd, &cloned_fp); ! 209: if (error) ! 210: return (error); ! 211: cloned_so = (struct socket *)cloned_fp->f_data; ! 212: } ! 213: ! 214: /* Always set socket non-blocking for OT */ ! 215: so->so_state |= SS_NBIO; ! 216: so->so_options |= SO_DONTTRUNC | SO_WANTMORE; ! 217: ! 218: if (cloned_so && so != cloned_so) { ! 219: /* Flags options */ ! 220: so->so_options |= cloned_so->so_options; ! 221: ! 222: /* SO_LINGER */ ! 223: if (so->so_options & SO_LINGER) ! 224: so->so_linger = cloned_so->so_linger; ! 225: ! 226: /* SO_SNDBUF, SO_RCVBUF */ ! 227: if (sbreserve(&so->so_snd, cloned_so->so_snd.sb_hiwat) == 0) { ! 228: error = ENOBUFS; ! 229: return (error); ! 230: } ! 231: if (sbreserve(&so->so_rcv, cloned_so->so_rcv.sb_hiwat) == 0) { ! 232: error = ENOBUFS; ! 233: return (error); ! 234: } ! 235: ! 236: /* SO_SNDLOWAT, SO_RCVLOWAT */ ! 237: so->so_snd.sb_lowat = ! 238: (cloned_so->so_snd.sb_lowat > so->so_snd.sb_hiwat) ? ! 239: so->so_snd.sb_hiwat : cloned_so->so_snd.sb_lowat; ! 240: so->so_rcv.sb_lowat = ! 241: (cloned_so->so_rcv.sb_lowat > so->so_rcv.sb_hiwat) ? ! 242: so->so_rcv.sb_hiwat : cloned_so->so_rcv.sb_lowat; ! 243: ! 244: /* SO_SNDTIMEO, SO_RCVTIMEO */ ! 245: so->so_snd.sb_timeo = cloned_so->so_snd.sb_timeo; ! 246: so->so_rcv.sb_timeo = cloned_so->so_rcv.sb_timeo; ! 247: } ! 248: ! 249: error = (*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, 0, p); ! 250: /* Just ignore protocols that do not understand it */ ! 251: if (error == EOPNOTSUPP) ! 252: error = 0; ! 253: return (error); ! 254: } ! 255: } ! 256: /* ! 257: * Interface/routing/protocol specific ioctls: ! 258: * interface and routing ioctls should have a ! 259: * different entry since a socket's unnecessary ! 260: */ ! 261: if (IOCGROUP(cmd) == 'i') ! 262: return (ifioctl(so, cmd, data, p)); ! 263: if (IOCGROUP(cmd) == 'r') ! 264: return (rtioctl(cmd, data, p)); ! 265: return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, 0, p)); ! 266: } ! 267: ! 268: int ! 269: soo_select(fp, which, p) ! 270: struct file *fp; ! 271: int which; ! 272: struct proc *p; ! 273: { ! 274: register struct socket *so = (struct socket *)fp->f_data; ! 275: register int s = splnet(); ! 276: ! 277: switch (which) { ! 278: ! 279: case FREAD: ! 280: if (soreadable(so)) { ! 281: splx(s); ! 282: return (1); ! 283: } ! 284: selrecord(p, &so->so_rcv.sb_sel); ! 285: so->so_rcv.sb_flags |= SB_SEL; ! 286: break; ! 287: ! 288: case FWRITE: ! 289: if (sowriteable(so)) { ! 290: splx(s); ! 291: return (1); ! 292: } ! 293: selrecord(p, &so->so_snd.sb_sel); ! 294: so->so_snd.sb_flags |= SB_SEL; ! 295: break; ! 296: ! 297: case 0: ! 298: if (so->so_oobmark || (so->so_state & SS_RCVATMARK)) { ! 299: splx(s); ! 300: return (1); ! 301: } ! 302: selrecord(p, &so->so_rcv.sb_sel); ! 303: so->so_rcv.sb_flags |= SB_SEL; ! 304: break; ! 305: } ! 306: splx(s); ! 307: return (0); ! 308: } ! 309: ! 310: ! 311: int ! 312: soo_stat(so, ub) ! 313: register struct socket *so; ! 314: register struct stat *ub; ! 315: { ! 316: ! 317: bzero((caddr_t)ub, sizeof (*ub)); ! 318: ub->st_mode = S_IFSOCK; ! 319: return ((*so->so_proto->pr_usrreqs->pru_sense)(so, ub)); ! 320: } ! 321: ! 322: /* ARGSUSED */ ! 323: int ! 324: soo_close(fp, p) ! 325: struct file *fp; ! 326: struct proc *p; ! 327: { ! 328: int error = 0; ! 329: ! 330: if (fp->f_data) ! 331: error = soclose((struct socket *)fp->f_data); ! 332: fp->f_data = 0; ! 333: return (error); ! 334: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.