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