1*a9643ea8Slogwang /* 2*a9643ea8Slogwang * Copyright (c) 2010 Kip Macy. All rights reserved. 3*a9643ea8Slogwang * Copyright (C) 2017 THL A29 Limited, a Tencent company. 4*a9643ea8Slogwang * All rights reserved. 5*a9643ea8Slogwang * 6*a9643ea8Slogwang * Redistribution and use in source and binary forms, with or without 7*a9643ea8Slogwang * modification, are permitted provided that the following conditions are met: 8*a9643ea8Slogwang * 9*a9643ea8Slogwang * 1. Redistributions of source code must retain the above copyright notice, this 10*a9643ea8Slogwang * list of conditions and the following disclaimer. 11*a9643ea8Slogwang * 2. Redistributions in binary form must reproduce the above copyright notice, 12*a9643ea8Slogwang * this list of conditions and the following disclaimer in the documentation 13*a9643ea8Slogwang * and/or other materials provided with the distribution. 14*a9643ea8Slogwang * 15*a9643ea8Slogwang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16*a9643ea8Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17*a9643ea8Slogwang * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18*a9643ea8Slogwang * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19*a9643ea8Slogwang * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20*a9643ea8Slogwang * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21*a9643ea8Slogwang * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22*a9643ea8Slogwang * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23*a9643ea8Slogwang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24*a9643ea8Slogwang * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25*a9643ea8Slogwang * 26*a9643ea8Slogwang * Derived in part from libplebnet's pn_syscall_wrapper.c. 27*a9643ea8Slogwang */ 28*a9643ea8Slogwang 29*a9643ea8Slogwang #include <sys/param.h> 30*a9643ea8Slogwang #include <sys/limits.h> 31*a9643ea8Slogwang #include <sys/uio.h> 32*a9643ea8Slogwang #include <sys/proc.h> 33*a9643ea8Slogwang #include <sys/syscallsubr.h> 34*a9643ea8Slogwang #include <sys/module.h> 35*a9643ea8Slogwang #include <sys/param.h> 36*a9643ea8Slogwang #include <sys/malloc.h> 37*a9643ea8Slogwang #include <sys/socketvar.h> 38*a9643ea8Slogwang #include <sys/event.h> 39*a9643ea8Slogwang #include <sys/kernel.h> 40*a9643ea8Slogwang #include <sys/refcount.h> 41*a9643ea8Slogwang #include <sys/sysctl.h> 42*a9643ea8Slogwang #include <sys/pcpu.h> 43*a9643ea8Slogwang #include <sys/select.h> 44*a9643ea8Slogwang #include <sys/poll.h> 45*a9643ea8Slogwang #include <sys/event.h> 46*a9643ea8Slogwang #include <sys/file.h> 47*a9643ea8Slogwang #include <netinet/in.h> 48*a9643ea8Slogwang #include <netinet/tcp.h> 49*a9643ea8Slogwang #include <sys/ttycom.h> 50*a9643ea8Slogwang #include <sys/filio.h> 51*a9643ea8Slogwang #include <sys/sysproto.h> 52*a9643ea8Slogwang #include <sys/fcntl.h> 53*a9643ea8Slogwang 54*a9643ea8Slogwang #include <machine/stdarg.h> 55*a9643ea8Slogwang 56*a9643ea8Slogwang #include "ff_api.h" 57*a9643ea8Slogwang #include "ff_host_interface.h" 58*a9643ea8Slogwang 59*a9643ea8Slogwang /* setsockopt/getsockopt define start */ 60*a9643ea8Slogwang 61*a9643ea8Slogwang #define LINUX_SOL_SOCKET 1 62*a9643ea8Slogwang 63*a9643ea8Slogwang #define LINUX_SO_DEBUG 1 64*a9643ea8Slogwang #define LINUX_SO_REUSEADDR 2 65*a9643ea8Slogwang #define LINUX_SO_ERROR 4 66*a9643ea8Slogwang #define LINUX_SO_DONTROUTE 5 67*a9643ea8Slogwang #define LINUX_SO_BROADCAST 6 68*a9643ea8Slogwang #define LINUX_SO_SNDBUF 7 69*a9643ea8Slogwang #define LINUX_SO_RCVBUF 8 70*a9643ea8Slogwang #define LINUX_SO_KEEPALIVE 9 71*a9643ea8Slogwang #define LINUX_SO_OOBINLINE 10 72*a9643ea8Slogwang #define LINUX_SO_LINGER 13 73*a9643ea8Slogwang #define LINUX_SO_RCVLOWAT 18 74*a9643ea8Slogwang #define LINUX_SO_SNDLOWAT 19 75*a9643ea8Slogwang #define LINUX_SO_RCVTIMEO 20 76*a9643ea8Slogwang #define LINUX_SO_SNDTIMEO 21 77*a9643ea8Slogwang #define LINUX_SO_ACCEPTCONN 30 78*a9643ea8Slogwang #define LINUX_SO_PROTOCOL 38 79*a9643ea8Slogwang 80*a9643ea8Slogwang 81*a9643ea8Slogwang #define LINUX_IP_TOS 1 82*a9643ea8Slogwang #define LINUX_IP_TTL 2 83*a9643ea8Slogwang #define LINUX_IP_HDRINCL 3 84*a9643ea8Slogwang #define LINUX_IP_OPTIONS 4 85*a9643ea8Slogwang 86*a9643ea8Slogwang #define LINUX_IP_MULTICAST_IF 32 87*a9643ea8Slogwang #define LINUX_IP_MULTICAST_TTL 33 88*a9643ea8Slogwang #define LINUX_IP_MULTICAST_LOOP 34 89*a9643ea8Slogwang #define LINUX_IP_ADD_MEMBERSHIP 35 90*a9643ea8Slogwang #define LINUX_IP_DROP_MEMBERSHIP 36 91*a9643ea8Slogwang 92*a9643ea8Slogwang #define LINUX_TCP_NODELAY 1 93*a9643ea8Slogwang #define LINUX_TCP_MAXSEG 2 94*a9643ea8Slogwang #define LINUX_TCP_KEEPIDLE 4 95*a9643ea8Slogwang #define LINUX_TCP_KEEPINTVL 5 96*a9643ea8Slogwang #define LINUX_TCP_KEEPCNT 6 97*a9643ea8Slogwang #define LINUX_TCP_MD5SIG 14 98*a9643ea8Slogwang 99*a9643ea8Slogwang /* setsockopt/getsockopt define end */ 100*a9643ea8Slogwang 101*a9643ea8Slogwang 102*a9643ea8Slogwang /* ioctl define start */ 103*a9643ea8Slogwang 104*a9643ea8Slogwang #define LINUX_TIOCEXCL 0x540C 105*a9643ea8Slogwang #define LINUX_TIOCNXCL 0x540D 106*a9643ea8Slogwang #define LINUX_TIOCSCTTY 0x540E 107*a9643ea8Slogwang #define LINUX_TIOCGPGRP 0x540F 108*a9643ea8Slogwang #define LINUX_TIOCSPGRP 0x5410 109*a9643ea8Slogwang #define LINUX_TIOCOUTQ 0x5411 110*a9643ea8Slogwang #define LINUX_TIOCSTI 0x5412 111*a9643ea8Slogwang #define LINUX_TIOCGWINSZ 0x5413 112*a9643ea8Slogwang #define LINUX_TIOCSWINSZ 0x5414 113*a9643ea8Slogwang #define LINUX_TIOCMGET 0x5415 114*a9643ea8Slogwang #define LINUX_TIOCMBIS 0x5416 115*a9643ea8Slogwang #define LINUX_TIOCMBIC 0x5417 116*a9643ea8Slogwang #define LINUX_TIOCMSET 0x5418 117*a9643ea8Slogwang 118*a9643ea8Slogwang #define LINUX_FIONREAD 0x541B 119*a9643ea8Slogwang #define LINUX_TIOCCONS 0x541D 120*a9643ea8Slogwang #define LINUX_TIOCPKT 0x5420 121*a9643ea8Slogwang #define LINUX_FIONBIO 0x5421 122*a9643ea8Slogwang #define LINUX_TIOCNOTTY 0x5422 123*a9643ea8Slogwang #define LINUX_TIOCSETD 0x5423 124*a9643ea8Slogwang #define LINUX_TIOCGETD 0x5424 125*a9643ea8Slogwang #define LINUX_TIOCSBRK 0x5427 126*a9643ea8Slogwang #define LINUX_TIOCCBRK 0x5428 127*a9643ea8Slogwang #define LINUX_TIOCGSID 0x5429 128*a9643ea8Slogwang 129*a9643ea8Slogwang #define LINUX_FIONCLEX 0x5450 130*a9643ea8Slogwang #define LINUX_FIOCLEX 0x5451 131*a9643ea8Slogwang #define LINUX_FIOASYNC 0x5452 132*a9643ea8Slogwang 133*a9643ea8Slogwang #define LINUX_TIOCPKT_DATA 0 134*a9643ea8Slogwang #define LINUX_TIOCPKT_FLUSHREAD 1 135*a9643ea8Slogwang #define LINUX_TIOCPKT_FLUSHWRITE 2 136*a9643ea8Slogwang #define LINUX_TIOCPKT_STOP 4 137*a9643ea8Slogwang #define LINUX_TIOCPKT_START 8 138*a9643ea8Slogwang #define LINUX_TIOCPKT_NOSTOP 16 139*a9643ea8Slogwang #define LINUX_TIOCPKT_DOSTOP 32 140*a9643ea8Slogwang #define LINUX_TIOCPKT_IOCTL 64 141*a9643ea8Slogwang 142*a9643ea8Slogwang /* ioctl define end */ 143*a9643ea8Slogwang 144*a9643ea8Slogwang 145*a9643ea8Slogwang extern int sendit(struct thread *td, int s, struct msghdr *mp, int flags); 146*a9643ea8Slogwang 147*a9643ea8Slogwang static long 148*a9643ea8Slogwang linux2freebsd_ioctl(unsigned long request) 149*a9643ea8Slogwang { 150*a9643ea8Slogwang switch(request) { 151*a9643ea8Slogwang case LINUX_TIOCEXCL: 152*a9643ea8Slogwang return TIOCEXCL; 153*a9643ea8Slogwang case LINUX_TIOCNXCL: 154*a9643ea8Slogwang return TIOCNXCL; 155*a9643ea8Slogwang case LINUX_TIOCSCTTY: 156*a9643ea8Slogwang return TIOCSCTTY; 157*a9643ea8Slogwang case LINUX_TIOCGPGRP: 158*a9643ea8Slogwang return TIOCGPGRP; 159*a9643ea8Slogwang case LINUX_TIOCSPGRP: 160*a9643ea8Slogwang return TIOCSPGRP; 161*a9643ea8Slogwang case LINUX_TIOCOUTQ: 162*a9643ea8Slogwang return TIOCOUTQ; 163*a9643ea8Slogwang case LINUX_TIOCSTI: 164*a9643ea8Slogwang return TIOCSTI; 165*a9643ea8Slogwang case LINUX_TIOCGWINSZ: 166*a9643ea8Slogwang return TIOCGWINSZ; 167*a9643ea8Slogwang case LINUX_TIOCSWINSZ: 168*a9643ea8Slogwang return TIOCSWINSZ; 169*a9643ea8Slogwang case LINUX_TIOCMGET: 170*a9643ea8Slogwang return TIOCMGET; 171*a9643ea8Slogwang case LINUX_TIOCMBIS: 172*a9643ea8Slogwang return TIOCMBIS; 173*a9643ea8Slogwang case LINUX_TIOCMBIC: 174*a9643ea8Slogwang return TIOCMBIC; 175*a9643ea8Slogwang case LINUX_TIOCMSET: 176*a9643ea8Slogwang return TIOCMSET; 177*a9643ea8Slogwang case LINUX_FIONREAD: 178*a9643ea8Slogwang return FIONREAD; 179*a9643ea8Slogwang case LINUX_TIOCCONS: 180*a9643ea8Slogwang return TIOCCONS; 181*a9643ea8Slogwang case LINUX_TIOCPKT: 182*a9643ea8Slogwang return TIOCPKT; 183*a9643ea8Slogwang case LINUX_FIONBIO: 184*a9643ea8Slogwang return FIONBIO; 185*a9643ea8Slogwang case LINUX_TIOCNOTTY: 186*a9643ea8Slogwang return TIOCNOTTY; 187*a9643ea8Slogwang case LINUX_TIOCSETD: 188*a9643ea8Slogwang return TIOCSETD; 189*a9643ea8Slogwang case LINUX_TIOCGETD: 190*a9643ea8Slogwang return TIOCGETD; 191*a9643ea8Slogwang case LINUX_TIOCSBRK: 192*a9643ea8Slogwang return TIOCSBRK; 193*a9643ea8Slogwang case LINUX_TIOCCBRK: 194*a9643ea8Slogwang return TIOCCBRK; 195*a9643ea8Slogwang case LINUX_TIOCGSID: 196*a9643ea8Slogwang return TIOCGSID; 197*a9643ea8Slogwang case LINUX_FIONCLEX: 198*a9643ea8Slogwang return FIONCLEX; 199*a9643ea8Slogwang case LINUX_FIOCLEX: 200*a9643ea8Slogwang return FIOCLEX; 201*a9643ea8Slogwang case LINUX_FIOASYNC: 202*a9643ea8Slogwang return FIOASYNC; 203*a9643ea8Slogwang case LINUX_TIOCPKT_DATA: 204*a9643ea8Slogwang return TIOCPKT_DATA; 205*a9643ea8Slogwang case LINUX_TIOCPKT_FLUSHREAD: 206*a9643ea8Slogwang return TIOCPKT_FLUSHREAD; 207*a9643ea8Slogwang case LINUX_TIOCPKT_FLUSHWRITE: 208*a9643ea8Slogwang return TIOCPKT_FLUSHWRITE; 209*a9643ea8Slogwang case LINUX_TIOCPKT_STOP: 210*a9643ea8Slogwang return TIOCPKT_STOP; 211*a9643ea8Slogwang case LINUX_TIOCPKT_START: 212*a9643ea8Slogwang return TIOCPKT_START; 213*a9643ea8Slogwang case LINUX_TIOCPKT_NOSTOP: 214*a9643ea8Slogwang return TIOCPKT_NOSTOP; 215*a9643ea8Slogwang case LINUX_TIOCPKT_DOSTOP: 216*a9643ea8Slogwang return TIOCPKT_DOSTOP; 217*a9643ea8Slogwang case LINUX_TIOCPKT_IOCTL: 218*a9643ea8Slogwang return TIOCPKT_IOCTL; 219*a9643ea8Slogwang default: 220*a9643ea8Slogwang return (-1); 221*a9643ea8Slogwang } 222*a9643ea8Slogwang } 223*a9643ea8Slogwang 224*a9643ea8Slogwang static int 225*a9643ea8Slogwang so_opt_convert(int optname) 226*a9643ea8Slogwang { 227*a9643ea8Slogwang switch(optname) { 228*a9643ea8Slogwang case LINUX_SO_DEBUG: 229*a9643ea8Slogwang return SO_DEBUG; 230*a9643ea8Slogwang case LINUX_SO_REUSEADDR: 231*a9643ea8Slogwang return SO_REUSEADDR; 232*a9643ea8Slogwang case LINUX_SO_ERROR: 233*a9643ea8Slogwang return SO_ERROR; 234*a9643ea8Slogwang case LINUX_SO_DONTROUTE: 235*a9643ea8Slogwang return SO_DONTROUTE; 236*a9643ea8Slogwang case LINUX_SO_BROADCAST: 237*a9643ea8Slogwang return SO_BROADCAST; 238*a9643ea8Slogwang case LINUX_SO_SNDBUF: 239*a9643ea8Slogwang return SO_SNDBUF; 240*a9643ea8Slogwang case LINUX_SO_RCVBUF: 241*a9643ea8Slogwang return SO_RCVBUF; 242*a9643ea8Slogwang case LINUX_SO_KEEPALIVE: 243*a9643ea8Slogwang return SO_KEEPALIVE; 244*a9643ea8Slogwang case LINUX_SO_OOBINLINE: 245*a9643ea8Slogwang return SO_OOBINLINE; 246*a9643ea8Slogwang case LINUX_SO_LINGER: 247*a9643ea8Slogwang return SO_LINGER; 248*a9643ea8Slogwang case LINUX_SO_RCVLOWAT: 249*a9643ea8Slogwang return SO_RCVLOWAT; 250*a9643ea8Slogwang case LINUX_SO_SNDLOWAT: 251*a9643ea8Slogwang return SO_SNDLOWAT; 252*a9643ea8Slogwang case LINUX_SO_RCVTIMEO: 253*a9643ea8Slogwang return SO_RCVTIMEO; 254*a9643ea8Slogwang case LINUX_SO_SNDTIMEO: 255*a9643ea8Slogwang return SO_SNDTIMEO; 256*a9643ea8Slogwang case LINUX_SO_ACCEPTCONN: 257*a9643ea8Slogwang return SO_ACCEPTCONN; 258*a9643ea8Slogwang case LINUX_SO_PROTOCOL: 259*a9643ea8Slogwang return SO_PROTOCOL; 260*a9643ea8Slogwang default: 261*a9643ea8Slogwang return (-1); 262*a9643ea8Slogwang } 263*a9643ea8Slogwang } 264*a9643ea8Slogwang 265*a9643ea8Slogwang static int 266*a9643ea8Slogwang ip_opt_convert(int optname) 267*a9643ea8Slogwang { 268*a9643ea8Slogwang switch(optname) { 269*a9643ea8Slogwang case LINUX_IP_TOS: 270*a9643ea8Slogwang return IP_TOS; 271*a9643ea8Slogwang case LINUX_IP_TTL: 272*a9643ea8Slogwang return IP_TTL; 273*a9643ea8Slogwang case LINUX_IP_HDRINCL: 274*a9643ea8Slogwang return IP_HDRINCL; 275*a9643ea8Slogwang case LINUX_IP_OPTIONS: 276*a9643ea8Slogwang return IP_OPTIONS; 277*a9643ea8Slogwang case LINUX_IP_MULTICAST_IF: 278*a9643ea8Slogwang return IP_MULTICAST_IF; 279*a9643ea8Slogwang case LINUX_IP_MULTICAST_TTL: 280*a9643ea8Slogwang return IP_MULTICAST_TTL; 281*a9643ea8Slogwang case LINUX_IP_MULTICAST_LOOP: 282*a9643ea8Slogwang return IP_MULTICAST_LOOP; 283*a9643ea8Slogwang case LINUX_IP_ADD_MEMBERSHIP: 284*a9643ea8Slogwang return IP_ADD_MEMBERSHIP; 285*a9643ea8Slogwang case LINUX_IP_DROP_MEMBERSHIP: 286*a9643ea8Slogwang return IP_DROP_MEMBERSHIP; 287*a9643ea8Slogwang default: 288*a9643ea8Slogwang return (-1); 289*a9643ea8Slogwang } 290*a9643ea8Slogwang } 291*a9643ea8Slogwang 292*a9643ea8Slogwang static int 293*a9643ea8Slogwang tcp_opt_convert(int optname) 294*a9643ea8Slogwang { 295*a9643ea8Slogwang switch(optname) { 296*a9643ea8Slogwang case LINUX_TCP_NODELAY: 297*a9643ea8Slogwang return TCP_NODELAY; 298*a9643ea8Slogwang case LINUX_TCP_MAXSEG: 299*a9643ea8Slogwang return TCP_MAXSEG; 300*a9643ea8Slogwang case LINUX_TCP_KEEPIDLE: 301*a9643ea8Slogwang return TCP_KEEPIDLE; 302*a9643ea8Slogwang case LINUX_TCP_KEEPINTVL: 303*a9643ea8Slogwang return TCP_KEEPINTVL; 304*a9643ea8Slogwang case LINUX_TCP_KEEPCNT: 305*a9643ea8Slogwang return TCP_KEEPCNT; 306*a9643ea8Slogwang case LINUX_TCP_MD5SIG: 307*a9643ea8Slogwang return TCP_MD5SIG; 308*a9643ea8Slogwang default: 309*a9643ea8Slogwang return (-1); 310*a9643ea8Slogwang } 311*a9643ea8Slogwang } 312*a9643ea8Slogwang 313*a9643ea8Slogwang static int 314*a9643ea8Slogwang linux2freebsd_opt(int level, int optname) 315*a9643ea8Slogwang { 316*a9643ea8Slogwang switch(level) { 317*a9643ea8Slogwang case SOL_SOCKET: 318*a9643ea8Slogwang return so_opt_convert(optname); 319*a9643ea8Slogwang case IPPROTO_IP: 320*a9643ea8Slogwang return ip_opt_convert(optname); 321*a9643ea8Slogwang case IPPROTO_TCP: 322*a9643ea8Slogwang return tcp_opt_convert(optname); 323*a9643ea8Slogwang default: 324*a9643ea8Slogwang return (-1); 325*a9643ea8Slogwang } 326*a9643ea8Slogwang } 327*a9643ea8Slogwang 328*a9643ea8Slogwang static void 329*a9643ea8Slogwang linux2freebsd_sockaddr(const struct linux_sockaddr *linux, 330*a9643ea8Slogwang socklen_t addrlen, struct sockaddr *freebsd) 331*a9643ea8Slogwang { 332*a9643ea8Slogwang if (linux == NULL) { 333*a9643ea8Slogwang return; 334*a9643ea8Slogwang } 335*a9643ea8Slogwang 336*a9643ea8Slogwang bzero(freebsd, sizeof(struct sockaddr)); 337*a9643ea8Slogwang freebsd->sa_len = addrlen; 338*a9643ea8Slogwang freebsd->sa_family = linux->sa_family; 339*a9643ea8Slogwang bcopy(linux->sa_data, freebsd->sa_data, sizeof(linux->sa_data)); 340*a9643ea8Slogwang } 341*a9643ea8Slogwang 342*a9643ea8Slogwang static void 343*a9643ea8Slogwang freebsd2linux_sockaddr(struct linux_sockaddr *linux, 344*a9643ea8Slogwang struct sockaddr *freebsd) 345*a9643ea8Slogwang { 346*a9643ea8Slogwang if (linux == NULL) { 347*a9643ea8Slogwang return; 348*a9643ea8Slogwang } 349*a9643ea8Slogwang 350*a9643ea8Slogwang linux->sa_family = freebsd->sa_family; 351*a9643ea8Slogwang bcopy(freebsd->sa_data, linux->sa_data, sizeof(freebsd->sa_data)); 352*a9643ea8Slogwang } 353*a9643ea8Slogwang 354*a9643ea8Slogwang int 355*a9643ea8Slogwang ff_socket(int domain, int type, int protocol) 356*a9643ea8Slogwang { 357*a9643ea8Slogwang int rc; 358*a9643ea8Slogwang struct socket_args sa; 359*a9643ea8Slogwang sa.domain = domain; 360*a9643ea8Slogwang sa.type = type; 361*a9643ea8Slogwang sa.protocol = protocol; 362*a9643ea8Slogwang if ((rc = sys_socket(curthread, &sa))) 363*a9643ea8Slogwang goto kern_fail; 364*a9643ea8Slogwang 365*a9643ea8Slogwang return curthread->td_retval[0]; 366*a9643ea8Slogwang kern_fail: 367*a9643ea8Slogwang ff_os_errno(rc); 368*a9643ea8Slogwang return (-1); 369*a9643ea8Slogwang } 370*a9643ea8Slogwang 371*a9643ea8Slogwang int 372*a9643ea8Slogwang ff_getsockopt(int s, int level, int optname, void *optval, 373*a9643ea8Slogwang socklen_t *optlen) 374*a9643ea8Slogwang { 375*a9643ea8Slogwang int rc; 376*a9643ea8Slogwang if (level == LINUX_SOL_SOCKET) 377*a9643ea8Slogwang level = SOL_SOCKET; 378*a9643ea8Slogwang 379*a9643ea8Slogwang optname = linux2freebsd_opt(level, optname); 380*a9643ea8Slogwang if (optname < 0) { 381*a9643ea8Slogwang rc = EINVAL; 382*a9643ea8Slogwang goto kern_fail; 383*a9643ea8Slogwang } 384*a9643ea8Slogwang 385*a9643ea8Slogwang if ((rc = kern_getsockopt(curthread, s, level, optname, 386*a9643ea8Slogwang optval, UIO_SYSSPACE, optlen))) 387*a9643ea8Slogwang goto kern_fail; 388*a9643ea8Slogwang 389*a9643ea8Slogwang return (rc); 390*a9643ea8Slogwang 391*a9643ea8Slogwang kern_fail: 392*a9643ea8Slogwang ff_os_errno(rc); 393*a9643ea8Slogwang return (-1); 394*a9643ea8Slogwang } 395*a9643ea8Slogwang 396*a9643ea8Slogwang int 397*a9643ea8Slogwang ff_setsockopt(int s, int level, int optname, const void *optval, 398*a9643ea8Slogwang socklen_t optlen) 399*a9643ea8Slogwang { 400*a9643ea8Slogwang int rc; 401*a9643ea8Slogwang 402*a9643ea8Slogwang if (level == LINUX_SOL_SOCKET) 403*a9643ea8Slogwang level = SOL_SOCKET; 404*a9643ea8Slogwang 405*a9643ea8Slogwang optname = linux2freebsd_opt(level, optname); 406*a9643ea8Slogwang if (optname < 0) { 407*a9643ea8Slogwang rc = EINVAL; 408*a9643ea8Slogwang goto kern_fail; 409*a9643ea8Slogwang } 410*a9643ea8Slogwang 411*a9643ea8Slogwang if ((rc = kern_setsockopt(curthread, s, level, optname, 412*a9643ea8Slogwang __DECONST(void *, optval), UIO_SYSSPACE, optlen))) 413*a9643ea8Slogwang goto kern_fail; 414*a9643ea8Slogwang 415*a9643ea8Slogwang return (rc); 416*a9643ea8Slogwang 417*a9643ea8Slogwang kern_fail: 418*a9643ea8Slogwang ff_os_errno(rc); 419*a9643ea8Slogwang return (-1); 420*a9643ea8Slogwang } 421*a9643ea8Slogwang 422*a9643ea8Slogwang int 423*a9643ea8Slogwang ff_ioctl(int fd, unsigned long request, ...) 424*a9643ea8Slogwang { 425*a9643ea8Slogwang int rc; 426*a9643ea8Slogwang va_list ap; 427*a9643ea8Slogwang caddr_t argp; 428*a9643ea8Slogwang 429*a9643ea8Slogwang long req = linux2freebsd_ioctl(request); 430*a9643ea8Slogwang if (req < 0) { 431*a9643ea8Slogwang rc = EINVAL; 432*a9643ea8Slogwang goto kern_fail; 433*a9643ea8Slogwang } 434*a9643ea8Slogwang 435*a9643ea8Slogwang va_start(ap, request); 436*a9643ea8Slogwang 437*a9643ea8Slogwang argp = va_arg(ap, caddr_t); 438*a9643ea8Slogwang va_end(ap); 439*a9643ea8Slogwang if ((rc = kern_ioctl(curthread, fd, req, argp))) 440*a9643ea8Slogwang goto kern_fail; 441*a9643ea8Slogwang 442*a9643ea8Slogwang return (rc); 443*a9643ea8Slogwang 444*a9643ea8Slogwang kern_fail: 445*a9643ea8Slogwang ff_os_errno(rc); 446*a9643ea8Slogwang return (-1); 447*a9643ea8Slogwang } 448*a9643ea8Slogwang 449*a9643ea8Slogwang int 450*a9643ea8Slogwang ff_close(int fd) 451*a9643ea8Slogwang { 452*a9643ea8Slogwang int rc; 453*a9643ea8Slogwang 454*a9643ea8Slogwang if ((rc = kern_close(curthread, fd))) 455*a9643ea8Slogwang goto kern_fail; 456*a9643ea8Slogwang 457*a9643ea8Slogwang return (rc); 458*a9643ea8Slogwang kern_fail: 459*a9643ea8Slogwang ff_os_errno(rc); 460*a9643ea8Slogwang return (-1); 461*a9643ea8Slogwang } 462*a9643ea8Slogwang 463*a9643ea8Slogwang ssize_t 464*a9643ea8Slogwang ff_read(int fd, void *buf, size_t nbytes) 465*a9643ea8Slogwang { 466*a9643ea8Slogwang struct uio auio; 467*a9643ea8Slogwang struct iovec aiov; 468*a9643ea8Slogwang int rc; 469*a9643ea8Slogwang 470*a9643ea8Slogwang if (nbytes > INT_MAX) { 471*a9643ea8Slogwang rc = EINVAL; 472*a9643ea8Slogwang goto kern_fail; 473*a9643ea8Slogwang } 474*a9643ea8Slogwang 475*a9643ea8Slogwang aiov.iov_base = buf; 476*a9643ea8Slogwang aiov.iov_len = nbytes; 477*a9643ea8Slogwang auio.uio_iov = &aiov; 478*a9643ea8Slogwang auio.uio_iovcnt = 1; 479*a9643ea8Slogwang auio.uio_resid = nbytes; 480*a9643ea8Slogwang auio.uio_segflg = UIO_SYSSPACE; 481*a9643ea8Slogwang if ((rc = kern_readv(curthread, fd, &auio))) 482*a9643ea8Slogwang goto kern_fail; 483*a9643ea8Slogwang rc = curthread->td_retval[0]; 484*a9643ea8Slogwang 485*a9643ea8Slogwang return (rc); 486*a9643ea8Slogwang kern_fail: 487*a9643ea8Slogwang ff_os_errno(rc); 488*a9643ea8Slogwang return (-1); 489*a9643ea8Slogwang } 490*a9643ea8Slogwang 491*a9643ea8Slogwang ssize_t 492*a9643ea8Slogwang ff_readv(int fd, const struct iovec *iov, int iovcnt) 493*a9643ea8Slogwang { 494*a9643ea8Slogwang struct uio auio; 495*a9643ea8Slogwang int rc, len, i; 496*a9643ea8Slogwang 497*a9643ea8Slogwang len = 0; 498*a9643ea8Slogwang for (i = 0; i < iovcnt; i++) 499*a9643ea8Slogwang len += iov[i].iov_len; 500*a9643ea8Slogwang auio.uio_iov = __DECONST(struct iovec *, iov); 501*a9643ea8Slogwang auio.uio_iovcnt = iovcnt; 502*a9643ea8Slogwang auio.uio_resid = len; 503*a9643ea8Slogwang auio.uio_segflg = UIO_SYSSPACE; 504*a9643ea8Slogwang 505*a9643ea8Slogwang if ((rc = kern_readv(curthread, fd, &auio))) 506*a9643ea8Slogwang goto kern_fail; 507*a9643ea8Slogwang rc = curthread->td_retval[0]; 508*a9643ea8Slogwang 509*a9643ea8Slogwang return (rc); 510*a9643ea8Slogwang kern_fail: 511*a9643ea8Slogwang ff_os_errno(rc); 512*a9643ea8Slogwang return (-1); 513*a9643ea8Slogwang } 514*a9643ea8Slogwang 515*a9643ea8Slogwang ssize_t 516*a9643ea8Slogwang ff_write(int fd, const void *buf, size_t nbytes) 517*a9643ea8Slogwang { 518*a9643ea8Slogwang struct uio auio; 519*a9643ea8Slogwang struct iovec aiov; 520*a9643ea8Slogwang int rc; 521*a9643ea8Slogwang 522*a9643ea8Slogwang if (nbytes > INT_MAX) { 523*a9643ea8Slogwang rc = EINVAL; 524*a9643ea8Slogwang goto kern_fail; 525*a9643ea8Slogwang } 526*a9643ea8Slogwang 527*a9643ea8Slogwang aiov.iov_base = (void *)(uintptr_t)buf; 528*a9643ea8Slogwang aiov.iov_len = nbytes; 529*a9643ea8Slogwang auio.uio_iov = &aiov; 530*a9643ea8Slogwang auio.uio_iovcnt = 1; 531*a9643ea8Slogwang auio.uio_resid = nbytes; 532*a9643ea8Slogwang auio.uio_segflg = UIO_SYSSPACE; 533*a9643ea8Slogwang if ((rc = kern_writev(curthread, fd, &auio))) 534*a9643ea8Slogwang goto kern_fail; 535*a9643ea8Slogwang rc = curthread->td_retval[0]; 536*a9643ea8Slogwang 537*a9643ea8Slogwang return (rc); 538*a9643ea8Slogwang kern_fail: 539*a9643ea8Slogwang ff_os_errno(rc); 540*a9643ea8Slogwang return (-1); 541*a9643ea8Slogwang } 542*a9643ea8Slogwang 543*a9643ea8Slogwang ssize_t 544*a9643ea8Slogwang ff_writev(int fd, const struct iovec *iov, int iovcnt) 545*a9643ea8Slogwang { 546*a9643ea8Slogwang struct uio auio; 547*a9643ea8Slogwang int i, rc, len; 548*a9643ea8Slogwang 549*a9643ea8Slogwang len = 0; 550*a9643ea8Slogwang for (i = 0; i < iovcnt; i++) 551*a9643ea8Slogwang len += iov[i].iov_len; 552*a9643ea8Slogwang auio.uio_iov = __DECONST(struct iovec *, iov); 553*a9643ea8Slogwang auio.uio_iovcnt = iovcnt; 554*a9643ea8Slogwang auio.uio_resid = len; 555*a9643ea8Slogwang auio.uio_segflg = UIO_SYSSPACE; 556*a9643ea8Slogwang if ((rc = kern_writev(curthread, fd, &auio))) 557*a9643ea8Slogwang goto kern_fail; 558*a9643ea8Slogwang rc = curthread->td_retval[0]; 559*a9643ea8Slogwang 560*a9643ea8Slogwang return (rc); 561*a9643ea8Slogwang kern_fail: 562*a9643ea8Slogwang ff_os_errno(rc); 563*a9643ea8Slogwang return (-1); 564*a9643ea8Slogwang } 565*a9643ea8Slogwang 566*a9643ea8Slogwang ssize_t 567*a9643ea8Slogwang ff_send(int s, const void *buf, size_t len, int flags) 568*a9643ea8Slogwang { 569*a9643ea8Slogwang return (ff_sendto(s, buf, len, flags, NULL, 0)); 570*a9643ea8Slogwang } 571*a9643ea8Slogwang 572*a9643ea8Slogwang ssize_t 573*a9643ea8Slogwang ff_sendto(int s, const void *buf, size_t len, int flags, 574*a9643ea8Slogwang const struct linux_sockaddr *to, socklen_t tolen) 575*a9643ea8Slogwang { 576*a9643ea8Slogwang struct msghdr msg; 577*a9643ea8Slogwang struct iovec aiov; 578*a9643ea8Slogwang int rc; 579*a9643ea8Slogwang 580*a9643ea8Slogwang struct sockaddr bsdaddr; 581*a9643ea8Slogwang struct sockaddr *pf = &bsdaddr; 582*a9643ea8Slogwang 583*a9643ea8Slogwang if (to) { 584*a9643ea8Slogwang linux2freebsd_sockaddr(to, tolen, pf); 585*a9643ea8Slogwang } else { 586*a9643ea8Slogwang pf = NULL; 587*a9643ea8Slogwang } 588*a9643ea8Slogwang 589*a9643ea8Slogwang msg.msg_name = pf; 590*a9643ea8Slogwang msg.msg_namelen = tolen; 591*a9643ea8Slogwang msg.msg_iov = &aiov; 592*a9643ea8Slogwang msg.msg_iovlen = 1; 593*a9643ea8Slogwang msg.msg_control = 0; 594*a9643ea8Slogwang aiov.iov_base = __DECONST(void *, buf); 595*a9643ea8Slogwang aiov.iov_len = len; 596*a9643ea8Slogwang if ((rc = sendit(curthread, s, &msg, flags))) 597*a9643ea8Slogwang goto kern_fail; 598*a9643ea8Slogwang 599*a9643ea8Slogwang rc = curthread->td_retval[0]; 600*a9643ea8Slogwang 601*a9643ea8Slogwang return (rc); 602*a9643ea8Slogwang kern_fail: 603*a9643ea8Slogwang ff_os_errno(rc); 604*a9643ea8Slogwang return (-1); 605*a9643ea8Slogwang } 606*a9643ea8Slogwang 607*a9643ea8Slogwang ssize_t 608*a9643ea8Slogwang ff_sendmsg(int s, const struct msghdr *msg, int flags) 609*a9643ea8Slogwang { 610*a9643ea8Slogwang int rc; 611*a9643ea8Slogwang 612*a9643ea8Slogwang if ((rc = sendit(curthread, s, __DECONST(struct msghdr *, msg), flags))) 613*a9643ea8Slogwang goto kern_fail; 614*a9643ea8Slogwang 615*a9643ea8Slogwang return (rc); 616*a9643ea8Slogwang kern_fail: 617*a9643ea8Slogwang ff_os_errno(rc); 618*a9643ea8Slogwang return (-1); 619*a9643ea8Slogwang } 620*a9643ea8Slogwang 621*a9643ea8Slogwang 622*a9643ea8Slogwang ssize_t 623*a9643ea8Slogwang ff_recv(int s, void *buf, size_t len, int flags) 624*a9643ea8Slogwang { 625*a9643ea8Slogwang return (ff_recvfrom(s, buf, len, flags, NULL, 0)); 626*a9643ea8Slogwang } 627*a9643ea8Slogwang 628*a9643ea8Slogwang ssize_t 629*a9643ea8Slogwang ff_recvfrom(int s, void *buf, size_t len, int flags, 630*a9643ea8Slogwang struct linux_sockaddr *from, socklen_t *fromlen) 631*a9643ea8Slogwang { 632*a9643ea8Slogwang struct msghdr msg; 633*a9643ea8Slogwang struct iovec aiov; 634*a9643ea8Slogwang int rc; 635*a9643ea8Slogwang struct sockaddr bsdaddr; 636*a9643ea8Slogwang 637*a9643ea8Slogwang if (fromlen != NULL) 638*a9643ea8Slogwang msg.msg_namelen = *fromlen; 639*a9643ea8Slogwang else 640*a9643ea8Slogwang msg.msg_namelen = 0; 641*a9643ea8Slogwang 642*a9643ea8Slogwang msg.msg_name = &bsdaddr; 643*a9643ea8Slogwang msg.msg_iov = &aiov; 644*a9643ea8Slogwang msg.msg_iovlen = 1; 645*a9643ea8Slogwang aiov.iov_base = buf; 646*a9643ea8Slogwang aiov.iov_len = len; 647*a9643ea8Slogwang msg.msg_control = 0; 648*a9643ea8Slogwang msg.msg_flags = flags; 649*a9643ea8Slogwang if ((rc = kern_recvit(curthread, s, &msg, UIO_SYSSPACE, NULL))) 650*a9643ea8Slogwang goto kern_fail; 651*a9643ea8Slogwang rc = curthread->td_retval[0]; 652*a9643ea8Slogwang if (fromlen != NULL) 653*a9643ea8Slogwang *fromlen = msg.msg_namelen; 654*a9643ea8Slogwang 655*a9643ea8Slogwang if (from) 656*a9643ea8Slogwang freebsd2linux_sockaddr(from, &bsdaddr); 657*a9643ea8Slogwang 658*a9643ea8Slogwang return (rc); 659*a9643ea8Slogwang kern_fail: 660*a9643ea8Slogwang ff_os_errno(rc); 661*a9643ea8Slogwang return (-1); 662*a9643ea8Slogwang } 663*a9643ea8Slogwang 664*a9643ea8Slogwang ssize_t 665*a9643ea8Slogwang ff_recvmsg(int s, struct msghdr *msg, int flags) 666*a9643ea8Slogwang { 667*a9643ea8Slogwang int rc, oldflags; 668*a9643ea8Slogwang 669*a9643ea8Slogwang oldflags = msg->msg_flags; 670*a9643ea8Slogwang msg->msg_flags = flags; 671*a9643ea8Slogwang 672*a9643ea8Slogwang if ((rc = kern_recvit(curthread, s, msg, UIO_SYSSPACE, NULL))) { 673*a9643ea8Slogwang msg->msg_flags = oldflags; 674*a9643ea8Slogwang goto kern_fail; 675*a9643ea8Slogwang } 676*a9643ea8Slogwang rc = curthread->td_retval[0]; 677*a9643ea8Slogwang 678*a9643ea8Slogwang return (rc); 679*a9643ea8Slogwang kern_fail: 680*a9643ea8Slogwang ff_os_errno(rc); 681*a9643ea8Slogwang return (-1); 682*a9643ea8Slogwang } 683*a9643ea8Slogwang 684*a9643ea8Slogwang int 685*a9643ea8Slogwang ff_fcntl(int fd, int cmd, ...) 686*a9643ea8Slogwang { 687*a9643ea8Slogwang int rc; 688*a9643ea8Slogwang va_list ap; 689*a9643ea8Slogwang uintptr_t argp; 690*a9643ea8Slogwang 691*a9643ea8Slogwang va_start(ap, cmd); 692*a9643ea8Slogwang 693*a9643ea8Slogwang argp = va_arg(ap, uintptr_t); 694*a9643ea8Slogwang va_end(ap); 695*a9643ea8Slogwang 696*a9643ea8Slogwang if ((rc = kern_fcntl(curthread, fd, cmd, argp))) 697*a9643ea8Slogwang goto kern_fail; 698*a9643ea8Slogwang rc = curthread->td_retval[0]; 699*a9643ea8Slogwang return (rc); 700*a9643ea8Slogwang kern_fail: 701*a9643ea8Slogwang ff_os_errno(rc); 702*a9643ea8Slogwang return (-1); 703*a9643ea8Slogwang } 704*a9643ea8Slogwang 705*a9643ea8Slogwang int 706*a9643ea8Slogwang ff_socketpair(int domain, int type, int protocol, int *sv) 707*a9643ea8Slogwang { 708*a9643ea8Slogwang int rc; 709*a9643ea8Slogwang if ((rc = kern_socketpair(curthread, domain, type, protocol, sv))) 710*a9643ea8Slogwang goto kern_fail; 711*a9643ea8Slogwang 712*a9643ea8Slogwang return (rc); 713*a9643ea8Slogwang kern_fail: 714*a9643ea8Slogwang ff_os_errno(rc); 715*a9643ea8Slogwang return (-1); 716*a9643ea8Slogwang } 717*a9643ea8Slogwang 718*a9643ea8Slogwang int 719*a9643ea8Slogwang ff_accept(int s, struct linux_sockaddr * addr, 720*a9643ea8Slogwang socklen_t * addrlen) 721*a9643ea8Slogwang { 722*a9643ea8Slogwang int rc; 723*a9643ea8Slogwang struct file *fp; 724*a9643ea8Slogwang struct sockaddr bsdaddr; 725*a9643ea8Slogwang struct sockaddr *pf = &bsdaddr; 726*a9643ea8Slogwang socklen_t socklen = sizeof(struct sockaddr); 727*a9643ea8Slogwang 728*a9643ea8Slogwang if ((rc = kern_accept(curthread, s, &pf, &socklen, &fp))) 729*a9643ea8Slogwang goto kern_fail; 730*a9643ea8Slogwang 731*a9643ea8Slogwang rc = curthread->td_retval[0]; 732*a9643ea8Slogwang fdrop(fp, curthread); 733*a9643ea8Slogwang 734*a9643ea8Slogwang if (addr) 735*a9643ea8Slogwang freebsd2linux_sockaddr(addr, pf); 736*a9643ea8Slogwang 737*a9643ea8Slogwang if (addrlen) 738*a9643ea8Slogwang *addrlen = socklen; 739*a9643ea8Slogwang 740*a9643ea8Slogwang return (rc); 741*a9643ea8Slogwang kern_fail: 742*a9643ea8Slogwang ff_os_errno(rc); 743*a9643ea8Slogwang return (-1); 744*a9643ea8Slogwang } 745*a9643ea8Slogwang 746*a9643ea8Slogwang int 747*a9643ea8Slogwang ff_listen(int s, int backlog) 748*a9643ea8Slogwang { 749*a9643ea8Slogwang int rc; 750*a9643ea8Slogwang struct listen_args la = { 751*a9643ea8Slogwang .s = s, 752*a9643ea8Slogwang .backlog = backlog, 753*a9643ea8Slogwang }; 754*a9643ea8Slogwang if ((rc = sys_listen(curthread, &la))) 755*a9643ea8Slogwang goto kern_fail; 756*a9643ea8Slogwang 757*a9643ea8Slogwang return (rc); 758*a9643ea8Slogwang kern_fail: 759*a9643ea8Slogwang ff_os_errno(rc); 760*a9643ea8Slogwang return (-1); 761*a9643ea8Slogwang } 762*a9643ea8Slogwang 763*a9643ea8Slogwang int 764*a9643ea8Slogwang ff_bind(int s, const struct linux_sockaddr *addr, socklen_t addrlen) 765*a9643ea8Slogwang { 766*a9643ea8Slogwang int rc; 767*a9643ea8Slogwang struct sockaddr bsdaddr; 768*a9643ea8Slogwang linux2freebsd_sockaddr(addr, addrlen, &bsdaddr); 769*a9643ea8Slogwang 770*a9643ea8Slogwang if ((rc = kern_bindat(curthread, AT_FDCWD, s, &bsdaddr))) 771*a9643ea8Slogwang goto kern_fail; 772*a9643ea8Slogwang 773*a9643ea8Slogwang return (rc); 774*a9643ea8Slogwang kern_fail: 775*a9643ea8Slogwang ff_os_errno(rc); 776*a9643ea8Slogwang return (-1); 777*a9643ea8Slogwang } 778*a9643ea8Slogwang 779*a9643ea8Slogwang int 780*a9643ea8Slogwang ff_connect(int s, const struct linux_sockaddr *name, socklen_t namelen) 781*a9643ea8Slogwang { 782*a9643ea8Slogwang int rc; 783*a9643ea8Slogwang struct sockaddr bsdaddr; 784*a9643ea8Slogwang linux2freebsd_sockaddr(name, namelen, &bsdaddr); 785*a9643ea8Slogwang 786*a9643ea8Slogwang if ((rc = kern_connectat(curthread, AT_FDCWD, s, &bsdaddr))) 787*a9643ea8Slogwang goto kern_fail; 788*a9643ea8Slogwang rc = curthread->td_retval[0]; 789*a9643ea8Slogwang return (rc); 790*a9643ea8Slogwang kern_fail: 791*a9643ea8Slogwang ff_os_errno(rc); 792*a9643ea8Slogwang return (-1); 793*a9643ea8Slogwang } 794*a9643ea8Slogwang 795*a9643ea8Slogwang int 796*a9643ea8Slogwang ff_getpeername(int s, struct linux_sockaddr * name, 797*a9643ea8Slogwang socklen_t *namelen) 798*a9643ea8Slogwang { 799*a9643ea8Slogwang int rc; 800*a9643ea8Slogwang struct sockaddr bsdaddr; 801*a9643ea8Slogwang struct sockaddr *pf = &bsdaddr; 802*a9643ea8Slogwang 803*a9643ea8Slogwang if ((rc = kern_getpeername(curthread, s, &pf, namelen))) 804*a9643ea8Slogwang goto kern_fail; 805*a9643ea8Slogwang 806*a9643ea8Slogwang if (name) 807*a9643ea8Slogwang freebsd2linux_sockaddr(name, pf); 808*a9643ea8Slogwang 809*a9643ea8Slogwang return (rc); 810*a9643ea8Slogwang kern_fail: 811*a9643ea8Slogwang ff_os_errno(rc); 812*a9643ea8Slogwang return (-1); 813*a9643ea8Slogwang } 814*a9643ea8Slogwang 815*a9643ea8Slogwang int 816*a9643ea8Slogwang ff_getsockname(int s, struct linux_sockaddr *name, 817*a9643ea8Slogwang socklen_t *namelen) 818*a9643ea8Slogwang { 819*a9643ea8Slogwang int rc; 820*a9643ea8Slogwang struct sockaddr bsdaddr; 821*a9643ea8Slogwang struct sockaddr *pf = &bsdaddr; 822*a9643ea8Slogwang 823*a9643ea8Slogwang if ((rc = kern_getsockname(curthread, s, &pf, namelen))) 824*a9643ea8Slogwang goto kern_fail; 825*a9643ea8Slogwang 826*a9643ea8Slogwang if (name) 827*a9643ea8Slogwang freebsd2linux_sockaddr(name, pf); 828*a9643ea8Slogwang 829*a9643ea8Slogwang return (rc); 830*a9643ea8Slogwang 831*a9643ea8Slogwang kern_fail: 832*a9643ea8Slogwang ff_os_errno(rc); 833*a9643ea8Slogwang return (-1); 834*a9643ea8Slogwang } 835*a9643ea8Slogwang 836*a9643ea8Slogwang int 837*a9643ea8Slogwang ff_shutdown(int s, int how) 838*a9643ea8Slogwang { 839*a9643ea8Slogwang int rc; 840*a9643ea8Slogwang 841*a9643ea8Slogwang struct shutdown_args sa = { 842*a9643ea8Slogwang .s = s, 843*a9643ea8Slogwang .how = how, 844*a9643ea8Slogwang }; 845*a9643ea8Slogwang if ((rc = sys_shutdown(curthread, &sa))) 846*a9643ea8Slogwang goto kern_fail; 847*a9643ea8Slogwang 848*a9643ea8Slogwang return (rc); 849*a9643ea8Slogwang kern_fail: 850*a9643ea8Slogwang ff_os_errno(rc); 851*a9643ea8Slogwang return (-1); 852*a9643ea8Slogwang } 853*a9643ea8Slogwang 854*a9643ea8Slogwang int 855*a9643ea8Slogwang ff_sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, 856*a9643ea8Slogwang const void *newp, size_t newlen) 857*a9643ea8Slogwang { 858*a9643ea8Slogwang int rc; 859*a9643ea8Slogwang size_t retval; 860*a9643ea8Slogwang 861*a9643ea8Slogwang rc = userland_sysctl(curthread, __DECONST(int *, name), namelen, oldp, oldlenp, 862*a9643ea8Slogwang 1, __DECONST(void *, newp), newlen, &retval, 0); 863*a9643ea8Slogwang if (rc) 864*a9643ea8Slogwang goto kern_fail; 865*a9643ea8Slogwang if (oldlenp) 866*a9643ea8Slogwang *oldlenp = retval; 867*a9643ea8Slogwang return (0); 868*a9643ea8Slogwang kern_fail: 869*a9643ea8Slogwang ff_os_errno(rc); 870*a9643ea8Slogwang return (-1); 871*a9643ea8Slogwang } 872*a9643ea8Slogwang 873*a9643ea8Slogwang int 874*a9643ea8Slogwang ff_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 875*a9643ea8Slogwang struct timeval *timeout) 876*a9643ea8Slogwang 877*a9643ea8Slogwang { 878*a9643ea8Slogwang int rc; 879*a9643ea8Slogwang 880*a9643ea8Slogwang rc = kern_select(curthread, nfds, readfds, writefds, exceptfds, timeout, 64); 881*a9643ea8Slogwang if (rc) 882*a9643ea8Slogwang goto kern_fail; 883*a9643ea8Slogwang rc = curthread->td_retval[0]; 884*a9643ea8Slogwang 885*a9643ea8Slogwang return (rc); 886*a9643ea8Slogwang kern_fail: 887*a9643ea8Slogwang ff_os_errno(rc); 888*a9643ea8Slogwang return (-1); 889*a9643ea8Slogwang 890*a9643ea8Slogwang } 891*a9643ea8Slogwang 892*a9643ea8Slogwang int 893*a9643ea8Slogwang ff_poll(struct pollfd fds[], nfds_t nfds, int timeout) 894*a9643ea8Slogwang { 895*a9643ea8Slogwang int rc; 896*a9643ea8Slogwang struct timespec ts; 897*a9643ea8Slogwang ts.tv_sec = 0; 898*a9643ea8Slogwang ts.tv_nsec = 0; 899*a9643ea8Slogwang if ((rc = kern_poll(curthread, fds, nfds, &ts, NULL))) 900*a9643ea8Slogwang goto kern_fail; 901*a9643ea8Slogwang rc = curthread->td_retval[0]; 902*a9643ea8Slogwang return (rc); 903*a9643ea8Slogwang 904*a9643ea8Slogwang kern_fail: 905*a9643ea8Slogwang ff_os_errno(rc); 906*a9643ea8Slogwang return (-1); 907*a9643ea8Slogwang } 908*a9643ea8Slogwang 909*a9643ea8Slogwang int 910*a9643ea8Slogwang ff_kqueue(void) 911*a9643ea8Slogwang { 912*a9643ea8Slogwang int rc; 913*a9643ea8Slogwang if ((rc = kern_kqueue(curthread, 0, NULL))) 914*a9643ea8Slogwang goto kern_fail; 915*a9643ea8Slogwang 916*a9643ea8Slogwang rc = curthread->td_retval[0]; 917*a9643ea8Slogwang return (rc); 918*a9643ea8Slogwang 919*a9643ea8Slogwang kern_fail: 920*a9643ea8Slogwang ff_os_errno(rc); 921*a9643ea8Slogwang return (-1); 922*a9643ea8Slogwang } 923*a9643ea8Slogwang 924*a9643ea8Slogwang struct sys_kevent_args { 925*a9643ea8Slogwang int fd; 926*a9643ea8Slogwang const struct kevent *changelist; 927*a9643ea8Slogwang int nchanges; 928*a9643ea8Slogwang struct kevent *eventlist; 929*a9643ea8Slogwang int nevents; 930*a9643ea8Slogwang const struct timespec *timeout; 931*a9643ea8Slogwang }; 932*a9643ea8Slogwang 933*a9643ea8Slogwang static int 934*a9643ea8Slogwang kevent_copyout(void *arg, struct kevent *kevp, int count) 935*a9643ea8Slogwang { 936*a9643ea8Slogwang struct sys_kevent_args *uap; 937*a9643ea8Slogwang 938*a9643ea8Slogwang uap = (struct sys_kevent_args *)arg; 939*a9643ea8Slogwang bcopy(kevp, uap->eventlist, count * sizeof *kevp); 940*a9643ea8Slogwang 941*a9643ea8Slogwang uap->eventlist += count; 942*a9643ea8Slogwang 943*a9643ea8Slogwang return (0); 944*a9643ea8Slogwang } 945*a9643ea8Slogwang 946*a9643ea8Slogwang /* 947*a9643ea8Slogwang * Copy 'count' items from the list pointed to by uap->changelist. 948*a9643ea8Slogwang */ 949*a9643ea8Slogwang static int 950*a9643ea8Slogwang kevent_copyin(void *arg, struct kevent *kevp, int count) 951*a9643ea8Slogwang { 952*a9643ea8Slogwang struct sys_kevent_args *uap; 953*a9643ea8Slogwang 954*a9643ea8Slogwang uap = (struct sys_kevent_args *)arg; 955*a9643ea8Slogwang bcopy(uap->changelist, kevp, count * sizeof *kevp); 956*a9643ea8Slogwang 957*a9643ea8Slogwang uap->changelist += count; 958*a9643ea8Slogwang 959*a9643ea8Slogwang return (0); 960*a9643ea8Slogwang } 961*a9643ea8Slogwang 962*a9643ea8Slogwang int 963*a9643ea8Slogwang ff_kevent(int kq, const struct kevent *changelist, int nchanges, 964*a9643ea8Slogwang struct kevent *eventlist, int nevents, const struct timespec *timeout) 965*a9643ea8Slogwang { 966*a9643ea8Slogwang int rc; 967*a9643ea8Slogwang struct timespec ts; 968*a9643ea8Slogwang ts.tv_sec = 0; 969*a9643ea8Slogwang ts.tv_nsec = 0; 970*a9643ea8Slogwang struct sys_kevent_args ska = { 971*a9643ea8Slogwang kq, 972*a9643ea8Slogwang changelist, 973*a9643ea8Slogwang nchanges, 974*a9643ea8Slogwang eventlist, 975*a9643ea8Slogwang nevents, 976*a9643ea8Slogwang &ts 977*a9643ea8Slogwang }; 978*a9643ea8Slogwang struct kevent_copyops k_ops = { 979*a9643ea8Slogwang &ska, 980*a9643ea8Slogwang kevent_copyout, 981*a9643ea8Slogwang kevent_copyin 982*a9643ea8Slogwang }; 983*a9643ea8Slogwang 984*a9643ea8Slogwang if ((rc = kern_kevent(curthread, kq, nchanges, nevents, &k_ops, 985*a9643ea8Slogwang &ts))) 986*a9643ea8Slogwang goto kern_fail; 987*a9643ea8Slogwang 988*a9643ea8Slogwang rc = curthread->td_retval[0]; 989*a9643ea8Slogwang return (rc); 990*a9643ea8Slogwang kern_fail: 991*a9643ea8Slogwang ff_os_errno(rc); 992*a9643ea8Slogwang return (-1); 993*a9643ea8Slogwang } 994