Annotation of XNU/bsd/kern/sys_socket.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.