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