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