from amd5.3 alpha11
[unix-history] / usr / src / sys / kern / uipc_syscalls.c
CommitLineData
da7c5cc6 1/*
da7c5cc6 2 *
dbf0c423 3 * %sccs.include.redist.c%
96e6449f 4 *
5e00df3b 5 * @(#)uipc_syscalls.c 7.21 (Berkeley) %G%
da7c5cc6 6 */
c8c7dd0e 7
94368568 8#include "param.h"
d9c2f47f 9#include "user.h"
5e00df3b 10#include "filedesc.h"
6d47a3da 11#include "proc.h"
94368568 12#include "file.h"
94368568 13#include "buf.h"
6d47a3da 14#include "malloc.h"
94368568
JB
15#include "mbuf.h"
16#include "protosw.h"
17#include "socket.h"
18#include "socketvar.h"
813b7cd1
MT
19#ifdef KTRACE
20#include "ktrace.h"
21#endif
4147b3f6 22
c8c7dd0e 23/*
cf012934 24 * System call interface to the socket abstraction.
c8c7dd0e
BJ
25 */
26
88a7a62a
SL
27extern struct fileops socketops;
28
85843d69
KM
29socket(p, uap, retval)
30 struct proc *p;
31 register struct args {
cf012934 32 int domain;
cc15ab5d 33 int type;
cf012934 34 int protocol;
85843d69
KM
35 } *uap;
36 int *retval;
37{
5e00df3b 38 struct filedesc *fdp = p->p_fd;
2b4b57cd 39 struct socket *so;
0c9a45f0 40 struct file *fp;
76ffad7c 41 int fd, error;
c8c7dd0e 42
5e00df3b 43 if (error = falloc(p, &fp, &fd))
d9c2f47f 44 return (error);
4147b3f6
BJ
45 fp->f_flag = FREAD|FWRITE;
46 fp->f_type = DTYPE_SOCKET;
88a7a62a 47 fp->f_ops = &socketops;
76ffad7c 48 if (error = socreate(uap->domain, &so, uap->type, uap->protocol)) {
5e00df3b 49 OFILE(fdp, fd) = 0;
76ffad7c
MK
50 crfree(fp->f_cred);
51 fp->f_count = 0;
52 } else {
53 fp->f_data = (caddr_t)so;
85843d69 54 *retval = fd;
76ffad7c 55 }
d9c2f47f 56 return (error);
c8c7dd0e 57}
ae921915 58
85843d69
KM
59/* ARGSUSED */
60bind(p, uap, retval)
61 struct proc *p;
62 register struct args {
cf012934
BJ
63 int s;
64 caddr_t name;
65 int namelen;
85843d69
KM
66 } *uap;
67 int *retval;
68{
5e00df3b 69 struct file *fp;
cf012934 70 struct mbuf *nam;
76ffad7c 71 int error;
ae921915 72
5e00df3b 73 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f 74 return (error);
76ffad7c 75 if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))
d9c2f47f 76 return (error);
76ffad7c 77 error = sobind((struct socket *)fp->f_data, nam);
cf012934 78 m_freem(nam);
d9c2f47f 79 return (error);
cf012934
BJ
80}
81
85843d69
KM
82/* ARGSUSED */
83listen(p, uap, retval)
84 struct proc *p;
85 register struct args {
cf012934
BJ
86 int s;
87 int backlog;
85843d69
KM
88 } *uap;
89 int *retval;
90{
5e00df3b 91 struct file *fp;
76ffad7c 92 int error;
cf012934 93
5e00df3b 94 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f
MK
95 return (error);
96 return (solisten((struct socket *)fp->f_data, uap->backlog));
cf012934
BJ
97}
98
f4d2893a 99#ifdef COMPAT_43
85843d69
KM
100accept(p, uap, retval)
101 struct proc *p;
102 struct args {
76ffad7c
MK
103 int s;
104 caddr_t name;
105 int *anamelen;
106 int compat_43;
85843d69
KM
107 } *uap;
108 int *retval;
109{
76ffad7c 110
85843d69 111 uap->compat_43 = 0;
d9c2f47f 112 return (accept1(p, uap, retval));
f4d2893a
MK
113}
114
85843d69
KM
115oaccept(p, uap, retval)
116 struct proc *p;
117 struct args {
76ffad7c
MK
118 int s;
119 caddr_t name;
120 int *anamelen;
121 int compat_43;
85843d69
KM
122 } *uap;
123 int *retval;
124{
76ffad7c 125
85843d69 126 uap->compat_43 = 1;
d9c2f47f 127 return (accept1(p, uap, retval));
f4d2893a 128}
76ffad7c 129#else /* COMPAT_43 */
f4d2893a 130
76ffad7c 131#define accept1 accept
f4d2893a 132#endif
76ffad7c 133
85843d69
KM
134accept1(p, uap, retval)
135 struct proc *p;
136 register struct args {
cf012934
BJ
137 int s;
138 caddr_t name;
139 int *anamelen;
76ffad7c
MK
140#ifdef COMPAT_43
141 int compat_43;
142#endif
85843d69
KM
143 } *uap;
144 int *retval;
145{
0c9a45f0 146 struct file *fp;
cf012934 147 struct mbuf *nam;
27f43765 148 int namelen, error, s;
cf012934
BJ
149 register struct socket *so;
150
7a22a33c
MK
151 if (uap->name && (error = copyin((caddr_t)uap->anamelen,
152 (caddr_t)&namelen, sizeof (namelen))))
d9c2f47f 153 return (error);
5e00df3b 154 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f 155 return (error);
2b4b57cd 156 s = splnet();
88a7a62a 157 so = (struct socket *)fp->f_data;
4147b3f6 158 if ((so->so_options & SO_ACCEPTCONN) == 0) {
4147b3f6 159 splx(s);
d9c2f47f 160 return (EINVAL);
4147b3f6
BJ
161 }
162 if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {
2b4b57cd 163 splx(s);
d9c2f47f 164 return (EWOULDBLOCK);
2b4b57cd 165 }
4147b3f6 166 while (so->so_qlen == 0 && so->so_error == 0) {
62229532
BJ
167 if (so->so_state & SS_CANTRCVMORE) {
168 so->so_error = ECONNABORTED;
169 break;
170 }
27f43765
MK
171 if (error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
172 netcon, 0)) {
173 splx(s);
d9c2f47f 174 return (error);
27f43765 175 }
62229532 176 }
f269ef23 177 if (so->so_error) {
27f43765 178 error = so->so_error;
f4ed5810 179 so->so_error = 0;
f269ef23 180 splx(s);
d9c2f47f 181 return (error);
f269ef23 182 }
5e00df3b 183 if (error = falloc(p, &fp, retval)) {
2b4b57cd 184 splx(s);
d9c2f47f 185 return (error);
cf012934
BJ
186 }
187 { struct socket *aso = so->so_q;
188 if (soqremque(aso, 1) == 0)
189 panic("accept");
190 so = aso;
2b4b57cd 191 }
4147b3f6
BJ
192 fp->f_type = DTYPE_SOCKET;
193 fp->f_flag = FREAD|FWRITE;
88a7a62a
SL
194 fp->f_ops = &socketops;
195 fp->f_data = (caddr_t)so;
cce93e4b 196 nam = m_get(M_WAIT, MT_SONAME);
66f52238 197 (void) soaccept(so, nam);
cf012934 198 if (uap->name) {
f4d2893a 199#ifdef COMPAT_43
76ffad7c 200 if (uap->compat_43)
f4d2893a
MK
201 mtod(nam, struct osockaddr *)->sa_family =
202 mtod(nam, struct sockaddr *)->sa_family;
203#endif
cf012934
BJ
204 if (namelen > nam->m_len)
205 namelen = nam->m_len;
206 /* SHOULD COPY OUT A CHAIN HERE */
7a22a33c
MK
207 if ((error = copyout(mtod(nam, caddr_t), (caddr_t)uap->name,
208 (u_int)namelen)) == 0)
209 error = copyout((caddr_t)&namelen,
210 (caddr_t)uap->anamelen, sizeof (*uap->anamelen));
cf012934
BJ
211 }
212 m_freem(nam);
2b4b57cd 213 splx(s);
d9c2f47f 214 return (error);
ae921915
BJ
215}
216
85843d69
KM
217/* ARGSUSED */
218connect(p, uap, retval)
219 struct proc *p;
220 register struct args {
cf012934
BJ
221 int s;
222 caddr_t name;
223 int namelen;
85843d69
KM
224 } *uap;
225 int *retval;
226{
5e00df3b 227 struct file *fp;
c8c7dd0e 228 register struct socket *so;
cf012934 229 struct mbuf *nam;
27f43765 230 int error, s;
c8c7dd0e 231
5e00df3b 232 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f 233 return (error);
88a7a62a 234 so = (struct socket *)fp->f_data;
27f43765 235 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
d9c2f47f 236 return (EALREADY);
27f43765 237 if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))
d9c2f47f 238 return (error);
27f43765
MK
239 error = soconnect(so, nam);
240 if (error)
cf012934 241 goto bad;
27f43765 242 if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
6222acc3 243 m_freem(nam);
d9c2f47f 244 return (EINPROGRESS);
6222acc3 245 }
c8c7dd0e 246 s = splnet();
cc15ab5d 247 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0)
27f43765
MK
248 if (error = tsleep((caddr_t)&so->so_timeo, PSOCK | PCATCH,
249 netcon, 0))
250 break;
251 if (error == 0) {
252 error = so->so_error;
253 so->so_error = 0;
254 }
cc15ab5d 255 splx(s);
cf012934 256bad:
6750daae 257 so->so_state &= ~SS_ISCONNECTING;
cf012934 258 m_freem(nam);
27f43765
MK
259 if (error == ERESTART)
260 error = EINTR;
d9c2f47f 261 return (error);
c8c7dd0e
BJ
262}
263
85843d69
KM
264socketpair(p, uap, retval)
265 struct proc *p;
266 register struct args {
5a48956d
SL
267 int domain;
268 int type;
269 int protocol;
270 int *rsv;
85843d69
KM
271 } *uap;
272 int retval[];
273{
5e00df3b 274 register struct filedesc *fdp = p->p_fd;
0c9a45f0 275 struct file *fp1, *fp2;
5a48956d 276 struct socket *so1, *so2;
76ffad7c 277 int fd, error, sv[2];
cf012934 278
76ffad7c 279 if (error = socreate(uap->domain, &so1, uap->type, uap->protocol))
d9c2f47f 280 return (error);
76ffad7c 281 if (error = socreate(uap->domain, &so2, uap->type, uap->protocol))
b242cf10 282 goto free1;
5e00df3b 283 if (error = falloc(p, &fp1, &fd))
5a48956d 284 goto free2;
0c9a45f0 285 sv[0] = fd;
5a48956d
SL
286 fp1->f_flag = FREAD|FWRITE;
287 fp1->f_type = DTYPE_SOCKET;
288 fp1->f_ops = &socketops;
289 fp1->f_data = (caddr_t)so1;
5e00df3b 290 if (error = falloc(p, &fp2, &fd))
5a48956d
SL
291 goto free3;
292 fp2->f_flag = FREAD|FWRITE;
293 fp2->f_type = DTYPE_SOCKET;
294 fp2->f_ops = &socketops;
295 fp2->f_data = (caddr_t)so2;
0c9a45f0 296 sv[1] = fd;
76ffad7c 297 if (error = soconnect2(so1, so2))
5a48956d 298 goto free4;
33446404
MK
299 if (uap->type == SOCK_DGRAM) {
300 /*
301 * Datagram socket connection is asymmetric.
302 */
76ffad7c 303 if (error = soconnect2(so2, so1))
33446404
MK
304 goto free4;
305 }
76ffad7c 306 error = copyout((caddr_t)sv, (caddr_t)uap->rsv, 2 * sizeof (int));
85843d69
KM
307 retval[0] = sv[0]; /* XXX ??? */
308 retval[1] = sv[1]; /* XXX ??? */
d9c2f47f 309 return (error);
5a48956d 310free4:
0c9a45f0 311 crfree(fp2->f_cred);
5a48956d 312 fp2->f_count = 0;
5e00df3b 313 OFILE(fdp, sv[1]) = 0;
5a48956d 314free3:
0c9a45f0 315 crfree(fp1->f_cred);
5a48956d 316 fp1->f_count = 0;
5e00df3b 317 OFILE(fdp, sv[0]) = 0;
5a48956d 318free2:
8011f5df 319 (void)soclose(so2);
b242cf10 320free1:
8011f5df 321 (void)soclose(so1);
d9c2f47f 322 return (error);
cf012934
BJ
323}
324
85843d69
KM
325sendto(p, uap, retval)
326 struct proc *p;
327 register struct args {
cf012934
BJ
328 int s;
329 caddr_t buf;
330 int len;
331 int flags;
332 caddr_t to;
333 int tolen;
85843d69
KM
334 } *uap;
335 int *retval;
336{
88a7a62a 337 struct msghdr msg;
d3d550b5 338 struct iovec aiov;
5e00df3b 339 int error;
c8c7dd0e 340
88a7a62a
SL
341 msg.msg_name = uap->to;
342 msg.msg_namelen = uap->tolen;
343 msg.msg_iov = &aiov;
344 msg.msg_iovlen = 1;
27f43765
MK
345 msg.msg_control = 0;
346#ifdef COMPAT_43
347 msg.msg_flags = 0;
348#endif
cf012934
BJ
349 aiov.iov_base = uap->buf;
350 aiov.iov_len = uap->len;
5e00df3b 351 return (sendit(p, uap->s, &msg, uap->flags, retval));
c8c7dd0e
BJ
352}
353
6d47a3da 354#ifdef COMPAT_43
85843d69
KM
355osend(p, uap, retval)
356 struct proc *p;
357 register struct args {
cf012934
BJ
358 int s;
359 caddr_t buf;
360 int len;
361 int flags;
85843d69
KM
362 } *uap;
363 int *retval;
364{
88a7a62a 365 struct msghdr msg;
a6b6f679 366 struct iovec aiov;
cc15ab5d 367
88a7a62a
SL
368 msg.msg_name = 0;
369 msg.msg_namelen = 0;
370 msg.msg_iov = &aiov;
371 msg.msg_iovlen = 1;
cf012934
BJ
372 aiov.iov_base = uap->buf;
373 aiov.iov_len = uap->len;
6d47a3da 374 msg.msg_control = 0;
27f43765 375 msg.msg_flags = 0;
5e00df3b 376 return (sendit(p, uap->s, &msg, uap->flags, retval));
88a7a62a
SL
377}
378
7a22a33c 379#define MSG_COMPAT 0x8000
85843d69
KM
380osendmsg(p, uap, retval)
381 struct proc *p;
382 register struct args {
6d47a3da
MK
383 int s;
384 caddr_t msg;
385 int flags;
85843d69
KM
386 } *uap;
387 int *retval;
388{
6d47a3da 389 struct msghdr msg;
813b7cd1 390 struct iovec aiov[UIO_SMALLIOV], *iov;
76ffad7c 391 int error;
6d47a3da 392
76ffad7c 393 if (error = copyin(uap->msg, (caddr_t)&msg, sizeof (struct omsghdr)))
d9c2f47f 394 return (error);
813b7cd1
MT
395 if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
396 if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
d9c2f47f 397 return (EMSGSIZE);
813b7cd1
MT
398 MALLOC(iov, struct iovec *,
399 sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
400 M_WAITOK);
401 } else
402 iov = aiov;
403 if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
404 (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
405 goto done;
7a22a33c 406 msg.msg_flags = MSG_COMPAT;
813b7cd1 407 msg.msg_iov = iov;
5e00df3b 408 error = sendit(p, uap->s, &msg, uap->flags, retval);
813b7cd1
MT
409done:
410 if (iov != aiov)
411 FREE(iov, M_IOV);
d9c2f47f 412 return (error);
6d47a3da
MK
413}
414#endif
415
85843d69
KM
416sendmsg(p, uap, retval)
417 struct proc *p;
418 register struct args {
88a7a62a
SL
419 int s;
420 caddr_t msg;
421 int flags;
85843d69
KM
422 } *uap;
423 int *retval;
424{
88a7a62a 425 struct msghdr msg;
813b7cd1 426 struct iovec aiov[UIO_SMALLIOV], *iov;
76ffad7c 427 int error;
88a7a62a 428
76ffad7c 429 if (error = copyin(uap->msg, (caddr_t)&msg, sizeof (msg)))
d9c2f47f 430 return (error);
813b7cd1
MT
431 if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
432 if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
d9c2f47f 433 return (EMSGSIZE);
813b7cd1
MT
434 MALLOC(iov, struct iovec *,
435 sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
436 M_WAITOK);
437 } else
438 iov = aiov;
3eb6310a 439 if (msg.msg_iovlen &&
813b7cd1
MT
440 (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
441 (unsigned)(msg.msg_iovlen * sizeof (struct iovec)))))
442 goto done;
443 msg.msg_iov = iov;
27f43765
MK
444#ifdef COMPAT_43
445 msg.msg_flags = 0;
446#endif
5e00df3b 447 error = sendit(p, uap->s, &msg, uap->flags, retval);
813b7cd1
MT
448done:
449 if (iov != aiov)
450 FREE(iov, M_IOV);
d9c2f47f 451 return (error);
88a7a62a
SL
452}
453
5e00df3b
KM
454sendit(p, s, mp, flags, retsize)
455 register struct proc *p;
88a7a62a
SL
456 int s;
457 register struct msghdr *mp;
85843d69 458 int flags, *retsize;
88a7a62a 459{
5e00df3b 460 struct file *fp;
88a7a62a
SL
461 struct uio auio;
462 register struct iovec *iov;
463 register int i;
27f43765 464 struct mbuf *to, *control;
76ffad7c 465 int len, error;
813b7cd1
MT
466#ifdef KTRACE
467 struct iovec *ktriov = NULL;
468#endif
88a7a62a 469
5e00df3b 470 if (error = getsock(p->p_fd, s, &fp))
76ffad7c 471 return (error);
88a7a62a
SL
472 auio.uio_iov = mp->msg_iov;
473 auio.uio_iovcnt = mp->msg_iovlen;
c41770c0 474 auio.uio_segflg = UIO_USERSPACE;
c4ec2128 475 auio.uio_rw = UIO_WRITE;
88a7a62a
SL
476 auio.uio_offset = 0; /* XXX */
477 auio.uio_resid = 0;
478 iov = mp->msg_iov;
125c8f95 479 for (i = 0; i < mp->msg_iovlen; i++, iov++) {
76ffad7c
MK
480 if (iov->iov_len < 0)
481 return (EINVAL);
7a22a33c
MK
482 if ((auio.uio_resid += iov->iov_len) < 0)
483 return (EINVAL);
88a7a62a
SL
484 }
485 if (mp->msg_name) {
76ffad7c
MK
486 if (error = sockargs(&to, mp->msg_name, mp->msg_namelen,
487 MT_SONAME))
488 return (error);
88a7a62a
SL
489 } else
490 to = 0;
6d47a3da 491 if (mp->msg_control) {
7a22a33c
MK
492 if (mp->msg_controllen < sizeof(struct cmsghdr)
493#ifdef COMPAT_43
a7a4c7b9 494 && mp->msg_flags != MSG_COMPAT
7a22a33c 495#endif
a7a4c7b9 496 ) {
7a22a33c
MK
497 error = EINVAL;
498 goto bad;
499 }
76ffad7c
MK
500 if (error = sockargs(&control, mp->msg_control,
501 mp->msg_controllen, MT_CONTROL))
6d47a3da 502 goto bad;
27f43765 503#ifdef COMPAT_43
7a22a33c 504 if (mp->msg_flags == MSG_COMPAT) {
27f43765 505 register struct cmsghdr *cm;
76ffad7c 506
27f43765 507 M_PREPEND(control, sizeof(*cm), M_WAIT);
76ffad7c
MK
508 if (control == 0) {
509 error = ENOBUFS;
510 goto bad;
511 } else {
27f43765
MK
512 cm = mtod(control, struct cmsghdr *);
513 cm->cmsg_len = control->m_len;
514 cm->cmsg_level = SOL_SOCKET;
515 cm->cmsg_type = SCM_RIGHTS;
516 }
517 }
518#endif
6d47a3da
MK
519 } else
520 control = 0;
813b7cd1 521#ifdef KTRACE
5e00df3b 522 if (KTRPOINT(p, KTR_GENIO)) {
813b7cd1
MT
523 int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
524
525 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
526 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
527 }
528#endif
88a7a62a 529 len = auio.uio_resid;
76ffad7c 530 if (error = sosend((struct socket *)fp->f_data, to, &auio,
7a22a33c 531 (struct mbuf *)0, control, flags)) {
76ffad7c
MK
532 if (auio.uio_resid != len && (error == ERESTART ||
533 error == EINTR || error == EWOULDBLOCK))
534 error = 0;
535 if (error == EPIPE)
5e00df3b 536 psignal(p, SIGPIPE);
813b7cd1
MT
537 }
538 if (error == 0)
85843d69 539 *retsize = len - auio.uio_resid;
813b7cd1
MT
540#ifdef KTRACE
541 if (ktriov != NULL) {
542 if (error == 0)
5e00df3b 543 ktrgenio(p->p_tracep, s, UIO_WRITE,
81ba99b6 544 ktriov, *retsize, error);
813b7cd1
MT
545 FREE(ktriov, M_TEMP);
546 }
547#endif
6d47a3da 548bad:
88a7a62a
SL
549 if (to)
550 m_freem(to);
76ffad7c 551 return (error);
cf012934
BJ
552}
553
f4d2893a 554#ifdef COMPAT_43
85843d69
KM
555orecvfrom(p, uap, retval)
556 struct proc *p;
557 struct args {
76ffad7c
MK
558 int s;
559 caddr_t buf;
560 int len;
561 int flags;
562 caddr_t from;
563 int *fromlenaddr;
85843d69
KM
564 } *uap;
565 int *retval;
566{
76ffad7c 567
85843d69 568 uap->flags |= MSG_COMPAT;
d9c2f47f 569 return (recvfrom(p, uap, retval));
f4d2893a 570}
f4d2893a 571#endif
76ffad7c 572
85843d69
KM
573recvfrom(p, uap, retval)
574 struct proc *p;
575 register struct args {
cf012934
BJ
576 int s;
577 caddr_t buf;
578 int len;
579 int flags;
580 caddr_t from;
581 int *fromlenaddr;
85843d69
KM
582 } *uap;
583 int *retval;
584{
88a7a62a 585 struct msghdr msg;
cf012934 586 struct iovec aiov;
7a22a33c 587 int error;
cf012934 588
6d47a3da 589 if (uap->fromlenaddr) {
7a22a33c
MK
590 if (error = copyin((caddr_t)uap->fromlenaddr,
591 (caddr_t)&msg.msg_namelen, sizeof (msg.msg_namelen)))
d9c2f47f 592 return (error);
6d47a3da 593 } else
7a22a33c 594 msg.msg_namelen = 0;
88a7a62a 595 msg.msg_name = uap->from;
88a7a62a
SL
596 msg.msg_iov = &aiov;
597 msg.msg_iovlen = 1;
cf012934
BJ
598 aiov.iov_base = uap->buf;
599 aiov.iov_len = uap->len;
6d47a3da 600 msg.msg_control = 0;
813b7cd1 601 msg.msg_flags = uap->flags;
5e00df3b 602 return (recvit(p, uap->s, &msg, (caddr_t)uap->fromlenaddr, retval));
cf012934 603}
76ffad7c 604
6d47a3da 605#ifdef COMPAT_43
85843d69
KM
606orecv(p, uap, retval)
607 struct proc *p;
608 register struct args {
cf012934
BJ
609 int s;
610 caddr_t buf;
611 int len;
612 int flags;
85843d69
KM
613 } *uap;
614 int *retval;
615{
88a7a62a 616 struct msghdr msg;
cf012934
BJ
617 struct iovec aiov;
618
88a7a62a
SL
619 msg.msg_name = 0;
620 msg.msg_namelen = 0;
621 msg.msg_iov = &aiov;
622 msg.msg_iovlen = 1;
cf012934
BJ
623 aiov.iov_base = uap->buf;
624 aiov.iov_len = uap->len;
6d47a3da
MK
625 msg.msg_control = 0;
626 msg.msg_flags = uap->flags;
5e00df3b 627 return (recvit(p, uap->s, &msg, (caddr_t)0, retval));
6d47a3da
MK
628}
629
7a22a33c
MK
630/*
631 * Old recvmsg. This code takes advantage of the fact that the old msghdr
632 * overlays the new one, missing only the flags, and with the (old) access
633 * rights where the control fields are now.
634 */
85843d69
KM
635orecvmsg(p, uap, retval)
636 struct proc *p;
637 register struct args {
6d47a3da
MK
638 int s;
639 struct omsghdr *msg;
640 int flags;
85843d69
KM
641 } *uap;
642 int *retval;
643{
6d47a3da 644 struct msghdr msg;
813b7cd1 645 struct iovec aiov[UIO_SMALLIOV], *iov;
76ffad7c 646 int error;
6d47a3da 647
76ffad7c
MK
648 if (error = copyin((caddr_t)uap->msg, (caddr_t)&msg,
649 sizeof (struct omsghdr)))
d9c2f47f 650 return (error);
813b7cd1
MT
651 if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
652 if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
d9c2f47f 653 return (EMSGSIZE);
813b7cd1
MT
654 MALLOC(iov, struct iovec *,
655 sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
656 M_WAITOK);
657 } else
658 iov = aiov;
7a22a33c 659 msg.msg_flags = uap->flags | MSG_COMPAT;
813b7cd1
MT
660 if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
661 (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
662 goto done;
663 msg.msg_iov = iov;
5e00df3b 664 error = recvit(p, uap->s, &msg, (caddr_t)&uap->msg->msg_namelen, retval);
7a22a33c
MK
665
666 if (msg.msg_controllen && error == 0)
667 error = copyout((caddr_t)&msg.msg_controllen,
668 (caddr_t)&uap->msg->msg_accrightslen, sizeof (int));
813b7cd1
MT
669done:
670 if (iov != aiov)
671 FREE(iov, M_IOV);
d9c2f47f 672 return (error);
cf012934 673}
6d47a3da 674#endif
cf012934 675
85843d69
KM
676recvmsg(p, uap, retval)
677 struct proc *p;
678 register struct args {
88a7a62a
SL
679 int s;
680 struct msghdr *msg;
681 int flags;
85843d69
KM
682 } *uap;
683 int *retval;
684{
88a7a62a 685 struct msghdr msg;
813b7cd1 686 struct iovec aiov[UIO_SMALLIOV], *uiov, *iov;
76ffad7c
MK
687 register int error;
688
689 if (error = copyin((caddr_t)uap->msg, (caddr_t)&msg, sizeof (msg)))
d9c2f47f 690 return (error);
813b7cd1
MT
691 if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) {
692 if ((u_int)msg.msg_iovlen >= UIO_MAXIOV)
d9c2f47f 693 return (EMSGSIZE);
813b7cd1
MT
694 MALLOC(iov, struct iovec *,
695 sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
696 M_WAITOK);
697 } else
698 iov = aiov;
7a22a33c
MK
699#ifdef COMPAT_43
700 msg.msg_flags = uap->flags &~ MSG_COMPAT;
701#else
6d47a3da 702 msg.msg_flags = uap->flags;
7a22a33c 703#endif
27f43765 704 uiov = msg.msg_iov;
813b7cd1
MT
705 msg.msg_iov = iov;
706 if (error = copyin((caddr_t)uiov, (caddr_t)iov,
707 (unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
708 goto done;
5e00df3b 709 if ((error = recvit(p, uap->s, &msg, (caddr_t)0, retval)) == 0) {
76ffad7c
MK
710 msg.msg_iov = uiov;
711 error = copyout((caddr_t)&msg, (caddr_t)uap->msg, sizeof(msg));
712 }
813b7cd1
MT
713done:
714 if (iov != aiov)
715 FREE(iov, M_IOV);
d9c2f47f 716 return (error);
cf012934
BJ
717}
718
5e00df3b
KM
719recvit(p, s, mp, namelenp, retsize)
720 register struct proc *p;
7a22a33c 721 int s;
88a7a62a 722 register struct msghdr *mp;
7a22a33c 723 caddr_t namelenp;
85843d69 724 int *retsize;
cf012934 725{
5e00df3b 726 struct file *fp;
88a7a62a
SL
727 struct uio auio;
728 register struct iovec *iov;
729 register int i;
76ffad7c 730 int len, error;
7a22a33c 731 struct mbuf *from = 0, *control = 0;
813b7cd1
MT
732#ifdef KTRACE
733 struct iovec *ktriov = NULL;
734#endif
88a7a62a 735
5e00df3b 736 if (error = getsock(p->p_fd, s, &fp))
76ffad7c 737 return (error);
88a7a62a
SL
738 auio.uio_iov = mp->msg_iov;
739 auio.uio_iovcnt = mp->msg_iovlen;
c41770c0 740 auio.uio_segflg = UIO_USERSPACE;
c4ec2128 741 auio.uio_rw = UIO_READ;
88a7a62a
SL
742 auio.uio_offset = 0; /* XXX */
743 auio.uio_resid = 0;
744 iov = mp->msg_iov;
125c8f95 745 for (i = 0; i < mp->msg_iovlen; i++, iov++) {
76ffad7c
MK
746 if (iov->iov_len < 0)
747 return (EINVAL);
7a22a33c
MK
748 if ((auio.uio_resid += iov->iov_len) < 0)
749 return (EINVAL);
88a7a62a 750 }
813b7cd1 751#ifdef KTRACE
5e00df3b 752 if (KTRPOINT(p, KTR_GENIO)) {
813b7cd1
MT
753 int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
754
755 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
756 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
757 }
758#endif
88a7a62a 759 len = auio.uio_resid;
76ffad7c 760 if (error = soreceive((struct socket *)fp->f_data, &from, &auio,
7a22a33c 761 (struct mbuf **)0, &control, &mp->msg_flags)) {
76ffad7c
MK
762 if (auio.uio_resid != len && (error == ERESTART ||
763 error == EINTR || error == EWOULDBLOCK))
764 error = 0;
765 }
813b7cd1
MT
766#ifdef KTRACE
767 if (ktriov != NULL) {
768 if (error == 0)
5e00df3b 769 ktrgenio(p->p_tracep, s, UIO_READ,
81ba99b6 770 ktriov, len - auio.uio_resid, error);
813b7cd1
MT
771 FREE(ktriov, M_TEMP);
772 }
773#endif
76ffad7c
MK
774 if (error)
775 goto out;
85843d69 776 *retsize = len - auio.uio_resid;
88a7a62a
SL
777 if (mp->msg_name) {
778 len = mp->msg_namelen;
779 if (len <= 0 || from == 0)
780 len = 0;
781 else {
f4d2893a 782#ifdef COMPAT_43
7a22a33c 783 if (mp->msg_flags & MSG_COMPAT)
f4d2893a
MK
784 mtod(from, struct osockaddr *)->sa_family =
785 mtod(from, struct sockaddr *)->sa_family;
786#endif
7a22a33c 787 if (len > from->m_len)
88a7a62a 788 len = from->m_len;
7a22a33c
MK
789 /* else if len < from->m_len ??? */
790 if (error = copyout(mtod(from, caddr_t),
791 (caddr_t)mp->msg_name, (unsigned)len))
792 goto out;
88a7a62a 793 }
a2aebb63 794 mp->msg_namelen = len;
7a22a33c
MK
795 if (namelenp &&
796 (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) {
797#ifdef COMPAT_43
798 if (mp->msg_flags & MSG_COMPAT)
799 error = 0; /* old recvfrom didn't check */
800 else
801#endif
802 goto out;
88a7a62a 803 }
6d47a3da
MK
804 }
805 if (mp->msg_control) {
7a22a33c
MK
806#ifdef COMPAT_43
807 /*
808 * We assume that old recvmsg calls won't receive access
809 * rights and other control info, esp. as control info
810 * is always optional and those options didn't exist in 4.3.
811 * If we receive rights, trim the cmsghdr; anything else
812 * is tossed.
813 */
814 if (control && mp->msg_flags & MSG_COMPAT) {
815 if (mtod(control, struct cmsghdr *)->cmsg_level !=
816 SOL_SOCKET ||
817 mtod(control, struct cmsghdr *)->cmsg_type !=
818 SCM_RIGHTS) {
819 mp->msg_controllen = 0;
820 goto out;
27f43765 821 }
7a22a33c
MK
822 control->m_len -= sizeof (struct cmsghdr);
823 control->m_data += sizeof (struct cmsghdr);
27f43765 824 }
7a22a33c 825#endif
6d47a3da
MK
826 len = mp->msg_controllen;
827 if (len <= 0 || control == 0)
828 len = 0;
829 else {
830 if (len >= control->m_len)
831 len = control->m_len;
832 else
833 mp->msg_flags |= MSG_CTRUNC;
7a22a33c 834 error = copyout((caddr_t)mtod(control, caddr_t),
6d47a3da
MK
835 (caddr_t)mp->msg_control, (unsigned)len);
836 }
a2aebb63 837 mp->msg_controllen = len;
88a7a62a 838 }
76ffad7c 839out:
88a7a62a
SL
840 if (from)
841 m_freem(from);
6d47a3da
MK
842 if (control)
843 m_freem(control);
76ffad7c 844 return (error);
cf012934
BJ
845}
846
85843d69
KM
847/* ARGSUSED */
848shutdown(p, uap, retval)
849 struct proc *p;
850 register struct args {
6ef233bf
SL
851 int s;
852 int how;
85843d69
KM
853 } *uap;
854 int *retval;
855{
6ef233bf 856 struct file *fp;
76ffad7c 857 int error;
cf012934 858
5e00df3b 859 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f
MK
860 return (error);
861 return (soshutdown((struct socket *)fp->f_data, uap->how));
cf012934
BJ
862}
863
85843d69
KM
864/* ARGSUSED */
865setsockopt(p, uap, retval)
866 struct proc *p;
867 register struct args {
66f52238
SL
868 int s;
869 int level;
870 int name;
871 caddr_t val;
872 int valsize;
85843d69
KM
873 } *uap;
874 int *retval;
875{
66f52238 876 struct file *fp;
d2cba8de 877 struct mbuf *m = NULL;
76ffad7c 878 int error;
66f52238 879
5e00df3b 880 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f 881 return (error);
76ffad7c 882 if (uap->valsize > MLEN)
d9c2f47f 883 return (EINVAL);
d2cba8de
SL
884 if (uap->val) {
885 m = m_get(M_WAIT, MT_SOOPTS);
76ffad7c 886 if (m == NULL)
d9c2f47f 887 return (ENOBUFS);
76ffad7c
MK
888 if (error = copyin(uap->val, mtod(m, caddr_t),
889 (u_int)uap->valsize)) {
61ec2127 890 (void) m_free(m);
d9c2f47f 891 return (error);
61ec2127 892 }
d2cba8de 893 m->m_len = uap->valsize;
66f52238 894 }
d9c2f47f 895 return (sosetopt((struct socket *)fp->f_data, uap->level,
76ffad7c 896 uap->name, m));
66f52238
SL
897}
898
85843d69
KM
899/* ARGSUSED */
900getsockopt(p, uap, retval)
901 struct proc *p;
902 register struct args {
66f52238
SL
903 int s;
904 int level;
905 int name;
906 caddr_t val;
907 int *avalsize;
85843d69
KM
908 } *uap;
909 int *retval;
910{
66f52238 911 struct file *fp;
d2cba8de 912 struct mbuf *m = NULL;
76ffad7c 913 int valsize, error;
66f52238 914
5e00df3b 915 if (error = getsock(p->p_fd, uap->s, &fp))
d9c2f47f 916 return (error);
d2cba8de 917 if (uap->val) {
76ffad7c
MK
918 if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
919 sizeof (valsize)))
d9c2f47f 920 return (error);
61ec2127
SL
921 } else
922 valsize = 0;
76ffad7c
MK
923 if ((error = sogetopt((struct socket *)fp->f_data, uap->level,
924 uap->name, &m)) == 0 && uap->val && valsize && m != NULL) {
d2cba8de
SL
925 if (valsize > m->m_len)
926 valsize = m->m_len;
76ffad7c
MK
927 error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
928 if (error == 0)
929 error = copyout((caddr_t)&valsize,
930 (caddr_t)uap->avalsize, sizeof (valsize));
d2cba8de 931 }
d2cba8de
SL
932 if (m != NULL)
933 (void) m_free(m);
d9c2f47f 934 return (error);
66f52238
SL
935}
936
85843d69
KM
937/* ARGSUSED */
938pipe(p, uap, retval)
939 struct proc *p;
940 struct args *uap;
941 int retval[];
cf012934 942{
5e00df3b 943 register struct filedesc *fdp = p->p_fd;
0c9a45f0 944 struct file *rf, *wf;
cf012934 945 struct socket *rso, *wso;
76ffad7c 946 int fd, error;
cf012934 947
76ffad7c 948 if (error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0))
d9c2f47f 949 return (error);
76ffad7c 950 if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0))
b242cf10 951 goto free1;
5e00df3b 952 if (error = falloc(p, &rf, &fd))
cf012934 953 goto free2;
85843d69 954 retval[0] = fd;
cf012934
BJ
955 rf->f_flag = FREAD;
956 rf->f_type = DTYPE_SOCKET;
88a7a62a
SL
957 rf->f_ops = &socketops;
958 rf->f_data = (caddr_t)rso;
5e00df3b 959 if (error = falloc(p, &wf, &fd))
cf012934
BJ
960 goto free3;
961 wf->f_flag = FWRITE;
962 wf->f_type = DTYPE_SOCKET;
88a7a62a
SL
963 wf->f_ops = &socketops;
964 wf->f_data = (caddr_t)wso;
85843d69 965 retval[1] = fd;
76ffad7c 966 if (error = unp_connect2(wso, rso))
cf012934 967 goto free4;
d9c2f47f 968 return (0);
cf012934
BJ
969free4:
970 wf->f_count = 0;
5e00df3b 971 OFILE(fdp, retval[1]) = 0;
cf012934
BJ
972free3:
973 rf->f_count = 0;
5e00df3b 974 OFILE(fdp, retval[0]) = 0;
cf012934 975free2:
8011f5df 976 (void)soclose(wso);
b242cf10 977free1:
8011f5df 978 (void)soclose(rso);
d9c2f47f 979 return (error);
cc15ab5d 980}
a3076b07
BJ
981
982/*
70f2eac5 983 * Get socket name.
a3076b07 984 */
f4d2893a 985#ifdef COMPAT_43
85843d69
KM
986getsockname(p, uap, retval)
987 struct proc *p;
988 struct args {
76ffad7c
MK
989 int fdes;
990 caddr_t asa;
991 int *alen;
992 int compat_43;
85843d69
KM
993 } *uap;
994 int *retval;
995{
76ffad7c 996
85843d69 997 uap->compat_43 = 0;
d9c2f47f 998 return (getsockname1(p, uap, retval));
f4d2893a
MK
999}
1000
85843d69
KM
1001ogetsockname(p, uap, retval)
1002 struct proc *p;
1003 struct args {
76ffad7c
MK
1004 int fdes;
1005 caddr_t asa;
1006 int *alen;
1007 int compat_43;
85843d69
KM
1008 } *uap;
1009 int *retval;
1010{
76ffad7c 1011
85843d69 1012 uap->compat_43 = 1;
d9c2f47f 1013 return (getsockname1(p, uap, retval));
f4d2893a 1014}
76ffad7c 1015#else /* COMPAT_43 */
f4d2893a 1016
76ffad7c 1017#define getsockname1 getsockname
f4d2893a 1018#endif
76ffad7c 1019
85843d69
KM
1020/* ARGSUSED */
1021getsockname1(p, uap, retval)
1022 struct proc *p;
1023 register struct args {
a3076b07 1024 int fdes;
70f2eac5
SL
1025 caddr_t asa;
1026 int *alen;
76ffad7c
MK
1027#ifdef COMPAT_43
1028 int compat_43;
1029#endif
85843d69
KM
1030 } *uap;
1031 int *retval;
1032{
5e00df3b 1033 struct file *fp;
05d69517 1034 register struct socket *so;
cf012934 1035 struct mbuf *m;
76ffad7c 1036 int len, error;
a3076b07 1037
5e00df3b 1038 if (error = getsock(p->p_fd, uap->fdes, &fp))
d9c2f47f 1039 return (error);
76ffad7c 1040 if (error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)))
d9c2f47f 1041 return (error);
88a7a62a 1042 so = (struct socket *)fp->f_data;
cce93e4b 1043 m = m_getclr(M_WAIT, MT_SONAME);
76ffad7c 1044 if (m == NULL)
d9c2f47f 1045 return (ENOBUFS);
76ffad7c 1046 if (error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0))
70f2eac5
SL
1047 goto bad;
1048 if (len > m->m_len)
1049 len = m->m_len;
f4d2893a 1050#ifdef COMPAT_43
76ffad7c 1051 if (uap->compat_43)
f4d2893a
MK
1052 mtod(m, struct osockaddr *)->sa_family =
1053 mtod(m, struct sockaddr *)->sa_family;
1054#endif
76ffad7c
MK
1055 error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len);
1056 if (error == 0)
1057 error = copyout((caddr_t)&len, (caddr_t)uap->alen,
f4d2893a 1058 sizeof (len));
cf012934
BJ
1059bad:
1060 m_freem(m);
d9c2f47f 1061 return (error);
cf012934
BJ
1062}
1063
f4d2893a
MK
1064/*
1065 * Get name of peer for connected socket.
1066 */
6d47a3da 1067#ifdef COMPAT_43
85843d69
KM
1068getpeername(p, uap, retval)
1069 struct proc *p;
1070 struct args {
76ffad7c
MK
1071 int fdes;
1072 caddr_t asa;
1073 int *alen;
1074 int compat_43;
85843d69
KM
1075 } *uap;
1076 int *retval;
1077{
76ffad7c 1078
85843d69 1079 uap->compat_43 = 0;
d9c2f47f 1080 return (getpeername1(p, uap, retval));
6d47a3da 1081}
6d47a3da 1082
85843d69
KM
1083ogetpeername(p, uap, retval)
1084 struct proc *p;
1085 struct args {
76ffad7c
MK
1086 int fdes;
1087 caddr_t asa;
1088 int *alen;
1089 int compat_43;
85843d69
KM
1090 } *uap;
1091 int *retval;
1092{
76ffad7c 1093
85843d69 1094 uap->compat_43 = 1;
d9c2f47f 1095 return (getpeername1(p, uap, retval));
f4d2893a 1096}
76ffad7c 1097#else /* COMPAT_43 */
f4d2893a 1098
76ffad7c 1099#define getpeername1 getpeername
f4d2893a 1100#endif
76ffad7c 1101
85843d69
KM
1102/* ARGSUSED */
1103getpeername1(p, uap, retval)
1104 struct proc *p;
1105 register struct args {
a7343092
SL
1106 int fdes;
1107 caddr_t asa;
1108 int *alen;
76ffad7c
MK
1109#ifdef COMPAT_43
1110 int compat_43;
1111#endif
85843d69
KM
1112 } *uap;
1113 int *retval;
1114{
5e00df3b 1115 struct file *fp;
a7343092
SL
1116 register struct socket *so;
1117 struct mbuf *m;
76ffad7c 1118 int len, error;
a7343092 1119
5e00df3b 1120 if (error = getsock(p->p_fd, uap->fdes, &fp))
d9c2f47f 1121 return (error);
a7343092 1122 so = (struct socket *)fp->f_data;
76ffad7c 1123 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
d9c2f47f 1124 return (ENOTCONN);
a7343092 1125 m = m_getclr(M_WAIT, MT_SONAME);
76ffad7c 1126 if (m == NULL)
d9c2f47f 1127 return (ENOBUFS);
76ffad7c 1128 if (error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)))
d9c2f47f 1129 return (error);
76ffad7c 1130 if (error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0))
a7343092
SL
1131 goto bad;
1132 if (len > m->m_len)
1133 len = m->m_len;
f4d2893a 1134#ifdef COMPAT_43
76ffad7c 1135 if (uap->compat_43)
f4d2893a
MK
1136 mtod(m, struct osockaddr *)->sa_family =
1137 mtod(m, struct sockaddr *)->sa_family;
1138#endif
76ffad7c 1139 if (error = copyout(mtod(m, caddr_t), (caddr_t)uap->asa, (u_int)len))
a7343092 1140 goto bad;
76ffad7c 1141 error = copyout((caddr_t)&len, (caddr_t)uap->alen, sizeof (len));
a7343092
SL
1142bad:
1143 m_freem(m);
d9c2f47f 1144 return (error);
a7343092
SL
1145}
1146
7a22a33c
MK
1147sockargs(mp, buf, buflen, type)
1148 struct mbuf **mp;
1149 caddr_t buf;
1150 int buflen, type;
cf012934
BJ
1151{
1152 register struct mbuf *m;
127f7d76 1153 int error;
cf012934 1154
7a22a33c 1155 if ((u_int)buflen > MLEN) {
3eb6310a 1156#ifdef COMPAT_43
7a22a33c
MK
1157 if (type == MT_SONAME && (u_int)buflen <= 112)
1158 buflen = MLEN; /* unix domain compat. hack */
3eb6310a
MK
1159 else
1160#endif
cf012934 1161 return (EINVAL);
3eb6310a 1162 }
98447d3f 1163 m = m_get(M_WAIT, type);
7c52d753
SL
1164 if (m == NULL)
1165 return (ENOBUFS);
7a22a33c
MK
1166 m->m_len = buflen;
1167 error = copyin(buf, mtod(m, caddr_t), (u_int)buflen);
127f7d76 1168 if (error)
cf012934 1169 (void) m_free(m);
127f7d76 1170 else
7a22a33c 1171 *mp = m;
a2aebb63
KS
1172 if (type == MT_SONAME) {
1173 register struct sockaddr *sa = mtod(m, struct sockaddr *);
76ffad7c 1174
f4d2893a 1175#if defined(COMPAT_43) && BYTE_ORDER != BIG_ENDIAN
a2aebb63
KS
1176 if (sa->sa_family == 0 && sa->sa_len < AF_MAX)
1177 sa->sa_family = sa->sa_len;
f4d2893a 1178#endif
7a22a33c 1179 sa->sa_len = buflen;
a2aebb63 1180 }
127f7d76 1181 return (error);
cf012934 1182}
88a7a62a 1183
5e00df3b
KM
1184getsock(fdp, fdes, fpp)
1185 struct filedesc *fdp;
1186 int fdes;
1187 struct file **fpp;
88a7a62a
SL
1188{
1189 register struct file *fp;
1190
5e00df3b
KM
1191 if ((unsigned)fdes >= fdp->fd_maxfiles ||
1192 (fp = OFILE(fdp, fdes)) == NULL)
1193 return (EBADF);
1194 if (fp->f_type != DTYPE_SOCKET)
1195 return (ENOTSOCK);
1196 *fpp = fp;
1197 return (0);
88a7a62a 1198}