|
1 | 1 | // Copyright (c) 2022-present INESC-ID. |
2 | 2 | // Distributed under the MIT license that can be found in the LICENSE file. |
3 | 3 |
|
4 | | -use crate::{AnyPtr, AsPointer, Ptr, Value}; |
| 4 | +use crate::{AnyPtr, AsPointer, CFile, Ptr, Value}; |
5 | 5 | use std::cell::{RefCell, UnsafeCell}; |
6 | 6 | use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; |
7 | 7 | use std::rc::Rc; |
@@ -48,6 +48,24 @@ thread_local! { |
48 | 48 | }; |
49 | 49 | } |
50 | 50 |
|
| 51 | +thread_local! { |
| 52 | + static C_STDIN: Value<CFile> = Rc::new(RefCell::new(CFile::new(0))); |
| 53 | + static C_STDOUT: Value<CFile> = Rc::new(RefCell::new(CFile::new(1))); |
| 54 | + static C_STDERR: Value<CFile> = Rc::new(RefCell::new(CFile::new(2))); |
| 55 | +} |
| 56 | + |
| 57 | +pub fn c_stdin() -> Ptr<CFile> { |
| 58 | + C_STDIN.with(AsPointer::as_pointer) |
| 59 | +} |
| 60 | + |
| 61 | +pub fn c_stdout() -> Ptr<CFile> { |
| 62 | + C_STDOUT.with(AsPointer::as_pointer) |
| 63 | +} |
| 64 | + |
| 65 | +pub fn c_stderr() -> Ptr<CFile> { |
| 66 | + C_STDERR.with(AsPointer::as_pointer) |
| 67 | +} |
| 68 | + |
51 | 69 | pub fn cin() -> Ptr<std::fs::File> { |
52 | 70 | SAFE_STDIN.with(AsPointer::as_pointer) |
53 | 71 | } |
@@ -84,79 +102,24 @@ pub unsafe fn cerr_unsafe() -> *mut std::fs::File { |
84 | 102 | UNSAFE_STDERR.with(UnsafeCell::get) |
85 | 103 | } |
86 | 104 |
|
87 | | -pub fn fread_refcount(a0: AnyPtr, a1: usize, a2: usize, a3: Ptr<::std::fs::File>) -> usize { |
| 105 | +pub fn fread_refcount(a0: AnyPtr, a1: usize, a2: usize, a3: Ptr<CFile>) -> usize { |
88 | 106 | let total = a1.saturating_mul(a2); |
89 | | - let mut dst = a0.reinterpret_cast::<u8>(); |
90 | | - |
91 | | - let f = (*a3.upgrade().deref()) |
92 | | - .try_clone() |
93 | | - .expect("try_clone failed"); |
94 | | - let mut reader = std::io::BufReader::with_capacity(64 * 1024, f); |
95 | | - |
96 | | - let mut read_bytes: usize = 0; |
97 | | - let mut buffer: [u8; 8192] = [0; 8192]; |
98 | | - |
99 | | - while read_bytes < total { |
100 | | - let remaining = total - read_bytes; |
101 | | - let to_read = std::cmp::min(buffer.len(), remaining); |
102 | | - |
103 | | - let n = match std::io::Read::read(&mut reader, &mut buffer[..to_read]) { |
104 | | - Ok(0) => break, |
105 | | - Ok(n) => n, |
106 | | - Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => continue, |
107 | | - Err(e) => panic!("Unhandled error in fread: {e}"), |
108 | | - }; |
109 | | - |
110 | | - for &byte in &buffer[..n] { |
111 | | - dst.write(byte); |
112 | | - dst += 1; |
113 | | - } |
114 | | - |
115 | | - read_bytes += n; |
| 107 | + if total == 0 { |
| 108 | + return 0; |
116 | 109 | } |
117 | | - |
| 110 | + let dst = a0.reinterpret_cast::<u8>(); |
| 111 | + let read_bytes = dst.with_slice_mut(total, |buf| a3.with_mut(|f| f.read(buf))); |
118 | 112 | read_bytes / a1 |
119 | 113 | } |
120 | 114 |
|
121 | | -pub fn fwrite_refcount(a0: AnyPtr, a1: usize, a2: usize, a3: Ptr<::std::fs::File>) -> usize { |
| 115 | +pub fn fwrite_refcount(a0: AnyPtr, a1: usize, a2: usize, a3: Ptr<CFile>) -> usize { |
122 | 116 | let total = a1.saturating_mul(a2); |
123 | | - let mut src = a0.reinterpret_cast::<u8>(); |
124 | | - |
125 | | - let f = (*a3.upgrade().deref()) |
126 | | - .try_clone() |
127 | | - .expect("try_clone failed"); |
128 | | - let mut writer = std::io::BufWriter::with_capacity(64 * 1024, f); |
129 | | - |
130 | | - let mut written_bytes: usize = 0; |
131 | | - let mut buffer: [u8; 8192] = [0; 8192]; |
132 | | - |
133 | | - while written_bytes < total { |
134 | | - let remaining = total - written_bytes; |
135 | | - let to_fill = std::cmp::min(buffer.len(), remaining); |
136 | | - |
137 | | - for b in buffer.iter_mut().take(to_fill) { |
138 | | - *b = src.read(); |
139 | | - src += 1; |
140 | | - } |
141 | | - |
142 | | - let mut off = 0; |
143 | | - while off < to_fill { |
144 | | - match std::io::Write::write(&mut writer, &buffer[off..to_fill]) { |
145 | | - Ok(0) => break, |
146 | | - Ok(n) => off += n, |
147 | | - Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => continue, |
148 | | - Err(e) => panic!("Unhandled error in fwrite: {e}"), |
149 | | - } |
150 | | - } |
151 | | - |
152 | | - if off == 0 { |
153 | | - break; |
154 | | - } |
155 | | - |
156 | | - written_bytes += off; |
| 117 | + if total == 0 { |
| 118 | + return 0; |
157 | 119 | } |
158 | | - |
159 | | - written_bytes / a1 |
| 120 | + let src = a0.reinterpret_cast::<u8>(); |
| 121 | + let written = src.with_slice(total, |bytes| a3.with_mut(|f| f.write(bytes))); |
| 122 | + written / a1 |
160 | 123 | } |
161 | 124 |
|
162 | 125 | unsafe extern "C" { |
|
0 commit comments