17
17
* along with Aero. If not, see <https://www.gnu.org/licenses/>.
18
18
*/
19
19
20
- use core:: sync:: atomic:: { AtomicU32 , Ordering } ;
20
+ use std:: sync:: atomic:: { AtomicU32 , Ordering } ;
21
+
22
+ use std:: error:: Error ;
23
+ use std:: io:: { BufRead , BufReader } ;
24
+
25
+ use std:: fs;
26
+ use std:: fs:: File ;
21
27
22
28
use aero_ipc:: SystemService ;
23
29
use aero_syscall:: signal:: * ;
@@ -86,13 +92,13 @@ fn repl(history: &mut Vec<String>) -> Result<(), AeroSyscallError> {
86
92
let message = args. collect :: < Vec < _ > > ( ) . join ( " " ) ;
87
93
let message = message. replace (
88
94
"$?" ,
89
- LAST_EXIT_CODE . load ( Ordering :: Relaxed ) . to_string ( ) . as_str ( ) ,
95
+ LAST_EXIT_CODE . load ( Ordering :: SeqCst ) . to_string ( ) . as_str ( ) ,
90
96
) ;
91
97
92
98
println ! ( "{}" , message) ;
93
99
}
94
100
95
- "ls" => list_directory ( args. next ( ) . unwrap_or ( "." ) ) ? ,
101
+ "ls" => list_directory ( args. next ( ) . unwrap_or ( "." ) ) . unwrap ( ) ,
96
102
"pwd" => println ! ( "{}" , pwd) ,
97
103
"cd" => {
98
104
sys_chdir ( args. next ( ) . unwrap_or ( ".." ) ) ?;
@@ -116,9 +122,9 @@ fn repl(history: &mut Vec<String>) -> Result<(), AeroSyscallError> {
116
122
} ,
117
123
None => sys_exit ( 0 ) ,
118
124
} ,
119
- "cat" => cat_file ( args. next ( ) ) ? ,
125
+ "cat" => cat_file ( args. next ( ) ) . unwrap ( ) ,
120
126
"clear" => print ! ( "{esc}[2J{esc}[1;1H" , esc = 27 as char ) ,
121
- "dmsg" => print_kernel_log ( ) ? ,
127
+ "dmsg" => print_kernel_log ( ) . unwrap ( ) ,
122
128
"uwufetch" => uwufetch ( ) ?,
123
129
"uname" => uname ( ) ?,
124
130
"history" => {
@@ -255,67 +261,46 @@ fn repl(history: &mut Vec<String>) -> Result<(), AeroSyscallError> {
255
261
Ok ( ( ) )
256
262
}
257
263
258
- fn list_directory ( path : & str ) -> Result < ( ) , AeroSyscallError > {
259
- let dir_fd = sys_open ( path, OpenFlags :: O_DIRECTORY ) ?;
260
-
261
- loop {
262
- let mut dir_ents_buffer = [ 0 ; 1024 ] ;
263
-
264
- let size = sys_getdents ( dir_fd, & mut dir_ents_buffer) ?;
265
-
266
- if size == 0 {
267
- break ;
268
- }
269
-
270
- let dir_entry = unsafe { & * ( dir_ents_buffer. as_ptr ( ) as * const SysDirEntry ) } ;
264
+ fn list_directory ( path : & str ) -> Result < ( ) , Box < dyn Error > > {
265
+ let rdir = fs:: read_dir ( path) ?;
271
266
272
- let name_start = core:: mem:: size_of :: < SysDirEntry > ( ) ;
273
- let name_end = dir_entry. reclen ;
267
+ for file in rdir {
268
+ let name = file?. file_name ( ) ;
269
+ let name_str = name. to_str ( ) . ok_or ( "ls: invalid filename" ) ?;
274
270
275
- let name =
276
- unsafe { core:: str:: from_utf8_unchecked ( & dir_ents_buffer[ name_start..name_end] ) } ;
277
-
278
- print ! ( "{} " , name) ;
271
+ print ! ( "{name_str} " ) ;
279
272
}
280
273
281
274
println ! ( ) ;
282
-
283
275
Ok ( ( ) )
284
276
}
285
277
286
- fn cat_file ( path : Option < & str > ) -> Result < ( ) , AeroSyscallError > {
287
- // On the `None` arm we default to 0 to take input from stdin.
288
- // This is the behaviour of `cat` that comes with any modern Linux distro.
289
- let fd = match path {
290
- Some ( path) => sys_open ( path, OpenFlags :: O_RDONLY ) ?,
291
- None => 0 ,
292
- } ;
278
+ fn cat_file ( path : Option < & str > ) -> Result < ( ) , Box < dyn Error > > {
279
+ let file = path
280
+ . map ( |e| File :: open ( e) )
281
+ // On the `None` arm, we take input from stdin until we get interrupted. This is the
282
+ // behaviour of `cat` that comes with any modern Linux distro.
283
+ . unwrap_or_else ( || File :: open ( "/dev/tty" ) ) ?;
293
284
294
- sys_seek ( fd, 0 , SeekWhence :: SeekSet ) ?;
295
-
296
- let mut buffer = [ 0 ; 1024 ] ;
285
+ let mut reader = BufReader :: new ( file) ;
297
286
298
287
loop {
299
- let length = sys_read ( fd, & mut buffer) ?;
288
+ let mut line = String :: new ( ) ;
289
+ let size = reader. read_line ( & mut line) ?;
300
290
301
- if length == 0 {
291
+ // We have reached the end of the file.
292
+ if size == 0 {
302
293
break ;
303
294
}
304
295
305
- let contents = unsafe { core:: str:: from_utf8_unchecked ( & buffer[ 0 ..length] ) } ;
306
-
307
- print ! ( "{}" , contents) ;
308
- }
309
-
310
- if fd != 0 {
311
- sys_close ( fd) ?;
296
+ print ! ( "{line}" ) ;
312
297
}
313
298
314
- print ! ( " \n " ) ;
299
+ println ! ( ) ;
315
300
Ok ( ( ) )
316
301
}
317
302
318
- fn print_kernel_log ( ) -> Result < ( ) , AeroSyscallError > {
303
+ fn print_kernel_log ( ) -> Result < ( ) , Box < dyn Error > > {
319
304
// dmsg is just a wrapper around `cat /dev/kmsg`
320
305
// TODO: Add colored output back :^)
321
306
0 commit comments