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