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