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