1 /*- 2 * Copyright (c) 2015 Dmitry Chagin 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <opt_inet6.h> 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/conf.h> 35 #include <sys/ctype.h> 36 #include <sys/file.h> 37 #include <sys/filedesc.h> 38 #include <sys/jail.h> 39 #include <sys/lock.h> 40 #include <sys/malloc.h> 41 #include <sys/poll.h> 42 #include <sys/proc.h> 43 #include <sys/signalvar.h> 44 #include <sys/socket.h> 45 #include <sys/socketvar.h> 46 47 #include <net/if.h> 48 #include <net/if_var.h> 49 #include <net/if_dl.h> 50 #include <net/if_types.h> 51 52 #include <sys/un.h> 53 #include <netinet/in.h> 54 55 #include <compat/linux/linux.h> 56 #include <compat/linux/linux_common.h> 57 #include <compat/linux/linux_mib.h> 58 #include <compat/linux/linux_util.h> 59 60 struct futex_list futex_list; 61 struct mtx futex_mtx; /* protects the futex list */ 62 63 CTASSERT(LINUX_IFNAMSIZ == IFNAMSIZ); 64 65 static int bsd_to_linux_sigtbl[LINUX_SIGTBLSZ] = { 66 LINUX_SIGHUP, /* SIGHUP */ 67 LINUX_SIGINT, /* SIGINT */ 68 LINUX_SIGQUIT, /* SIGQUIT */ 69 LINUX_SIGILL, /* SIGILL */ 70 LINUX_SIGTRAP, /* SIGTRAP */ 71 LINUX_SIGABRT, /* SIGABRT */ 72 0, /* SIGEMT */ 73 LINUX_SIGFPE, /* SIGFPE */ 74 LINUX_SIGKILL, /* SIGKILL */ 75 LINUX_SIGBUS, /* SIGBUS */ 76 LINUX_SIGSEGV, /* SIGSEGV */ 77 LINUX_SIGSYS, /* SIGSYS */ 78 LINUX_SIGPIPE, /* SIGPIPE */ 79 LINUX_SIGALRM, /* SIGALRM */ 80 LINUX_SIGTERM, /* SIGTERM */ 81 LINUX_SIGURG, /* SIGURG */ 82 LINUX_SIGSTOP, /* SIGSTOP */ 83 LINUX_SIGTSTP, /* SIGTSTP */ 84 LINUX_SIGCONT, /* SIGCONT */ 85 LINUX_SIGCHLD, /* SIGCHLD */ 86 LINUX_SIGTTIN, /* SIGTTIN */ 87 LINUX_SIGTTOU, /* SIGTTOU */ 88 LINUX_SIGIO, /* SIGIO */ 89 LINUX_SIGXCPU, /* SIGXCPU */ 90 LINUX_SIGXFSZ, /* SIGXFSZ */ 91 LINUX_SIGVTALRM,/* SIGVTALRM */ 92 LINUX_SIGPROF, /* SIGPROF */ 93 LINUX_SIGWINCH, /* SIGWINCH */ 94 0, /* SIGINFO */ 95 LINUX_SIGUSR1, /* SIGUSR1 */ 96 LINUX_SIGUSR2 /* SIGUSR2 */ 97 }; 98 99 static int linux_to_bsd_sigtbl[LINUX_SIGTBLSZ] = { 100 SIGHUP, /* LINUX_SIGHUP */ 101 SIGINT, /* LINUX_SIGINT */ 102 SIGQUIT, /* LINUX_SIGQUIT */ 103 SIGILL, /* LINUX_SIGILL */ 104 SIGTRAP, /* LINUX_SIGTRAP */ 105 SIGABRT, /* LINUX_SIGABRT */ 106 SIGBUS, /* LINUX_SIGBUS */ 107 SIGFPE, /* LINUX_SIGFPE */ 108 SIGKILL, /* LINUX_SIGKILL */ 109 SIGUSR1, /* LINUX_SIGUSR1 */ 110 SIGSEGV, /* LINUX_SIGSEGV */ 111 SIGUSR2, /* LINUX_SIGUSR2 */ 112 SIGPIPE, /* LINUX_SIGPIPE */ 113 SIGALRM, /* LINUX_SIGALRM */ 114 SIGTERM, /* LINUX_SIGTERM */ 115 SIGBUS, /* LINUX_SIGSTKFLT */ 116 SIGCHLD, /* LINUX_SIGCHLD */ 117 SIGCONT, /* LINUX_SIGCONT */ 118 SIGSTOP, /* LINUX_SIGSTOP */ 119 SIGTSTP, /* LINUX_SIGTSTP */ 120 SIGTTIN, /* LINUX_SIGTTIN */ 121 SIGTTOU, /* LINUX_SIGTTOU */ 122 SIGURG, /* LINUX_SIGURG */ 123 SIGXCPU, /* LINUX_SIGXCPU */ 124 SIGXFSZ, /* LINUX_SIGXFSZ */ 125 SIGVTALRM, /* LINUX_SIGVTALARM */ 126 SIGPROF, /* LINUX_SIGPROF */ 127 SIGWINCH, /* LINUX_SIGWINCH */ 128 SIGIO, /* LINUX_SIGIO */ 129 /* 130 * FreeBSD does not have SIGPWR signal, map Linux SIGPWR signal 131 * to the first unused FreeBSD signal number. Since Linux supports 132 * signals from 1 to 64 we are ok here as our SIGRTMIN = 65. 133 */ 134 SIGRTMIN, /* LINUX_SIGPWR */ 135 SIGSYS /* LINUX_SIGSYS */ 136 }; 137 138 static struct cdev *dev_shm_cdev; 139 static struct cdevsw dev_shm_cdevsw = { 140 .d_version = D_VERSION, 141 .d_name = "dev_shm", 142 }; 143 144 /* 145 * Map Linux RT signals to the FreeBSD RT signals. 146 */ 147 static inline int 148 linux_to_bsd_rt_signal(int sig) 149 { 150 151 return (SIGRTMIN + 1 + sig - LINUX_SIGRTMIN); 152 } 153 154 static inline int 155 bsd_to_linux_rt_signal(int sig) 156 { 157 158 return (sig - SIGRTMIN - 1 + LINUX_SIGRTMIN); 159 } 160 161 int 162 linux_to_bsd_signal(int sig) 163 { 164 165 KASSERT(sig > 0 && sig <= LINUX_SIGRTMAX, ("invalid Linux signal %d\n", sig)); 166 167 if (sig < LINUX_SIGRTMIN) 168 return (linux_to_bsd_sigtbl[_SIG_IDX(sig)]); 169 170 return (linux_to_bsd_rt_signal(sig)); 171 } 172 173 int 174 bsd_to_linux_signal(int sig) 175 { 176 177 if (sig <= LINUX_SIGTBLSZ) 178 return (bsd_to_linux_sigtbl[_SIG_IDX(sig)]); 179 if (sig == SIGRTMIN) 180 return (LINUX_SIGPWR); 181 182 return (bsd_to_linux_rt_signal(sig)); 183 } 184 185 int 186 linux_to_bsd_sigaltstack(int lsa) 187 { 188 int bsa = 0; 189 190 if (lsa & LINUX_SS_DISABLE) 191 bsa |= SS_DISABLE; 192 /* 193 * Linux ignores SS_ONSTACK flag for ss 194 * parameter while FreeBSD prohibits it. 195 */ 196 return (bsa); 197 } 198 199 int 200 bsd_to_linux_sigaltstack(int bsa) 201 { 202 int lsa = 0; 203 204 if (bsa & SS_DISABLE) 205 lsa |= LINUX_SS_DISABLE; 206 if (bsa & SS_ONSTACK) 207 lsa |= LINUX_SS_ONSTACK; 208 return (lsa); 209 } 210 211 void 212 linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss) 213 { 214 int b, l; 215 216 SIGEMPTYSET(*bss); 217 for (l = 1; l <= LINUX_SIGRTMAX; l++) { 218 if (LINUX_SIGISMEMBER(*lss, l)) { 219 b = linux_to_bsd_signal(l); 220 if (b) 221 SIGADDSET(*bss, b); 222 } 223 } 224 } 225 226 void 227 bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) 228 { 229 int b, l; 230 231 LINUX_SIGEMPTYSET(*lss); 232 for (b = 1; b <= SIGRTMAX; b++) { 233 if (SIGISMEMBER(*bss, b)) { 234 l = bsd_to_linux_signal(b); 235 if (l) 236 LINUX_SIGADDSET(*lss, l); 237 } 238 } 239 } 240 241 /* 242 * Translate a Linux interface name to a FreeBSD interface name, 243 * and return the associated ifnet structure 244 * bsdname and lxname need to be least IFNAMSIZ bytes long, but 245 * can point to the same buffer. 246 */ 247 struct ifnet * 248 ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname) 249 { 250 struct ifnet *ifp; 251 int len, unit; 252 char *ep; 253 int index; 254 bool is_eth, is_lo; 255 256 for (len = 0; len < LINUX_IFNAMSIZ; ++len) 257 if (!isalpha(lxname[len]) || lxname[len] == '\0') 258 break; 259 if (len == 0 || len == LINUX_IFNAMSIZ) 260 return (NULL); 261 /* Linux loopback interface name is lo (not lo0) */ 262 is_lo = (len == 2 && strncmp(lxname, "lo", len) == 0); 263 unit = (int)strtoul(lxname + len, &ep, 10); 264 if ((ep == NULL || ep == lxname + len || ep >= lxname + LINUX_IFNAMSIZ) && 265 is_lo == 0) 266 return (NULL); 267 index = 0; 268 is_eth = (len == 3 && strncmp(lxname, "eth", len) == 0); 269 270 CURVNET_SET(TD_TO_VNET(td)); 271 IFNET_RLOCK(); 272 CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { 273 /* 274 * Allow Linux programs to use FreeBSD names. Don't presume 275 * we never have an interface named "eth", so don't make 276 * the test optional based on is_eth. 277 */ 278 if (strncmp(ifp->if_xname, lxname, LINUX_IFNAMSIZ) == 0) 279 break; 280 if (is_eth && IFP_IS_ETH(ifp) && unit == index++) 281 break; 282 if (is_lo && IFP_IS_LOOP(ifp)) 283 break; 284 } 285 IFNET_RUNLOCK(); 286 CURVNET_RESTORE(); 287 if (ifp != NULL && bsdname != NULL) 288 strlcpy(bsdname, ifp->if_xname, IFNAMSIZ); 289 return (ifp); 290 } 291 292 void 293 linux_ifflags(struct ifnet *ifp, short *flags) 294 { 295 unsigned short fl; 296 297 fl = (ifp->if_flags | ifp->if_drv_flags) & 0xffff; 298 *flags = 0; 299 if (fl & IFF_UP) 300 *flags |= LINUX_IFF_UP; 301 if (fl & IFF_BROADCAST) 302 *flags |= LINUX_IFF_BROADCAST; 303 if (fl & IFF_DEBUG) 304 *flags |= LINUX_IFF_DEBUG; 305 if (fl & IFF_LOOPBACK) 306 *flags |= LINUX_IFF_LOOPBACK; 307 if (fl & IFF_POINTOPOINT) 308 *flags |= LINUX_IFF_POINTOPOINT; 309 if (fl & IFF_DRV_RUNNING) 310 *flags |= LINUX_IFF_RUNNING; 311 if (fl & IFF_NOARP) 312 *flags |= LINUX_IFF_NOARP; 313 if (fl & IFF_PROMISC) 314 *flags |= LINUX_IFF_PROMISC; 315 if (fl & IFF_ALLMULTI) 316 *flags |= LINUX_IFF_ALLMULTI; 317 if (fl & IFF_MULTICAST) 318 *flags |= LINUX_IFF_MULTICAST; 319 } 320 321 int 322 linux_ifhwaddr(struct ifnet *ifp, struct l_sockaddr *lsa) 323 { 324 struct ifaddr *ifa; 325 struct sockaddr_dl *sdl; 326 327 if (IFP_IS_LOOP(ifp)) { 328 bzero(lsa, sizeof(*lsa)); 329 lsa->sa_family = LINUX_ARPHRD_LOOPBACK; 330 return (0); 331 } 332 333 if (!IFP_IS_ETH(ifp)) 334 return (ENOENT); 335 336 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 337 sdl = (struct sockaddr_dl*)ifa->ifa_addr; 338 if (sdl != NULL && (sdl->sdl_family == AF_LINK) && 339 (sdl->sdl_type == IFT_ETHER)) { 340 bzero(lsa, sizeof(*lsa)); 341 lsa->sa_family = LINUX_ARPHRD_ETHER; 342 bcopy(LLADDR(sdl), lsa->sa_data, LINUX_IFHWADDRLEN); 343 return (0); 344 } 345 } 346 347 return (ENOENT); 348 } 349 350 int 351 linux_to_bsd_domain(int domain) 352 { 353 354 switch (domain) { 355 case LINUX_AF_UNSPEC: 356 return (AF_UNSPEC); 357 case LINUX_AF_UNIX: 358 return (AF_LOCAL); 359 case LINUX_AF_INET: 360 return (AF_INET); 361 case LINUX_AF_INET6: 362 return (AF_INET6); 363 case LINUX_AF_AX25: 364 return (AF_CCITT); 365 case LINUX_AF_IPX: 366 return (AF_IPX); 367 case LINUX_AF_APPLETALK: 368 return (AF_APPLETALK); 369 } 370 return (-1); 371 } 372 373 int 374 bsd_to_linux_domain(int domain) 375 { 376 377 switch (domain) { 378 case AF_UNSPEC: 379 return (LINUX_AF_UNSPEC); 380 case AF_LOCAL: 381 return (LINUX_AF_UNIX); 382 case AF_INET: 383 return (LINUX_AF_INET); 384 case AF_INET6: 385 return (LINUX_AF_INET6); 386 case AF_CCITT: 387 return (LINUX_AF_AX25); 388 case AF_IPX: 389 return (LINUX_AF_IPX); 390 case AF_APPLETALK: 391 return (LINUX_AF_APPLETALK); 392 } 393 return (-1); 394 } 395 396 /* 397 * Based on the fact that: 398 * 1. Native and Linux storage of struct sockaddr 399 * and struct sockaddr_in6 are equal. 400 * 2. On Linux sa_family is the first member of all struct sockaddr. 401 */ 402 int 403 bsd_to_linux_sockaddr(const struct sockaddr *sa, struct l_sockaddr **lsa, 404 socklen_t len) 405 { 406 struct l_sockaddr *kosa; 407 int error, bdom; 408 409 *lsa = NULL; 410 if (len < 2 || len > UCHAR_MAX) 411 return (EINVAL); 412 413 kosa = malloc(len, M_SONAME, M_WAITOK); 414 bcopy(sa, kosa, len); 415 416 bdom = bsd_to_linux_domain(sa->sa_family); 417 if (bdom == -1) { 418 error = EAFNOSUPPORT; 419 goto out; 420 } 421 422 kosa->sa_family = bdom; 423 *lsa = kosa; 424 return (0); 425 426 out: 427 free(kosa, M_SONAME); 428 return (error); 429 } 430 431 int 432 linux_to_bsd_sockaddr(const struct l_sockaddr *osa, struct sockaddr **sap, 433 socklen_t *len) 434 { 435 struct sockaddr *sa; 436 struct l_sockaddr *kosa; 437 #ifdef INET6 438 struct sockaddr_in6 *sin6; 439 bool oldv6size; 440 #endif 441 char *name; 442 int salen, bdom, error, hdrlen, namelen; 443 444 if (*len < 2 || *len > UCHAR_MAX) 445 return (EINVAL); 446 447 salen = *len; 448 449 #ifdef INET6 450 oldv6size = false; 451 /* 452 * Check for old (pre-RFC2553) sockaddr_in6. We may accept it 453 * if it's a v4-mapped address, so reserve the proper space 454 * for it. 455 */ 456 if (salen == sizeof(struct sockaddr_in6) - sizeof(uint32_t)) { 457 salen += sizeof(uint32_t); 458 oldv6size = true; 459 } 460 #endif 461 462 kosa = malloc(salen, M_SONAME, M_WAITOK); 463 464 if ((error = copyin(osa, kosa, *len))) 465 goto out; 466 467 bdom = linux_to_bsd_domain(kosa->sa_family); 468 if (bdom == -1) { 469 error = EAFNOSUPPORT; 470 goto out; 471 } 472 473 #ifdef INET6 474 /* 475 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6, 476 * which lacks the scope id compared with RFC2553 one. If we detect 477 * the situation, reject the address and write a message to system log. 478 * 479 * Still accept addresses for which the scope id is not used. 480 */ 481 if (oldv6size) { 482 if (bdom == AF_INET6) { 483 sin6 = (struct sockaddr_in6 *)kosa; 484 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) || 485 (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && 486 !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && 487 !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) && 488 !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) && 489 !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) { 490 sin6->sin6_scope_id = 0; 491 } else { 492 linux_msg(curthread, 493 "obsolete pre-RFC2553 sockaddr_in6 rejected"); 494 error = EINVAL; 495 goto out; 496 } 497 } else 498 salen -= sizeof(uint32_t); 499 } 500 #endif 501 if (bdom == AF_INET) { 502 if (salen < sizeof(struct sockaddr_in)) { 503 error = EINVAL; 504 goto out; 505 } 506 salen = sizeof(struct sockaddr_in); 507 } 508 509 if (bdom == AF_LOCAL && salen > sizeof(struct sockaddr_un)) { 510 hdrlen = offsetof(struct sockaddr_un, sun_path); 511 name = ((struct sockaddr_un *)kosa)->sun_path; 512 if (*name == '\0') { 513 /* 514 * Linux abstract namespace starts with a NULL byte. 515 * XXX We do not support abstract namespace yet. 516 */ 517 namelen = strnlen(name + 1, salen - hdrlen - 1) + 1; 518 } else 519 namelen = strnlen(name, salen - hdrlen); 520 salen = hdrlen + namelen; 521 if (salen > sizeof(struct sockaddr_un)) { 522 error = ENAMETOOLONG; 523 goto out; 524 } 525 } 526 527 sa = (struct sockaddr *)kosa; 528 sa->sa_family = bdom; 529 sa->sa_len = salen; 530 531 *sap = sa; 532 *len = salen; 533 return (0); 534 535 out: 536 free(kosa, M_SONAME); 537 return (error); 538 } 539 540 void 541 linux_dev_shm_create(void) 542 { 543 int error; 544 545 error = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, &dev_shm_cdev, 546 &dev_shm_cdevsw, NULL, UID_ROOT, GID_WHEEL, 0, "shm/.mountpoint"); 547 if (error != 0) { 548 printf("%s: failed to create device node, error %d\n", 549 __func__, error); 550 } 551 } 552 553 void 554 linux_dev_shm_destroy(void) 555 { 556 557 destroy_dev(dev_shm_cdev); 558 } 559 560 int 561 bsd_to_linux_bits_(int value, struct bsd_to_linux_bitmap *bitmap, 562 size_t mapcnt, int no_value) 563 { 564 int bsd_mask, bsd_value, linux_mask, linux_value; 565 int linux_ret; 566 size_t i; 567 bool applied; 568 569 applied = false; 570 linux_ret = 0; 571 for (i = 0; i < mapcnt; ++i) { 572 bsd_mask = bitmap[i].bsd_mask; 573 bsd_value = bitmap[i].bsd_value; 574 if (bsd_mask == 0) 575 bsd_mask = bsd_value; 576 577 linux_mask = bitmap[i].linux_mask; 578 linux_value = bitmap[i].linux_value; 579 if (linux_mask == 0) 580 linux_mask = linux_value; 581 582 /* 583 * If a mask larger than just the value is set, we explicitly 584 * want to make sure that only this bit we mapped within that 585 * mask is set. 586 */ 587 if ((value & bsd_mask) == bsd_value) { 588 linux_ret = (linux_ret & ~linux_mask) | linux_value; 589 applied = true; 590 } 591 } 592 593 if (!applied) 594 return (no_value); 595 return (linux_ret); 596 } 597 598 int 599 linux_to_bsd_bits_(int value, struct bsd_to_linux_bitmap *bitmap, 600 size_t mapcnt, int no_value) 601 { 602 int bsd_mask, bsd_value, linux_mask, linux_value; 603 int bsd_ret; 604 size_t i; 605 bool applied; 606 607 applied = false; 608 bsd_ret = 0; 609 for (i = 0; i < mapcnt; ++i) { 610 bsd_mask = bitmap[i].bsd_mask; 611 bsd_value = bitmap[i].bsd_value; 612 if (bsd_mask == 0) 613 bsd_mask = bsd_value; 614 615 linux_mask = bitmap[i].linux_mask; 616 linux_value = bitmap[i].linux_value; 617 if (linux_mask == 0) 618 linux_mask = linux_value; 619 620 /* 621 * If a mask larger than just the value is set, we explicitly 622 * want to make sure that only this bit we mapped within that 623 * mask is set. 624 */ 625 if ((value & linux_mask) == linux_value) { 626 bsd_ret = (bsd_ret & ~bsd_mask) | bsd_value; 627 applied = true; 628 } 629 } 630 631 if (!applied) 632 return (no_value); 633 return (bsd_ret); 634 } 635 636 void 637 linux_to_bsd_poll_events(struct thread *td, int fd, short lev, 638 short *bev) 639 { 640 struct proc *p = td->td_proc; 641 struct filedesc *fdp; 642 struct file *fp; 643 int error; 644 short bits = 0; 645 646 if (lev & LINUX_POLLIN) 647 bits |= POLLIN; 648 if (lev & LINUX_POLLPRI) 649 bits |= POLLPRI; 650 if (lev & LINUX_POLLOUT) 651 bits |= POLLOUT; 652 if (lev & LINUX_POLLERR) 653 bits |= POLLERR; 654 if (lev & LINUX_POLLHUP) 655 bits |= POLLHUP; 656 if (lev & LINUX_POLLNVAL) 657 bits |= POLLNVAL; 658 if (lev & LINUX_POLLRDNORM) 659 bits |= POLLRDNORM; 660 if (lev & LINUX_POLLRDBAND) 661 bits |= POLLRDBAND; 662 if (lev & LINUX_POLLWRBAND) 663 bits |= POLLWRBAND; 664 if (lev & LINUX_POLLWRNORM) 665 bits |= POLLWRNORM; 666 667 if (lev & LINUX_POLLRDHUP) { 668 /* 669 * It seems that the Linux silencly ignores POLLRDHUP 670 * on non-socket file descriptors unlike FreeBSD, where 671 * events bits is more strictly checked (POLLSTANDARD). 672 */ 673 fdp = p->p_fd; 674 error = fget_unlocked(fdp, fd, &cap_no_rights, &fp); 675 if (error == 0) { 676 /* 677 * XXX. On FreeBSD POLLRDHUP applies only to 678 * stream sockets. 679 */ 680 if (fp->f_type == DTYPE_SOCKET) 681 bits |= POLLRDHUP; 682 fdrop(fp, td); 683 } 684 } 685 686 if (lev & LINUX_POLLMSG) 687 LINUX_RATELIMIT_MSG_OPT1("unsupported POLLMSG, events(%d)", lev); 688 if (lev & LINUX_POLLREMOVE) 689 LINUX_RATELIMIT_MSG_OPT1("unsupported POLLREMOVE, events(%d)", lev); 690 691 *bev = bits; 692 } 693 694 void 695 bsd_to_linux_poll_events(short bev, short *lev) 696 { 697 short bits = 0; 698 699 if (bev & POLLIN) 700 bits |= LINUX_POLLIN; 701 if (bev & POLLPRI) 702 bits |= LINUX_POLLPRI; 703 if (bev & (POLLOUT | POLLWRNORM)) 704 /* 705 * POLLWRNORM is equal to POLLOUT on FreeBSD, 706 * but not on Linux 707 */ 708 bits |= LINUX_POLLOUT; 709 if (bev & POLLERR) 710 bits |= LINUX_POLLERR; 711 if (bev & POLLHUP) 712 bits |= LINUX_POLLHUP; 713 if (bev & POLLNVAL) 714 bits |= LINUX_POLLNVAL; 715 if (bev & POLLRDNORM) 716 bits |= LINUX_POLLRDNORM; 717 if (bev & POLLRDBAND) 718 bits |= LINUX_POLLRDBAND; 719 if (bev & POLLWRBAND) 720 bits |= LINUX_POLLWRBAND; 721 if (bev & POLLRDHUP) 722 bits |= LINUX_POLLRDHUP; 723 724 *lev = bits; 725 } 726