1: /*
   2:  * Copyright (c) 1982, 1986 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:  *	@(#)uipc_syscalls.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "param.h"
  10: #include "systm.h"
  11: #include "dir.h"
  12: #include "user.h"
  13: #include "proc.h"
  14: #include "file.h"
  15: #include "inode.h"
  16: #include "buf.h"
  17: #include "mbuf.h"
  18: #include "protosw.h"
  19: #include "socket.h"
  20: #include "socketvar.h"
  21: #include "uio.h"
  22: 
  23: /*
  24:  * System call interface to the socket abstraction.
  25:  */
  26: 
  27: struct  file *getsock();
  28: extern  struct fileops socketops;
  29: 
  30: socket()
  31: {
  32:     register struct a {
  33:         int domain;
  34:         int type;
  35:         int protocol;
  36:     } *uap = (struct a *)u.u_ap;
  37:     struct socket *so;
  38:     register struct file *fp;
  39: 
  40:     if ((fp = falloc()) == NULL)
  41:         return;
  42:     fp->f_flag = FREAD|FWRITE;
  43:     fp->f_type = DTYPE_SOCKET;
  44:     fp->f_ops = &socketops;
  45:     u.u_error = socreate(uap->domain, &so, uap->type, uap->protocol);
  46:     if (u.u_error)
  47:         goto bad;
  48:     fp->f_data = (caddr_t)so;
  49:     return;
  50: bad:
  51:     u.u_ofile[u.u_r.r_val1] = 0;
  52:     fp->f_count = 0;
  53: }
  54: 
  55: bind()
  56: {
  57:     register struct a {
  58:         int s;
  59:         caddr_t name;
  60:         int namelen;
  61:     } *uap = (struct a *)u.u_ap;
  62:     register struct file *fp;
  63:     struct mbuf *nam;
  64: 
  65:     fp = getsock(uap->s);
  66:     if (fp == 0)
  67:         return;
  68:     u.u_error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME);
  69:     if (u.u_error)
  70:         return;
  71:     u.u_error = sobind((struct socket *)fp->f_data, nam);
  72:     m_freem(nam);
  73: }
  74: 
  75: listen()
  76: {
  77:     register struct a {
  78:         int s;
  79:         int backlog;
  80:     } *uap = (struct a *)u.u_ap;
  81:     register struct file *fp;
  82: 
  83:     fp = getsock(uap->s);
  84:     if (fp == 0)
  85:         return;
  86:     u.u_error = solisten((struct socket *)fp->f_data, uap->backlog);
  87: }
  88: 
  89: accept()
  90: {
  91:     register struct a {
  92:         int s;
  93:         caddr_t name;
  94:         int *anamelen;
  95:     } *uap = (struct a *)u.u_ap;
  96:     register struct file *fp;
  97:     struct mbuf *nam;
  98:     int namelen;
  99:     int s;
 100:     register struct socket *so;
 101: 
 102:     if (uap->name == 0)
 103:         goto noname;
 104:     u.u_error = copyin((caddr_t)uap->anamelen, (caddr_t)&namelen,
 105:         sizeof (namelen));
 106:     if (u.u_error)
 107:         return;
 108:     if (useracc((caddr_t)uap->name, (u_int)namelen, B_WRITE) == 0) {
 109:         u.u_error = EFAULT;
 110:         return;
 111:     }
 112: noname:
 113:     fp = getsock(uap->s);
 114:     if (fp == 0)
 115:         return;
 116:     s = splnet();
 117:     so = (struct socket *)fp->f_data;
 118:     if ((so->so_options & SO_ACCEPTCONN) == 0) {
 119:         u.u_error = EINVAL;
 120:         splx(s);
 121:         return;
 122:     }
 123:     if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {
 124:         u.u_error = EWOULDBLOCK;
 125:         splx(s);
 126:         return;
 127:     }
 128:     while (so->so_qlen == 0 && so->so_error == 0) {
 129:         if (so->so_state & SS_CANTRCVMORE) {
 130:             so->so_error = ECONNABORTED;
 131:             break;
 132:         }
 133:         sleep((caddr_t)&so->so_timeo, PZERO+1);
 134:     }
 135:     if (so->so_error) {
 136:         u.u_error = so->so_error;
 137:         so->so_error = 0;
 138:         splx(s);
 139:         return;
 140:     }
 141:     if (ufalloc(0) < 0) {
 142:         splx(s);
 143:         return;
 144:     }
 145:     fp = falloc();
 146:     if (fp == 0) {
 147:         u.u_ofile[u.u_r.r_val1] = 0;
 148:         splx(s);
 149:         return;
 150:     }
 151:     { struct socket *aso = so->so_q;
 152:       if (soqremque(aso, 1) == 0)
 153:         panic("accept");
 154:       so = aso;
 155:     }
 156:     fp->f_type = DTYPE_SOCKET;
 157:     fp->f_flag = FREAD|FWRITE;
 158:     fp->f_ops = &socketops;
 159:     fp->f_data = (caddr_t)so;
 160:     nam = m_get(M_WAIT, MT_SONAME);
 161:     (void) soaccept(so, nam);
 162:     if (uap->name) {
 163:         if (namelen > nam->m_len)
 164:             namelen = nam->m_len;
 165:         /* SHOULD COPY OUT A CHAIN HERE */
 166:         (void) copyout(mtod(nam, caddr_t), (caddr_t)uap->name,
 167:             (u_int)namelen);
 168:         (void) copyout((caddr_t)&namelen, (caddr_t)uap->anamelen,
 169:             sizeof (*uap->anamelen));
 170:     }
 171:     m_freem(nam);
 172:     splx(s);
 173: }
 174: 
 175: connect()
 176: {
 177:     register struct a {
 178:         int s;
 179:         caddr_t name;
 180:         int namelen;
 181:     } *uap = (struct a *)u.u_ap;
 182:     register struct file *fp;
 183:     register struct socket *so;
 184:     struct mbuf *nam;
 185:     int s;
 186: 
 187:     fp = getsock(uap->s);
 188:     if (fp == 0)
 189:         return;
 190:     so = (struct socket *)fp->f_data;
 191:     if ((so->so_state & SS_NBIO) &&
 192:         (so->so_state & SS_ISCONNECTING)) {
 193:         u.u_error = EALREADY;
 194:         return;
 195:     }
 196:     u.u_error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME);
 197:     if (u.u_error)
 198:         return;
 199:     u.u_error = soconnect(so, nam);
 200:     if (u.u_error)
 201:         goto bad;
 202:     if ((so->so_state & SS_NBIO) &&
 203:         (so->so_state & SS_ISCONNECTING)) {
 204:         u.u_error = EINPROGRESS;
 205:         m_freem(nam);
 206:         return;
 207:     }
 208:     s = splnet();
 209:     if (setjmp(&u.u_qsave)) {
 210:         if (u.u_error == 0)
 211:             u.u_error = EINTR;
 212:         goto bad2;
 213:     }
 214:     while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
 215:         sleep((caddr_t)&so->so_timeo, PZERO+1);
 216:     u.u_error = so->so_error;
 217:     so->so_error = 0;
 218: bad2:
 219:     splx(s);
 220: bad:
 221:     so->so_state &= ~SS_ISCONNECTING;
 222:     m_freem(nam);
 223: }
 224: 
 225: socketpair()
 226: {
 227:     register struct a {
 228:         int domain;
 229:         int type;
 230:         int protocol;
 231:         int *rsv;
 232:     } *uap = (struct a *)u.u_ap;
 233:     register struct file *fp1, *fp2;
 234:     struct socket *so1, *so2;
 235:     int sv[2];
 236: 
 237:     if (useracc((caddr_t)uap->rsv, 2 * sizeof (int), B_WRITE) == 0) {
 238:         u.u_error = EFAULT;
 239:         return;
 240:     }
 241:     u.u_error = socreate(uap->domain, &so1, uap->type, uap->protocol);
 242:     if (u.u_error)
 243:         return;
 244:     u.u_error = socreate(uap->domain, &so2, uap->type, uap->protocol);
 245:     if (u.u_error)
 246:         goto free;
 247:     fp1 = falloc();
 248:     if (fp1 == NULL)
 249:         goto free2;
 250:     sv[0] = u.u_r.r_val1;
 251:     fp1->f_flag = FREAD|FWRITE;
 252:     fp1->f_type = DTYPE_SOCKET;
 253:     fp1->f_ops = &socketops;
 254:     fp1->f_data = (caddr_t)so1;
 255:     fp2 = falloc();
 256:     if (fp2 == NULL)
 257:         goto free3;
 258:     fp2->f_flag = FREAD|FWRITE;
 259:     fp2->f_type = DTYPE_SOCKET;
 260:     fp2->f_ops = &socketops;
 261:     fp2->f_data = (caddr_t)so2;
 262:     sv[1] = u.u_r.r_val1;
 263:     u.u_error = soconnect2(so1, so2);
 264:     if (u.u_error)
 265:         goto free4;
 266:     if (uap->type == SOCK_DGRAM) {
 267:         /*
 268: 		 * Datagram socket connection is asymmetric.
 269: 		 */
 270:          u.u_error = soconnect2(so2, so1);
 271:          if (u.u_error)
 272:             goto free4;
 273:     }
 274:     u.u_r.r_val1 = 0;
 275:     (void) copyout((caddr_t)sv, (caddr_t)uap->rsv, 2 * sizeof (int));
 276:     return;
 277: free4:
 278:     fp2->f_count = 0;
 279:     u.u_ofile[sv[1]] = 0;
 280: free3:
 281:     fp1->f_count = 0;
 282:     u.u_ofile[sv[0]] = 0;
 283: free2:
 284:     (void)soclose(so2);
 285: free:
 286:     (void)soclose(so1);
 287: }
 288: 
 289: sendto()
 290: {
 291:     register struct a {
 292:         int s;
 293:         caddr_t buf;
 294:         int len;
 295:         int flags;
 296:         caddr_t to;
 297:         int tolen;
 298:     } *uap = (struct a *)u.u_ap;
 299:     struct msghdr msg;
 300:     struct iovec aiov;
 301: 
 302:     msg.msg_name = uap->to;
 303:     msg.msg_namelen = uap->tolen;
 304:     msg.msg_iov = &aiov;
 305:     msg.msg_iovlen = 1;
 306:     aiov.iov_base = uap->buf;
 307:     aiov.iov_len = uap->len;
 308:     msg.msg_accrights = 0;
 309:     msg.msg_accrightslen = 0;
 310:     sendit(uap->s, &msg, uap->flags);
 311: }
 312: 
 313: send()
 314: {
 315:     register struct a {
 316:         int s;
 317:         caddr_t buf;
 318:         int len;
 319:         int flags;
 320:     } *uap = (struct a *)u.u_ap;
 321:     struct msghdr msg;
 322:     struct iovec aiov;
 323: 
 324:     msg.msg_name = 0;
 325:     msg.msg_namelen = 0;
 326:     msg.msg_iov = &aiov;
 327:     msg.msg_iovlen = 1;
 328:     aiov.iov_base = uap->buf;
 329:     aiov.iov_len = uap->len;
 330:     msg.msg_accrights = 0;
 331:     msg.msg_accrightslen = 0;
 332:     sendit(uap->s, &msg, uap->flags);
 333: }
 334: 
 335: sendmsg()
 336: {
 337:     register struct a {
 338:         int s;
 339:         caddr_t msg;
 340:         int flags;
 341:     } *uap = (struct a *)u.u_ap;
 342:     struct msghdr msg;
 343:     struct iovec aiov[MSG_MAXIOVLEN];
 344: 
 345:     u.u_error = copyin(uap->msg, (caddr_t)&msg, sizeof (msg));
 346:     if (u.u_error)
 347:         return;
 348:     if ((u_int)msg.msg_iovlen >= sizeof (aiov) / sizeof (aiov[0])) {
 349:         u.u_error = EMSGSIZE;
 350:         return;
 351:     }
 352:     u.u_error =
 353:         copyin((caddr_t)msg.msg_iov, (caddr_t)aiov,
 354:         (unsigned)(msg.msg_iovlen * sizeof (aiov[0])));
 355:     if (u.u_error)
 356:         return;
 357:     msg.msg_iov = aiov;
 358:     sendit(uap->s, &msg, uap->flags);
 359: }
 360: 
 361: sendit(s, mp, flags)
 362:     int s;
 363:     register struct msghdr *mp;
 364:     int flags;
 365: {
 366:     register struct file *fp;
 367:     struct uio auio;
 368:     register struct iovec *iov;
 369:     register int i;
 370:     struct mbuf *to, *rights;
 371:     int len;
 372: 
 373:     fp = getsock(s);
 374:     if (fp == 0)
 375:         return;
 376:     auio.uio_iov = mp->msg_iov;
 377:     auio.uio_iovcnt = mp->msg_iovlen;
 378:     auio.uio_segflg = UIO_USERSPACE;
 379:     auio.uio_offset = 0;            /* XXX */
 380:     auio.uio_resid = 0;
 381:     iov = mp->msg_iov;
 382:     for (i = 0; i < mp->msg_iovlen; i++, iov++) {
 383:         if (iov->iov_len < 0) {
 384:             u.u_error = EINVAL;
 385:             return;
 386:         }
 387:         if (iov->iov_len == 0)
 388:             continue;
 389:         if (useracc(iov->iov_base, (u_int)iov->iov_len, B_READ) == 0) {
 390:             u.u_error = EFAULT;
 391:             return;
 392:         }
 393:         auio.uio_resid += iov->iov_len;
 394:     }
 395:     if (mp->msg_name) {
 396:         u.u_error =
 397:             sockargs(&to, mp->msg_name, mp->msg_namelen, MT_SONAME);
 398:         if (u.u_error)
 399:             return;
 400:     } else
 401:         to = 0;
 402:     if (mp->msg_accrights) {
 403:         u.u_error =
 404:             sockargs(&rights, mp->msg_accrights, mp->msg_accrightslen,
 405:             MT_RIGHTS);
 406:         if (u.u_error)
 407:             goto bad;
 408:     } else
 409:         rights = 0;
 410:     len = auio.uio_resid;
 411:     u.u_error =
 412:         sosend((struct socket *)fp->f_data, to, &auio, flags, rights);
 413:     u.u_r.r_val1 = len - auio.uio_resid;
 414:     if (rights)
 415:         m_freem(rights);
 416: bad:
 417:     if (to)
 418:         m_freem(to);
 419: }
 420: 
 421: recvfrom()
 422: {
 423:     register struct a {
 424:         int s;
 425:         caddr_t buf;
 426:         int len;
 427:         int flags;
 428:         caddr_t from;
 429:         int *fromlenaddr;
 430:     } *uap = (struct a *)u.u_ap;
 431:     struct msghdr msg;
 432:     struct iovec aiov;
 433:     int len;
 434: 
 435:     u.u_error = copyin((caddr_t)uap->fromlenaddr, (caddr_t)&len,
 436:        sizeof (len));
 437:     if (u.u_error)
 438:         return;
 439:     msg.msg_name = uap->from;
 440:     msg.msg_namelen = len;
 441:     msg.msg_iov = &aiov;
 442:     msg.msg_iovlen = 1;
 443:     aiov.iov_base = uap->buf;
 444:     aiov.iov_len = uap->len;
 445:     msg.msg_accrights = 0;
 446:     msg.msg_accrightslen = 0;
 447:     recvit(uap->s, &msg, uap->flags, (caddr_t)uap->fromlenaddr, (caddr_t)0);
 448: }
 449: 
 450: recv()
 451: {
 452:     register struct a {
 453:         int s;
 454:         caddr_t buf;
 455:         int len;
 456:         int flags;
 457:     } *uap = (struct a *)u.u_ap;
 458:     struct msghdr msg;
 459:     struct iovec aiov;
 460: 
 461:     msg.msg_name = 0;
 462:     msg.msg_namelen = 0;
 463:     msg.msg_iov = &aiov;
 464:     msg.msg_iovlen = 1;
 465:     aiov.iov_base = uap->buf;
 466:     aiov.iov_len = uap->len;
 467:     msg.msg_accrights = 0;
 468:     msg.msg_accrightslen = 0;
 469:     recvit(uap->s, &msg, uap->flags, (caddr_t)0, (caddr_t)0);
 470: }
 471: 
 472: recvmsg()
 473: {
 474:     register struct a {
 475:         int s;
 476:         struct  msghdr *msg;
 477:         int flags;
 478:     } *uap = (struct a *)u.u_ap;
 479:     struct msghdr msg;
 480:     struct iovec aiov[MSG_MAXIOVLEN];
 481: 
 482:     u.u_error = copyin((caddr_t)uap->msg, (caddr_t)&msg, sizeof (msg));
 483:     if (u.u_error)
 484:         return;
 485:     if ((u_int)msg.msg_iovlen >= sizeof (aiov) / sizeof (aiov[0])) {
 486:         u.u_error = EMSGSIZE;
 487:         return;
 488:     }
 489:     u.u_error =
 490:         copyin((caddr_t)msg.msg_iov, (caddr_t)aiov,
 491:         (unsigned)(msg.msg_iovlen * sizeof (aiov[0])));
 492:     if (u.u_error)
 493:         return;
 494:     msg.msg_iov = aiov;
 495:     if (msg.msg_accrights)
 496:         if (useracc((caddr_t)msg.msg_accrights,
 497:             (unsigned)msg.msg_accrightslen, B_WRITE) == 0) {
 498:             u.u_error = EFAULT;
 499:             return;
 500:         }
 501:     recvit(uap->s, &msg, uap->flags,
 502:         (caddr_t)&uap->msg->msg_namelen,
 503:         (caddr_t)&uap->msg->msg_accrightslen);
 504: }
 505: 
 506: recvit(s, mp, flags, namelenp, rightslenp)
 507:     int s;
 508:     register struct msghdr *mp;
 509:     int flags;
 510:     caddr_t namelenp, rightslenp;
 511: {
 512:     register struct file *fp;
 513:     struct uio auio;
 514:     register struct iovec *iov;
 515:     register int i;
 516:     struct mbuf *from, *rights;
 517:     int len;
 518: 
 519:     fp = getsock(s);
 520:     if (fp == 0)
 521:         return;
 522:     auio.uio_iov = mp->msg_iov;
 523:     auio.uio_iovcnt = mp->msg_iovlen;
 524:     auio.uio_segflg = UIO_USERSPACE;
 525:     auio.uio_offset = 0;            /* XXX */
 526:     auio.uio_resid = 0;
 527:     iov = mp->msg_iov;
 528:     for (i = 0; i < mp->msg_iovlen; i++, iov++) {
 529:         if (iov->iov_len < 0) {
 530:             u.u_error = EINVAL;
 531:             return;
 532:         }
 533:         if (iov->iov_len == 0)
 534:             continue;
 535:         if (useracc(iov->iov_base, (u_int)iov->iov_len, B_WRITE) == 0) {
 536:             u.u_error = EFAULT;
 537:             return;
 538:         }
 539:         auio.uio_resid += iov->iov_len;
 540:     }
 541:     len = auio.uio_resid;
 542:     u.u_error =
 543:         soreceive((struct socket *)fp->f_data, &from, &auio,
 544:         flags, &rights);
 545:     u.u_r.r_val1 = len - auio.uio_resid;
 546:     if (mp->msg_name) {
 547:         len = mp->msg_namelen;
 548:         if (len <= 0 || from == 0)
 549:             len = 0;
 550:         else {
 551:             if (len > from->m_len)
 552:                 len = from->m_len;
 553:             (void) copyout((caddr_t)mtod(from, caddr_t),
 554:                 (caddr_t)mp->msg_name, (unsigned)len);
 555:         }
 556:         (void) copyout((caddr_t)&len, namelenp, sizeof (int));
 557:     }
 558:     if (mp->msg_accrights) {
 559:         len = mp->msg_accrightslen;
 560:         if (len <= 0 || rights == 0)
 561:             len = 0;
 562:         else {
 563:             if (len > rights->m_len)
 564:                 len = rights->m_len;
 565:             (void) copyout((caddr_t)mtod(rights, caddr_t),
 566:                 (caddr_t)mp->msg_accrights, (unsigned)len);
 567:         }
 568:         (void) copyout((caddr_t)&len, rightslenp, sizeof (int));
 569:     }
 570:     if (rights)
 571:         m_freem(rights);
 572:     if (from)
 573:         m_freem(from);
 574: }
 575: 
 576: shutdown()
 577: {
 578:     struct a {
 579:         int s;
 580:         int how;
 581:     } *uap = (struct a *)u.u_ap;
 582:     struct file *fp;
 583: 
 584:     fp = getsock(uap->s);
 585:     if (fp == 0)
 586:         return;
 587:     u.u_error = soshutdown((struct socket *)fp->f_data, uap->how);
 588: }
 589: 
 590: setsockopt()
 591: {
 592:     struct a {
 593:         int s;
 594:         int level;
 595:         int name;
 596:         caddr_t val;
 597:         int valsize;
 598:     } *uap = (struct a *)u.u_ap;
 599:     struct file *fp;
 600:     struct mbuf *m = NULL;
 601: 
 602:     fp = getsock(uap->s);
 603:     if (fp == 0)
 604:         return;
 605:     if (uap->valsize > MLEN) {
 606:         u.u_error = EINVAL;
 607:         return;
 608:     }
 609:     if (uap->val) {
 610:         m = m_get(M_WAIT, MT_SOOPTS);
 611:         if (m == NULL) {
 612:             u.u_error = ENOBUFS;
 613:             return;
 614:         }
 615:         u.u_error =
 616:             copyin(uap->val, mtod(m, caddr_t), (u_int)uap->valsize);
 617:         if (u.u_error) {
 618:             (void) m_free(m);
 619:             return;
 620:         }
 621:         m->m_len = uap->valsize;
 622:     }
 623:     u.u_error =
 624:         sosetopt((struct socket *)fp->f_data, uap->level, uap->name, m);
 625: }
 626: 
 627: getsockopt()
 628: {
 629:     struct a {
 630:         int s;
 631:         int level;
 632:         int name;
 633:         caddr_t val;
 634:         int *avalsize;
 635:     } *uap = (struct a *)u.u_ap;
 636:     struct file *fp;
 637:     struct mbuf *m = NULL;
 638:     int valsize;
 639: 
 640:     fp = getsock(uap->s);
 641:     if (fp == 0)
 642:         return;
 643:     if (uap->val) {
 644:         u.u_error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
 645:             sizeof (valsize));
 646:         if (u.u_error)
 647:             return;
 648:     } else
 649:         valsize = 0;
 650:     u.u_error =
 651:         sogetopt((struct socket *)fp->f_data, uap->level, uap->name, &m);
 652:     if (u.u_error)
 653:         goto bad;
 654:     if (uap->val && valsize && m != NULL) {
 655:         if (valsize > m->m_len)
 656:             valsize = m->m_len;
 657:         u.u_error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
 658:         if (u.u_error)
 659:             goto bad;
 660:         u.u_error = copyout((caddr_t)&valsize, (caddr_t)uap->avalsize,
 661:             sizeof (valsize));
 662:     }
 663: bad:
 664:     if (m != NULL)
 665:         (void) m_free(m);
 666: }
 667: 
 668: pipe()
 669: {
 670:     register struct file *rf, *wf;
 671:     struct socket *rso, *wso;
 672:     int r;
 673: 
 674:     u.u_error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0);
 675:     if (u.u_error)
 676:         return;
 677:     u.u_error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0);
 678:     if (u.u_error)
 679:         goto free;
 680:     rf = falloc();
 681:     if (rf == NULL)
 682:         goto free2;
 683:     r = u.u_r.r_val1;
 684:     rf->f_flag = FREAD;
 685:     rf->f_type = DTYPE_SOCKET;
 686:     rf->f_ops = &socketops;
 687:     rf->f_data = (caddr_t)rso;
 688:     wf = falloc();
 689:     if (wf == NULL)
 690:         goto free3;
 691:     wf->f_flag = FWRITE;
 692:     wf->f_type = DTYPE_SOCKET;
 693:     wf->f_ops = &socketops;
 694:     wf->f_data = (caddr_t)wso;
 695:     u.u_r.r_val2 = u.u_r.r_val1;
 696:     u.u_r.r_val1 = r;
 697:     if (u.u_error = unp_connect2(wso, rso))
 698:         goto free4;
 699:     wso->so_state |= SS_CANTRCVMORE;
 700:     rso->so_state |= SS_CANTSENDMORE;
 701:     return;
 702: free4:
 703:     wf->f_count = 0;
 704:     u.u_ofile[u.u_r.r_val2] = 0;
 705: free3:
 706:     rf->f_count = 0;
 707:     u.u_ofile[r] = 0;
 708: free2:
 709:     (void)soclose(wso);
 710: free:
 711:     (void)soclose(rso);
 712: }
 713: 
 714: /*
 715:  * Get socket name.
 716:  */
 717: getsockname()
 718: {
 719:     register struct a {
 720:         int fdes;
 721:         caddr_t asa;
 722:         int *alen;
 723:     } *uap = (struct a *)u.u_ap;
 724:     register struct file *fp;
 725:     register struct socket *so;
 726:     struct mbuf *m;
 727:     int len;
 728: 
 729:     fp = getsock(uap->fdes);
 730:     if (fp == 0)
 731:         return;
 732:     u.u_error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len));
 733:     if (u.u_error)
 734:         return;
 735:     so = (struct socket *)fp->f_data;
 736:     m = m_getclr(M_WAIT, MT_SONAME);
 737:     if (m == NULL) {
 738:         u.u_error = ENOBUFS;
 739:         return;
 740:     }
 741:     u.u_error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0);
 742:     if (u.u_error)
 743:         goto bad;
 744:     if (len > m->m_len)
 745:         len = m->m_len;
 746:     u.u_error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len);
 747:     if (u.u_error)
 748:         goto bad;
 749:     u.u_error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len));
 750: bad:
 751:     m_freem(m);
 752: }
 753: 
 754: /*
 755:  * Get name of peer for connected socket.
 756:  */
 757: getpeername()
 758: {
 759:     register struct a {
 760:         int fdes;
 761:         caddr_t asa;
 762:         int *alen;
 763:     } *uap = (struct a *)u.u_ap;
 764:     register struct file *fp;
 765:     register struct socket *so;
 766:     struct mbuf *m;
 767:     int len;
 768: 
 769:     fp = getsock(uap->fdes);
 770:     if (fp == 0)
 771:         return;
 772:     so = (struct socket *)fp->f_data;
 773:     if ((so->so_state & SS_ISCONNECTED) == 0) {
 774:         u.u_error = ENOTCONN;
 775:         return;
 776:     }
 777:     m = m_getclr(M_WAIT, MT_SONAME);
 778:     if (m == NULL) {
 779:         u.u_error = ENOBUFS;
 780:         return;
 781:     }
 782:     u.u_error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len));
 783:     if (u.u_error)
 784:         return;
 785:     u.u_error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0);
 786:     if (u.u_error)
 787:         goto bad;
 788:     if (len > m->m_len)
 789:         len = m->m_len;
 790:     u.u_error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len);
 791:     if (u.u_error)
 792:         goto bad;
 793:     u.u_error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len));
 794: bad:
 795:     m_freem(m);
 796: }
 797: 
 798: sockargs(aname, name, namelen, type)
 799:     struct mbuf **aname;
 800:     caddr_t name;
 801:     int namelen, type;
 802: {
 803:     register struct mbuf *m;
 804:     int error;
 805: 
 806:     if (namelen > MLEN)
 807:         return (EINVAL);
 808:     m = m_get(M_WAIT, type);
 809:     if (m == NULL)
 810:         return (ENOBUFS);
 811:     m->m_len = namelen;
 812:     error = copyin(name, mtod(m, caddr_t), (u_int)namelen);
 813:     if (error)
 814:         (void) m_free(m);
 815:     else
 816:         *aname = m;
 817:     return (error);
 818: }
 819: 
 820: struct file *
 821: getsock(fdes)
 822:     int fdes;
 823: {
 824:     register struct file *fp;
 825: 
 826:     fp = getf(fdes);
 827:     if (fp == NULL)
 828:         return (0);
 829:     if (fp->f_type != DTYPE_SOCKET) {
 830:         u.u_error = ENOTSOCK;
 831:         return (0);
 832:     }
 833:     return (fp);
 834: }

Defined functions

accept defined in line 89; used 2 times
bind defined in line 55; used 2 times
connect defined in line 175; used 2 times
getpeername defined in line 757; used 2 times
getsock defined in line 820; used 12 times
getsockname defined in line 717; used 2 times
getsockopt defined in line 627; used 2 times
listen defined in line 75; used 2 times
pipe defined in line 668; used 2 times
recv defined in line 450; used 2 times
recvfrom defined in line 421; used 2 times
recvit defined in line 506; used 3 times
recvmsg defined in line 472; used 2 times
send defined in line 313; used 2 times
sendit defined in line 361; used 3 times
sendmsg defined in line 335; used 2 times
sendto defined in line 289; used 2 times
setsockopt defined in line 590; used 2 times
shutdown defined in line 576; used 2 times
sockargs defined in line 798; used 4 times
socket defined in line 30; used 2 times
socketpair defined in line 225; used 2 times

Defined struct's

a defined in line 759; used 34 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2542
Valid CSS Valid XHTML 1.0 Strict