Skip to content

Commit 2da2141

Browse files
committed
Add rules + test for errno
1 parent 59bcd25 commit 2da2141

6 files changed

Lines changed: 122 additions & 0 deletions

File tree

rules/errno/ir_unsafe.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"f1": {
3+
"body": [
4+
{
5+
"text": "libc::__errno_location()"
6+
}
7+
],
8+
"return_type": {
9+
"type": "*mut i32",
10+
"is_unsafe_pointer": true
11+
}
12+
}
13+
}

rules/errno/src.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
#include <errno.h>
5+
6+
int *f1(void) { return __errno_location(); }

rules/errno/tgt_unsafe.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
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() -> *mut i32 {
5+
libc::__errno_location()
6+
}

rules/src/modules.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ pub mod cstring_tgt_unsafe;
3434
pub mod deque_tgt_refcount;
3535
#[path = r#"../deque/tgt_unsafe.rs"#]
3636
pub mod deque_tgt_unsafe;
37+
#[path = r#"../errno/tgt_unsafe.rs"#]
38+
pub mod errno_tgt_unsafe;
3739
#[path = r#"../fstream/tgt_refcount.rs"#]
3840
pub mod fstream_tgt_refcount;
3941
#[path = r#"../fstream/tgt_unsafe.rs"#]

tests/unit/errno.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// no-compile: refcount
2+
#include <assert.h>
3+
#include <errno.h>
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
8+
static void test_errno(void) {
9+
errno = 0;
10+
assert(errno == 0);
11+
errno = 42;
12+
assert(errno == 42);
13+
int saved = errno;
14+
assert(saved == 42);
15+
errno = 0;
16+
}
17+
18+
static void test_errno_preserved_across_strdup(void) {
19+
errno = 99;
20+
char *d = strdup("hello");
21+
assert(d != NULL);
22+
assert(errno == 99);
23+
free(d);
24+
errno = 0;
25+
}
26+
27+
static void test_errno_from_fseek(void) {
28+
errno = 0;
29+
int r = fseek(stdin, 0, SEEK_SET);
30+
assert(r == -1);
31+
assert(errno == ESPIPE);
32+
errno = 0;
33+
}
34+
35+
int main(void) {
36+
test_errno();
37+
test_errno_preserved_across_strdup();
38+
test_errno_from_fseek();
39+
return 0;
40+
}

tests/unit/out/unsafe/errno.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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_errno_0() {
10+
(*libc::__errno_location()) = 0;
11+
assert!(((((*libc::__errno_location()) == (0)) as i32) != 0));
12+
(*libc::__errno_location()) = 42;
13+
assert!(((((*libc::__errno_location()) == (42)) as i32) != 0));
14+
let mut saved: i32 = (*libc::__errno_location());
15+
assert!(((((saved) == (42)) as i32) != 0));
16+
(*libc::__errno_location()) = 0;
17+
}
18+
pub unsafe fn test_errno_preserved_across_strdup_1() {
19+
(*libc::__errno_location()) = 99;
20+
let mut d: *mut u8 =
21+
libc::strdup((b"hello\0".as_ptr().cast_mut()).cast_const() as *const i8) as *mut u8;
22+
assert!((((!((d).is_null())) as i32) != 0));
23+
assert!(((((*libc::__errno_location()) == (99)) as i32) != 0));
24+
libc::free((d as *mut u8 as *mut ::libc::c_void));
25+
(*libc::__errno_location()) = 0;
26+
}
27+
pub unsafe fn test_errno_from_fseek_2() {
28+
(*libc::__errno_location()) = 0;
29+
let mut r: i32 = if (match 0 {
30+
0 => (*libcc2rs::cin_unsafe()).seek(std::io::SeekFrom::Start(0_i64 as u64)),
31+
1 => (*libcc2rs::cin_unsafe()).seek(std::io::SeekFrom::Current(0_i64)),
32+
2 => (*libcc2rs::cin_unsafe()).seek(std::io::SeekFrom::End(0_i64)),
33+
_ => Err(std::io::Error::other("unsupported whence for fseek.")),
34+
})
35+
.is_ok()
36+
{
37+
0
38+
} else {
39+
-1
40+
};
41+
assert!(((((r) == (-1_i32)) as i32) != 0));
42+
assert!(((((*libc::__errno_location()) == (29)) as i32) != 0));
43+
(*libc::__errno_location()) = 0;
44+
}
45+
pub fn main() {
46+
unsafe {
47+
std::process::exit(main_0() as i32);
48+
}
49+
}
50+
unsafe fn main_0() -> i32 {
51+
(unsafe { test_errno_0() });
52+
(unsafe { test_errno_preserved_across_strdup_1() });
53+
(unsafe { test_errno_from_fseek_2() });
54+
return 0;
55+
}

0 commit comments

Comments
 (0)