kern_sendfile.c (25201) | kern_sendfile.c (28270) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 | 1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 |
34 * $Id: uipc_syscalls.c,v 1.25 1997/04/09 16:53:40 bde Exp $ | 34 * $Id: uipc_syscalls.c,v 1.26 1997/04/27 20:00:45 wollman Exp $ |
35 */ 36 37#include "opt_ktrace.h" 38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/sysproto.h> 42#include <sys/filedesc.h> --- 73 unchanged lines hidden (view full) --- 116 register struct bind_args /* { 117 int s; 118 caddr_t name; 119 int namelen; 120 } */ *uap; 121 int *retval; 122{ 123 struct file *fp; | 35 */ 36 37#include "opt_ktrace.h" 38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/sysproto.h> 42#include <sys/filedesc.h> --- 73 unchanged lines hidden (view full) --- 116 register struct bind_args /* { 117 int s; 118 caddr_t name; 119 int namelen; 120 } */ *uap; 121 int *retval; 122{ 123 struct file *fp; |
124 struct mbuf *nam; | 124 struct sockaddr *sa; |
125 int error; 126 127 error = getsock(p->p_fd, uap->s, &fp); 128 if (error) 129 return (error); | 125 int error; 126 127 error = getsock(p->p_fd, uap->s, &fp); 128 if (error) 129 return (error); |
130 error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME); | 130 error = getsockaddr(&sa, uap->name, uap->namelen); |
131 if (error) 132 return (error); | 131 if (error) 132 return (error); |
133 error = sobind((struct socket *)fp->f_data, nam, p); 134 m_freem(nam); | 133 error = sobind((struct socket *)fp->f_data, sa, p); 134 FREE(sa, M_SONAME); |
135 return (error); 136} 137 138/* ARGSUSED */ 139int 140listen(p, uap, retval) 141 struct proc *p; 142 register struct listen_args /* { --- 18 unchanged lines hidden (view full) --- 161 int s; 162 caddr_t name; 163 int *anamelen; 164 } */ *uap; 165 int *retval; 166 int compat; 167{ 168 struct file *fp; | 135 return (error); 136} 137 138/* ARGSUSED */ 139int 140listen(p, uap, retval) 141 struct proc *p; 142 register struct listen_args /* { --- 18 unchanged lines hidden (view full) --- 161 int s; 162 caddr_t name; 163 int *anamelen; 164 } */ *uap; 165 int *retval; 166 int compat; 167{ 168 struct file *fp; |
169 struct mbuf *nam; | 169 struct sockaddr *sa; |
170 int namelen, error, s; 171 struct socket *head, *so; 172 short fflag; /* type must match fp->f_flag */ 173 174 if (uap->name) { 175 error = copyin((caddr_t)uap->anamelen, (caddr_t)&namelen, 176 sizeof (namelen)); 177 if(error) --- 60 unchanged lines hidden (view full) --- 238 239 so->so_state &= ~SS_COMP; 240 so->so_head = NULL; 241 242 fp->f_type = DTYPE_SOCKET; 243 fp->f_flag = fflag; 244 fp->f_ops = &socketops; 245 fp->f_data = (caddr_t)so; | 170 int namelen, error, s; 171 struct socket *head, *so; 172 short fflag; /* type must match fp->f_flag */ 173 174 if (uap->name) { 175 error = copyin((caddr_t)uap->anamelen, (caddr_t)&namelen, 176 sizeof (namelen)); 177 if(error) --- 60 unchanged lines hidden (view full) --- 238 239 so->so_state &= ~SS_COMP; 240 so->so_head = NULL; 241 242 fp->f_type = DTYPE_SOCKET; 243 fp->f_flag = fflag; 244 fp->f_ops = &socketops; 245 fp->f_data = (caddr_t)so; |
246 nam = m_get(M_WAIT, MT_SONAME); 247 (void) soaccept(so, nam); | 246 sa = 0; 247 (void) soaccept(so, &sa); 248 if (sa == 0) { 249 namelen = 0; 250 if (uap->name) 251 goto gotnoname; 252 return 0; 253 } 254 if ((u_long)sa < 0xf0000000) { 255 panic("accept1 bad sa"); 256 } |
248 if (uap->name) { 249#ifdef COMPAT_OLDSOCK 250 if (compat) | 257 if (uap->name) { 258#ifdef COMPAT_OLDSOCK 259 if (compat) |
251 mtod(nam, struct osockaddr *)->sa_family = 252 mtod(nam, struct sockaddr *)->sa_family; | 260 ((struct osockaddr *)sa)->sa_family = 261 sa->sa_family; |
253#endif | 262#endif |
254 if (namelen > nam->m_len) 255 namelen = nam->m_len; 256 /* SHOULD COPY OUT A CHAIN HERE */ 257 error = copyout(mtod(nam, caddr_t), (caddr_t)uap->name, 258 (u_int)namelen); | 263 if (namelen > sa->sa_len) 264 namelen = sa->sa_len; 265 error = copyout(sa, (caddr_t)uap->name, (u_int)namelen); |
259 if (!error) | 266 if (!error) |
267gotnoname: |
|
260 error = copyout((caddr_t)&namelen, 261 (caddr_t)uap->anamelen, sizeof (*uap->anamelen)); 262 } | 268 error = copyout((caddr_t)&namelen, 269 (caddr_t)uap->anamelen, sizeof (*uap->anamelen)); 270 } |
263 m_freem(nam); | 271 FREE(sa, M_SONAME); |
264 splx(s); 265 return (error); 266} 267 268int 269accept(p, uap, retval) 270 struct proc *p; 271 struct accept_args *uap; --- 23 unchanged lines hidden (view full) --- 295 int s; 296 caddr_t name; 297 int namelen; 298 } */ *uap; 299 int *retval; 300{ 301 struct file *fp; 302 register struct socket *so; | 272 splx(s); 273 return (error); 274} 275 276int 277accept(p, uap, retval) 278 struct proc *p; 279 struct accept_args *uap; --- 23 unchanged lines hidden (view full) --- 303 int s; 304 caddr_t name; 305 int namelen; 306 } */ *uap; 307 int *retval; 308{ 309 struct file *fp; 310 register struct socket *so; |
303 struct mbuf *nam; | 311 struct sockaddr *sa; |
304 int error, s; 305 306 error = getsock(p->p_fd, uap->s, &fp); 307 if (error) 308 return (error); 309 so = (struct socket *)fp->f_data; 310 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) 311 return (EALREADY); | 312 int error, s; 313 314 error = getsock(p->p_fd, uap->s, &fp); 315 if (error) 316 return (error); 317 so = (struct socket *)fp->f_data; 318 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) 319 return (EALREADY); |
312 error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME); | 320 error = getsockaddr(&sa, uap->name, uap->namelen); |
313 if (error) 314 return (error); | 321 if (error) 322 return (error); |
315 error = soconnect(so, nam, p); | 323 error = soconnect(so, sa, p); |
316 if (error) 317 goto bad; 318 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { | 324 if (error) 325 goto bad; 326 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { |
319 m_freem(nam); | 327 FREE(sa, M_SONAME); |
320 return (EINPROGRESS); 321 } 322 s = splnet(); 323 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { 324 error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH, 325 "connec", 0); 326 if (error) 327 break; 328 } 329 if (error == 0) { 330 error = so->so_error; 331 so->so_error = 0; 332 } 333 splx(s); 334bad: 335 so->so_state &= ~SS_ISCONNECTING; | 328 return (EINPROGRESS); 329 } 330 s = splnet(); 331 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { 332 error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH, 333 "connec", 0); 334 if (error) 335 break; 336 } 337 if (error == 0) { 338 error = so->so_error; 339 so->so_error = 0; 340 } 341 splx(s); 342bad: 343 so->so_state &= ~SS_ISCONNECTING; |
336 m_freem(nam); | 344 FREE(sa, M_SONAME); |
337 if (error == ERESTART) 338 error = EINTR; 339 return (error); 340} 341 342int 343socketpair(p, uap, retval) 344 struct proc *p; --- 68 unchanged lines hidden (view full) --- 413 int s; 414 register struct msghdr *mp; 415 int flags, *retsize; 416{ 417 struct file *fp; 418 struct uio auio; 419 register struct iovec *iov; 420 register int i; | 345 if (error == ERESTART) 346 error = EINTR; 347 return (error); 348} 349 350int 351socketpair(p, uap, retval) 352 struct proc *p; --- 68 unchanged lines hidden (view full) --- 421 int s; 422 register struct msghdr *mp; 423 int flags, *retsize; 424{ 425 struct file *fp; 426 struct uio auio; 427 register struct iovec *iov; 428 register int i; |
421 struct mbuf *to, *control; | 429 struct mbuf *control; 430 struct sockaddr *to; |
422 int len, error; 423 struct socket *so; 424#ifdef KTRACE 425 struct iovec *ktriov = NULL; 426#endif 427 428 error = getsock(p->p_fd, s, &fp); 429 if (error) --- 6 unchanged lines hidden (view full) --- 436 auio.uio_offset = 0; /* XXX */ 437 auio.uio_resid = 0; 438 iov = mp->msg_iov; 439 for (i = 0; i < mp->msg_iovlen; i++, iov++) { 440 if ((auio.uio_resid += iov->iov_len) < 0) 441 return (EINVAL); 442 } 443 if (mp->msg_name) { | 431 int len, error; 432 struct socket *so; 433#ifdef KTRACE 434 struct iovec *ktriov = NULL; 435#endif 436 437 error = getsock(p->p_fd, s, &fp); 438 if (error) --- 6 unchanged lines hidden (view full) --- 445 auio.uio_offset = 0; /* XXX */ 446 auio.uio_resid = 0; 447 iov = mp->msg_iov; 448 for (i = 0; i < mp->msg_iovlen; i++, iov++) { 449 if ((auio.uio_resid += iov->iov_len) < 0) 450 return (EINVAL); 451 } 452 if (mp->msg_name) { |
444 error = sockargs(&to, mp->msg_name, mp->msg_namelen, MT_SONAME); | 453 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); |
445 if (error) 446 return (error); 447 } else 448 to = 0; 449 if (mp->msg_control) { 450 if (mp->msg_controllen < sizeof(struct cmsghdr) 451#ifdef COMPAT_OLDSOCK 452 && mp->msg_flags != MSG_COMPAT --- 30 unchanged lines hidden (view full) --- 483 484 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 485 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 486 } 487#endif 488 len = auio.uio_resid; 489 so = (struct socket *)fp->f_data; 490 error = so->so_proto->pr_usrreqs->pru_sosend(so, to, &auio, 0, control, | 454 if (error) 455 return (error); 456 } else 457 to = 0; 458 if (mp->msg_control) { 459 if (mp->msg_controllen < sizeof(struct cmsghdr) 460#ifdef COMPAT_OLDSOCK 461 && mp->msg_flags != MSG_COMPAT --- 30 unchanged lines hidden (view full) --- 492 493 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 494 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 495 } 496#endif 497 len = auio.uio_resid; 498 so = (struct socket *)fp->f_data; 499 error = so->so_proto->pr_usrreqs->pru_sosend(so, to, &auio, 0, control, |
491 flags); | 500 flags, p); |
492 if (error) { 493 if (auio.uio_resid != len && (error == ERESTART || 494 error == EINTR || error == EWOULDBLOCK)) 495 error = 0; 496 if (error == EPIPE) 497 psignal(p, SIGPIPE); 498 } 499 if (error == 0) 500 *retsize = len - auio.uio_resid; 501#ifdef KTRACE 502 if (ktriov != NULL) { 503 if (error == 0) 504 ktrgenio(p->p_tracep, s, UIO_WRITE, 505 ktriov, *retsize, error); 506 FREE(ktriov, M_TEMP); 507 } 508#endif 509bad: 510 if (to) | 501 if (error) { 502 if (auio.uio_resid != len && (error == ERESTART || 503 error == EINTR || error == EWOULDBLOCK)) 504 error = 0; 505 if (error == EPIPE) 506 psignal(p, SIGPIPE); 507 } 508 if (error == 0) 509 *retsize = len - auio.uio_resid; 510#ifdef KTRACE 511 if (ktriov != NULL) { 512 if (error == 0) 513 ktrgenio(p->p_tracep, s, UIO_WRITE, 514 ktriov, *retsize, error); 515 FREE(ktriov, M_TEMP); 516 } 517#endif 518bad: 519 if (to) |
511 m_freem(to); | 520 FREE(to, M_SONAME); |
512 return (error); 513} 514 515int 516sendto(p, uap, retval) 517 struct proc *p; 518 register struct sendto_args /* { 519 int s; --- 134 unchanged lines hidden (view full) --- 654 caddr_t namelenp; 655 int *retsize; 656{ 657 struct file *fp; 658 struct uio auio; 659 register struct iovec *iov; 660 register int i; 661 int len, error; | 521 return (error); 522} 523 524int 525sendto(p, uap, retval) 526 struct proc *p; 527 register struct sendto_args /* { 528 int s; --- 134 unchanged lines hidden (view full) --- 663 caddr_t namelenp; 664 int *retsize; 665{ 666 struct file *fp; 667 struct uio auio; 668 register struct iovec *iov; 669 register int i; 670 int len, error; |
662 struct mbuf *m, *from = 0, *control = 0; | 671 struct mbuf *m, *control = 0; |
663 caddr_t ctlbuf; 664 struct socket *so; | 672 caddr_t ctlbuf; 673 struct socket *so; |
674 struct sockaddr *fromsa = 0; |
|
665#ifdef KTRACE 666 struct iovec *ktriov = NULL; 667#endif 668 669 error = getsock(p->p_fd, s, &fp); 670 if (error) 671 return (error); 672 auio.uio_iov = mp->msg_iov; --- 13 unchanged lines hidden (view full) --- 686 int iovlen = auio.uio_iovcnt * sizeof (struct iovec); 687 688 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 689 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 690 } 691#endif 692 len = auio.uio_resid; 693 so = (struct socket *)fp->f_data; | 675#ifdef KTRACE 676 struct iovec *ktriov = NULL; 677#endif 678 679 error = getsock(p->p_fd, s, &fp); 680 if (error) 681 return (error); 682 auio.uio_iov = mp->msg_iov; --- 13 unchanged lines hidden (view full) --- 696 int iovlen = auio.uio_iovcnt * sizeof (struct iovec); 697 698 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 699 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 700 } 701#endif 702 len = auio.uio_resid; 703 so = (struct socket *)fp->f_data; |
694 error = so->so_proto->pr_usrreqs->pru_soreceive(so, &from, &auio, | 704 error = so->so_proto->pr_usrreqs->pru_soreceive(so, &fromsa, &auio, |
695 (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0, 696 &mp->msg_flags); 697 if (error) { 698 if (auio.uio_resid != len && (error == ERESTART || 699 error == EINTR || error == EWOULDBLOCK)) 700 error = 0; 701 } 702#ifdef KTRACE --- 4 unchanged lines hidden (view full) --- 707 FREE(ktriov, M_TEMP); 708 } 709#endif 710 if (error) 711 goto out; 712 *retsize = len - auio.uio_resid; 713 if (mp->msg_name) { 714 len = mp->msg_namelen; | 705 (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0, 706 &mp->msg_flags); 707 if (error) { 708 if (auio.uio_resid != len && (error == ERESTART || 709 error == EINTR || error == EWOULDBLOCK)) 710 error = 0; 711 } 712#ifdef KTRACE --- 4 unchanged lines hidden (view full) --- 717 FREE(ktriov, M_TEMP); 718 } 719#endif 720 if (error) 721 goto out; 722 *retsize = len - auio.uio_resid; 723 if (mp->msg_name) { 724 len = mp->msg_namelen; |
715 if (len <= 0 || from == 0) | 725 if (len <= 0 || fromsa == 0) |
716 len = 0; 717 else { 718#ifdef COMPAT_OLDSOCK 719 if (mp->msg_flags & MSG_COMPAT) | 726 len = 0; 727 else { 728#ifdef COMPAT_OLDSOCK 729 if (mp->msg_flags & MSG_COMPAT) |
720 mtod(from, struct osockaddr *)->sa_family = 721 mtod(from, struct sockaddr *)->sa_family; | 730 ((struct osockaddr *)fromsa)->sa_family = 731 fromsa->sa_family; |
722#endif | 732#endif |
723 if (len > from->m_len) 724 len = from->m_len; 725 /* else if len < from->m_len ??? */ 726 error = copyout(mtod(from, caddr_t), | 733#ifndef MIN 734#define MIN(a,b) ((a)>(b)?(b):(a)) 735#endif 736 len = MIN(len, fromsa->sa_len); 737 error = copyout(fromsa, |
727 (caddr_t)mp->msg_name, (unsigned)len); 728 if (error) 729 goto out; 730 } 731 mp->msg_namelen = len; 732 if (namelenp && 733 (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) { 734#ifdef COMPAT_OLDSOCK --- 46 unchanged lines hidden (view full) --- 781 782 ctlbuf += tocopy; 783 len -= tocopy; 784 m = m->m_next; 785 } 786 mp->msg_controllen = ctlbuf - mp->msg_control; 787 } 788out: | 738 (caddr_t)mp->msg_name, (unsigned)len); 739 if (error) 740 goto out; 741 } 742 mp->msg_namelen = len; 743 if (namelenp && 744 (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) { 745#ifdef COMPAT_OLDSOCK --- 46 unchanged lines hidden (view full) --- 792 793 ctlbuf += tocopy; 794 len -= tocopy; 795 m = m->m_next; 796 } 797 mp->msg_controllen = ctlbuf - mp->msg_control; 798 } 799out: |
789 if (from) 790 m_freem(from); | 800 if (fromsa) 801 FREE(fromsa, M_SONAME); |
791 if (control) 792 m_freem(control); 793 return (error); 794} 795 796int 797recvfrom(p, uap, retval) 798 struct proc *p; --- 280 unchanged lines hidden (view full) --- 1079 caddr_t asa; 1080 int *alen; 1081 } */ *uap; 1082 int *retval; 1083 int compat; 1084{ 1085 struct file *fp; 1086 register struct socket *so; | 802 if (control) 803 m_freem(control); 804 return (error); 805} 806 807int 808recvfrom(p, uap, retval) 809 struct proc *p; --- 280 unchanged lines hidden (view full) --- 1090 caddr_t asa; 1091 int *alen; 1092 } */ *uap; 1093 int *retval; 1094 int compat; 1095{ 1096 struct file *fp; 1097 register struct socket *so; |
1087 struct mbuf *m; | 1098 struct sockaddr *sa; |
1088 int len, error; 1089 1090 error = getsock(p->p_fd, uap->fdes, &fp); 1091 if (error) 1092 return (error); 1093 error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)); 1094 if (error) 1095 return (error); 1096 so = (struct socket *)fp->f_data; | 1099 int len, error; 1100 1101 error = getsock(p->p_fd, uap->fdes, &fp); 1102 if (error) 1103 return (error); 1104 error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)); 1105 if (error) 1106 return (error); 1107 so = (struct socket *)fp->f_data; |
1097 m = m_getclr(M_WAIT, MT_SONAME); 1098 if (m == NULL) 1099 return (ENOBUFS); 1100 error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, m); | 1108 sa = 0; 1109 error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, &sa); |
1101 if (error) 1102 goto bad; | 1110 if (error) 1111 goto bad; |
1103 if (len > m->m_len) 1104 len = m->m_len; | 1112 if (sa == 0) { 1113 len = 0; 1114 goto gotnothing; 1115 } 1116 1117 len = MIN(len, sa->sa_len); |
1105#ifdef COMPAT_OLDSOCK 1106 if (compat) | 1118#ifdef COMPAT_OLDSOCK 1119 if (compat) |
1107 mtod(m, struct osockaddr *)->sa_family = 1108 mtod(m, struct sockaddr *)->sa_family; | 1120 ((struct osockaddr *)sa)->sa_family = sa->sa_family; |
1109#endif | 1121#endif |
1110 error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len); | 1122 error = copyout(sa, (caddr_t)uap->asa, (u_int)len); |
1111 if (error == 0) | 1123 if (error == 0) |
1124gotnothing: |
|
1112 error = copyout((caddr_t)&len, (caddr_t)uap->alen, 1113 sizeof (len)); 1114bad: | 1125 error = copyout((caddr_t)&len, (caddr_t)uap->alen, 1126 sizeof (len)); 1127bad: |
1115 m_freem(m); | 1128 if (sa) 1129 FREE(sa, M_SONAME); |
1116 return (error); 1117} 1118 1119int 1120getsockname(p, uap, retval) 1121 struct proc *p; 1122 struct getsockname_args *uap; 1123 int *retval; --- 26 unchanged lines hidden (view full) --- 1150 caddr_t asa; 1151 int *alen; 1152 } */ *uap; 1153 int *retval; 1154 int compat; 1155{ 1156 struct file *fp; 1157 register struct socket *so; | 1130 return (error); 1131} 1132 1133int 1134getsockname(p, uap, retval) 1135 struct proc *p; 1136 struct getsockname_args *uap; 1137 int *retval; --- 26 unchanged lines hidden (view full) --- 1164 caddr_t asa; 1165 int *alen; 1166 } */ *uap; 1167 int *retval; 1168 int compat; 1169{ 1170 struct file *fp; 1171 register struct socket *so; |
1158 struct mbuf *m; | 1172 struct sockaddr *sa; |
1159 int len, error; 1160 1161 error = getsock(p->p_fd, uap->fdes, &fp); 1162 if (error) 1163 return (error); 1164 so = (struct socket *)fp->f_data; 1165 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) 1166 return (ENOTCONN); 1167 error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)); 1168 if (error) 1169 return (error); | 1173 int len, error; 1174 1175 error = getsock(p->p_fd, uap->fdes, &fp); 1176 if (error) 1177 return (error); 1178 so = (struct socket *)fp->f_data; 1179 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) 1180 return (ENOTCONN); 1181 error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)); 1182 if (error) 1183 return (error); |
1170 m = m_getclr(M_WAIT, MT_SONAME); 1171 if (m == NULL) 1172 return (ENOBUFS); 1173 error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, m); | 1184 sa = 0; 1185 error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, &sa); |
1174 if (error) 1175 goto bad; | 1186 if (error) 1187 goto bad; |
1176 if (len > m->m_len) 1177 len = m->m_len; | 1188 if (sa == 0) { 1189 len = 0; 1190 goto gotnothing; 1191 } 1192 len = MIN(len, sa->sa_len); |
1178#ifdef COMPAT_OLDSOCK 1179 if (compat) | 1193#ifdef COMPAT_OLDSOCK 1194 if (compat) |
1180 mtod(m, struct osockaddr *)->sa_family = 1181 mtod(m, struct sockaddr *)->sa_family; | 1195 ((struct osockaddr *)sa)->sa_family = 1196 sa->sa_family; |
1182#endif | 1197#endif |
1183 error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len); | 1198 error = copyout(sa, (caddr_t)uap->asa, (u_int)len); |
1184 if (error) 1185 goto bad; | 1199 if (error) 1200 goto bad; |
1201gotnothing: |
|
1186 error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len)); 1187bad: | 1202 error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len)); 1203bad: |
1188 m_freem(m); | 1204 if (sa) FREE(sa, M_SONAME); |
1189 return (error); 1190} 1191 1192int 1193getpeername(p, uap, retval) 1194 struct proc *p; 1195 struct getpeername_args *uap; 1196 int *retval; --- 51 unchanged lines hidden (view full) --- 1248#endif 1249 sa->sa_len = buflen; 1250 } 1251 } 1252 return (error); 1253} 1254 1255int | 1205 return (error); 1206} 1207 1208int 1209getpeername(p, uap, retval) 1210 struct proc *p; 1211 struct getpeername_args *uap; 1212 int *retval; --- 51 unchanged lines hidden (view full) --- 1264#endif 1265 sa->sa_len = buflen; 1266 } 1267 } 1268 return (error); 1269} 1270 1271int |
1272getsockaddr(namp, uaddr, len) 1273 struct sockaddr **namp; 1274 caddr_t uaddr; 1275 size_t len; 1276{ 1277 struct sockaddr *sa; 1278 int error; 1279 1280 if (len > SOCK_MAXADDRLEN) 1281 return ENAMETOOLONG; 1282 MALLOC(sa, struct sockaddr *, len, M_SONAME, M_WAITOK); 1283 error = copyin(uaddr, sa, len); 1284 if (error) { 1285 FREE(sa, M_SONAME); 1286 } else { 1287#if defined(COMPAT_OLDSOCK) && BYTE_ORDER != BIG_ENDIAN 1288 if (sa->sa_family == 0 && sa->sa_len < AF_MAX) 1289 sa->sa_family = sa->sa_len; 1290#endif 1291 sa->sa_len = len; 1292 *namp = sa; 1293 } 1294 return error; 1295} 1296 1297int |
|
1256getsock(fdp, fdes, fpp) 1257 struct filedesc *fdp; 1258 int fdes; 1259 struct file **fpp; 1260{ 1261 register struct file *fp; 1262 1263 if ((unsigned)fdes >= fdp->fd_nfiles || 1264 (fp = fdp->fd_ofiles[fdes]) == NULL) 1265 return (EBADF); 1266 if (fp->f_type != DTYPE_SOCKET) 1267 return (ENOTSOCK); 1268 *fpp = fp; 1269 return (0); 1270} | 1298getsock(fdp, fdes, fpp) 1299 struct filedesc *fdp; 1300 int fdes; 1301 struct file **fpp; 1302{ 1303 register struct file *fp; 1304 1305 if ((unsigned)fdes >= fdp->fd_nfiles || 1306 (fp = fdp->fd_ofiles[fdes]) == NULL) 1307 return (EBADF); 1308 if (fp->f_type != DTYPE_SOCKET) 1309 return (ENOTSOCK); 1310 *fpp = fp; 1311 return (0); 1312} |