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