Skip to content

Commit da1e211

Browse files
committed
Add translation rule for stdin
1 parent 7cfa0e0 commit da1e211

7 files changed

Lines changed: 56 additions & 0 deletions

File tree

libcc2rs/src/io.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,25 @@ use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
77
use std::rc::Rc;
88

99
thread_local! {
10+
static SAFE_STDIN: Value<std::fs::File> = Rc::new(RefCell::new(std::fs::File::from(
11+
std::io::stdin().as_fd().try_clone_to_owned().unwrap(),
12+
)));
1013
static SAFE_STDOUT: Value<std::fs::File> = Rc::new(RefCell::new(std::fs::File::from(
1114
std::io::stdout().as_fd().try_clone_to_owned().unwrap(),
1215
)));
1316
static SAFE_STDERR: Value<std::fs::File> = Rc::new(RefCell::new(std::fs::File::from(
1417
std::io::stderr().as_fd().try_clone_to_owned().unwrap(),
1518
)));
19+
static UNSAFE_STDIN: UnsafeCell<std::fs::File> = unsafe {
20+
UnsafeCell::new(
21+
std::fs::File::from_raw_fd(
22+
std::io::stdin()
23+
.as_fd()
24+
.try_clone_to_owned()
25+
.unwrap()
26+
.into_raw_fd(),
27+
))
28+
};
1629
static UNSAFE_STDOUT: UnsafeCell<std::fs::File> = unsafe {
1730
UnsafeCell::new(
1831
std::fs::File::from_raw_fd(
@@ -35,6 +48,10 @@ thread_local! {
3548
};
3649
}
3750

51+
pub fn cin() -> Ptr<std::fs::File> {
52+
SAFE_STDIN.with(AsPointer::as_pointer)
53+
}
54+
3855
pub fn cout() -> Ptr<std::fs::File> {
3956
SAFE_STDOUT.with(AsPointer::as_pointer)
4057
}
@@ -43,6 +60,14 @@ pub fn cerr() -> Ptr<std::fs::File> {
4360
SAFE_STDERR.with(AsPointer::as_pointer)
4461
}
4562

63+
/// # Safety
64+
///
65+
/// The caller must ensure that the returned pointer is not used after the
66+
// thread finishes.
67+
pub unsafe fn cin_unsafe() -> *mut std::fs::File {
68+
UNSAFE_STDIN.with(UnsafeCell::get)
69+
}
70+
4671
/// # Safety
4772
///
4873
/// The caller must ensure that the returned pointer is not used after the

rules/stdio/ir_refcount.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,17 @@
890890
"is_refcount_pointer": true
891891
}
892892
},
893+
"f10": {
894+
"body": [
895+
{
896+
"text": "libcc2rs::cin()"
897+
}
898+
],
899+
"return_type": {
900+
"type": "Ptr<::std::fs::File>",
901+
"is_refcount_pointer": true
902+
}
903+
},
893904
"t1": {
894905
"init": "Ptr::null()",
895906
"type": "Ptr<::std::fs::File>",

rules/stdio/ir_unsafe.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,17 @@
861861
"is_unsafe_pointer": true
862862
}
863863
},
864+
"f10": {
865+
"body": [
866+
{
867+
"text": "libcc2rs::cin_unsafe()"
868+
}
869+
],
870+
"return_type": {
871+
"type": "*mut ::std::fs::File",
872+
"is_unsafe_pointer": true
873+
}
874+
},
864875
"t1": {
865876
"init": "Default::default()",
866877
"type": "*mut ::std::fs::File",

rules/stdio/src.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,5 @@ int f7(FILE *stream) { return fflush(stream); }
3030
FILE *f8() { return stdout; }
3131

3232
FILE *f9() { return stderr; }
33+
34+
FILE *f10() { return stdin; }

tests/unit/out/refcount/printfs.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ fn main_0() -> i32 {
2626
println!("{}", Ptr::from_string_literal("fprintf stdout"));
2727
println!("{} {} {}", 1, 2_u32, 3_i64);
2828
print!("hello world");
29+
let in_: Value<Ptr<::std::fs::File>> = Rc::new(RefCell::new((libcc2rs::cin()).clone()));
30+
assert!(((*in_.borrow()) != Default::default()));
2931
println!("{}", Ptr::from_string_literal("printf"));
3032
print!("hello world");
3133
let s: Value<Vec<u8>> = Rc::new(RefCell::new(

tests/unit/out/unsafe/printfs.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ unsafe fn main_0() -> i32 {
3434
);
3535
printf(b"%d %u %ld\n\0".as_ptr() as *const i8, 1, 2_u32, 3_i64);
3636
printf(b"hello world\0".as_ptr() as *const i8);
37+
let mut in_: *mut ::std::fs::File = libcc2rs::cin_unsafe();
38+
assert!(((in_) != (std::ptr::null_mut())));
3739
printf(b"%s\n\0".as_ptr() as *const i8, b"printf\0".as_ptr());
3840
printf(b"hello world\0".as_ptr() as *const i8);
3941
let mut s: Vec<u8> = {

tests/unit/printfs.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) 2022-present INESC-ID.
22
// Distributed under the MIT license that can be found in the LICENSE file.
33

4+
#include <cassert>
45
#include <cstdio>
56
#include <string>
67

@@ -12,6 +13,8 @@ int main() {
1213
fprintf(stdout, "%s\n", "fprintf stdout");
1314
fprintf(stdout, "%d %u %ld\n", 1, 2U, 3L);
1415
fprintf(stdout, "hello world");
16+
FILE *in = stdin;
17+
assert(in != NULL);
1518
printf("%s\n", "printf");
1619
printf("hello world");
1720
std::string s = "a string";

0 commit comments

Comments
 (0)