Skip to content

Commit 7a29f51

Browse files
authored
[unsafe] Add stat.h rules (#132)
1 parent 24c1c62 commit 7a29f51

6 files changed

Lines changed: 320 additions & 0 deletions

File tree

rules/src/modules.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ pub mod pair_tgt_refcount;
6464
pub mod pair_tgt_unsafe;
6565
#[path = r#"../socket/tgt_unsafe.rs"#]
6666
pub mod socket_tgt_unsafe;
67+
#[path = r#"../stat/tgt_unsafe.rs"#]
68+
pub mod stat_tgt_unsafe;
6769
#[path = r#"../stdio/tgt_refcount.rs"#]
6870
pub mod stdio_tgt_refcount;
6971
#[path = r#"../stdio/tgt_unsafe.rs"#]

rules/stat/ir_unsafe.json

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
{
2+
"f1": {
3+
"body": [
4+
{
5+
"text": "libc::stat("
6+
},
7+
{
8+
"placeholder": {
9+
"arg": 0,
10+
"access": "read"
11+
}
12+
},
13+
{
14+
"text": " as *const i8, "
15+
},
16+
{
17+
"placeholder": {
18+
"arg": 1,
19+
"access": "read"
20+
}
21+
},
22+
{
23+
"text": ")"
24+
}
25+
],
26+
"params": {
27+
"a0": {
28+
"type": "*const u8",
29+
"is_unsafe_pointer": true
30+
},
31+
"a1": {
32+
"type": "*mut ::libc::stat",
33+
"is_unsafe_pointer": true
34+
}
35+
},
36+
"return_type": {
37+
"type": "i32"
38+
}
39+
},
40+
"f2": {
41+
"body": [
42+
{
43+
"text": "libc::fstat("
44+
},
45+
{
46+
"placeholder": {
47+
"arg": 0,
48+
"access": "read"
49+
}
50+
},
51+
{
52+
"text": ", "
53+
},
54+
{
55+
"placeholder": {
56+
"arg": 1,
57+
"access": "read"
58+
}
59+
},
60+
{
61+
"text": ")"
62+
}
63+
],
64+
"params": {
65+
"a0": {
66+
"type": "i32"
67+
},
68+
"a1": {
69+
"type": "*mut ::libc::stat",
70+
"is_unsafe_pointer": true
71+
}
72+
},
73+
"return_type": {
74+
"type": "i32"
75+
}
76+
},
77+
"f3": {
78+
"body": [
79+
{
80+
"text": "libc::mkdir("
81+
},
82+
{
83+
"placeholder": {
84+
"arg": 0,
85+
"access": "read"
86+
}
87+
},
88+
{
89+
"text": " as *const i8, "
90+
},
91+
{
92+
"placeholder": {
93+
"arg": 1,
94+
"access": "read"
95+
}
96+
},
97+
{
98+
"text": " as ::libc::mode_t)"
99+
}
100+
],
101+
"params": {
102+
"a0": {
103+
"type": "*const u8",
104+
"is_unsafe_pointer": true
105+
},
106+
"a1": {
107+
"type": "::libc::mode_t"
108+
}
109+
},
110+
"return_type": {
111+
"type": "i32"
112+
}
113+
}
114+
}

rules/stat/src.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
#include <sys/stat.h>
5+
6+
int f1(const char *pathname, struct stat *statbuf) {
7+
return stat(pathname, statbuf);
8+
}
9+
10+
int f2(int fd, struct stat *statbuf) { return fstat(fd, statbuf); }
11+
12+
int f3(const char *pathname, mode_t mode) { return mkdir(pathname, mode); }

rules/stat/tgt_unsafe.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
unsafe fn f1(a0: *const u8, a1: *mut ::libc::stat) -> i32 {
5+
libc::stat(a0 as *const i8, a1)
6+
}
7+
8+
unsafe fn f2(a0: i32, a1: *mut ::libc::stat) -> i32 {
9+
libc::fstat(a0, a1)
10+
}
11+
12+
unsafe fn f3(a0: *const u8, a1: ::libc::mode_t) -> i32 {
13+
libc::mkdir(a0 as *const i8, a1 as ::libc::mode_t)
14+
}

tests/unit/out/unsafe/sys_stat.rs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
pub unsafe fn test_stat_0() {
10+
let mut path: *const u8 = (b"/tmp/cpp2rust_stat_test.tmp\0".as_ptr().cast_mut()).cast_const();
11+
let mut fp: *mut ::std::fs::File =
12+
match std::ffi::CStr::from_ptr((b"wb\0".as_ptr().cast_mut()).cast_const() as *const i8)
13+
.to_str()
14+
.expect("invalid c-string")
15+
{
16+
v if v == "rb" => std::fs::OpenOptions::new()
17+
.read(true)
18+
.open(
19+
std::ffi::CStr::from_ptr(path as *const i8)
20+
.to_str()
21+
.expect("invalid c-string"),
22+
)
23+
.ok()
24+
.map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))),
25+
v if v == "wb" => std::fs::OpenOptions::new()
26+
.write(true)
27+
.create(true)
28+
.truncate(true)
29+
.open(
30+
std::ffi::CStr::from_ptr(path as *const i8)
31+
.to_str()
32+
.expect("invalid c-string"),
33+
)
34+
.ok()
35+
.map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))),
36+
_ => panic!("unsupported mode"),
37+
};
38+
assert!((((!((fp).is_null())) as i32) != 0));
39+
{
40+
let bytes =
41+
std::ffi::CStr::from_ptr((b"hello\0".as_ptr().cast_mut()).cast_const() as *const i8)
42+
.to_bytes();
43+
match (*fp).write_all(bytes) {
44+
Ok(()) => 0,
45+
Err(_) => -1,
46+
}
47+
};
48+
assert!(
49+
(((({
50+
Box::from_raw(fp);
51+
0
52+
}) == (0)) as i32)
53+
!= 0)
54+
);
55+
let mut st: stat = std::mem::zeroed::<stat>();
56+
assert!(((((libc::stat(path as *const i8, (&mut st as *mut stat))) == (0)) as i32) != 0));
57+
assert!(((((st.st_size) == (5_i64)) as i32) != 0));
58+
libc::unlink(path as *const i8);
59+
}
60+
pub unsafe fn test_fstat_1() {
61+
let mut path: *const u8 = (b"/tmp/cpp2rust_fstat_test.tmp\0".as_ptr().cast_mut()).cast_const();
62+
let mut fp: *mut ::std::fs::File =
63+
match std::ffi::CStr::from_ptr((b"wb\0".as_ptr().cast_mut()).cast_const() as *const i8)
64+
.to_str()
65+
.expect("invalid c-string")
66+
{
67+
v if v == "rb" => std::fs::OpenOptions::new()
68+
.read(true)
69+
.open(
70+
std::ffi::CStr::from_ptr(path as *const i8)
71+
.to_str()
72+
.expect("invalid c-string"),
73+
)
74+
.ok()
75+
.map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))),
76+
v if v == "wb" => std::fs::OpenOptions::new()
77+
.write(true)
78+
.create(true)
79+
.truncate(true)
80+
.open(
81+
std::ffi::CStr::from_ptr(path as *const i8)
82+
.to_str()
83+
.expect("invalid c-string"),
84+
)
85+
.ok()
86+
.map_or(std::ptr::null_mut(), |f| Box::into_raw(Box::new(f))),
87+
_ => panic!("unsupported mode"),
88+
};
89+
assert!((((!((fp).is_null())) as i32) != 0));
90+
{
91+
let bytes = std::ffi::CStr::from_ptr(
92+
(b"hello world\0".as_ptr().cast_mut()).cast_const() as *const i8
93+
)
94+
.to_bytes();
95+
match (*fp).write_all(bytes) {
96+
Ok(()) => 0,
97+
Err(_) => -1,
98+
}
99+
};
100+
if !(fp).is_null() {
101+
match (*fp).sync_all() {
102+
Ok(_) => 0,
103+
Err(_) => -1,
104+
}
105+
} else {
106+
::std::io::stdout().flush().unwrap();
107+
::std::io::stderr().flush().unwrap();
108+
0
109+
};
110+
let mut fd: i32 = if fp == libcc2rs::cin_unsafe() {
111+
0
112+
} else if fp == libcc2rs::cout_unsafe() {
113+
1
114+
} else if fp == libcc2rs::cerr_unsafe() {
115+
2
116+
} else {
117+
::std::os::fd::AsRawFd::as_raw_fd(&*fp)
118+
};
119+
let mut st: stat = std::mem::zeroed::<stat>();
120+
assert!(((((libc::fstat(fd, (&mut st as *mut stat))) == (0)) as i32) != 0));
121+
assert!(((((st.st_size) == (11_i64)) as i32) != 0));
122+
assert!(
123+
(((({
124+
Box::from_raw(fp);
125+
0
126+
}) == (0)) as i32)
127+
!= 0)
128+
);
129+
libc::unlink(path as *const i8);
130+
}
131+
pub fn main() {
132+
unsafe {
133+
std::process::exit(main_0() as i32);
134+
}
135+
}
136+
unsafe fn main_0() -> i32 {
137+
(unsafe { test_stat_0() });
138+
(unsafe { test_fstat_1() });
139+
return 0;
140+
}

tests/unit/sys_stat.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// no-compile: refcount
2+
#include <assert.h>
3+
#include <errno.h>
4+
#include <stdio.h>
5+
#include <sys/stat.h>
6+
#include <unistd.h>
7+
8+
static void test_stat(void) {
9+
const char *path = "/tmp/cpp2rust_stat_test.tmp";
10+
FILE *fp = fopen(path, "wb");
11+
assert(fp != NULL);
12+
fputs("hello", fp);
13+
assert(fclose(fp) == 0);
14+
struct stat st;
15+
assert(stat(path, &st) == 0);
16+
assert(st.st_size == 5);
17+
unlink(path);
18+
}
19+
20+
static void test_fstat(void) {
21+
const char *path = "/tmp/cpp2rust_fstat_test.tmp";
22+
FILE *fp = fopen(path, "wb");
23+
assert(fp != NULL);
24+
fputs("hello world", fp);
25+
fflush(fp);
26+
int fd = fileno(fp);
27+
struct stat st;
28+
assert(fstat(fd, &st) == 0);
29+
assert(st.st_size == 11);
30+
assert(fclose(fp) == 0);
31+
unlink(path);
32+
}
33+
34+
int main(void) {
35+
test_stat();
36+
test_fstat();
37+
return 0;
38+
}

0 commit comments

Comments
 (0)