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