diff --git a/rules/src/modules.rs b/rules/src/modules.rs index 6357cfc6..d2e5d0e9 100644 --- a/rules/src/modules.rs +++ b/rules/src/modules.rs @@ -74,6 +74,8 @@ pub mod string_tgt_unsafe; pub mod unique_ptr_tgt_refcount; #[path = r#"../unique_ptr/tgt_unsafe.rs"#] pub mod unique_ptr_tgt_unsafe; +#[path = r#"../unistd/tgt_unsafe.rs"#] +pub mod unistd_tgt_unsafe; #[path = r#"../vector/tgt_refcount.rs"#] pub mod vector_tgt_refcount; #[path = r#"../vector/tgt_unsafe.rs"#] diff --git a/rules/unistd/ir_unsafe.json b/rules/unistd/ir_unsafe.json new file mode 100644 index 00000000..6d4aaddd --- /dev/null +++ b/rules/unistd/ir_unsafe.json @@ -0,0 +1,354 @@ +{ + "f1": { + "body": [ + { + "text": "libc::close(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": ")" + } + ], + "params": { + "a0": { + "type": "i32" + } + }, + "return_type": { + "type": "i32" + } + }, + "f10": { + "body": [ + { + "text": "libc::write(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": ", " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": ", " + }, + { + "placeholder": { + "arg": 2, + "access": "read" + } + }, + { + "text": " as usize) as i64" + } + ], + "params": { + "a0": { + "type": "i32" + }, + "a1": { + "type": "*const ::libc::c_void", + "is_unsafe_pointer": true + }, + "a2": { + "type": "u64" + } + }, + "return_type": { + "type": "i64" + } + }, + "f11": { + "body": [ + { + "text": "libc::rmdir(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8)" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "i32" + } + }, + "f2": { + "body": [ + { + "text": "libc::lseek(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": ", " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": ", " + }, + { + "placeholder": { + "arg": 2, + "access": "read" + } + }, + { + "text": ")" + } + ], + "params": { + "a0": { + "type": "i32" + }, + "a1": { + "type": "i64" + }, + "a2": { + "type": "i32" + } + }, + "return_type": { + "type": "i64" + } + }, + "f3": { + "body": [ + { + "text": "libc::read(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": ", " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": ", " + }, + { + "placeholder": { + "arg": 2, + "access": "read" + } + }, + { + "text": " as usize) as i64" + } + ], + "params": { + "a0": { + "type": "i32" + }, + "a1": { + "type": "*mut ::libc::c_void", + "is_unsafe_pointer": true + }, + "a2": { + "type": "u64" + } + }, + "return_type": { + "type": "i64" + } + }, + "f4": { + "body": [ + { + "text": "libc::unlink(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8)" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "i32" + } + }, + "f5": { + "body": [ + { + "text": "libc::pipe(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": ")" + } + ], + "params": { + "a0": { + "type": "*mut i32", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "i32" + } + }, + "f6": { + "body": [ + { + "text": "libc::ftruncate(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": ", " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": ")" + } + ], + "params": { + "a0": { + "type": "i32" + }, + "a1": { + "type": "i64" + } + }, + "return_type": { + "type": "i32" + } + }, + "f7": { + "body": [ + { + "text": "libc::isatty(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": ")" + } + ], + "params": { + "a0": { + "type": "i32" + } + }, + "return_type": { + "type": "i32" + } + }, + "f8": { + "body": [ + { + "text": "libc::geteuid()" + } + ], + "return_type": { + "type": "u32" + } + }, + "f9": { + "body": [ + { + "text": "libc::gethostname(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *mut i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as usize)" + } + ], + "params": { + "a0": { + "type": "*mut u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "u64" + } + }, + "return_type": { + "type": "i32" + } + } +} diff --git a/rules/unistd/src.cpp b/rules/unistd/src.cpp new file mode 100644 index 00000000..7b0bd0f7 --- /dev/null +++ b/rules/unistd/src.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +#include + +int f1(int fd) { return close(fd); } + +off_t f2(int fd, off_t offset, int whence) { return lseek(fd, offset, whence); } + +ssize_t f3(int fd, void *buf, size_t count) { return read(fd, buf, count); } + +int f4(const char *pathname) { return unlink(pathname); } + +int f5(int pipefd[2]) { return pipe(pipefd); } + +int f6(int fd, off_t length) { return ftruncate(fd, length); } + +int f7(int fd) { return isatty(fd); } + +uid_t f8(void) { return geteuid(); } + +int f9(char *name, size_t len) { return gethostname(name, len); } + +ssize_t f10(int fd, const void *buf, size_t count) { + return write(fd, buf, count); +} + +int f11(const char *pathname) { return rmdir(pathname); } diff --git a/rules/unistd/tgt_unsafe.rs b/rules/unistd/tgt_unsafe.rs new file mode 100644 index 00000000..674bfcf2 --- /dev/null +++ b/rules/unistd/tgt_unsafe.rs @@ -0,0 +1,46 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +unsafe fn f1(a0: i32) -> i32 { + libc::close(a0) +} + +unsafe fn f2(a0: i32, a1: i64, a2: i32) -> i64 { + libc::lseek(a0, a1, a2) +} + +unsafe fn f3(a0: i32, a1: *mut ::libc::c_void, a2: u64) -> i64 { + libc::read(a0, a1, a2 as usize) as i64 +} + +unsafe fn f4(a0: *const u8) -> i32 { + libc::unlink(a0 as *const i8) +} + +unsafe fn f5(a0: *mut i32) -> i32 { + libc::pipe(a0) +} + +unsafe fn f6(a0: i32, a1: i64) -> i32 { + libc::ftruncate(a0, a1) +} + +unsafe fn f7(a0: i32) -> i32 { + libc::isatty(a0) +} + +unsafe fn f8() -> u32 { + libc::geteuid() +} + +unsafe fn f9(a0: *mut u8, a1: u64) -> i32 { + libc::gethostname(a0 as *mut i8, a1 as usize) +} + +unsafe fn f10(a0: i32, a1: *const ::libc::c_void, a2: u64) -> i64 { + libc::write(a0, a1, a2 as usize) as i64 +} + +unsafe fn f11(a0: *const u8) -> i32 { + libc::rmdir(a0 as *const i8) +} diff --git a/tests/unit/out/unsafe/stdio.rs b/tests/unit/out/unsafe/stdio.rs index 484b7cd5..2114c852 100644 --- a/tests/unit/out/unsafe/stdio.rs +++ b/tests/unit/out/unsafe/stdio.rs @@ -175,6 +175,7 @@ pub unsafe fn test_fileno_3() { Box::from_raw(fp); 0 }; + assert!(((((libc::unlink(file as *const i8)) == (0)) as i32) != 0)); } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/unistd.rs b/tests/unit/out/unsafe/unistd.rs new file mode 100644 index 00000000..f461a788 --- /dev/null +++ b/tests/unit/out/unsafe/unistd.rs @@ -0,0 +1,530 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub unsafe fn test_close_0() { + let mut fds: [i32; 2] = [0_i32; 2]; + assert!(((((libc::pipe(fds.as_mut_ptr())) == (0)) as i32) != 0)); + assert!(((((libc::close(fds[(0) as usize])) == (0)) as i32) != 0)); + let mut buf: [u8; 1] = [0_u8; 1]; + assert!( + ((((libc::read( + fds[(0) as usize], + (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void), + 1_u64 as usize + ) as i64) + == (-1_i32 as i64)) as i32) + != 0) + ); + assert!(((((libc::close(fds[(1) as usize])) == (0)) as i32) != 0)); +} +pub unsafe fn test_lseek_1() { + let mut path: *const u8 = (b"/tmp/cpp2rust_lseek_test.tmp\0".as_ptr().cast_mut()).cast_const(); + let mut fp: *mut ::std::fs::File = + match std::ffi::CStr::from_ptr((b"wb\0".as_ptr().cast_mut()).cast_const() as *const i8) + .to_str() + .expect("invalid c-string") + { + v if v == "rb" => std::fs::OpenOptions::new() + .read(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + v if v == "wb" => std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + _ => panic!("unsupported mode"), + }; + assert!((((!((fp).is_null())) as i32) != 0)); + { + let bytes = std::ffi::CStr::from_ptr( + (b"hello world\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) + .to_bytes(); + match (*fp).write_all(bytes) { + Ok(()) => 0, + Err(_) => -1, + } + }; + assert!( + (((({ + Box::from_raw(fp); + 0 + }) == (0)) as i32) + != 0) + ); + fp = match std::ffi::CStr::from_ptr((b"rb\0".as_ptr().cast_mut()).cast_const() as *const i8) + .to_str() + .expect("invalid c-string") + { + v if v == "rb" => std::fs::OpenOptions::new() + .read(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + v if v == "wb" => std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + _ => panic!("unsupported mode"), + }; + assert!((((!((fp).is_null())) as i32) != 0)); + let mut fd: i32 = if fp == libcc2rs::cin_unsafe() { + 0 + } else if fp == libcc2rs::cout_unsafe() { + 1 + } else if fp == libcc2rs::cerr_unsafe() { + 2 + } else { + ::std::os::fd::AsRawFd::as_raw_fd(&*fp) + }; + assert!(((((libc::lseek(fd, 0_i64, 2)) == (11_i64)) as i32) != 0)); + assert!(((((libc::lseek(fd, 6_i64, 0)) == (6_i64)) as i32) != 0)); + let mut buf: [u8; 8] = [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8]; + assert!( + ((((libc::read( + fd, + (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void), + 5_u64 as usize + ) as i64) + == (5_i64)) as i32) + != 0) + ); + assert!( + (((({ + let sa = core::slice::from_raw_parts( + (buf.as_mut_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 5_u64 as usize, + ); + let sb = core::slice::from_raw_parts( + (b"world\0".as_ptr().cast_mut() as *const u8 as *const ::libc::c_void) as *const u8, + 5_u64 as usize, + ); + let mut diff = 0_i32; + for (x, y) in sa.iter().zip(sb.iter()) { + if x != y { + diff = (*x as i32) - (*y as i32); + break; + } + } + diff + }) == (0)) as i32) + != 0) + ); + assert!( + (((({ + Box::from_raw(fp); + 0 + }) == (0)) as i32) + != 0) + ); + libc::unlink(path as *const i8); +} +pub unsafe fn test_read_2() { + let mut path: *const u8 = (b"/tmp/cpp2rust_read_test.tmp\0".as_ptr().cast_mut()).cast_const(); + let mut fp: *mut ::std::fs::File = + match std::ffi::CStr::from_ptr((b"wb\0".as_ptr().cast_mut()).cast_const() as *const i8) + .to_str() + .expect("invalid c-string") + { + v if v == "rb" => std::fs::OpenOptions::new() + .read(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + v if v == "wb" => std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + _ => panic!("unsupported mode"), + }; + assert!((((!((fp).is_null())) as i32) != 0)); + { + let bytes = std::ffi::CStr::from_ptr( + (b"hello world\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) + .to_bytes(); + match (*fp).write_all(bytes) { + Ok(()) => 0, + Err(_) => -1, + } + }; + assert!( + (((({ + Box::from_raw(fp); + 0 + }) == (0)) as i32) + != 0) + ); + fp = match std::ffi::CStr::from_ptr((b"rb\0".as_ptr().cast_mut()).cast_const() as *const i8) + .to_str() + .expect("invalid c-string") + { + v if v == "rb" => std::fs::OpenOptions::new() + .read(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + v if v == "wb" => std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + _ => panic!("unsupported mode"), + }; + assert!((((!((fp).is_null())) as i32) != 0)); + let mut fd: i32 = if fp == libcc2rs::cin_unsafe() { + 0 + } else if fp == libcc2rs::cout_unsafe() { + 1 + } else if fp == libcc2rs::cerr_unsafe() { + 2 + } else { + ::std::os::fd::AsRawFd::as_raw_fd(&*fp) + }; + let mut buf: [u8; 16] = [ + 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, + 0_u8, + ]; + assert!( + ((((libc::read( + fd, + (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void), + 16_u64 as usize + ) as i64) + == (11_i64)) as i32) + != 0) + ); + assert!( + (((({ + let sa = core::slice::from_raw_parts( + (buf.as_mut_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 11_u64 as usize, + ); + let sb = core::slice::from_raw_parts( + (b"hello world\0".as_ptr().cast_mut() as *const u8 as *const ::libc::c_void) + as *const u8, + 11_u64 as usize, + ); + let mut diff = 0_i32; + for (x, y) in sa.iter().zip(sb.iter()) { + if x != y { + diff = (*x as i32) - (*y as i32); + break; + } + } + diff + }) == (0)) as i32) + != 0) + ); + assert!( + (((({ + Box::from_raw(fp); + 0 + }) == (0)) as i32) + != 0) + ); + libc::unlink(path as *const i8); +} +pub unsafe fn test_unlink_3() { + let mut path: *const u8 = (b"/tmp/cpp2rust_unlink_test.tmp\0".as_ptr().cast_mut()).cast_const(); + let mut fp: *mut ::std::fs::File = + match std::ffi::CStr::from_ptr((b"wb\0".as_ptr().cast_mut()).cast_const() as *const i8) + .to_str() + .expect("invalid c-string") + { + v if v == "rb" => std::fs::OpenOptions::new() + .read(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + v if v == "wb" => std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + _ => panic!("unsupported mode"), + }; + assert!((((!((fp).is_null())) as i32) != 0)); + assert!( + (((({ + Box::from_raw(fp); + 0 + }) == (0)) as i32) + != 0) + ); + assert!(((((libc::unlink(path as *const i8)) == (0)) as i32) != 0)); + assert!(((((libc::unlink(path as *const i8)) == (-1_i32)) as i32) != 0)); +} +pub unsafe fn test_pipe_4() { + let mut fds: [i32; 2] = [0_i32; 2]; + assert!(((((libc::pipe(fds.as_mut_ptr())) == (0)) as i32) != 0)); + let mut msg: *const u8 = (b"world\0".as_ptr().cast_mut()).cast_const(); + assert!( + ((((libc::write( + fds[(1) as usize], + (msg as *const u8 as *const ::libc::c_void), + 5_u64 as usize + ) as i64) + == (5_i64)) as i32) + != 0) + ); + let mut buf: [u8; 8] = [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8]; + assert!( + ((((libc::read( + fds[(0) as usize], + (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void), + 8_u64 as usize + ) as i64) + == (5_i64)) as i32) + != 0) + ); + assert!( + (((({ + let sa = core::slice::from_raw_parts( + (buf.as_mut_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 5_u64 as usize, + ); + let sb = core::slice::from_raw_parts( + (msg as *const u8 as *const ::libc::c_void) as *const u8, + 5_u64 as usize, + ); + let mut diff = 0_i32; + for (x, y) in sa.iter().zip(sb.iter()) { + if x != y { + diff = (*x as i32) - (*y as i32); + break; + } + } + diff + }) == (0)) as i32) + != 0) + ); + assert!(((((libc::close(fds[(1) as usize])) == (0)) as i32) != 0)); + assert!( + ((((libc::read( + fds[(0) as usize], + (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void), + 8_u64 as usize + ) as i64) + == (0_i64)) as i32) + != 0) + ); + assert!(((((libc::close(fds[(0) as usize])) == (0)) as i32) != 0)); +} +pub unsafe fn test_ftruncate_5() { + let mut path: *const u8 = + (b"/tmp/cpp2rust_ftruncate_test.tmp\0".as_ptr().cast_mut()).cast_const(); + let mut fp: *mut ::std::fs::File = + match std::ffi::CStr::from_ptr((b"wb\0".as_ptr().cast_mut()).cast_const() as *const i8) + .to_str() + .expect("invalid c-string") + { + v if v == "rb" => std::fs::OpenOptions::new() + .read(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + v if v == "wb" => std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + _ => panic!("unsupported mode"), + }; + assert!((((!((fp).is_null())) as i32) != 0)); + { + let bytes = std::ffi::CStr::from_ptr( + (b"hello world\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) + .to_bytes(); + match (*fp).write_all(bytes) { + Ok(()) => 0, + Err(_) => -1, + } + }; + if !(fp).is_null() { + match (*fp).sync_all() { + Ok(_) => 0, + Err(_) => -1, + } + } else { + ::std::io::stdout().flush().unwrap(); + ::std::io::stderr().flush().unwrap(); + 0 + }; + let mut fd: i32 = if fp == libcc2rs::cin_unsafe() { + 0 + } else if fp == libcc2rs::cout_unsafe() { + 1 + } else if fp == libcc2rs::cerr_unsafe() { + 2 + } else { + ::std::os::fd::AsRawFd::as_raw_fd(&*fp) + }; + assert!(((((libc::ftruncate(fd, 5_i64)) == (0)) as i32) != 0)); + assert!( + (((({ + Box::from_raw(fp); + 0 + }) == (0)) as i32) + != 0) + ); + fp = match std::ffi::CStr::from_ptr((b"rb\0".as_ptr().cast_mut()).cast_const() as *const i8) + .to_str() + .expect("invalid c-string") + { + v if v == "rb" => std::fs::OpenOptions::new() + .read(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + v if v == "wb" => std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open( + std::ffi::CStr::from_ptr(path as *const i8) + .to_str() + .expect("invalid c-string"), + ) + .ok() + .map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))), + _ => panic!("unsupported mode"), + }; + assert!((((!((fp).is_null())) as i32) != 0)); + fd = (if fp == libcc2rs::cin_unsafe() { + 0 + } else if fp == libcc2rs::cout_unsafe() { + 1 + } else if fp == libcc2rs::cerr_unsafe() { + 2 + } else { + ::std::os::fd::AsRawFd::as_raw_fd(&*fp) + }) + .clone(); + assert!(((((libc::lseek(fd, 0_i64, 2)) == (5_i64)) as i32) != 0)); + assert!( + (((({ + Box::from_raw(fp); + 0 + }) == (0)) as i32) + != 0) + ); + libc::unlink(path as *const i8); +} +pub unsafe fn test_isatty_6() { + printf( + (b"%d\n\0".as_ptr().cast_mut()).cast_const() as *const i8, + libc::isatty(0), + ); +} +pub unsafe fn test_geteuid_7() { + printf( + (b"%u\n\0".as_ptr().cast_mut()).cast_const() as *const i8, + libc::geteuid(), + ); +} +pub unsafe fn test_gethostname_8() { + let mut name: [u8; 256] = [0_u8; 256]; + assert!( + ((((libc::gethostname( + name.as_mut_ptr() as *mut i8, + ::std::mem::size_of::<[u8; 256]>() as u64 as usize + )) == (0)) as i32) + != 0) + ); + printf( + (b"%s\n\0".as_ptr().cast_mut()).cast_const() as *const i8, + name.as_mut_ptr(), + ); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + (unsafe { test_close_0() }); + (unsafe { test_lseek_1() }); + (unsafe { test_read_2() }); + (unsafe { test_unlink_3() }); + (unsafe { test_pipe_4() }); + (unsafe { test_ftruncate_5() }); + (unsafe { test_isatty_6() }); + (unsafe { test_geteuid_7() }); + (unsafe { test_gethostname_8() }); + return 0; +} diff --git a/tests/unit/stdio.c b/tests/unit/stdio.c index 63078e68..6552cdf8 100644 --- a/tests/unit/stdio.c +++ b/tests/unit/stdio.c @@ -1,6 +1,7 @@ // no-compile: refcount #include #include +#include static void test_fputc(void) { fputc('H', stdout); @@ -34,8 +35,7 @@ static void test_fileno(void) { assert(fp != NULL); assert(fileno(fp) > 2); fclose(fp); - // TODO: uncomment when unlink is available - // assert(unlink(file) == 0); + assert(unlink(file) == 0); } int main(void) { diff --git a/tests/unit/unistd.c b/tests/unit/unistd.c new file mode 100644 index 00000000..2ed49f68 --- /dev/null +++ b/tests/unit/unistd.c @@ -0,0 +1,111 @@ +// no-compile: refcount +#include +#include +#include +#include +#include + +static void test_close(void) { + int fds[2]; + assert(pipe(fds) == 0); + assert(close(fds[0]) == 0); + char buf[1]; + assert(read(fds[0], buf, 1) == -1); + assert(close(fds[1]) == 0); +} + +static void test_lseek(void) { + const char *path = "/tmp/cpp2rust_lseek_test.tmp"; + FILE *fp = fopen(path, "wb"); + assert(fp != NULL); + fputs("hello world", fp); + assert(fclose(fp) == 0); + fp = fopen(path, "rb"); + assert(fp != NULL); + int fd = fileno(fp); + assert(lseek(fd, 0, SEEK_END) == 11); + assert(lseek(fd, 6, SEEK_SET) == 6); + char buf[8] = {0}; + assert(read(fd, buf, 5) == 5); + assert(memcmp(buf, "world", 5) == 0); + assert(fclose(fp) == 0); + unlink(path); +} + +static void test_read(void) { + const char *path = "/tmp/cpp2rust_read_test.tmp"; + FILE *fp = fopen(path, "wb"); + assert(fp != NULL); + fputs("hello world", fp); + assert(fclose(fp) == 0); + fp = fopen(path, "rb"); + assert(fp != NULL); + int fd = fileno(fp); + char buf[16] = {0}; + assert(read(fd, buf, 16) == 11); + assert(memcmp(buf, "hello world", 11) == 0); + assert(fclose(fp) == 0); + unlink(path); +} + +static void test_unlink(void) { + const char *path = "/tmp/cpp2rust_unlink_test.tmp"; + FILE *fp = fopen(path, "wb"); + assert(fp != NULL); + assert(fclose(fp) == 0); + assert(unlink(path) == 0); + assert(unlink(path) == -1); +} + +static void test_pipe(void) { + int fds[2]; + assert(pipe(fds) == 0); + const char *msg = "world"; + assert(write(fds[1], msg, 5) == 5); + char buf[8] = {0}; + assert(read(fds[0], buf, 8) == 5); + assert(memcmp(buf, msg, 5) == 0); + assert(close(fds[1]) == 0); + assert(read(fds[0], buf, 8) == 0); + assert(close(fds[0]) == 0); +} + +static void test_ftruncate(void) { + const char *path = "/tmp/cpp2rust_ftruncate_test.tmp"; + FILE *fp = fopen(path, "wb"); + assert(fp != NULL); + fputs("hello world", fp); + fflush(fp); + int fd = fileno(fp); + assert(ftruncate(fd, 5) == 0); + assert(fclose(fp) == 0); + fp = fopen(path, "rb"); + assert(fp != NULL); + fd = fileno(fp); + assert(lseek(fd, 0, SEEK_END) == 5); + assert(fclose(fp) == 0); + unlink(path); +} + +static void test_isatty(void) { printf("%d\n", isatty(0)); } + +static void test_geteuid(void) { printf("%u\n", geteuid()); } + +static void test_gethostname(void) { + char name[256]; + assert(gethostname(name, sizeof(name)) == 0); + printf("%s\n", name); +} + +int main(void) { + test_close(); + test_lseek(); + test_read(); + test_unlink(); + test_pipe(); + test_ftruncate(); + test_isatty(); + test_geteuid(); + test_gethostname(); + return 0; +}