From a532ca41f6905ca4136e738f1aaa3d4dd1f8cfa6 Mon Sep 17 00:00:00 2001 From: lhw2002426 <1466397747@qq.com> Date: Mon, 22 Jul 2024 21:58:43 +0800 Subject: [PATCH] add loopback by multi-socketset --- api/arceos_posix_api/src/ctypes_gen.rs | 3458 +++++++++++++++++ apps/c/httpserver_loopback/axbuild.mk | 1 + apps/c/httpserver_loopback/features.txt | 4 + apps/c/httpserver_loopback/httpserver.c | 139 + crates/driver_net/src/lib.rs | 2 + crates/driver_net/src/loopback.rs | 126 + modules/ruxfs/Cargo.toml | 2 +- modules/ruxfs/tests/test_fatfs.rs | 4 +- modules/ruxfs/tests/test_ramfs.rs | 4 +- modules/ruxnet/Cargo.toml | 2 +- modules/ruxnet/src/smoltcp_impl/dns.rs | 49 +- .../ruxnet/src/smoltcp_impl/listen_table.rs | 51 +- modules/ruxnet/src/smoltcp_impl/mod.rs | 110 +- modules/ruxnet/src/smoltcp_impl/tcp.rs | 213 +- modules/ruxnet/src/smoltcp_impl/udp.rs | 133 +- 15 files changed, 4107 insertions(+), 191 deletions(-) create mode 100644 api/arceos_posix_api/src/ctypes_gen.rs create mode 100644 apps/c/httpserver_loopback/axbuild.mk create mode 100644 apps/c/httpserver_loopback/features.txt create mode 100644 apps/c/httpserver_loopback/httpserver.c create mode 100644 crates/driver_net/src/loopback.rs diff --git a/api/arceos_posix_api/src/ctypes_gen.rs b/api/arceos_posix_api/src/ctypes_gen.rs new file mode 100644 index 000000000..9b2b3f2fd --- /dev/null +++ b/api/arceos_posix_api/src/ctypes_gen.rs @@ -0,0 +1,3458 @@ +/* automatically generated by rust-bindgen 0.66.1 */ + +#[repr(C)] +#[derive(Default)] +pub struct __IncompleteArrayField(::core::marker::PhantomData, [T; 0]); +impl __IncompleteArrayField { + #[inline] + pub const fn new() -> Self { + __IncompleteArrayField(::core::marker::PhantomData, []) + } + #[inline] + pub fn as_ptr(&self) -> *const T { + self as *const _ as *const T + } + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut T { + self as *mut _ as *mut T + } + #[inline] + pub unsafe fn as_slice(&self, len: usize) -> &[T] { + ::core::slice::from_raw_parts(self.as_ptr(), len) + } + #[inline] + pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { + ::core::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + } +} +impl ::core::fmt::Debug for __IncompleteArrayField { + fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + fmt.write_str("__IncompleteArrayField") + } +} +pub const EINVAL: u32 = 22; +pub const O_CREAT: u32 = 64; +pub const O_EXCL: u32 = 128; +pub const O_NOCTTY: u32 = 256; +pub const O_TRUNC: u32 = 512; +pub const O_APPEND: u32 = 1024; +pub const O_NONBLOCK: u32 = 2048; +pub const O_DSYNC: u32 = 4096; +pub const O_SYNC: u32 = 1052672; +pub const O_RSYNC: u32 = 1052672; +pub const O_DIRECTORY: u32 = 65536; +pub const O_NOFOLLOW: u32 = 131072; +pub const O_CLOEXEC: u32 = 524288; +pub const O_ASYNC: u32 = 8192; +pub const O_DIRECT: u32 = 16384; +pub const O_LARGEFILE: u32 = 32768; +pub const O_NOATIME: u32 = 262144; +pub const O_PATH: u32 = 2097152; +pub const O_TMPFILE: u32 = 4259840; +pub const O_NDELAY: u32 = 2048; +pub const O_SEARCH: u32 = 2097152; +pub const O_EXEC: u32 = 2097152; +pub const O_TTY_INIT: u32 = 0; +pub const O_ACCMODE: u32 = 2097155; +pub const O_RDONLY: u32 = 0; +pub const O_WRONLY: u32 = 1; +pub const O_RDWR: u32 = 2; +pub const F_DUPFD: u32 = 0; +pub const F_GETFD: u32 = 1; +pub const F_SETFD: u32 = 2; +pub const F_GETFL: u32 = 3; +pub const F_SETFL: u32 = 4; +pub const F_SETOWN: u32 = 8; +pub const F_GETOWN: u32 = 9; +pub const F_SETSIG: u32 = 10; +pub const F_GETSIG: u32 = 11; +pub const F_GETLK: u32 = 5; +pub const F_SETLK: u32 = 6; +pub const F_SETLKW: u32 = 7; +pub const FD_CLOEXEC: u32 = 1; +pub const F_DUPFD_CLOEXEC: u32 = 1030; +pub const F_RDLCK: u32 = 0; +pub const F_WRLCK: u32 = 1; +pub const F_UNLCK: u32 = 2; +pub const F_OK: u32 = 0; +pub const F_ULOCK: u32 = 0; +pub const F_LOCK: u32 = 1; +pub const F_TLOCK: u32 = 2; +pub const F_TEST: u32 = 3; +pub const AT_FDCWD: i32 = -100; +pub const AT_EMPTY_PATH: u32 = 4096; +pub const AT_REMOVEDIR: u32 = 512; +pub const SOCK_STREAM: u32 = 1; +pub const SOCK_DGRAM: u32 = 2; +pub const SOCK_RAW: u32 = 3; +pub const SOCK_RDM: u32 = 4; +pub const SOCK_SEQPACKET: u32 = 5; +pub const SOCK_DCCP: u32 = 6; +pub const SOCK_PACKET: u32 = 10; +pub const SOCK_CLOEXEC: u32 = 524288; +pub const SOCK_NONBLOCK: u32 = 2048; +pub const AF_UNSPEC: u32 = 0; +pub const AF_LOCAL: u32 = 1; +pub const AF_UNIX: u32 = 1; +pub const AF_FILE: u32 = 1; +pub const AF_INET: u32 = 2; +pub const AF_AX25: u32 = 3; +pub const AF_IPX: u32 = 4; +pub const AF_APPLETALK: u32 = 5; +pub const AF_NETROM: u32 = 6; +pub const AF_BRIDGE: u32 = 7; +pub const AF_ATMPVC: u32 = 8; +pub const AF_X25: u32 = 9; +pub const AF_INET6: u32 = 10; +pub const AF_ROSE: u32 = 11; +pub const AF_DECnet: u32 = 12; +pub const AF_NETBEUI: u32 = 13; +pub const AF_SECURITY: u32 = 14; +pub const AF_KEY: u32 = 15; +pub const AF_NETLINK: u32 = 16; +pub const AF_ROUTE: u32 = 16; +pub const AF_PACKET: u32 = 17; +pub const AF_ASH: u32 = 18; +pub const AF_ECONET: u32 = 19; +pub const AF_ATMSVC: u32 = 20; +pub const AF_RDS: u32 = 21; +pub const AF_SNA: u32 = 22; +pub const AF_IRDA: u32 = 23; +pub const AF_PPPOX: u32 = 24; +pub const AF_WANPIPE: u32 = 25; +pub const AF_LLC: u32 = 26; +pub const AF_IB: u32 = 27; +pub const AF_MPLS: u32 = 28; +pub const AF_CAN: u32 = 29; +pub const AF_TIPC: u32 = 30; +pub const AF_BLUETOOTH: u32 = 31; +pub const AF_IUCV: u32 = 32; +pub const AF_RXRPC: u32 = 33; +pub const AF_ISDN: u32 = 34; +pub const AF_PHONET: u32 = 35; +pub const AF_IEEE802154: u32 = 36; +pub const AF_CAIF: u32 = 37; +pub const AF_ALG: u32 = 38; +pub const AF_NFC: u32 = 39; +pub const AF_VSOCK: u32 = 40; +pub const AF_KCM: u32 = 41; +pub const AF_QIPCRTR: u32 = 42; +pub const AF_SMC: u32 = 43; +pub const AF_XDP: u32 = 44; +pub const AF_MAX: u32 = 45; +pub const IPPROTO_IP: u32 = 0; +pub const IPPROTO_HOPOPTS: u32 = 0; +pub const IPPROTO_ICMP: u32 = 1; +pub const IPPROTO_IGMP: u32 = 2; +pub const IPPROTO_IPIP: u32 = 4; +pub const IPPROTO_TCP: u32 = 6; +pub const IPPROTO_EGP: u32 = 8; +pub const IPPROTO_PUP: u32 = 12; +pub const IPPROTO_UDP: u32 = 17; +pub const IPPROTO_IDP: u32 = 22; +pub const IPPROTO_TP: u32 = 29; +pub const IPPROTO_DCCP: u32 = 33; +pub const IPPROTO_IPV6: u32 = 41; +pub const IPPROTO_ROUTING: u32 = 43; +pub const IPPROTO_FRAGMENT: u32 = 44; +pub const IPPROTO_RSVP: u32 = 46; +pub const IPPROTO_GRE: u32 = 47; +pub const IPPROTO_ESP: u32 = 50; +pub const IPPROTO_AH: u32 = 51; +pub const IPPROTO_ICMPV6: u32 = 58; +pub const IPPROTO_NONE: u32 = 59; +pub const IPPROTO_DSTOPTS: u32 = 60; +pub const IPPROTO_MTP: u32 = 92; +pub const IPPROTO_BEETPH: u32 = 94; +pub const IPPROTO_ENCAP: u32 = 98; +pub const IPPROTO_PIM: u32 = 103; +pub const IPPROTO_COMP: u32 = 108; +pub const IPPROTO_SCTP: u32 = 132; +pub const IPPROTO_MH: u32 = 135; +pub const IPPROTO_UDPLITE: u32 = 136; +pub const IPPROTO_MPLS: u32 = 137; +pub const IPPROTO_ETHERNET: u32 = 143; +pub const IPPROTO_RAW: u32 = 255; +pub const IPPROTO_MPTCP: u32 = 262; +pub const IPPROTO_MAX: u32 = 263; +pub const EAI_BADFLAGS: i32 = -1; +pub const EAI_NONAME: i32 = -2; +pub const EAI_AGAIN: i32 = -3; +pub const EAI_FAIL: i32 = -4; +pub const EAI_FAMILY: i32 = -6; +pub const EAI_SOCKTYPE: i32 = -7; +pub const EAI_SERVICE: i32 = -8; +pub const EAI_MEMORY: i32 = -10; +pub const EAI_SYSTEM: i32 = -11; +pub const EAI_OVERFLOW: i32 = -12; +pub const MAXADDRS: u32 = 48; +pub const ITIMER_REAL: u32 = 0; +pub const ITIMER_VIRTUAL: u32 = 1; +pub const ITIMER_PROF: u32 = 2; +pub const SIGCANCEL: u32 = 33; +pub const CLONE_NEWTIME: u32 = 128; +pub const CLONE_VM: u32 = 256; +pub const CLONE_FS: u32 = 512; +pub const CLONE_FILES: u32 = 1024; +pub const CLONE_SIGHAND: u32 = 2048; +pub const CLONE_PIDFD: u32 = 4096; +pub const CLONE_PTRACE: u32 = 8192; +pub const CLONE_VFORK: u32 = 16384; +pub const CLONE_PARENT: u32 = 32768; +pub const CLONE_THREAD: u32 = 65536; +pub const CLONE_NEWNS: u32 = 131072; +pub const CLONE_SYSVSEM: u32 = 262144; +pub const CLONE_SETTLS: u32 = 524288; +pub const CLONE_PARENT_SETTID: u32 = 1048576; +pub const CLONE_CHILD_CLEARTID: u32 = 2097152; +pub const CLONE_DETACHED: u32 = 4194304; +pub const CLONE_UNTRACED: u32 = 8388608; +pub const CLONE_CHILD_SETTID: u32 = 16777216; +pub const CLONE_NEWCGROUP: u32 = 33554432; +pub const CLONE_NEWUTS: u32 = 67108864; +pub const CLONE_NEWIPC: u32 = 134217728; +pub const CLONE_NEWUSER: u32 = 268435456; +pub const CLONE_NEWPID: u32 = 536870912; +pub const CLONE_NEWNET: u32 = 1073741824; +pub const CLONE_IO: u32 = 2147483648; +pub const SIG_BLOCK: u32 = 0; +pub const SIG_UNBLOCK: u32 = 1; +pub const SIG_SETMASK: u32 = 2; +pub const SIGHUP: u32 = 1; +pub const SIGINT: u32 = 2; +pub const SIGQUIT: u32 = 3; +pub const SIGILL: u32 = 4; +pub const SIGTRAP: u32 = 5; +pub const SIGABRT: u32 = 6; +pub const SIGIOT: u32 = 6; +pub const SIGBUS: u32 = 7; +pub const SIGFPE: u32 = 8; +pub const SIGKILL: u32 = 9; +pub const SIGUSR1: u32 = 10; +pub const SIGSEGV: u32 = 11; +pub const SIGUSR2: u32 = 12; +pub const SIGPIPE: u32 = 13; +pub const SIGALRM: u32 = 14; +pub const SIGTERM: u32 = 15; +pub const SIGSTKFLT: u32 = 16; +pub const SIGCHLD: u32 = 17; +pub const SIGCONT: u32 = 18; +pub const SIGSTOP: u32 = 19; +pub const SIGTSTP: u32 = 20; +pub const SIGTTIN: u32 = 21; +pub const SIGTTOU: u32 = 22; +pub const SIGURG: u32 = 23; +pub const SIGXCPU: u32 = 24; +pub const SIGXFSZ: u32 = 25; +pub const SIGVTALRM: u32 = 26; +pub const SIGPROF: u32 = 27; +pub const SIGWINCH: u32 = 28; +pub const SIGIO: u32 = 29; +pub const SIGPOLL: u32 = 29; +pub const SIGPWR: u32 = 30; +pub const SIGSYS: u32 = 31; +pub const SIGUNUSED: u32 = 31; +pub const SIGERR: i32 = -1; +pub const SIGDFL: u32 = 0; +pub const SIGIGN: u32 = 1; +pub const EPOLL_CLOEXEC: u32 = 524288; +pub const EPOLL_NONBLOCK: u32 = 2048; +pub const EPOLLIN: u32 = 1; +pub const EPOLLPRI: u32 = 2; +pub const EPOLLOUT: u32 = 4; +pub const EPOLLRDNORM: u32 = 64; +pub const EPOLLNVAL: u32 = 32; +pub const EPOLLRDBAND: u32 = 128; +pub const EPOLLWRNORM: u32 = 256; +pub const EPOLLWRBAND: u32 = 512; +pub const EPOLLMSG: u32 = 1024; +pub const EPOLLERR: u32 = 8; +pub const EPOLLHUP: u32 = 16; +pub const EPOLLRDHUP: u32 = 8192; +pub const EPOLLEXCLUSIVE: u32 = 268435456; +pub const EPOLLWAKEUP: u32 = 536870912; +pub const EPOLLONESHOT: u32 = 1073741824; +pub const EPOLLET: u32 = 2147483648; +pub const EPOLL_CTL_ADD: u32 = 1; +pub const EPOLL_CTL_DEL: u32 = 2; +pub const EPOLL_CTL_MOD: u32 = 3; +pub const RLIMIT_CPU: u32 = 0; +pub const RLIMIT_FSIZE: u32 = 1; +pub const RLIMIT_DATA: u32 = 2; +pub const RLIMIT_STACK: u32 = 3; +pub const RLIMIT_CORE: u32 = 4; +pub const RLIMIT_RSS: u32 = 5; +pub const RLIMIT_NPROC: u32 = 6; +pub const RLIMIT_NOFILE: u32 = 7; +pub const RLIMIT_MEMLOCK: u32 = 8; +pub const RLIMIT_AS: u32 = 9; +pub const RLIMIT_LOCKS: u32 = 10; +pub const RLIMIT_SIGPENDING: u32 = 11; +pub const RLIMIT_MSGQUEUE: u32 = 12; +pub const RLIMIT_NICE: u32 = 13; +pub const RLIMIT_RTPRIO: u32 = 14; +pub const RLIMIT_RTTIME: u32 = 15; +pub const RLIMIT_NLIMITS: u32 = 16; +pub const FD_SETSIZE: u32 = 1024; +pub const _SC_ARG_MAX: u32 = 0; +pub const _SC_CHILD_MAX: u32 = 1; +pub const _SC_CLK_TCK: u32 = 2; +pub const _SC_NGROUPS_MAX: u32 = 3; +pub const _SC_OPEN_MAX: u32 = 4; +pub const _SC_STREAM_MAX: u32 = 5; +pub const _SC_TZNAME_MAX: u32 = 6; +pub const _SC_JOB_CONTROL: u32 = 7; +pub const _SC_SAVED_IDS: u32 = 8; +pub const _SC_REALTIME_SIGNALS: u32 = 9; +pub const _SC_PRIORITY_SCHEDULING: u32 = 10; +pub const _SC_TIMERS: u32 = 11; +pub const _SC_ASYNCHRONOUS_IO: u32 = 12; +pub const _SC_PRIORITIZED_IO: u32 = 13; +pub const _SC_SYNCHRONIZED_IO: u32 = 14; +pub const _SC_FSYNC: u32 = 15; +pub const _SC_MAPPED_FILES: u32 = 16; +pub const _SC_MEMLOCK: u32 = 17; +pub const _SC_MEMLOCK_RANGE: u32 = 18; +pub const _SC_MEMORY_PROTECTION: u32 = 19; +pub const _SC_MESSAGE_PASSING: u32 = 20; +pub const _SC_SEMAPHORES: u32 = 21; +pub const _SC_SHARED_MEMORY_OBJECTS: u32 = 22; +pub const _SC_AIO_LISTIO_MAX: u32 = 23; +pub const _SC_AIO_MAX: u32 = 24; +pub const _SC_AIO_PRIO_DELTA_MAX: u32 = 25; +pub const _SC_DELAYTIMER_MAX: u32 = 26; +pub const _SC_MQ_OPEN_MAX: u32 = 27; +pub const _SC_MQ_PRIO_MAX: u32 = 28; +pub const _SC_VERSION: u32 = 29; +pub const _SC_PAGE_SIZE: u32 = 30; +pub const _SC_PAGESIZE: u32 = 30; +pub const _SC_RTSIG_MAX: u32 = 31; +pub const _SC_SEM_NSEMS_MAX: u32 = 32; +pub const _SC_SEM_VALUE_MAX: u32 = 33; +pub const _SC_SIGQUEUE_MAX: u32 = 34; +pub const _SC_TIMER_MAX: u32 = 35; +pub const _SC_BC_BASE_MAX: u32 = 36; +pub const _SC_BC_DIM_MAX: u32 = 37; +pub const _SC_BC_SCALE_MAX: u32 = 38; +pub const _SC_BC_STRING_MAX: u32 = 39; +pub const _SC_COLL_WEIGHTS_MAX: u32 = 40; +pub const _SC_EXPR_NEST_MAX: u32 = 42; +pub const _SC_LINE_MAX: u32 = 43; +pub const _SC_RE_DUP_MAX: u32 = 44; +pub const _SC_2_VERSION: u32 = 46; +pub const _SC_2_C_BIND: u32 = 47; +pub const _SC_2_C_DEV: u32 = 48; +pub const _SC_2_FORT_DEV: u32 = 49; +pub const _SC_2_FORT_RUN: u32 = 50; +pub const _SC_2_SW_DEV: u32 = 51; +pub const _SC_2_LOCALEDEF: u32 = 52; +pub const _SC_UIO_MAXIOV: u32 = 60; +pub const _SC_IOV_MAX: u32 = 60; +pub const _SC_THREADS: u32 = 67; +pub const _SC_THREAD_SAFE_FUNCTIONS: u32 = 68; +pub const _SC_GETGR_R_SIZE_MAX: u32 = 69; +pub const _SC_GETPW_R_SIZE_MAX: u32 = 70; +pub const _SC_LOGIN_NAME_MAX: u32 = 71; +pub const _SC_TTY_NAME_MAX: u32 = 72; +pub const _SC_THREAD_DESTRUCTOR_ITERATIONS: u32 = 73; +pub const _SC_THREAD_KEYS_MAX: u32 = 74; +pub const _SC_THREAD_STACK_MIN: u32 = 75; +pub const _SC_THREAD_THREADS_MAX: u32 = 76; +pub const _SC_THREAD_ATTR_STACKADDR: u32 = 77; +pub const _SC_THREAD_ATTR_STACKSIZE: u32 = 78; +pub const _SC_THREAD_PRIORITY_SCHEDULING: u32 = 79; +pub const _SC_THREAD_PRIO_INHERIT: u32 = 80; +pub const _SC_THREAD_PRIO_PROTECT: u32 = 81; +pub const _SC_THREAD_PROCESS_SHARED: u32 = 82; +pub const _SC_NPROCESSORS_CONF: u32 = 83; +pub const _SC_NPROCESSORS_ONLN: u32 = 84; +pub const _SC_PHYS_PAGES: u32 = 85; +pub const _SC_AVPHYS_PAGES: u32 = 86; +pub const _SC_ATEXIT_MAX: u32 = 87; +pub const _SC_PASS_MAX: u32 = 88; +pub const _SC_XOPEN_VERSION: u32 = 89; +pub const _SC_XOPEN_XCU_VERSION: u32 = 90; +pub const _SC_XOPEN_UNIX: u32 = 91; +pub const _SC_XOPEN_CRYPT: u32 = 92; +pub const _SC_XOPEN_ENH_I18N: u32 = 93; +pub const _SC_XOPEN_SHM: u32 = 94; +pub const _SC_2_CHAR_TERM: u32 = 95; +pub const _SC_2_UPE: u32 = 97; +pub const _SC_XOPEN_XPG2: u32 = 98; +pub const _SC_XOPEN_XPG3: u32 = 99; +pub const _SC_XOPEN_XPG4: u32 = 100; +pub const _SC_NZERO: u32 = 109; +pub const _SC_XBS5_ILP32_OFF32: u32 = 125; +pub const _SC_XBS5_ILP32_OFFBIG: u32 = 126; +pub const _SC_XBS5_LP64_OFF64: u32 = 127; +pub const _SC_XBS5_LPBIG_OFFBIG: u32 = 128; +pub const _SC_XOPEN_LEGACY: u32 = 129; +pub const _SC_XOPEN_REALTIME: u32 = 130; +pub const _SC_XOPEN_REALTIME_THREADS: u32 = 131; +pub const _SC_ADVISORY_INFO: u32 = 132; +pub const _SC_BARRIERS: u32 = 133; +pub const _SC_CLOCK_SELECTION: u32 = 137; +pub const _SC_CPUTIME: u32 = 138; +pub const _SC_THREAD_CPUTIME: u32 = 139; +pub const _SC_MONOTONIC_CLOCK: u32 = 149; +pub const _SC_READER_WRITER_LOCKS: u32 = 153; +pub const _SC_SPIN_LOCKS: u32 = 154; +pub const _SC_REGEXP: u32 = 155; +pub const _SC_SHELL: u32 = 157; +pub const _SC_SPAWN: u32 = 159; +pub const _SC_SPORADIC_SERVER: u32 = 160; +pub const _SC_THREAD_SPORADIC_SERVER: u32 = 161; +pub const _SC_TIMEOUTS: u32 = 164; +pub const _SC_TYPED_MEMORY_OBJECTS: u32 = 165; +pub const _SC_2_PBS: u32 = 168; +pub const _SC_2_PBS_ACCOUNTING: u32 = 169; +pub const _SC_2_PBS_LOCATE: u32 = 170; +pub const _SC_2_PBS_MESSAGE: u32 = 171; +pub const _SC_2_PBS_TRACK: u32 = 172; +pub const _SC_SYMLOOP_MAX: u32 = 173; +pub const _SC_STREAMS: u32 = 174; +pub const _SC_2_PBS_CHECKPOINT: u32 = 175; +pub const _SC_V6_ILP32_OFF32: u32 = 176; +pub const _SC_V6_ILP32_OFFBIG: u32 = 177; +pub const _SC_V6_LP64_OFF64: u32 = 178; +pub const _SC_V6_LPBIG_OFFBIG: u32 = 179; +pub const _SC_HOST_NAME_MAX: u32 = 180; +pub const _SC_TRACE: u32 = 181; +pub const _SC_TRACE_EVENT_FILTER: u32 = 182; +pub const _SC_TRACE_INHERIT: u32 = 183; +pub const _SC_TRACE_LOG: u32 = 184; +pub const _SC_IPV6: u32 = 235; +pub const _SC_RAW_SOCKETS: u32 = 236; +pub const _SC_V7_ILP32_OFF32: u32 = 237; +pub const _SC_V7_ILP32_OFFBIG: u32 = 238; +pub const _SC_V7_LP64_OFF64: u32 = 239; +pub const _SC_V7_LPBIG_OFFBIG: u32 = 240; +pub const _SC_SS_REPL_MAX: u32 = 241; +pub const _SC_TRACE_EVENT_NAME_MAX: u32 = 242; +pub const _SC_TRACE_NAME_MAX: u32 = 243; +pub const _SC_TRACE_SYS_MAX: u32 = 244; +pub const _SC_TRACE_USER_EVENT_MAX: u32 = 245; +pub const _SC_XOPEN_STREAMS: u32 = 246; +pub const _SC_THREAD_ROBUST_PRIO_INHERIT: u32 = 247; +pub const _SC_THREAD_ROBUST_PRIO_PROTECT: u32 = 248; +pub type size_t = usize; +pub type ssize_t = isize; +pub type clockid_t = ::core::ffi::c_int; +pub type mode_t = ::core::ffi::c_uint; +pub type nlink_t = u32; +pub type off_t = i64; +pub type ino_t = u64; +pub type dev_t = u64; +pub type blksize_t = ::core::ffi::c_long; +pub type blkcnt_t = i64; +pub type pid_t = ::core::ffi::c_int; +pub type uid_t = ::core::ffi::c_uint; +pub type gid_t = ::core::ffi::c_uint; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct k_sigaction { + pub handler: ::core::option::Option, + pub flags: ::core::ffi::c_ulong, + pub restorer: ::core::option::Option, + pub mask: [::core::ffi::c_uint; 2usize], +} +#[test] +fn bindgen_test_layout_k_sigaction() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(k_sigaction)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(k_sigaction)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).handler) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(k_sigaction), + "::", + stringify!(handler) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).flags) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(k_sigaction), + "::", + stringify!(flags) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).restorer) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(k_sigaction), + "::", + stringify!(restorer) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).mask) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(k_sigaction), + "::", + stringify!(mask) + ) + ); +} +pub type socklen_t = ::core::ffi::c_uint; +pub type sa_family_t = ::core::ffi::c_ushort; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct msghdr { + pub msg_name: *mut ::core::ffi::c_void, + pub msg_namelen: socklen_t, + pub msg_iov: *mut iovec, + pub msg_iovlen: ::core::ffi::c_int, + pub __pad1: ::core::ffi::c_int, + pub msg_control: *mut ::core::ffi::c_void, + pub msg_controllen: socklen_t, + pub __pad2: ::core::ffi::c_int, + pub msg_flags: ::core::ffi::c_int, +} +#[test] +fn bindgen_test_layout_msghdr() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 56usize, + concat!("Size of: ", stringify!(msghdr)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(msghdr)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).msg_name) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(msghdr), + "::", + stringify!(msg_name) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).msg_namelen) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(msghdr), + "::", + stringify!(msg_namelen) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).msg_iov) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(msghdr), + "::", + stringify!(msg_iov) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).msg_iovlen) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(msghdr), + "::", + stringify!(msg_iovlen) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__pad1) as usize - ptr as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(msghdr), + "::", + stringify!(__pad1) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).msg_control) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(msghdr), + "::", + stringify!(msg_control) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).msg_controllen) as usize - ptr as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(msghdr), + "::", + stringify!(msg_controllen) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__pad2) as usize - ptr as usize }, + 44usize, + concat!( + "Offset of field: ", + stringify!(msghdr), + "::", + stringify!(__pad2) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).msg_flags) as usize - ptr as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(msghdr), + "::", + stringify!(msg_flags) + ) + ); +} +impl Default for msghdr { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct sockaddr { + pub sa_family: sa_family_t, + pub sa_data: [::core::ffi::c_char; 14usize], +} +#[test] +fn bindgen_test_layout_sockaddr() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(sockaddr)) + ); + assert_eq!( + ::core::mem::align_of::(), + 2usize, + concat!("Alignment of ", stringify!(sockaddr)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sa_family) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sockaddr), + "::", + stringify!(sa_family) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sa_data) as usize - ptr as usize }, + 2usize, + concat!( + "Offset of field: ", + stringify!(sockaddr), + "::", + stringify!(sa_data) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sockaddr_storage { + pub ss_family: sa_family_t, + pub __ss_padding: [::core::ffi::c_char; 118usize], + pub __ss_align: ::core::ffi::c_ulong, +} +#[test] +fn bindgen_test_layout_sockaddr_storage() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 128usize, + concat!("Size of: ", stringify!(sockaddr_storage)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(sockaddr_storage)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ss_family) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_storage), + "::", + stringify!(ss_family) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__ss_padding) as usize - ptr as usize }, + 2usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_storage), + "::", + stringify!(__ss_padding) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__ss_align) as usize - ptr as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_storage), + "::", + stringify!(__ss_align) + ) + ); +} +impl Default for sockaddr_storage { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +pub type in_port_t = u16; +pub type in_addr_t = u32; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct in_addr { + pub s_addr: in_addr_t, +} +#[test] +fn bindgen_test_layout_in_addr() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(in_addr)) + ); + assert_eq!( + ::core::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(in_addr)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).s_addr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(in_addr), + "::", + stringify!(s_addr) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct sockaddr_in { + pub sin_family: sa_family_t, + pub sin_port: in_port_t, + pub sin_addr: in_addr, + pub sin_zero: [u8; 8usize], +} +#[test] +fn bindgen_test_layout_sockaddr_in() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(sockaddr_in)) + ); + assert_eq!( + ::core::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(sockaddr_in)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sin_family) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_in), + "::", + stringify!(sin_family) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sin_port) as usize - ptr as usize }, + 2usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_in), + "::", + stringify!(sin_port) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sin_addr) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_in), + "::", + stringify!(sin_addr) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sin_zero) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_in), + "::", + stringify!(sin_zero) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct in6_addr { + pub __in6_union: in6_addr__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union in6_addr__bindgen_ty_1 { + pub __s6_addr: [u8; 16usize], + pub __s6_addr16: [u16; 8usize], + pub __s6_addr32: [u32; 4usize], +} +#[test] +fn bindgen_test_layout_in6_addr__bindgen_ty_1() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(in6_addr__bindgen_ty_1)) + ); + assert_eq!( + ::core::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(in6_addr__bindgen_ty_1)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__s6_addr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(in6_addr__bindgen_ty_1), + "::", + stringify!(__s6_addr) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__s6_addr16) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(in6_addr__bindgen_ty_1), + "::", + stringify!(__s6_addr16) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__s6_addr32) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(in6_addr__bindgen_ty_1), + "::", + stringify!(__s6_addr32) + ) + ); +} +impl Default for in6_addr__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[test] +fn bindgen_test_layout_in6_addr() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(in6_addr)) + ); + assert_eq!( + ::core::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(in6_addr)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__in6_union) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(in6_addr), + "::", + stringify!(__in6_union) + ) + ); +} +impl Default for in6_addr { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sockaddr_in6 { + pub sin6_family: sa_family_t, + pub sin6_port: in_port_t, + pub sin6_flowinfo: u32, + pub sin6_addr: in6_addr, + pub sin6_scope_id: u32, +} +#[test] +fn bindgen_test_layout_sockaddr_in6() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 28usize, + concat!("Size of: ", stringify!(sockaddr_in6)) + ); + assert_eq!( + ::core::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(sockaddr_in6)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sin6_family) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_in6), + "::", + stringify!(sin6_family) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sin6_port) as usize - ptr as usize }, + 2usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_in6), + "::", + stringify!(sin6_port) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sin6_flowinfo) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_in6), + "::", + stringify!(sin6_flowinfo) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sin6_addr) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_in6), + "::", + stringify!(sin6_addr) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sin6_scope_id) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(sockaddr_in6), + "::", + stringify!(sin6_scope_id) + ) + ); +} +impl Default for sockaddr_in6 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct addrinfo { + pub ai_flags: ::core::ffi::c_int, + pub ai_family: ::core::ffi::c_int, + pub ai_socktype: ::core::ffi::c_int, + pub ai_protocol: ::core::ffi::c_int, + pub ai_addrlen: socklen_t, + pub ai_addr: *mut sockaddr, + pub ai_canonname: *mut ::core::ffi::c_char, + pub ai_next: *mut addrinfo, +} +#[test] +fn bindgen_test_layout_addrinfo() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 48usize, + concat!("Size of: ", stringify!(addrinfo)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(addrinfo)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ai_flags) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(addrinfo), + "::", + stringify!(ai_flags) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ai_family) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(addrinfo), + "::", + stringify!(ai_family) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ai_socktype) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(addrinfo), + "::", + stringify!(ai_socktype) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ai_protocol) as usize - ptr as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(addrinfo), + "::", + stringify!(ai_protocol) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ai_addrlen) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(addrinfo), + "::", + stringify!(ai_addrlen) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ai_addr) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(addrinfo), + "::", + stringify!(ai_addr) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ai_canonname) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(addrinfo), + "::", + stringify!(ai_canonname) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ai_next) as usize - ptr as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(addrinfo), + "::", + stringify!(ai_next) + ) + ); +} +impl Default for addrinfo { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct aibuf { + pub ai: addrinfo, + pub sa: aibuf_sa, + pub lock: [::core::ffi::c_int; 1usize], + pub slot: ::core::ffi::c_short, + pub ref_: ::core::ffi::c_short, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union aibuf_sa { + pub sin: sockaddr_in, + pub sin6: sockaddr_in6, +} +#[test] +fn bindgen_test_layout_aibuf_sa() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 28usize, + concat!("Size of: ", stringify!(aibuf_sa)) + ); + assert_eq!( + ::core::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(aibuf_sa)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sin) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(aibuf_sa), + "::", + stringify!(sin) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sin6) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(aibuf_sa), + "::", + stringify!(sin6) + ) + ); +} +impl Default for aibuf_sa { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[test] +fn bindgen_test_layout_aibuf() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 88usize, + concat!("Size of: ", stringify!(aibuf)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(aibuf)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ai) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(aibuf), "::", stringify!(ai)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sa) as usize - ptr as usize }, + 48usize, + concat!("Offset of field: ", stringify!(aibuf), "::", stringify!(sa)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).lock) as usize - ptr as usize }, + 76usize, + concat!( + "Offset of field: ", + stringify!(aibuf), + "::", + stringify!(lock) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).slot) as usize - ptr as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(aibuf), + "::", + stringify!(slot) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ref_) as usize - ptr as usize }, + 82usize, + concat!( + "Offset of field: ", + stringify!(aibuf), + "::", + stringify!(ref_) + ) + ); +} +impl Default for aibuf { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct pollfd { + pub fd: ::core::ffi::c_int, + pub events: ::core::ffi::c_short, + pub revents: ::core::ffi::c_short, +} +#[test] +fn bindgen_test_layout_pollfd() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(pollfd)) + ); + assert_eq!( + ::core::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(pollfd)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).fd) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pollfd), + "::", + stringify!(fd) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).events) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(pollfd), + "::", + stringify!(events) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).revents) as usize - ptr as usize }, + 6usize, + concat!( + "Offset of field: ", + stringify!(pollfd), + "::", + stringify!(revents) + ) + ); +} +pub type nfds_t = ::core::ffi::c_ulong; +pub type time_t = ::core::ffi::c_longlong; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct timeval { + pub tv_sec: time_t, + pub tv_usec: ::core::ffi::c_long, +} +#[test] +fn bindgen_test_layout_timeval() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(timeval)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(timeval)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).tv_sec) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(timeval), + "::", + stringify!(tv_sec) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).tv_usec) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(timeval), + "::", + stringify!(tv_usec) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: ::core::ffi::c_long, +} +#[test] +fn bindgen_test_layout_timespec() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(timespec)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(timespec)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).tv_sec) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(timespec), + "::", + stringify!(tv_sec) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).tv_nsec) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(timespec), + "::", + stringify!(tv_nsec) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct itimerval { + pub it_interval: timeval, + pub it_value: timeval, +} +#[test] +fn bindgen_test_layout_itimerval() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(itimerval)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(itimerval)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).it_interval) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(itimerval), + "::", + stringify!(it_interval) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).it_value) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(itimerval), + "::", + stringify!(it_value) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct pthread_condattr_t { + pub __attr: ::core::ffi::c_uint, +} +#[test] +fn bindgen_test_layout_pthread_condattr_t() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(pthread_condattr_t)) + ); + assert_eq!( + ::core::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(pthread_condattr_t)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__attr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_condattr_t), + "::", + stringify!(__attr) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct pthread_cond_t { + pub __l: [::core::ffi::c_long; 1usize], +} +#[test] +fn bindgen_test_layout_pthread_cond_t() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(pthread_cond_t)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_cond_t)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__l) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_cond_t), + "::", + stringify!(__l) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct pthread_mutex_t { + pub __l: [::core::ffi::c_long; 1usize], +} +#[test] +fn bindgen_test_layout_pthread_mutex_t() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(pthread_mutex_t)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_mutex_t)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__l) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutex_t), + "::", + stringify!(__l) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct pthread_mutexattr_t { + pub __attr: ::core::ffi::c_uint, +} +#[test] +fn bindgen_test_layout_pthread_mutexattr_t() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(pthread_mutexattr_t)) + ); + assert_eq!( + ::core::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(pthread_mutexattr_t)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__attr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_mutexattr_t), + "::", + stringify!(__attr) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct pthread_attr_t { + pub __u: pthread_attr_t__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union pthread_attr_t__bindgen_ty_1 { + pub __i: [::core::ffi::c_int; 14usize], + pub __vi: [::core::ffi::c_int; 14usize], + pub __s: [::core::ffi::c_ulong; 7usize], +} +#[test] +fn bindgen_test_layout_pthread_attr_t__bindgen_ty_1() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 56usize, + concat!("Size of: ", stringify!(pthread_attr_t__bindgen_ty_1)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_attr_t__bindgen_ty_1)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__i) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_attr_t__bindgen_ty_1), + "::", + stringify!(__i) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__vi) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_attr_t__bindgen_ty_1), + "::", + stringify!(__vi) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__s) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_attr_t__bindgen_ty_1), + "::", + stringify!(__s) + ) + ); +} +impl Default for pthread_attr_t__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[test] +fn bindgen_test_layout_pthread_attr_t() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 56usize, + concat!("Size of: ", stringify!(pthread_attr_t)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pthread_attr_t)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__u) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pthread_attr_t), + "::", + stringify!(__u) + ) + ); +} +impl Default for pthread_attr_t { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +pub type pthread_t = *mut ::core::ffi::c_void; +pub type pthread_key_t = ::core::ffi::c_uint; +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigval { + pub sival_int: ::core::ffi::c_int, + pub sival_ptr: *mut ::core::ffi::c_void, +} +#[test] +fn bindgen_test_layout_sigval() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(sigval)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(sigval)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sival_int) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sigval), + "::", + stringify!(sival_int) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sival_ptr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sigval), + "::", + stringify!(sival_ptr) + ) + ); +} +impl Default for sigval { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t { + pub si_signo: ::core::ffi::c_int, + pub si_errno: ::core::ffi::c_int, + pub si_code: ::core::ffi::c_int, + pub __si_fields: siginfo_t__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union siginfo_t__bindgen_ty_1 { + pub __pad: [::core::ffi::c_char; 112usize], + pub __si_common: siginfo_t__bindgen_ty_1__bindgen_ty_1, + pub __sigfault: siginfo_t__bindgen_ty_1__bindgen_ty_2, + pub __sigpoll: siginfo_t__bindgen_ty_1__bindgen_ty_3, + pub __sigsys: siginfo_t__bindgen_ty_1__bindgen_ty_4, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_1 { + pub __first: siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, + pub __second: siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 { + pub __piduid: siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, + pub __timer: siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 { + pub si_pid: ::core::ffi::c_int, + pub si_uid: ::core::ffi::c_uint, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1() { + const UNINIT: ::core::mem::MaybeUninit< + siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1, + > = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 8usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + ::core::mem::align_of::( + ), + 4usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_pid) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(si_pid) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_uid) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(si_uid) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2 { + pub si_timerid: ::core::ffi::c_int, + pub si_overrun: ::core::ffi::c_int, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2() { + const UNINIT: ::core::mem::MaybeUninit< + siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2, + > = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 8usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2) + ) + ); + assert_eq!( + ::core::mem::align_of::( + ), + 4usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_timerid) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2), + "::", + stringify!(si_timerid) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_overrun) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2), + "::", + stringify!(si_overrun) + ) + ); +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 8usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + ::core::mem::align_of::(), + 4usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__piduid) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(__piduid) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__timer) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(__timer) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2 { + pub si_value: sigval, + pub __sigchld: siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1 { + pub si_status: ::core::ffi::c_int, + pub si_utime: ::core::ffi::c_long, + pub si_stime: ::core::ffi::c_long, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1() { + const UNINIT: ::core::mem::MaybeUninit< + siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1, + > = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 24usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1) + ) + ); + assert_eq!( + ::core::mem::align_of::( + ), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_status) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1), + "::", + stringify!(si_status) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_utime) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1), + "::", + stringify!(si_utime) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_stime) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1), + "::", + stringify!(si_stime) + ) + ); +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 24usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2) + ) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_value) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2), + "::", + stringify!(si_value) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__sigchld) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2), + "::", + stringify!(__sigchld) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_1() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__first) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(__first) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__second) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(__second) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_2 { + pub si_addr: *mut ::core::ffi::c_void, + pub si_addr_lsb: ::core::ffi::c_short, + pub __first: siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1 { + pub __addr_bnd: siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1__bindgen_ty_1, + pub si_pkey: ::core::ffi::c_uint, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1__bindgen_ty_1 { + pub si_lower: *mut ::core::ffi::c_void, + pub si_upper: *mut ::core::ffi::c_void, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1__bindgen_ty_1() { + const UNINIT: ::core::mem::MaybeUninit< + siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1__bindgen_ty_1, + > = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + ::core::mem::align_of::( + ), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1__bindgen_ty_1) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_lower) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(si_lower) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_upper) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1__bindgen_ty_1), + "::", + stringify!(si_upper) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1) + ) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__addr_bnd) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1), + "::", + stringify!(__addr_bnd) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_pkey) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1), + "::", + stringify!(si_pkey) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_2__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_2() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2) + ) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_addr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2), + "::", + stringify!(si_addr) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_addr_lsb) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2), + "::", + stringify!(si_addr_lsb) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__first) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_2), + "::", + stringify!(__first) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_2 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_3 { + pub si_band: ::core::ffi::c_long, + pub si_fd: ::core::ffi::c_int, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_3() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_3) + ) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_3) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_band) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_3), + "::", + stringify!(si_band) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_fd) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_3), + "::", + stringify!(si_fd) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct siginfo_t__bindgen_ty_1__bindgen_ty_4 { + pub si_call_addr: *mut ::core::ffi::c_void, + pub si_syscall: ::core::ffi::c_int, + pub si_arch: ::core::ffi::c_uint, +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1__bindgen_ty_4() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!( + "Size of: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4) + ) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!( + "Alignment of ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_call_addr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4), + "::", + stringify!(si_call_addr) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_syscall) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4), + "::", + stringify!(si_syscall) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_arch) as usize - ptr as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1__bindgen_ty_4), + "::", + stringify!(si_arch) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1__bindgen_ty_4 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[test] +fn bindgen_test_layout_siginfo_t__bindgen_ty_1() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 112usize, + concat!("Size of: ", stringify!(siginfo_t__bindgen_ty_1)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(siginfo_t__bindgen_ty_1)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__pad) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(__pad) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__si_common) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(__si_common) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__sigfault) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(__sigfault) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__sigpoll) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(__sigpoll) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__sigsys) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t__bindgen_ty_1), + "::", + stringify!(__sigsys) + ) + ); +} +impl Default for siginfo_t__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[test] +fn bindgen_test_layout_siginfo_t() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 128usize, + concat!("Size of: ", stringify!(siginfo_t)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(siginfo_t)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_signo) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t), + "::", + stringify!(si_signo) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_errno) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t), + "::", + stringify!(si_errno) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).si_code) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t), + "::", + stringify!(si_code) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__si_fields) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(siginfo_t), + "::", + stringify!(__si_fields) + ) + ); +} +impl Default for siginfo_t { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct __sigset_t { + pub __bits: [::core::ffi::c_ulong; 16usize], +} +#[test] +fn bindgen_test_layout___sigset_t() { + const UNINIT: ::core::mem::MaybeUninit<__sigset_t> = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::<__sigset_t>(), + 128usize, + concat!("Size of: ", stringify!(__sigset_t)) + ); + assert_eq!( + ::core::mem::align_of::<__sigset_t>(), + 8usize, + concat!("Alignment of ", stringify!(__sigset_t)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__bits) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__sigset_t), + "::", + stringify!(__bits) + ) + ); +} +pub type sigset_t = __sigset_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigaction { + pub __sa_handler: sigaction__bindgen_ty_1, + pub sa_mask: sigset_t, + pub sa_flags: ::core::ffi::c_int, + pub sa_restorer: ::core::option::Option, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigaction__bindgen_ty_1 { + pub sa_handler: ::core::option::Option, + pub sa_sigaction: ::core::option::Option< + unsafe extern "C" fn( + arg1: ::core::ffi::c_int, + arg2: *mut siginfo_t, + arg3: *mut ::core::ffi::c_void, + ), + >, +} +#[test] +fn bindgen_test_layout_sigaction__bindgen_ty_1() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(sigaction__bindgen_ty_1)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(sigaction__bindgen_ty_1)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sa_handler) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sigaction__bindgen_ty_1), + "::", + stringify!(sa_handler) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sa_sigaction) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sigaction__bindgen_ty_1), + "::", + stringify!(sa_sigaction) + ) + ); +} +impl Default for sigaction__bindgen_ty_1 { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[test] +fn bindgen_test_layout_sigaction() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 152usize, + concat!("Size of: ", stringify!(sigaction)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(sigaction)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__sa_handler) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sigaction), + "::", + stringify!(__sa_handler) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sa_mask) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(sigaction), + "::", + stringify!(sa_mask) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sa_flags) as usize - ptr as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(sigaction), + "::", + stringify!(sa_flags) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sa_restorer) as usize - ptr as usize }, + 144usize, + concat!( + "Offset of field: ", + stringify!(sigaction), + "::", + stringify!(sa_restorer) + ) + ); +} +impl Default for sigaction { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union epoll_data { + pub ptr: *mut ::core::ffi::c_void, + pub fd: ::core::ffi::c_int, + pub u32_: u32, + pub u64_: u64, +} +#[test] +fn bindgen_test_layout_epoll_data() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(epoll_data)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(epoll_data)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).ptr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(epoll_data), + "::", + stringify!(ptr) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).fd) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(epoll_data), + "::", + stringify!(fd) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).u32_) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(epoll_data), + "::", + stringify!(u32_) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).u64_) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(epoll_data), + "::", + stringify!(u64_) + ) + ); +} +impl Default for epoll_data { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +pub type epoll_data_t = epoll_data; +#[repr(C, packed)] +#[derive(Copy, Clone)] +pub struct epoll_event { + pub events: u32, + pub data: epoll_data_t, +} +#[test] +fn bindgen_test_layout_epoll_event() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 12usize, + concat!("Size of: ", stringify!(epoll_event)) + ); + assert_eq!( + ::core::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(epoll_event)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).events) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(epoll_event), + "::", + stringify!(events) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).data) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(epoll_event), + "::", + stringify!(data) + ) + ); +} +impl Default for epoll_event { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} +pub type rlim_t = ::core::ffi::c_ulonglong; +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct rlimit { + pub rlim_cur: rlim_t, + pub rlim_max: rlim_t, +} +#[test] +fn bindgen_test_layout_rlimit() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(rlimit)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(rlimit)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).rlim_cur) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(rlimit), + "::", + stringify!(rlim_cur) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).rlim_max) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(rlimit), + "::", + stringify!(rlim_max) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct fd_set { + pub fds_bits: [::core::ffi::c_ulong; 16usize], +} +#[test] +fn bindgen_test_layout_fd_set() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 128usize, + concat!("Size of: ", stringify!(fd_set)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(fd_set)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).fds_bits) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(fd_set), + "::", + stringify!(fds_bits) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct stat { + pub st_dev: dev_t, + pub st_ino: ino_t, + pub st_mode: mode_t, + pub st_nlink: nlink_t, + pub st_uid: uid_t, + pub st_gid: gid_t, + pub st_rdev: dev_t, + pub st_size: off_t, + pub st_blksize: blksize_t, + pub st_blocks: blkcnt_t, + pub st_atime: timespec, + pub st_mtime: timespec, + pub st_ctime: timespec, +} +#[test] +fn bindgen_test_layout_stat() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 112usize, + concat!("Size of: ", stringify!(stat)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(stat)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_dev) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_dev) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_ino) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_ino) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_mode) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_mode) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_nlink) as usize - ptr as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_nlink) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_uid) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_uid) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_gid) as usize - ptr as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_gid) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_rdev) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_rdev) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_size) as usize - ptr as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_size) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_blksize) as usize - ptr as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_blksize) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_blocks) as usize - ptr as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_blocks) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_atime) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_atime) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_mtime) as usize - ptr as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_mtime) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_ctime) as usize - ptr as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(stat), + "::", + stringify!(st_ctime) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct kstat { + pub st_dev: dev_t, + pub st_ino: ino_t, + pub st_nlink: nlink_t, + pub st_mode: mode_t, + pub st_uid: uid_t, + pub st_gid: gid_t, + pub __pad0: ::core::ffi::c_uint, + pub st_rdev: dev_t, + pub st_size: off_t, + pub st_blksize: blksize_t, + pub st_blocks: blkcnt_t, + pub st_atime_sec: ::core::ffi::c_long, + pub st_atime_nsec: ::core::ffi::c_long, + pub st_mtime_sec: ::core::ffi::c_long, + pub st_mtime_nsec: ::core::ffi::c_long, + pub st_ctime_sec: ::core::ffi::c_long, + pub st_ctime_nsec: ::core::ffi::c_long, + pub __unused: [::core::ffi::c_long; 3usize], +} +#[test] +fn bindgen_test_layout_kstat() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 144usize, + concat!("Size of: ", stringify!(kstat)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(kstat)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_dev) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_dev) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_ino) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_ino) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_nlink) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_nlink) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_mode) as usize - ptr as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_mode) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_uid) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_uid) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_gid) as usize - ptr as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_gid) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__pad0) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(__pad0) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_rdev) as usize - ptr as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_rdev) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_size) as usize - ptr as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_size) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_blksize) as usize - ptr as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_blksize) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_blocks) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_blocks) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_atime_sec) as usize - ptr as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_atime_sec) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_atime_nsec) as usize - ptr as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_atime_nsec) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_mtime_sec) as usize - ptr as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_mtime_sec) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_mtime_nsec) as usize - ptr as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_mtime_nsec) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_ctime_sec) as usize - ptr as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_ctime_sec) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).st_ctime_nsec) as usize - ptr as usize }, + 112usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(st_ctime_nsec) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).__unused) as usize - ptr as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(kstat), + "::", + stringify!(__unused) + ) + ); +} +#[repr(C)] +#[derive(Debug, Default)] +pub struct sysinfo { + pub uptime: ::core::ffi::c_long, + pub loads: [::core::ffi::c_ulong; 3usize], + pub totalram: ::core::ffi::c_ulong, + pub freeram: ::core::ffi::c_ulong, + pub sharedram: ::core::ffi::c_ulong, + pub bufferram: ::core::ffi::c_ulong, + pub totalswap: ::core::ffi::c_ulong, + pub freeswap: ::core::ffi::c_ulong, + pub procs: ::core::ffi::c_ushort, + pub pad: ::core::ffi::c_ushort, + pub totalhigh: ::core::ffi::c_ulong, + pub freehigh: ::core::ffi::c_ulong, + pub mem_unit: ::core::ffi::c_uint, + pub _f: __IncompleteArrayField<::core::ffi::c_char>, +} +#[test] +fn bindgen_test_layout_sysinfo() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 112usize, + concat!("Size of: ", stringify!(sysinfo)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(sysinfo)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).uptime) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(uptime) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).loads) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(loads) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).totalram) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(totalram) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).freeram) as usize - ptr as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(freeram) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).sharedram) as usize - ptr as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(sharedram) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).bufferram) as usize - ptr as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(bufferram) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).totalswap) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(totalswap) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).freeswap) as usize - ptr as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(freeswap) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).procs) as usize - ptr as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(procs) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).pad) as usize - ptr as usize }, + 82usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(pad) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).totalhigh) as usize - ptr as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(totalhigh) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).freehigh) as usize - ptr as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(freehigh) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).mem_unit) as usize - ptr as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(mem_unit) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr)._f) as usize - ptr as usize }, + 108usize, + concat!( + "Offset of field: ", + stringify!(sysinfo), + "::", + stringify!(_f) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct iovec { + pub iov_base: *mut ::core::ffi::c_void, + pub iov_len: size_t, +} +#[test] +fn bindgen_test_layout_iovec() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(iovec)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(iovec)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).iov_base) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(iovec), + "::", + stringify!(iov_base) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).iov_len) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(iovec), + "::", + stringify!(iov_len) + ) + ); +} +impl Default for iovec { + fn default() -> Self { + let mut s = ::core::mem::MaybeUninit::::uninit(); + unsafe { + ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); + s.assume_init() + } + } +} diff --git a/apps/c/httpserver_loopback/axbuild.mk b/apps/c/httpserver_loopback/axbuild.mk new file mode 100644 index 000000000..c30772479 --- /dev/null +++ b/apps/c/httpserver_loopback/axbuild.mk @@ -0,0 +1 @@ +app-objs := httpserver.o diff --git a/apps/c/httpserver_loopback/features.txt b/apps/c/httpserver_loopback/features.txt new file mode 100644 index 000000000..61954150d --- /dev/null +++ b/apps/c/httpserver_loopback/features.txt @@ -0,0 +1,4 @@ +alloc +paging +net +multitask diff --git a/apps/c/httpserver_loopback/httpserver.c b/apps/c/httpserver_loopback/httpserver.c new file mode 100644 index 000000000..e8af1fd10 --- /dev/null +++ b/apps/c/httpserver_loopback/httpserver.c @@ -0,0 +1,139 @@ +/* Copyright (c) [2023] [Syswonder Community] + * [Ruxos] is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define PORT 5555 +#define BUFFER_SIZE 1024 + +void *handle_client(void *arg) { + int new_socket = *(int*)arg; + char buffer[BUFFER_SIZE] = {0}; + + read(new_socket, buffer, BUFFER_SIZE); + printf("Server received: %s\n", buffer); + send(new_socket, "Hello from server", strlen("Hello from server"), 0); + printf("Server sent: %s\n", "Hello from server"); + + close(new_socket); + free(arg); // Free the allocated memory for the socket + + return NULL; +} + +void *server_thread(void *arg) { + int server_fd, *new_socket; + struct sockaddr_in address; + int addrlen = sizeof(address); + + if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { + perror("Socket failed"); + exit(EXIT_FAILURE); + } + + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(PORT); + + if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { + perror("Bind failed"); + close(server_fd); + exit(EXIT_FAILURE); + } + + if (listen(server_fd, 3) < 0) { + perror("Listen failed"); + close(server_fd); + exit(EXIT_FAILURE); + } + + printf("Server listening on 127.0.0.1:%d\n", PORT); + + while (1) { + new_socket = malloc(sizeof(int)); + if ((*new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { + perror("Accept failed"); + free(new_socket); + continue; + } + + pthread_t client_thread; + if (pthread_create(&client_thread, NULL, handle_client, new_socket) != 0) { + perror("Failed to create client thread"); + free(new_socket); + } + } + + close(server_fd); + + return NULL; +} + +void *client_thread(void *arg) { + sleep(1); // Ensure the server is listening before the client tries to connect + + struct sockaddr_in serv_addr; + char *message = "Hello from client"; + char buffer[BUFFER_SIZE] = {0}; + int sock = 0; + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("Socket creation error"); + return NULL; + } + + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(PORT); + + if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { + perror("Invalid address / Address not supported"); + close(sock); + return NULL; + } + + if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + perror("Connection failed"); + close(sock); + return NULL; + } + + send(sock, message, strlen(message), 0); + printf("Client sent: %s\n", message); + read(sock, buffer, BUFFER_SIZE); + printf("Client received: %s\n", buffer); + + close(sock); + + return NULL; +} + +int main() { + pthread_t server_tid, client_tid; + + if (pthread_create(&server_tid, NULL, server_thread, NULL) != 0) { + perror("Failed to create server thread"); + exit(EXIT_FAILURE); + } + + if (pthread_create(&client_tid, NULL, client_thread, NULL) != 0) { + perror("Failed to create client thread"); + exit(EXIT_FAILURE); + } + + pthread_join(server_tid, NULL); + pthread_join(client_tid, NULL); + + return 0; +} diff --git a/crates/driver_net/src/lib.rs b/crates/driver_net/src/lib.rs index 6fd20c600..2f7faae2e 100644 --- a/crates/driver_net/src/lib.rs +++ b/crates/driver_net/src/lib.rs @@ -20,6 +20,8 @@ use alloc::sync::Arc; #[cfg(feature = "ixgbe")] /// ixgbe NIC device driver. pub mod ixgbe; +/// loopback device driver +pub mod loopback; mod net_buf; use core::ptr::NonNull; diff --git a/crates/driver_net/src/loopback.rs b/crates/driver_net/src/loopback.rs new file mode 100644 index 000000000..2c745f942 --- /dev/null +++ b/crates/driver_net/src/loopback.rs @@ -0,0 +1,126 @@ +/* Copyright (c) [2023] [Syswonder Community] +* [Ruxos] is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ +use crate::{EthernetAddress, NetBuf, NetBufBox, NetBufPool, NetBufPtr, NetDriverOps}; +use alloc::collections::VecDeque; +use alloc::sync::Arc; +use driver_common::{BaseDriverOps, DevError, DevResult, DeviceType}; + +extern crate alloc; + +const NET_BUF_LEN: usize = 1526; + +/// The VirtIO network device driver. +/// +/// `QS` is the VirtIO queue size. +pub struct LoopbackDevice { + mac_address: EthernetAddress, + pub(crate) queue: VecDeque, + buf_pool: Arc, +} + +unsafe impl Send for LoopbackDevice {} +unsafe impl Sync for LoopbackDevice {} + +impl LoopbackDevice { + /// Creates a new driver instance and initializes the device + pub fn new(mac_address: [u8; 6]) -> Self { + let buf_pool = match NetBufPool::new(1024, NET_BUF_LEN) { + Ok(pool) => pool, + Err(_) => { + panic!("fail to create netbufpool"); + } + }; + Self { + mac_address: EthernetAddress(mac_address), + queue: VecDeque::new(), + buf_pool: buf_pool, + } + } +} + +impl BaseDriverOps for LoopbackDevice { + fn device_name(&self) -> &str { + "loopback" + } + + fn device_type(&self) -> DeviceType { + DeviceType::Net + } +} + +impl NetDriverOps for LoopbackDevice { + #[inline] + fn mac_address(&self) -> EthernetAddress { + EthernetAddress(self.mac_address.0) + } + + #[inline] + fn can_transmit(&self) -> bool { + true + } + + #[inline] + fn can_receive(&self) -> bool { + !self.queue.is_empty() + } + + #[inline] + fn rx_queue_size(&self) -> usize { + self.queue.len() + } + + #[inline] + fn tx_queue_size(&self) -> usize { + self.queue.len() + } + + fn fill_rx_buffers(&mut self, buf_pool: &Arc) -> DevResult { + Ok(()) + } + + fn recycle_rx_buffer(&mut self, rx_buf: NetBufPtr) -> DevResult { + Ok(()) + } + + fn recycle_tx_buffers(&mut self) -> DevResult { + Ok(()) + } + + fn prepare_tx_buffer(&self, tx_buf: &mut NetBuf, pkt_len: usize) -> DevResult { + Ok(()) + } + + fn transmit(&mut self, tx_buf: NetBufPtr) -> DevResult { + unsafe { self.queue.push_back(NetBuf::from_buf_ptr(tx_buf)) } + Ok(()) + } + + fn receive(&mut self) -> DevResult { + if let Some(token) = self.queue.pop_front() { + Ok(token.into_buf_ptr()) + } else { + Err(DevError::Again) + } + } + + fn alloc_tx_buffer(&mut self, size: usize) -> DevResult { + let mut net_buf = self.buf_pool.alloc_boxed().ok_or(DevError::NoMemory)?; + let pkt_len = size; + + // 1. Check if the buffer is large enough. + let hdr_len = net_buf.header_len(); + if hdr_len + pkt_len > net_buf.capacity() { + return Err(DevError::InvalidParam); + } + net_buf.set_packet_len(pkt_len); + + // 2. Return the buffer. + Ok(net_buf.into_buf_ptr()) + } +} diff --git a/modules/ruxfs/Cargo.toml b/modules/ruxfs/Cargo.toml index 0ca624616..88e7415d9 100644 --- a/modules/ruxfs/Cargo.toml +++ b/modules/ruxfs/Cargo.toml @@ -55,7 +55,7 @@ features = [ # no std ] [dev-dependencies] -ruxdriver = { path = "../ruxdriver", features = ["block", "ramdisk"] } +ruxdriver = { path = "../ruxdriver", features = ["block", "ramdisk", "dyn"] } driver_block = { path = "../../crates/driver_block", features = ["ramdisk"] } axsync = { path = "../axsync", features = ["multitask"] } ruxtask = { path = "../ruxtask", features = ["test"] } diff --git a/modules/ruxfs/tests/test_fatfs.rs b/modules/ruxfs/tests/test_fatfs.rs index da542c00a..88d844882 100644 --- a/modules/ruxfs/tests/test_fatfs.rs +++ b/modules/ruxfs/tests/test_fatfs.rs @@ -33,7 +33,9 @@ fn test_fatfs() { // By default, mount_points[0] will be rootfs let mut mount_points: Vec = Vec::new(); // setup and initialize blkfs as one mountpoint for rootfs - mount_points.push(ruxfs::init_blkfs(AxDeviceContainer::from_one(disk))); + mount_points.push(ruxfs::init_blkfs(AxDeviceContainer::from_one(Box::new( + disk, + )))); ruxfs::prepare_commonfs(&mut mount_points); // setup and initialize rootfs diff --git a/modules/ruxfs/tests/test_ramfs.rs b/modules/ruxfs/tests/test_ramfs.rs index da93bff19..61c57a45d 100644 --- a/modules/ruxfs/tests/test_ramfs.rs +++ b/modules/ruxfs/tests/test_ramfs.rs @@ -58,9 +58,9 @@ fn test_ramfs() { // By default, mount_points[0] will be rootfs let mut mount_points: Vec = Vec::new(); // setup and initialize blkfs as one mountpoint for rootfs - mount_points.push(ruxfs::init_blkfs(AxDeviceContainer::from_one( + mount_points.push(ruxfs::init_blkfs(AxDeviceContainer::from_one(Box::new( RamDisk::default(), - ))); + )))); ruxfs::prepare_commonfs(&mut mount_points); // setup and initialize rootfs diff --git a/modules/ruxnet/Cargo.toml b/modules/ruxnet/Cargo.toml index 3c81a2510..9e2a7f4e5 100644 --- a/modules/ruxnet/Cargo.toml +++ b/modules/ruxnet/Cargo.toml @@ -27,7 +27,7 @@ ruxhal = { path = "../ruxhal" } axsync = { path = "../axsync" } axlog = { path = "../axlog" } ruxtask = { path = "../ruxtask" } -ruxdriver = { path = "../ruxdriver", features = ["net"] } +ruxdriver = { path = "../ruxdriver", features = ["net", "dyn"] } cty = { version = "0.2.2", optional = true } axio = { path = "../../crates/axio" } diff --git a/modules/ruxnet/src/smoltcp_impl/dns.rs b/modules/ruxnet/src/smoltcp_impl/dns.rs index 00b7c0575..0d1fcfeeb 100644 --- a/modules/ruxnet/src/smoltcp_impl/dns.rs +++ b/modules/ruxnet/src/smoltcp_impl/dns.rs @@ -1,12 +1,13 @@ /* Copyright (c) [2023] [Syswonder Community] - * [Ruxos] is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ +* [Ruxos] is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ +use alloc::string::ToString; use alloc::vec::Vec; use axerrno::{ax_err_type, AxError, AxResult}; use core::net::IpAddr; @@ -28,16 +29,18 @@ impl DnsSocket { /// Creates a new DNS socket. pub fn new() -> Self { let socket = SocketSetWrapper::new_dns_socket(); - let handle = Some(SOCKET_SET.add(socket)); + let handle = Some(SOCKET_SET.add(socket, ETH0.name().to_string())); Self { handle } } #[allow(dead_code)] /// Update the list of DNS servers, will replace all existing servers. pub fn update_servers(self, servers: &[smoltcp::wire::IpAddress]) { - SOCKET_SET.with_socket_mut::(self.handle.unwrap(), |socket| { - socket.update_servers(servers) - }); + SOCKET_SET.with_socket_mut::( + self.handle.unwrap(), + ETH0.name().to_string(), + |socket| socket.update_servers(servers), + ); } /// Query a address with given DNS query type. @@ -46,7 +49,7 @@ impl DnsSocket { let handle = self.handle.ok_or_else(|| ax_err_type!(InvalidInput))?; let iface = Ð0.iface; let query_handle = SOCKET_SET - .with_socket_mut::(handle, |socket| { + .with_socket_mut::(handle, ETH0.name().to_string(), |socket| { socket.start_query(iface.lock().context(), name, query_type) }) .map_err(|e| match e { @@ -62,14 +65,18 @@ impl DnsSocket { })?; loop { SOCKET_SET.poll_interfaces(); - match SOCKET_SET.with_socket_mut::(handle, |socket| { - socket.get_query_result(query_handle).map_err(|e| match e { - GetQueryResultError::Pending => AxError::WouldBlock, - GetQueryResultError::Failed => { - ax_err_type!(ConnectionRefused, "socket query() failed") - } - }) - }) { + match SOCKET_SET.with_socket_mut::( + handle, + ETH0.name().to_string(), + |socket| { + socket.get_query_result(query_handle).map_err(|e| match e { + GetQueryResultError::Pending => AxError::WouldBlock, + GetQueryResultError::Failed => { + ax_err_type!(ConnectionRefused, "socket query() failed") + } + }) + }, + ) { Ok(n) => { let mut res = Vec::with_capacity(n.capacity()); for ip in n { @@ -87,7 +94,7 @@ impl DnsSocket { impl Drop for DnsSocket { fn drop(&mut self) { if let Some(handle) = self.handle { - SOCKET_SET.remove(handle); + SOCKET_SET.remove(handle, ETH0.name().to_string()); } } } diff --git a/modules/ruxnet/src/smoltcp_impl/listen_table.rs b/modules/ruxnet/src/smoltcp_impl/listen_table.rs index a89b20d02..8d9537b95 100644 --- a/modules/ruxnet/src/smoltcp_impl/listen_table.rs +++ b/modules/ruxnet/src/smoltcp_impl/listen_table.rs @@ -1,12 +1,13 @@ /* Copyright (c) [2023] [Syswonder Community] - * [Ruxos] is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ - +* [Ruxos] is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +use alloc::string::String; use alloc::{boxed::Box, collections::VecDeque}; use core::ops::{Deref, DerefMut}; @@ -16,13 +17,13 @@ use smoltcp::iface::{SocketHandle, SocketSet}; use smoltcp::socket::tcp::{self, State}; use smoltcp::wire::{IpAddress, IpEndpoint, IpListenEndpoint}; -use super::{SocketSetWrapper, LISTEN_QUEUE_SIZE, SOCKET_SET}; +use super::{route_dev, to_static_str, SocketSetWrapper, ETH0, LISTEN_QUEUE_SIZE, LO, SOCKET_SET}; const PORT_NUM: usize = 65536; struct ListenTableEntry { listen_endpoint: IpListenEndpoint, - syn_queue: VecDeque, + syn_queue: VecDeque<(SocketHandle, String)>, } impl ListenTableEntry { @@ -44,8 +45,8 @@ impl ListenTableEntry { impl Drop for ListenTableEntry { fn drop(&mut self) { - for &handle in &self.syn_queue { - SOCKET_SET.remove(handle); + for handle in &self.syn_queue { + SOCKET_SET.remove(handle.0, handle.1.clone()); } } } @@ -89,7 +90,10 @@ impl ListenTable { pub fn can_accept(&self, port: u16) -> AxResult { if let Some(entry) = self.tcp[port as usize].lock().deref() { - Ok(entry.syn_queue.iter().any(|&handle| is_connected(handle))) + Ok(entry + .syn_queue + .iter() + .any(|handle| is_connected(handle.0, handle.1.clone()))) } else { ax_err!(InvalidInput, "socket accept() failed: not listen") } @@ -101,8 +105,9 @@ impl ListenTable { let (idx, addr_tuple) = syn_queue .iter() .enumerate() - .find_map(|(idx, &handle)| { - is_connected(handle).then(|| (idx, get_addr_tuple(handle))) + .find_map(|(idx, handle)| { + is_connected(handle.0, handle.1.clone()) + .then(|| (idx, get_addr_tuple(handle.0, handle.1.clone()))) }) .ok_or(AxError::WouldBlock)?; // wait for connection if idx > 0 { @@ -113,7 +118,7 @@ impl ListenTable { ); } let handle = syn_queue.swap_remove_front(idx).unwrap(); - Ok((handle, addr_tuple)) + Ok((handle.0, addr_tuple)) } else { ax_err!(InvalidInput, "socket accept() failed: not listen") } @@ -142,20 +147,24 @@ impl ListenTable { "TCP socket {}: prepare for connection {} -> {}", handle, src, entry.listen_endpoint ); - entry.syn_queue.push_back(handle); + let iface_name = match dst.addr { + IpAddress::Ipv4(addr) => route_dev(addr.0), + _ => panic!("IPv6 not supported"), + }; + entry.syn_queue.push_back((handle, iface_name)); } } } } -fn is_connected(handle: SocketHandle) -> bool { - SOCKET_SET.with_socket::(handle, |socket| { +fn is_connected(handle: SocketHandle, iface_name: String) -> bool { + SOCKET_SET.with_socket::(handle, iface_name, |socket| { !matches!(socket.state(), State::Listen | State::SynReceived) }) } -fn get_addr_tuple(handle: SocketHandle) -> (IpEndpoint, IpEndpoint) { - SOCKET_SET.with_socket::(handle, |socket| { +fn get_addr_tuple(handle: SocketHandle, iface_name: String) -> (IpEndpoint, IpEndpoint) { + SOCKET_SET.with_socket::(handle, iface_name, |socket| { ( socket.local_endpoint().unwrap(), socket.remote_endpoint().unwrap(), diff --git a/modules/ruxnet/src/smoltcp_impl/mod.rs b/modules/ruxnet/src/smoltcp_impl/mod.rs index da911f2f7..dc3b5ffea 100644 --- a/modules/ruxnet/src/smoltcp_impl/mod.rs +++ b/modules/ruxnet/src/smoltcp_impl/mod.rs @@ -14,6 +14,8 @@ mod listen_table; mod tcp; mod udp; +use alloc::boxed::Box; +use alloc::string::{String, ToString}; use alloc::vec; use core::cell::RefCell; use core::ops::DerefMut; @@ -35,6 +37,8 @@ pub use self::dns::dns_query; pub use self::tcp::TcpSocket; pub use self::udp::UdpSocket; +pub use driver_net::loopback::LoopbackDevice; + macro_rules! env_or_default { ($key:literal) => { match option_env!($key) { @@ -62,8 +66,25 @@ const LISTEN_QUEUE_SIZE: usize = 512; static LISTEN_TABLE: LazyInit = LazyInit::new(); static SOCKET_SET: LazyInit = LazyInit::new(); static ETH0: LazyInit = LazyInit::new(); +static LO: LazyInit = LazyInit::new(); //loopback net device +static STRING_POOL: LazyInit>> = LazyInit::new(); + +fn to_static_str(s: String) -> &'static str { + let mut pool = STRING_POOL.lock(); + pool.push(s); + let s_ref = pool.last().unwrap(); + unsafe { &*(s_ref.as_str() as *const str) } +} + +fn route_dev(addr: [u8; 4]) -> String { + if addr[0] == 127 { + LO.name().to_string() + } else { + ETH0.name().to_string() + } +} -struct SocketSetWrapper<'a>(Mutex>); +struct SocketSetWrapper<'a>(vec::Vec<(Mutex>, &'a str)>); struct DeviceWrapper { inner: RefCell, // use `RefCell` is enough since it's wrapped in `Mutex` in `InterfaceWrapper`. @@ -78,7 +99,11 @@ struct InterfaceWrapper { impl<'a> SocketSetWrapper<'a> { fn new() -> Self { - Self(Mutex::new(SocketSet::new(vec![]))) + Self(vec::Vec::new()) + } + + fn add_iface(&mut self, name: &'a str) { + self.0.push((Mutex::new(SocketSet::new(vec![])), name)) } pub fn new_tcp_socket() -> socket::tcp::Socket<'a> { @@ -104,36 +129,81 @@ impl<'a> SocketSetWrapper<'a> { socket::dns::Socket::new(&[server_addr], vec![]) } - pub fn add>(&self, socket: T) -> SocketHandle { - let handle = self.0.lock().add(socket); + pub fn add>(&self, socket: T, name: String) -> SocketHandle { + let handle = self + .0 + .iter() + .find(|socketset| socketset.1 == name) + .unwrap() + .0 + .lock() + .add(socket); debug!("socket {}: created", handle); handle } - pub fn with_socket, R, F>(&self, handle: SocketHandle, f: F) -> R + pub fn with_socket, R, F>(&self, handle: SocketHandle, name: String, f: F) -> R where F: FnOnce(&T) -> R, { - let set = self.0.lock(); + let set = self + .0 + .iter() + .find(|socketset| socketset.1 == name) + .unwrap() + .0 + .lock(); let socket = set.get(handle); f(socket) } - pub fn with_socket_mut, R, F>(&self, handle: SocketHandle, f: F) -> R + pub fn with_socket_mut, R, F>( + &self, + handle: SocketHandle, + name: String, + f: F, + ) -> R where F: FnOnce(&mut T) -> R, { - let mut set = self.0.lock(); + let mut set = self + .0 + .iter() + .find(|socketset| socketset.1 == name) + .unwrap() + .0 + .lock(); let socket = set.get_mut(handle); f(socket) } pub fn poll_interfaces(&self) { - ETH0.poll(&self.0); + LO.poll( + &self + .0 + .iter() + .find(|socketset| socketset.1 == LO.name()) + .unwrap() + .0, + ); + ETH0.poll( + &self + .0 + .iter() + .find(|socketset| socketset.1 == ETH0.name()) + .unwrap() + .0, + ); } - pub fn remove(&self, handle: SocketHandle) { - self.0.lock().remove(handle); + pub fn remove(&self, handle: SocketHandle, name: String) { + self.0 + .iter() + .find(|socketset| socketset.1 == name) + .unwrap() + .0 + .lock() + .remove(handle); debug!("socket {}: destroyed", handle); } } @@ -328,12 +398,28 @@ pub(crate) fn init(net_dev: AxNetDevice) { eth0.setup_ip_addr(ip, IP_PREFIX); eth0.setup_gateway(gateway); + let lo_addr = EthernetAddress::default(); + let lo_device = LoopbackDevice::new(lo_addr.0); + let lo = InterfaceWrapper::new("lo", Box::new(lo_device), lo_addr); + let local_ip = "127.0.0.1".parse().expect("invalid IP address"); + lo.setup_ip_addr(local_ip, 8); + + let mut socketset = SocketSetWrapper::new(); + socketset.add_iface("lo"); + socketset.add_iface("eth0"); + ETH0.init_by(eth0); - SOCKET_SET.init_by(SocketSetWrapper::new()); + LO.init_by(lo); + SOCKET_SET.init_by(socketset); + STRING_POOL.init_by(Mutex::new(vec::Vec::new())); LISTEN_TABLE.init_by(ListenTable::new()); info!("created net interface {:?}:", ETH0.name()); info!(" ether: {}", ETH0.ethernet_address()); info!(" ip: {}/{}", ip, IP_PREFIX); info!(" gateway: {}", gateway); + + info!("created net interface {:?}:", LO.name()); + info!(" ether: {}", LO.ethernet_address()); + info!(" ip: {}/{}", local_ip, 8); } diff --git a/modules/ruxnet/src/smoltcp_impl/tcp.rs b/modules/ruxnet/src/smoltcp_impl/tcp.rs index de9c14fd5..0dda3797b 100644 --- a/modules/ruxnet/src/smoltcp_impl/tcp.rs +++ b/modules/ruxnet/src/smoltcp_impl/tcp.rs @@ -1,26 +1,28 @@ /* Copyright (c) [2023] [Syswonder Community] - * [Ruxos] is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ +* [Ruxos] is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ use core::cell::UnsafeCell; use core::net::SocketAddr; +use core::str::FromStr; use core::sync::atomic::{AtomicBool, AtomicU8, Ordering}; +use alloc::string::{String, ToString}; use axerrno::{ax_err, ax_err_type, AxError, AxResult}; use axio::PollState; use axsync::Mutex; use smoltcp::iface::SocketHandle; use smoltcp::socket::tcp::{self, ConnectError, State}; -use smoltcp::wire::{IpEndpoint, IpListenEndpoint}; +use smoltcp::wire::{IpAddress, IpEndpoint, IpListenEndpoint}; use super::addr::{from_core_sockaddr, into_core_sockaddr, is_unspecified, UNSPECIFIED_ENDPOINT}; -use super::{SocketSetWrapper, ETH0, LISTEN_TABLE, SOCKET_SET}; +use super::{route_dev, to_static_str, SocketSetWrapper, ETH0, LISTEN_TABLE, LO, SOCKET_SET}; // State transitions: // CLOSED -(connect)-> BUSY -> CONNECTING -> CONNECTED -(shutdown)-> BUSY -> CLOSED @@ -49,7 +51,7 @@ const MSG_DONTWAIT: i32 = 4; /// [`accept`]: TcpSocket::accept pub struct TcpSocket { state: AtomicU8, - handle: UnsafeCell>, + handle: UnsafeCell>, local_addr: UnsafeCell, peer_addr: UnsafeCell, nonblock: AtomicBool, @@ -72,12 +74,13 @@ impl TcpSocket { /// Creates a new TCP socket that is already connected. const fn new_connected( handle: SocketHandle, + name: &'static str, local_addr: IpEndpoint, peer_addr: IpEndpoint, ) -> Self { Self { state: AtomicU8::new(STATE_CONNECTED), - handle: UnsafeCell::new(Some(handle)), + handle: UnsafeCell::new(Some((handle, name))), local_addr: UnsafeCell::new(local_addr), peer_addr: UnsafeCell::new(peer_addr), nonblock: AtomicBool::new(false), @@ -133,15 +136,27 @@ impl TcpSocket { pub fn connect(&self, remote_addr: SocketAddr) -> AxResult { self.update_state(STATE_CLOSED, STATE_CONNECTING, || { // SAFETY: no other threads can read or write these fields. - let handle = unsafe { self.handle.get().read() } - .unwrap_or_else(|| SOCKET_SET.add(SocketSetWrapper::new_tcp_socket())); + let iface_name = match remote_addr { + SocketAddr::V4(addr) => route_dev(addr.ip().octets()), + _ => panic!("IPv6 not supported"), + }; + let iface = match iface_name.as_str() { + "lo" => &LO.iface, + "eth0" => Ð0.iface, + &_ => todo!(), + }; + let handle = unsafe { self.handle.get().read() }.unwrap_or_else(|| { + ( + SOCKET_SET.add(SocketSetWrapper::new_tcp_socket(), iface_name.clone()), + to_static_str(iface_name), + ) + }); // TODO: check remote addr unreachable let remote_endpoint = from_core_sockaddr(remote_addr); let bound_endpoint = self.bound_endpoint()?; - let iface = Ð0.iface; let (local_endpoint, remote_endpoint) = SOCKET_SET - .with_socket_mut::(handle, |socket| { + .with_socket_mut::(handle.0, handle.1.to_string(), |socket| { socket .connect(iface.lock().context(), remote_endpoint, bound_endpoint) .or_else(|e| match e { @@ -208,6 +223,20 @@ impl TcpSocket { return ax_err!(InvalidInput, "socket bind() failed: already bound"); } self.local_addr.get().write(from_core_sockaddr(local_addr)); + let iface_name = match local_addr { + SocketAddr::V4(addr) => route_dev(addr.ip().octets()), + _ => panic!("IPv6 not supported"), + }; + let handle = self.handle.get().read().unwrap_or_else(|| { + ( + SOCKET_SET.add( + SocketSetWrapper::new_tcp_socket(), + String::from_str(LO.name()).unwrap(), + ), + to_static_str(iface_name), + ) + }); + self.handle.get().write(Some(handle)); } Ok(()) }) @@ -247,7 +276,13 @@ impl TcpSocket { self.block_on(|| { let (handle, (local_addr, peer_addr)) = LISTEN_TABLE.accept(local_port)?; debug!("TCP socket accepted a new connection {}", peer_addr); - Ok(TcpSocket::new_connected(handle, local_addr, peer_addr)) + let iface_name = match peer_addr.addr { + IpAddress::Ipv4(addr) => route_dev(addr.0), + _ => panic!("IPv6 not supported"), + }; + let sock = + TcpSocket::new_connected(handle, to_static_str(iface_name), local_addr, peer_addr); + Ok(sock) }) } @@ -258,10 +293,14 @@ impl TcpSocket { // SAFETY: `self.handle` should be initialized in a connected socket, and // no other threads can read or write it. let handle = unsafe { self.handle.get().read().unwrap() }; - SOCKET_SET.with_socket_mut::(handle, |socket| { - debug!("TCP socket {}: shutting down", handle); - socket.close(); - }); + SOCKET_SET.with_socket_mut::( + handle.0, + handle.1.to_string(), + |socket| { + debug!("TCP socket {}: shutting down", handle.0); + socket.close(); + }, + ); unsafe { self.local_addr.get().write(UNSPECIFIED_ENDPOINT) }; // clear bound address SOCKET_SET.poll_interfaces(); Ok(()) @@ -295,35 +334,39 @@ impl TcpSocket { // SAFETY: `self.handle` should be initialized in a connected socket. let handle = unsafe { self.handle.get().read().unwrap() }; self.block_on(|| { - SOCKET_SET.with_socket_mut::(handle, |socket| { - if !socket.is_active() { - // not open - ax_err!(ConnectionRefused, "socket recv() failed") - } else if !socket.may_recv() { - // connection closed - Ok(0) - } else if socket.recv_queue() > 0 { - // data available - // TODO: use socket.recv(|buf| {...}) - if flags & MSG_DONTWAIT != 0 { - self.set_nonblocking(true); - } - if flags & MSG_PEEK != 0 { - let len = socket - .peek_slice(buf) - .map_err(|_| ax_err_type!(BadState, "socket recv() failed"))?; - Ok(len) + SOCKET_SET.with_socket_mut::( + handle.0, + handle.1.to_string(), + |socket| { + if !socket.is_active() { + // not open + ax_err!(ConnectionRefused, "socket recv() failed") + } else if !socket.may_recv() { + // connection closed + Ok(0) + } else if socket.recv_queue() > 0 { + // data available + // TODO: use socket.recv(|buf| {...}) + if flags & MSG_DONTWAIT != 0 { + self.set_nonblocking(true); + } + if flags & MSG_PEEK != 0 { + let len = socket + .peek_slice(buf) + .map_err(|_| ax_err_type!(BadState, "socket recv() failed"))?; + Ok(len) + } else { + let len = socket + .recv_slice(buf) + .map_err(|_| ax_err_type!(BadState, "socket recv() failed"))?; + Ok(len) + } } else { - let len = socket - .recv_slice(buf) - .map_err(|_| ax_err_type!(BadState, "socket recv() failed"))?; - Ok(len) + // no more data + Err(AxError::WouldBlock) } - } else { - // no more data - Err(AxError::WouldBlock) - } - }) + }, + ) }) } @@ -339,22 +382,26 @@ impl TcpSocket { // SAFETY: `self.handle` should be initialized in a connected socket. let handle = unsafe { self.handle.get().read().unwrap() }; self.block_on(|| { - SOCKET_SET.with_socket_mut::(handle, |socket| { - if !socket.is_active() || !socket.may_send() { - // closed by remote - ax_err!(ConnectionReset, "socket send() failed") - } else if socket.can_send() { - // connected, and the tx buffer is not full - // TODO: use socket.send(|buf| {...}) - let len = socket - .send_slice(buf) - .map_err(|_| ax_err_type!(BadState, "socket send() failed"))?; - Ok(len) - } else { - // tx buffer is full - Err(AxError::WouldBlock) - } - }) + SOCKET_SET.with_socket_mut::( + handle.0, + handle.1.to_string(), + |socket| { + if !socket.is_active() || !socket.may_send() { + // closed by remote + ax_err!(ConnectionReset, "socket send() failed") + } else if socket.can_send() { + // connected, and the tx buffer is not full + // TODO: use socket.send(|buf| {...}) + let len = socket + .send_slice(buf) + .map_err(|_| ax_err_type!(BadState, "socket send() failed"))?; + Ok(len) + } else { + // tx buffer is full + Err(AxError::WouldBlock) + } + }, + ) }) } @@ -449,24 +496,26 @@ impl TcpSocket { // SAFETY: `self.handle` should be initialized above. let handle = unsafe { self.handle.get().read().unwrap() }; let writable = - SOCKET_SET.with_socket::(handle, |socket| match socket.state() { - State::SynSent => false, // wait for connection - State::Established => { - self.set_state(STATE_CONNECTED); // connected - debug!( - "TCP socket {}: connected to {}", - handle, - socket.remote_endpoint().unwrap(), - ); - true - } - _ => { - unsafe { - self.local_addr.get().write(UNSPECIFIED_ENDPOINT); - self.peer_addr.get().write(UNSPECIFIED_ENDPOINT); + SOCKET_SET.with_socket::(handle.0, handle.1.to_string(), |socket| { + match socket.state() { + State::SynSent => false, // wait for connection + State::Established => { + self.set_state(STATE_CONNECTED); // connected + debug!( + "TCP socket {}: connected to {}", + handle.0, + socket.remote_endpoint().unwrap(), + ); + true + } + _ => { + unsafe { + self.local_addr.get().write(UNSPECIFIED_ENDPOINT); + self.peer_addr.get().write(UNSPECIFIED_ENDPOINT); + } + self.set_state(STATE_CLOSED); // connection failed + true } - self.set_state(STATE_CLOSED); // connection failed - true } }); Ok(PollState { @@ -478,7 +527,7 @@ impl TcpSocket { fn poll_stream(&self) -> AxResult { // SAFETY: `self.handle` should be initialized in a connected socket. let handle = unsafe { self.handle.get().read().unwrap() }; - SOCKET_SET.with_socket::(handle, |socket| { + SOCKET_SET.with_socket::(handle.0, handle.1.to_string(), |socket| { Ok(PollState { readable: !socket.may_recv() || socket.can_recv(), writable: !socket.may_send() || socket.can_send(), @@ -524,7 +573,7 @@ impl Drop for TcpSocket { self.shutdown().ok(); // Safe because we have mut reference to `self`. if let Some(handle) = unsafe { self.handle.get().read() } { - SOCKET_SET.remove(handle); + SOCKET_SET.remove(handle.0, handle.1.to_string()); } } } diff --git a/modules/ruxnet/src/smoltcp_impl/udp.rs b/modules/ruxnet/src/smoltcp_impl/udp.rs index 5bf098166..86d4dd614 100644 --- a/modules/ruxnet/src/smoltcp_impl/udp.rs +++ b/modules/ruxnet/src/smoltcp_impl/udp.rs @@ -1,15 +1,17 @@ /* Copyright (c) [2023] [Syswonder Community] - * [Ruxos] is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ - +* [Ruxos] is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +use core::cell::UnsafeCell; use core::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use core::sync::atomic::{AtomicBool, Ordering}; +use alloc::string::ToString; use axerrno::{ax_err, ax_err_type, AxError, AxResult}; use axio::PollState; use axsync::Mutex; @@ -20,11 +22,11 @@ use smoltcp::socket::udp::{self, BindError, SendError}; use smoltcp::wire::{IpEndpoint, IpListenEndpoint}; use super::addr::{from_core_sockaddr, into_core_sockaddr, is_unspecified, UNSPECIFIED_ENDPOINT}; -use super::{SocketSetWrapper, SOCKET_SET}; +use super::{route_dev, to_static_str, SocketSetWrapper, SOCKET_SET}; /// A UDP socket that provides POSIX-like APIs. pub struct UdpSocket { - handle: SocketHandle, + handle: UnsafeCell>, local_addr: RwLock>, peer_addr: RwLock>, nonblock: AtomicBool, @@ -34,10 +36,8 @@ impl UdpSocket { /// Creates a new UDP socket. #[allow(clippy::new_without_default)] pub fn new() -> Self { - let socket = SocketSetWrapper::new_udp_socket(); - let handle = SOCKET_SET.add(socket); Self { - handle, + handle: UnsafeCell::new(None), local_addr: RwLock::new(None), peer_addr: RwLock::new(None), nonblock: AtomicBool::new(false), @@ -97,15 +97,29 @@ impl UdpSocket { addr: (!is_unspecified(local_endpoint.addr)).then_some(local_endpoint.addr), port: local_endpoint.port, }; - SOCKET_SET.with_socket_mut::(self.handle, |socket| { - socket.bind(endpoint).or_else(|e| match e { - BindError::InvalidState => ax_err!(AlreadyExists, "socket bind() failed"), - BindError::Unaddressable => ax_err!(InvalidInput, "socket bind() failed"), - }) - })?; + let iface_name = match local_addr { + SocketAddr::V4(addr) => route_dev(addr.ip().octets()), + _ => panic!("IPv6 not supported"), + }; + let handle = unsafe { self.handle.get().read() }.unwrap_or_else(|| { + ( + SOCKET_SET.add(SocketSetWrapper::new_tcp_socket(), iface_name.clone()), + to_static_str(iface_name), + ) + }); + SOCKET_SET.with_socket_mut::( + handle.0, + handle.1.to_string(), + |socket| { + socket.bind(endpoint).or_else(|e| match e { + BindError::InvalidState => ax_err!(AlreadyExists, "socket bind() failed"), + BindError::Unaddressable => ax_err!(InvalidInput, "socket bind() failed"), + }) + }, + )?; *self_local_addr = Some(local_endpoint); - debug!("UDP socket {}: bound on {}", self.handle, endpoint); + debug!("UDP socket {}: bound on {}", handle.0, endpoint); Ok(()) } @@ -151,7 +165,13 @@ impl UdpSocket { } *self_peer_addr = Some(from_core_sockaddr(addr)); - debug!("UDP socket {}: connected to {}", self.handle, addr); + unsafe { + debug!( + "UDP socket {}: connected to {}", + self.handle.get().read().unwrap().0, + addr + ); + } Ok(()) } @@ -181,8 +201,9 @@ impl UdpSocket { /// Close the socket. pub fn shutdown(&self) -> AxResult { - SOCKET_SET.with_socket_mut::(self.handle, |socket| { - debug!("UDP socket {}: shutting down", self.handle); + let handle = unsafe { self.handle.get().read().unwrap() }; + SOCKET_SET.with_socket_mut::(handle.0, handle.1.to_string(), |socket| { + debug!("UDP socket {}: shutting down", handle.0); socket.close(); }); SOCKET_SET.poll_interfaces(); @@ -197,7 +218,8 @@ impl UdpSocket { writable: false, }); } - SOCKET_SET.with_socket_mut::(self.handle, |socket| { + let handle = unsafe { self.handle.get().read().unwrap() }; + SOCKET_SET.with_socket_mut::(handle.0, handle.1.to_string(), |socket| { Ok(PollState { readable: socket.can_recv(), writable: socket.can_send(), @@ -222,22 +244,27 @@ impl UdpSocket { } self.block_on(|| { - SOCKET_SET.with_socket_mut::(self.handle, |socket| { - if socket.can_send() { - socket - .send_slice(buf, remote_endpoint) - .map_err(|e| match e { - SendError::BufferFull => AxError::WouldBlock, - SendError::Unaddressable => { - ax_err_type!(ConnectionRefused, "socket send() failed") - } - })?; - Ok(buf.len()) - } else { - // tx buffer is full - Err(AxError::WouldBlock) - } - }) + let handle = unsafe { self.handle.get().read().unwrap() }; + SOCKET_SET.with_socket_mut::( + handle.0, + handle.1.to_string(), + |socket| { + if socket.can_send() { + socket + .send_slice(buf, remote_endpoint) + .map_err(|e| match e { + SendError::BufferFull => AxError::WouldBlock, + SendError::Unaddressable => { + ax_err_type!(ConnectionRefused, "socket send() failed") + } + })?; + Ok(buf.len()) + } else { + // tx buffer is full + Err(AxError::WouldBlock) + } + }, + ) }) } @@ -250,15 +277,20 @@ impl UdpSocket { } self.block_on(|| { - SOCKET_SET.with_socket_mut::(self.handle, |socket| { - if socket.can_recv() { - // data available - op(socket) - } else { - // no more data - Err(AxError::WouldBlock) - } - }) + let handle = unsafe { self.handle.get().read().unwrap() }; + SOCKET_SET.with_socket_mut::( + handle.0, + handle.1.to_string(), + |socket| { + if socket.can_recv() { + // data available + op(socket) + } else { + // no more data + Err(AxError::WouldBlock) + } + }, + ) }) } @@ -284,7 +316,8 @@ impl UdpSocket { impl Drop for UdpSocket { fn drop(&mut self) { self.shutdown().ok(); - SOCKET_SET.remove(self.handle); + let handle = unsafe { self.handle.get().read().unwrap() }; + SOCKET_SET.remove(handle.0, handle.1.to_string()); } }