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