xref: /csrg-svn/sys/kern/uipc_socket.c (revision 23421)
1 /*
2  * Copyright (c) 1982 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)uipc_socket.c	6.15 (Berkeley) 06/08/85
7  */
8 
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 "un.h"
19 #include "domain.h"
20 #include "protosw.h"
21 #include "socket.h"
22 #include "socketvar.h"
23 #include "stat.h"
24 #include "ioctl.h"
25 #include "uio.h"
26 #include "../net/route.h"
27 #include "../netinet/in.h"
28 #include "../net/if.h"
29 
30 /*
31  * Socket operation routines.
32  * These routines are called by the routines in
33  * sys_socket.c or from a system process, and
34  * implement the semantics of socket operations by
35  * switching out to the protocol specific routines.
36  *
37  * TODO:
38  *	test socketpair
39  *	clean up async
40  *	out-of-band is a kludge
41  */
42 /*ARGSUSED*/
43 socreate(dom, aso, type, proto)
44 	struct socket **aso;
45 	register int type;
46 	int proto;
47 {
48 	register struct protosw *prp;
49 	register struct socket *so;
50 	register struct mbuf *m;
51 	register int error;
52 
53 	if (proto)
54 		prp = pffindproto(dom, proto, type);
55 	else
56 		prp = pffindtype(dom, type);
57 	if (prp == 0)
58 		return (EPROTONOSUPPORT);
59 	if (prp->pr_type != type)
60 		return (EPROTOTYPE);
61 	m = m_getclr(M_WAIT, MT_SOCKET);
62 	so = mtod(m, struct socket *);
63 	so->so_options = 0;
64 	so->so_state = 0;
65 	so->so_type = type;
66 	if (u.u_uid == 0)
67 		so->so_state = SS_PRIV;
68 	so->so_proto = prp;
69 	error =
70 	    (*prp->pr_usrreq)(so, PRU_ATTACH,
71 		(struct mbuf *)0, (struct mbuf *)proto, (struct mbuf *)0);
72 	if (error) {
73 		so->so_state |= SS_NOFDREF;
74 		sofree(so);
75 		return (error);
76 	}
77 	*aso = so;
78 	return (0);
79 }
80 
81 sobind(so, nam)
82 	struct socket *so;
83 	struct mbuf *nam;
84 {
85 	int s = splnet();
86 	int error;
87 
88 	error =
89 	    (*so->so_proto->pr_usrreq)(so, PRU_BIND,
90 		(struct mbuf *)0, nam, (struct mbuf *)0);
91 	splx(s);
92 	return (error);
93 }
94 
95 solisten(so, backlog)
96 	register struct socket *so;
97 	int backlog;
98 {
99 	int s = splnet(), error;
100 
101 	error =
102 	    (*so->so_proto->pr_usrreq)(so, PRU_LISTEN,
103 		(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
104 	if (error) {
105 		splx(s);
106 		return (error);
107 	}
108 	if (so->so_q == 0) {
109 		so->so_q = so;
110 		so->so_q0 = so;
111 		so->so_options |= SO_ACCEPTCONN;
112 	}
113 	if (backlog < 0)
114 		backlog = 0;
115 	so->so_qlimit = MIN(backlog, SOMAXCONN);
116 	splx(s);
117 	return (0);
118 }
119 
120 sofree(so)
121 	register struct socket *so;
122 {
123 
124 	if (so->so_head) {
125 		if (!soqremque(so, 0) && !soqremque(so, 1))
126 			panic("sofree dq");
127 		so->so_head = 0;
128 	}
129 	if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
130 		return;
131 	sbrelease(&so->so_snd);
132 	sorflush(so);
133 	(void) m_free(dtom(so));
134 }
135 
136 /*
137  * Close a socket on last file table reference removal.
138  * Initiate disconnect if connected.
139  * Free socket when disconnect complete.
140  */
141 soclose(so)
142 	register struct socket *so;
143 {
144 	int s = splnet();		/* conservative */
145 	int error;
146 
147 	if (so->so_options & SO_ACCEPTCONN) {
148 		while (so->so_q0 != so)
149 			(void) soabort(so->so_q0);
150 		while (so->so_q != so)
151 			(void) soabort(so->so_q);
152 	}
153 	if (so->so_pcb == 0)
154 		goto discard;
155 	if (so->so_state & SS_ISCONNECTED) {
156 		if ((so->so_state & SS_ISDISCONNECTING) == 0) {
157 			error = sodisconnect(so, (struct mbuf *)0);
158 			if (error)
159 				goto drop;
160 		}
161 		if (so->so_options & SO_LINGER) {
162 			if ((so->so_state & SS_ISDISCONNECTING) &&
163 			    (so->so_state & SS_NBIO))
164 				goto drop;
165 			while (so->so_state & SS_ISCONNECTED)
166 				sleep((caddr_t)&so->so_timeo, PZERO+1);
167 		}
168 	}
169 drop:
170 	if (so->so_pcb) {
171 		int error2 =
172 		    (*so->so_proto->pr_usrreq)(so, PRU_DETACH,
173 			(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
174 		if (error == 0)
175 			error = error2;
176 	}
177 discard:
178 	if (so->so_state & SS_NOFDREF)
179 		panic("soclose: NOFDREF");
180 	so->so_state |= SS_NOFDREF;
181 	sofree(so);
182 	splx(s);
183 	return (error);
184 }
185 
186 /*
187  * Must be called at splnet...
188  */
189 soabort(so)
190 	struct socket *so;
191 {
192 
193 	return (
194 	    (*so->so_proto->pr_usrreq)(so, PRU_ABORT,
195 		(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
196 }
197 
198 soaccept(so, nam)
199 	register struct socket *so;
200 	struct mbuf *nam;
201 {
202 	int s = splnet();
203 	int error;
204 
205 	if ((so->so_state & SS_NOFDREF) == 0)
206 		panic("soaccept: !NOFDREF");
207 	so->so_state &= ~SS_NOFDREF;
208 	error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT,
209 	    (struct mbuf *)0, nam, (struct mbuf *)0);
210 	splx(s);
211 	return (error);
212 }
213 
214 soconnect(so, nam)
215 	register struct socket *so;
216 	struct mbuf *nam;
217 {
218 	int s = splnet();
219 	int error;
220 
221 	if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) {
222 		error = EISCONN;
223 		goto bad;
224 	}
225 	error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
226 	    (struct mbuf *)0, nam, (struct mbuf *)0);
227 bad:
228 	splx(s);
229 	return (error);
230 }
231 
232 soconnect2(so1, so2)
233 	register struct socket *so1;
234 	struct socket *so2;
235 {
236 	int s = splnet();
237 	int error;
238 
239 	error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2,
240 	    (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0);
241 	splx(s);
242 	return (error);
243 }
244 
245 sodisconnect(so, nam)
246 	register struct socket *so;
247 	struct mbuf *nam;
248 {
249 	int s = splnet();
250 	int error;
251 
252 	if ((so->so_state & SS_ISCONNECTED) == 0) {
253 		error = ENOTCONN;
254 		goto bad;
255 	}
256 	if (so->so_state & SS_ISDISCONNECTING) {
257 		error = EALREADY;
258 		goto bad;
259 	}
260 	error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,
261 	    (struct mbuf *)0, nam, (struct mbuf *)0);
262 bad:
263 	splx(s);
264 	return (error);
265 }
266 
267 /*
268  * Send on a socket.
269  * If send must go all at once and message is larger than
270  * send buffering, then hard error.
271  * Lock against other senders.
272  * If must go all at once and not enough room now, then
273  * inform user that this would block and do nothing.
274  * Otherwise, if nonblocking, send as much as possible.
275  */
276 sosend(so, nam, uio, flags, rights)
277 	register struct socket *so;
278 	struct mbuf *nam;
279 	register struct uio *uio;
280 	int flags;
281 	struct mbuf *rights;
282 {
283 	struct mbuf *top = 0;
284 	register struct mbuf *m, **mp;
285 	register int space;
286 	int len, error = 0, s, dontroute, first = 1;
287 
288 	if (sosendallatonce(so) && uio->uio_resid > so->so_snd.sb_hiwat)
289 		return (EMSGSIZE);
290 	dontroute =
291 	    (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
292 	    (so->so_proto->pr_flags & PR_ATOMIC);
293 	u.u_ru.ru_msgsnd++;
294 #define	snderr(errno)	{ error = errno; splx(s); goto release; }
295 
296 restart:
297 	sblock(&so->so_snd);
298 	do {
299 		s = splnet();
300 		if (so->so_state & SS_CANTSENDMORE)
301 			snderr(EPIPE);
302 		if (so->so_error) {
303 			error = so->so_error;
304 			so->so_error = 0;			/* ??? */
305 			splx(s);
306 			goto release;
307 		}
308 		if ((so->so_state & SS_ISCONNECTED) == 0) {
309 			if (so->so_proto->pr_flags & PR_CONNREQUIRED)
310 				snderr(ENOTCONN);
311 			if (nam == 0)
312 				snderr(EDESTADDRREQ);
313 		}
314 		if (flags & MSG_OOB)
315 			space = 1024;
316 		else {
317 			space = sbspace(&so->so_snd);
318 			if (space <= 0 ||
319 			   (sosendallatonce(so) && space < uio->uio_resid) ||
320 			   (uio->uio_resid >= CLBYTES && space < CLBYTES &&
321 			   so->so_snd.sb_cc >= CLBYTES &&
322 			   (so->so_state & SS_NBIO) == 0)) {
323 				if (so->so_state & SS_NBIO) {
324 					if (first)
325 						error = EWOULDBLOCK;
326 					splx(s);
327 					goto release;
328 				}
329 				sbunlock(&so->so_snd);
330 				sbwait(&so->so_snd);
331 				splx(s);
332 				goto restart;
333 			}
334 		}
335 		splx(s);
336 		mp = &top;
337 		while (space > 0) {
338 			register struct iovec *iov = uio->uio_iov;
339 
340 			MGET(m, M_WAIT, MT_DATA);
341 			if (iov->iov_len >= NBPG && space >= CLBYTES) {
342 				register struct mbuf *p;
343 				MCLGET(p, 1);
344 				if (p == 0)
345 					goto nopages;
346 				m->m_off = (int)p - (int)m;
347 				len = min(CLBYTES, iov->iov_len);
348 				space -= CLBYTES;
349 			} else {
350 nopages:
351 				len = MIN(MLEN, iov->iov_len);
352 				space -= len;
353 			}
354 			error = uiomove(mtod(m, caddr_t), len, UIO_WRITE, uio);
355 			m->m_len = len;
356 			*mp = m;
357 			if (error)
358 				goto release;
359 			mp = &m->m_next;
360 			if (uio->uio_resid <= 0)
361 				break;
362 			while (uio->uio_iov->iov_len == 0) {
363 				uio->uio_iov++;
364 				uio->uio_iovcnt--;
365 				if (uio->uio_iovcnt <= 0)
366 					panic("sosend");
367 			}
368 		}
369 		if (dontroute)
370 			so->so_options |= SO_DONTROUTE;
371 		s = splnet();					/* XXX */
372 		error = (*so->so_proto->pr_usrreq)(so,
373 		    (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
374 		    top, (caddr_t)nam, rights);
375 		splx(s);
376 		if (dontroute)
377 			so->so_options &= ~SO_DONTROUTE;
378 		rights = 0;
379 		top = 0;
380 		first = 0;
381 		if (error)
382 			break;
383 	} while (uio->uio_resid);
384 
385 release:
386 	sbunlock(&so->so_snd);
387 	if (top)
388 		m_freem(top);
389 	if (error == EPIPE)
390 		psignal(u.u_procp, SIGPIPE);
391 	return (error);
392 }
393 
394 soreceive(so, aname, uio, flags, rightsp)
395 	register struct socket *so;
396 	struct mbuf **aname;
397 	register struct uio *uio;
398 	int flags;
399 	struct mbuf **rightsp;
400 {
401 	register struct mbuf *m, *n;
402 	register int len, error = 0, s, tomark;
403 	struct protosw *pr = so->so_proto;
404 	struct mbuf *nextrecord;
405 	int moff;
406 
407 	if (rightsp)
408 		*rightsp = 0;
409 	if (aname)
410 		*aname = 0;
411 	if (flags & MSG_OOB) {
412 		m = m_get(M_WAIT, MT_DATA);
413 		error = (*pr->pr_usrreq)(so, PRU_RCVOOB,
414 		    m, (struct mbuf *)0, (struct mbuf *)0);
415 		if (error)
416 			goto bad;
417 		do {
418 			len = uio->uio_resid;
419 			if (len > m->m_len)
420 				len = m->m_len;
421 			error =
422 			    uiomove(mtod(m, caddr_t), (int)len, UIO_READ, uio);
423 			m = m_free(m);
424 		} while (uio->uio_resid && error == 0 && m);
425 bad:
426 		if (m)
427 			m_freem(m);
428 		return (error);
429 	}
430 
431 restart:
432 	sblock(&so->so_rcv);
433 	s = splnet();
434 
435 #define	rcverr(errno)	{ error = errno; splx(s); goto release; }
436 	if (so->so_rcv.sb_cc == 0) {
437 		if (so->so_error) {
438 			error = so->so_error;
439 			so->so_error = 0;
440 			splx(s);
441 			goto release;
442 		}
443 		if (so->so_state & SS_CANTRCVMORE) {
444 			splx(s);
445 			goto release;
446 		}
447 		if ((so->so_state & SS_ISCONNECTED) == 0 &&
448 		    (so->so_proto->pr_flags & PR_CONNREQUIRED))
449 			rcverr(ENOTCONN);
450 		if (so->so_state & SS_NBIO)
451 			rcverr(EWOULDBLOCK);
452 		sbunlock(&so->so_rcv);
453 		sbwait(&so->so_rcv);
454 		splx(s);
455 		goto restart;
456 	}
457 	u.u_ru.ru_msgrcv++;
458 	m = so->so_rcv.sb_mb;
459 	if (pr->pr_flags & PR_ADDR) {
460 		if (m == 0 || m->m_type != MT_SONAME)
461 			panic("receive 1a");
462 		if (flags & MSG_PEEK) {
463 			if (aname)
464 				*aname = m_copy(m, 0, m->m_len);
465 			else
466 				m = m->m_act;
467 		} else {
468 			if (aname) {
469 				*aname = m;
470 				sbfree(&so->so_rcv, m);
471 if(m->m_next) panic("receive 1b");
472 				so->so_rcv.sb_mb = m = m->m_act;
473 			} else
474 				m = sbdroprecord(&so->so_rcv);
475 		}
476 	}
477 	if (m && m->m_type == MT_RIGHTS) {
478 		if ((pr->pr_flags & PR_RIGHTS) == 0)
479 			panic("receive 2a");
480 		if (flags & MSG_PEEK) {
481 			if (rightsp)
482 				*rightsp = m_copy(m, 0, m->m_len);
483 			else
484 				m = m->m_act;
485 		} else {
486 			if (rightsp) {
487 				*rightsp = m;
488 				sbfree(&so->so_rcv, m);
489 if(m->m_next) panic("receive 2b");
490 				so->so_rcv.sb_mb = m = m->m_act;
491 			} else
492 				m = sbdroprecord(&so->so_rcv);
493 		}
494 	}
495 	if (m == 0 || (m->m_type != MT_DATA && m->m_type != MT_HEADER))
496 		panic("receive 3");
497 	moff = 0;
498 	tomark = so->so_oobmark;
499 	while (m && uio->uio_resid > 0 && error == 0) {
500 		len = uio->uio_resid;
501 		so->so_state &= ~SS_RCVATMARK;
502 		if (tomark && len > tomark)
503 			len = tomark;
504 		if (len > m->m_len - moff)
505 			len = m->m_len - moff;
506 		splx(s);
507 		error =
508 		    uiomove(mtod(m, caddr_t) + moff, (int)len, UIO_READ, uio);
509 		s = splnet();
510 		if (len == m->m_len - moff) {
511 			if ((flags & MSG_PEEK) == 0) {
512 				nextrecord = m->m_act;
513 				sbfree(&so->so_rcv, m);
514 				MFREE(m, n);
515 				if (m = n)
516 					m->m_act = nextrecord;
517 				so->so_rcv.sb_mb = m;
518 			} else
519 				m = m->m_next;
520 			moff = 0;
521 		} else {
522 			if (flags & MSG_PEEK)
523 				moff += len;
524 			else {
525 				m->m_off += len;
526 				m->m_len -= len;
527 				so->so_rcv.sb_cc -= len;
528 			}
529 		}
530 		if ((flags & MSG_PEEK) == 0 && so->so_oobmark) {
531 			so->so_oobmark -= len;
532 			if (so->so_oobmark == 0) {
533 				so->so_state |= SS_RCVATMARK;
534 				break;
535 			}
536 		}
537 		if (tomark) {
538 			tomark -= len;
539 			if (tomark == 0)
540 				break;
541 		}
542 	}
543 	if ((flags & MSG_PEEK) == 0) {
544 		if (m == 0)
545 			so->so_rcv.sb_mb = nextrecord;
546 		else if (pr->pr_flags & PR_ATOMIC)
547 			(void) sbdroprecord(&so->so_rcv);
548 		if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
549 			(*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
550 			    (struct mbuf *)0, (struct mbuf *)0);
551 	}
552 release:
553 	sbunlock(&so->so_rcv);
554 	if (error == 0 && rightsp && *rightsp && pr->pr_domain->dom_externalize)
555 		error = (*pr->pr_domain->dom_externalize)(*rightsp);
556 	splx(s);
557 	return (error);
558 }
559 
560 soshutdown(so, how)
561 	register struct socket *so;
562 	register int how;
563 {
564 	register struct protosw *pr = so->so_proto;
565 
566 	how++;
567 	if (how & FREAD)
568 		sorflush(so);
569 	if (how & FWRITE)
570 		return ((*pr->pr_usrreq)(so, PRU_SHUTDOWN,
571 		    (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
572 	return (0);
573 }
574 
575 sorflush(so)
576 	register struct socket *so;
577 {
578 	register struct sockbuf *sb = &so->so_rcv;
579 	register struct protosw *pr = so->so_proto;
580 	register int s;
581 	struct sockbuf asb;
582 
583 	sblock(sb);
584 	s = splimp();
585 	socantrcvmore(so);
586 	sbunlock(sb);
587 	asb = *sb;
588 	bzero((caddr_t)sb, sizeof (*sb));
589 	splx(s);
590 	if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)
591 		(*pr->pr_domain->dom_dispose)(asb.sb_mb);
592 	sbrelease(&asb);
593 }
594 
595 sosetopt(so, level, optname, m0)
596 	register struct socket *so;
597 	int level, optname;
598 	struct mbuf *m0;
599 {
600 	int error = 0;
601 	register struct mbuf *m = m0;
602 
603 	if (level != SOL_SOCKET) {
604 		if (so->so_proto && so->so_proto->pr_ctloutput)
605 			return ((*so->so_proto->pr_ctloutput)
606 				  (PRCO_SETOPT, so, level, optname, &m0));
607 		error = ENOPROTOOPT;
608 	} else {
609 		switch (optname) {
610 
611 		case SO_LINGER:
612 			if (m == NULL || m->m_len != sizeof (struct linger)) {
613 				error = EINVAL;
614 				goto bad;
615 			}
616 			so->so_linger = mtod(m, struct linger *)->l_linger;
617 			/* fall thru... */
618 
619 		case SO_DEBUG:
620 		case SO_KEEPALIVE:
621 		case SO_DONTROUTE:
622 		case SO_USELOOPBACK:
623 		case SO_BROADCAST:
624 		case SO_REUSEADDR:
625 			if (m == NULL || m->m_len < sizeof (int)) {
626 				error = EINVAL;
627 				goto bad;
628 			}
629 			if (*mtod(m, int *))
630 				so->so_options |= optname;
631 			else
632 				so->so_options &= ~optname;
633 			break;
634 
635 		case SO_SNDBUF:
636 		case SO_RCVBUF:
637 		case SO_SNDLOWAT:
638 		case SO_RCVLOWAT:
639 		case SO_SNDTIMEO:
640 		case SO_RCVTIMEO:
641 			if (m == NULL || m->m_len < sizeof (int)) {
642 				error = EINVAL;
643 				goto bad;
644 			}
645 			switch (optname) {
646 
647 			case SO_SNDBUF:
648 			case SO_RCVBUF:
649 				if (sbreserve(optname == SO_SNDBUF ? &so->so_snd :
650 				    &so->so_rcv, *mtod(m, int *)) == 0) {
651 					error = ENOBUFS;
652 					goto bad;
653 				}
654 				break;
655 
656 			case SO_SNDLOWAT:
657 				so->so_snd.sb_lowat = *mtod(m, int *);
658 				break;
659 			case SO_RCVLOWAT:
660 				so->so_rcv.sb_lowat = *mtod(m, int *);
661 				break;
662 			case SO_SNDTIMEO:
663 				so->so_snd.sb_timeo = *mtod(m, int *);
664 				break;
665 			case SO_RCVTIMEO:
666 				so->so_rcv.sb_timeo = *mtod(m, int *);
667 				break;
668 			}
669 			break;
670 
671 		default:
672 			error = ENOPROTOOPT;
673 			break;
674 		}
675 	}
676 bad:
677 	if (m)
678 		(void) m_free(m);
679 	return (error);
680 }
681 
682 sogetopt(so, level, optname, mp)
683 	register struct socket *so;
684 	int level, optname;
685 	struct mbuf **mp;
686 {
687 	register struct mbuf *m;
688 
689 	if (level != SOL_SOCKET) {
690 		if (so->so_proto && so->so_proto->pr_ctloutput) {
691 			return ((*so->so_proto->pr_ctloutput)
692 				  (PRCO_GETOPT, so, level, optname, mp));
693 		} else
694 			return (ENOPROTOOPT);
695 	} else {
696 		m = m_get(M_WAIT, MT_SOOPTS);
697 		switch (optname) {
698 
699 		case SO_LINGER:
700 			m->m_len = sizeof (struct linger);
701 			mtod(m, struct linger *)->l_onoff =
702 				so->so_options & SO_LINGER;
703 			mtod(m, struct linger *)->l_linger = so->so_linger;
704 			break;
705 
706 		case SO_USELOOPBACK:
707 		case SO_DONTROUTE:
708 		case SO_DEBUG:
709 		case SO_KEEPALIVE:
710 		case SO_REUSEADDR:
711 		case SO_BROADCAST:
712 			m->m_len = sizeof (int);
713 			*mtod(m, int *) = so->so_options & optname;
714 			break;
715 
716 		case SO_SNDBUF:
717 			*mtod(m, int *) = so->so_snd.sb_hiwat;
718 			break;
719 
720 		case SO_RCVBUF:
721 			*mtod(m, int *) = so->so_rcv.sb_hiwat;
722 			break;
723 
724 		case SO_SNDLOWAT:
725 			*mtod(m, int *) = so->so_snd.sb_lowat;
726 			break;
727 
728 		case SO_RCVLOWAT:
729 			*mtod(m, int *) = so->so_rcv.sb_lowat;
730 			break;
731 
732 		case SO_SNDTIMEO:
733 			*mtod(m, int *) = so->so_snd.sb_timeo;
734 			break;
735 
736 		case SO_RCVTIMEO:
737 			*mtod(m, int *) = so->so_rcv.sb_timeo;
738 			break;
739 
740 		default:
741 			m_free(m);
742 			return (ENOPROTOOPT);
743 		}
744 		*mp = m;
745 		return (0);
746 	}
747 }
748 
749 sohasoutofband(so)
750 	register struct socket *so;
751 {
752 	struct proc *p;
753 
754 	if (so->so_pgrp < 0)
755 		gsignal(-so->so_pgrp, SIGURG);
756 	else if (so->so_pgrp > 0 && (p = pfind(so->so_pgrp)) != 0)
757 		psignal(p, SIGURG);
758 }
759