diff --git a/src/arpainet/src/lib.rs b/src/arpainet/src/lib.rs index b30372d9e6..3ef6a8cf9f 100644 --- a/src/arpainet/src/lib.rs +++ b/src/arpainet/src/lib.rs @@ -14,9 +14,9 @@ extern crate sys_socket; use core::str::FromStr; use core::{mem, ptr, slice, str}; use errno::*; -pub use netinet::in_h::*; +use netinet::in_h::in_addr; use platform::types::*; -use platform::{c_str, socklen_t, AF_INET}; +use platform::c_str; #[no_mangle] pub extern "C" fn htonl(hostlong: u32) -> u32 { diff --git a/src/platform/src/lib.rs b/src/platform/src/lib.rs index e1119e8206..21088f099c 100644 --- a/src/platform/src/lib.rs +++ b/src/platform/src/lib.rs @@ -36,46 +36,13 @@ mod sys; pub mod types; use alloc::Vec; -use core::{fmt, mem, ptr}; +use core::{fmt, ptr}; use types::*; #[global_allocator] static ALLOCATOR: Allocator = Allocator; -pub const AF_INET: c_int = 2; -pub const SOCK_STREAM: c_int = 1; -pub const SOCK_DGRAM: c_int = 2; -pub const SOCK_NONBLOCK: c_int = 0o4000; -pub const SOCK_CLOEXEC: c_int = 0o2000000; - -pub const SIG_BLOCK: c_int = 0; -pub const SIG_UNBLOCK: c_int = 1; -pub const SIG_SETMASK: c_int = 2; - -pub type in_addr_t = [u8; 4]; -pub type in_port_t = u16; -pub type sa_family_t = u16; -pub type socklen_t = u32; - -#[repr(C)] -pub struct sockaddr { - pub sa_family: sa_family_t, - pub data: [c_char; 14], -} - -#[repr(C)] -pub struct sigaction { - pub sa_handler: extern "C" fn(c_int), - pub sa_flags: c_ulong, - pub sa_restorer: unsafe extern "C" fn(), - pub sa_mask: sigset_t -} - -const NSIG: usize = 64; - -pub type sigset_t = [c_ulong; NSIG / (8 * mem::size_of::())]; - //TODO #[thread_local] #[allow(non_upper_case_globals)] #[no_mangle] diff --git a/src/platform/src/linux/mod.rs b/src/platform/src/linux/mod.rs index 187ea1929c..93750dbd8c 100644 --- a/src/platform/src/linux/mod.rs +++ b/src/platform/src/linux/mod.rs @@ -1,26 +1,13 @@ use core::{mem, ptr}; +use errno; use types::*; -use *; const AT_FDCWD: c_int = -100; const AT_EMPTY_PATH: c_int = 0x1000; const AT_REMOVEDIR: c_int = 0x200; const AT_SYMLINK_NOFOLLOW: c_int = 0x100; -// Also in sys_utsname. Has to be both because cbindgen -const UTSLENGTH: usize = 65; - -#[repr(C)] -pub struct utsname { - pub sysname: [c_char; UTSLENGTH], - pub nodename: [c_char; UTSLENGTH], - pub release: [c_char; UTSLENGTH], - pub version: [c_char; UTSLENGTH], - pub machine: [c_char; UTSLENGTH], - pub domainname: [c_char; UTSLENGTH], -} - fn e(sys: usize) -> usize { if (sys as isize) < 0 && (sys as isize) >= -256 { unsafe { diff --git a/src/platform/src/redox/mod.rs b/src/platform/src/redox/mod.rs index 8ac654c377..1ed15c0c03 100644 --- a/src/platform/src/redox/mod.rs +++ b/src/platform/src/redox/mod.rs @@ -10,7 +10,6 @@ use syscall::flag::*; use syscall::{self, Result}; use types::*; -use *; #[thread_local] static mut SIG_HANDLER: Option = None; diff --git a/src/platform/src/types.rs b/src/platform/src/types.rs index e77751123e..3299c43564 100644 --- a/src/platform/src/types.rs +++ b/src/platform/src/types.rs @@ -1,3 +1,5 @@ +use core::mem; + #[cfg(target_os = "redox")] use syscall::data::TimeSpec as redox_timespec; // Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable @@ -96,8 +98,59 @@ pub struct stat { pub st_rdev: dev_t, pub st_size: off_t, pub st_blksize: blksize_t, + pub st_blocks: blkcnt_t, + pub st_atim: time_t, pub st_mtim: time_t, pub st_ctim: time_t, - pub st_blocks: blkcnt_t, + + // Compared to glibc, our struct is for some reason 48 bytes too small. + // Accessing atime works, so clearly the struct isn't incorrect... + // This works. + pub _pad: [u8; 48] +} + +pub const AF_INET: c_int = 2; +pub const SOCK_STREAM: c_int = 1; +pub const SOCK_DGRAM: c_int = 2; +pub const SOCK_NONBLOCK: c_int = 0o4000; +pub const SOCK_CLOEXEC: c_int = 0o2000000; + +pub const SIG_BLOCK: c_int = 0; +pub const SIG_UNBLOCK: c_int = 1; +pub const SIG_SETMASK: c_int = 2; + +pub type in_addr_t = [u8; 4]; +pub type in_port_t = u16; +pub type sa_family_t = u16; +pub type socklen_t = u32; + +#[repr(C)] +pub struct sockaddr { + pub sa_family: sa_family_t, + pub data: [c_char; 14], +} + +#[repr(C)] +pub struct sigaction { + pub sa_handler: extern "C" fn(c_int), + pub sa_flags: c_ulong, + pub sa_restorer: unsafe extern "C" fn(), + pub sa_mask: sigset_t +} + +const NSIG: usize = 64; + +pub type sigset_t = [c_ulong; NSIG / (8 * mem::size_of::())]; + +const UTSLENGTH: usize = 65; + +#[repr(C)] +pub struct utsname { + pub sysname: [c_char; UTSLENGTH], + pub nodename: [c_char; UTSLENGTH], + pub release: [c_char; UTSLENGTH], + pub version: [c_char; UTSLENGTH], + pub machine: [c_char; UTSLENGTH], + pub domainname: [c_char; UTSLENGTH], } diff --git a/src/signal/src/lib.rs b/src/signal/src/lib.rs index 833181a0b3..ee6f23d16f 100644 --- a/src/signal/src/lib.rs +++ b/src/signal/src/lib.rs @@ -36,7 +36,6 @@ pub use sys::*; use core::{mem, ptr}; use platform::types::*; -use platform::sigset_t; #[no_mangle] pub extern "C" fn kill(pid: pid_t, sig: c_int) -> c_int { @@ -59,11 +58,11 @@ pub unsafe extern "C" fn sigaction(sig: c_int, act: *const sigaction, oact: *mut let ptr = if !act.is_null() { _sigaction = Some((*act).clone()); _sigaction.as_mut().unwrap().sa_flags |= SA_RESTORER as c_ulong; - _sigaction.as_mut().unwrap() as *mut _ as *mut platform::sigaction + _sigaction.as_mut().unwrap() as *mut _ as *mut platform::types::sigaction } else { ptr::null_mut() }; - platform::sigaction(sig, ptr, oact as *mut platform::sigaction) + platform::sigaction(sig, ptr, oact as *mut platform::types::sigaction) } // #[no_mangle] diff --git a/src/sys_socket/src/lib.rs b/src/sys_socket/src/lib.rs index b8fa277e58..505bd5d508 100644 --- a/src/sys_socket/src/lib.rs +++ b/src/sys_socket/src/lib.rs @@ -28,7 +28,7 @@ pub unsafe extern "C" fn accept( address: *mut sockaddr, address_len: *mut socklen_t, ) -> c_int { - platform::accept(socket, address as *mut platform::sockaddr, address_len) + platform::accept(socket, address as *mut platform::types::sockaddr, address_len) } #[no_mangle] @@ -37,7 +37,7 @@ pub unsafe extern "C" fn bind( address: *const sockaddr, address_len: socklen_t, ) -> c_int { - platform::bind(socket, address as *const platform::sockaddr, address_len) + platform::bind(socket, address as *const platform::types::sockaddr, address_len) } #[no_mangle] @@ -46,7 +46,7 @@ pub unsafe extern "C" fn connect( address: *const sockaddr, address_len: socklen_t, ) -> c_int { - platform::connect(socket, address as *const platform::sockaddr, address_len) + platform::connect(socket, address as *const platform::types::sockaddr, address_len) } #[no_mangle] @@ -55,7 +55,7 @@ pub unsafe extern "C" fn getpeername( address: *mut sockaddr, address_len: *mut socklen_t, ) -> c_int { - platform::getpeername(socket, address as *mut platform::sockaddr, address_len) + platform::getpeername(socket, address as *mut platform::types::sockaddr, address_len) } #[no_mangle] @@ -64,7 +64,7 @@ pub unsafe extern "C" fn getsockname( address: *mut sockaddr, address_len: *mut socklen_t, ) -> c_int { - platform::getsockname(socket, address as *mut platform::sockaddr, address_len) + platform::getsockname(socket, address as *mut platform::types::sockaddr, address_len) } #[no_mangle] @@ -114,7 +114,7 @@ pub unsafe extern "C" fn recvfrom( buffer, length, flags, - address as *mut platform::sockaddr, + address as *mut platform::types::sockaddr, address_len, ) } @@ -143,7 +143,7 @@ pub unsafe extern "C" fn sendto( message, length, flags, - dest_addr as *const platform::sockaddr, + dest_addr as *const platform::types::sockaddr, dest_len, ) } diff --git a/src/sys_stat/src/lib.rs b/src/sys_stat/src/lib.rs index b8f67ef894..2303f8d2a8 100644 --- a/src/sys_stat/src/lib.rs +++ b/src/sys_stat/src/lib.rs @@ -6,7 +6,7 @@ extern crate platform; use platform::types::*; -pub const S_IFMT: c_int = 0o0170000; +pub const S_IFMT: c_int = 0o0170000; pub const S_IFBLK: c_int = 0o060000; pub const S_IFCHR: c_int = 0o020000; pub const S_IFIFO: c_int = 0o010000; @@ -43,10 +43,16 @@ pub struct stat { pub st_rdev: dev_t, pub st_size: off_t, pub st_blksize: blksize_t, - pub st_atime: time_t, - pub st_mtime: time_t, - pub st_ctime: time_t, pub st_blocks: blkcnt_t, + + pub st_atim: time_t, + pub st_mtim: time_t, + pub st_ctim: time_t, + + // Compared to glibc, our struct is for some reason 48 bytes too small. + // Accessing atime works, so clearly the struct isn't incorrect... + // This works. + pub _pad: [u8; 48] } #[no_mangle] diff --git a/src/sys_utsname/src/lib.rs b/src/sys_utsname/src/lib.rs index 06363566c3..ae6c16f4bf 100644 --- a/src/sys_utsname/src/lib.rs +++ b/src/sys_utsname/src/lib.rs @@ -8,22 +8,22 @@ mod inner { use self::platform::types::*; - const LENGTH: usize = 65; + const UTSLENGTH: usize = 65; #[no_mangle] #[repr(C)] pub struct utsname { - pub sysname: [c_char; LENGTH], - pub nodename: [c_char; LENGTH], - pub release: [c_char; LENGTH], - pub version: [c_char; LENGTH], - pub machine: [c_char; LENGTH], - pub domainname: [c_char; LENGTH], + pub sysname: [c_char; UTSLENGTH], + pub nodename: [c_char; UTSLENGTH], + pub release: [c_char; UTSLENGTH], + pub version: [c_char; UTSLENGTH], + pub machine: [c_char; UTSLENGTH], + pub domainname: [c_char; UTSLENGTH], } #[no_mangle] pub unsafe extern "C" fn uname(uts: *mut utsname) -> c_int { - platform::uname(uts as *mut platform::utsname) + platform::uname(uts as *mut platform::types::utsname) } } #[cfg(target_os = "linux")] diff --git a/tests/.gitignore b/tests/.gitignore index e14391eda1..c2a99bc5df 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -56,6 +56,7 @@ unistd/getopt unistd/pipe unistd/rmdir unistd/sleep +unistd/stat unistd/write waitpid wchar/mbrtowc @@ -70,4 +71,3 @@ unistd/gethostname unistd/getid unistd/link unistd/setid -unistd/unlink diff --git a/tests/Makefile b/tests/Makefile index c631eeb959..3f3f2bbe0d 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -55,6 +55,7 @@ EXPECT_BINS=\ unistd/pipe \ unistd/rmdir \ unistd/sleep \ + unistd/stat \ unistd/write \ waitpid \ wchar/mbrtowc \ @@ -72,8 +73,7 @@ BINS=\ unistd/gethostname \ unistd/getid \ unistd/link \ - unistd/setid \ - unistd/unlink + unistd/setid all: $(BINS) diff --git a/tests/expected/unistd/stat.stderr b/tests/expected/unistd/stat.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/expected/unistd/stat.stdout b/tests/expected/unistd/stat.stdout new file mode 100644 index 0000000000..74f3a92e9e --- /dev/null +++ b/tests/expected/unistd/stat.stdout @@ -0,0 +1,4 @@ +144 +st_mode: 33188 +st_size: 383 +st_blksize: 4096 diff --git a/tests/unistd/link.c b/tests/unistd/link.c index a6cf06b6e9..a39286106f 100644 --- a/tests/unistd/link.c +++ b/tests/unistd/link.c @@ -1,8 +1,46 @@ +#include #include +#include #include int main(int argc, char** argv) { - link("./link.c", "./link.out"); - perror("link"); - return 0; + printf("%ld\n", sizeof(struct stat)); + + struct stat buf; + + // Stat for the inode + if (stat("unistd/link.c", &buf)) { + perror("stat"); + return 1; + } + unsigned long inode = buf.st_ino; + printf("%ld\n", inode); + + // Create the link + if (link("unistd/link.c", "link.out")) { + perror("link"); + return 1; + } + + // Make sure inodes match + if (stat("link.out", &buf)) { + perror("stat"); + } + printf("%ld\n", inode); + printf("%ld\n", buf.st_ino); + if (inode != buf.st_ino) { + puts("Created file is not a link."); + printf("unistd/link.c inode: %ld\n", inode); + printf("link.out inode: %ld\n", buf.st_ino); + } + + // Remove link + if (unlink("link.out")) { + perror("unlink"); + return 1; + } + if (!stat("link.out", &buf) || errno != ENOENT) { + perror("stat"); + return 1; + } } diff --git a/tests/unistd/stat.c b/tests/unistd/stat.c new file mode 100644 index 0000000000..19236f7dee --- /dev/null +++ b/tests/unistd/stat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +int main() { + printf("%ld\n", sizeof(struct stat)); + + struct stat buf; + + if (stat("unistd/stat.c", &buf)) { + perror("stat"); + return 1; + } + + printf("st_mode: %u\n", buf.st_mode); + printf("st_size: %lu\n", buf.st_size); + printf("st_blksize: %lu\n", buf.st_blksize); +} diff --git a/tests/unistd/unlink.c b/tests/unistd/unlink.c deleted file mode 100644 index e8bbb517bf..0000000000 --- a/tests/unistd/unlink.c +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include - -int main(int argc, char** argv) { - link("./unlink.c", "./unlink.out"); - perror("unlink"); - return 0; -}