1
- use core:: ffi :: CStr ;
1
+ use core:: mem :: size_of ;
2
2
3
- use alloc:: {
4
- string:: { String , ToString } ,
5
- sync:: Arc ,
6
- vec:: Vec ,
7
- } ;
3
+ use alloc:: { string:: String , sync:: Arc , vec:: Vec } ;
8
4
use system_error:: SystemError ;
9
5
10
6
use crate :: {
11
7
driver:: base:: { block:: SeekFrom , device:: device_number:: DeviceNumber } ,
12
8
filesystem:: vfs:: file:: FileDescriptorVec ,
13
- kerror,
14
9
libs:: rwlock:: RwLockWriteGuard ,
15
10
mm:: { verify_area, VirtAddr } ,
16
11
process:: ProcessManager ,
17
12
syscall:: {
18
- user_access:: { check_and_clone_cstr, UserBufferReader , UserBufferWriter } ,
13
+ user_access:: { check_and_clone_cstr, UserBufferWriter } ,
19
14
Syscall ,
20
15
} ,
21
16
time:: TimeSpec ,
@@ -86,6 +81,7 @@ bitflags! {
86
81
}
87
82
88
83
#[ repr( C ) ]
84
+ #[ derive( Clone , Copy ) ]
89
85
/// # 文件信息结构体
90
86
pub struct PosixKstat {
91
87
/// 硬件设备ID
@@ -248,22 +244,34 @@ impl Syscall {
248
244
///
249
245
/// @return 文件描述符编号,或者是错误码
250
246
pub fn open (
251
- path : & str ,
252
- flags : FileMode ,
253
- mode : ModeType ,
247
+ path : * const u8 ,
248
+ o_flags : u32 ,
249
+ mode : u32 ,
254
250
follow_symlink : bool ,
255
251
) -> Result < usize , SystemError > {
256
- return do_sys_open ( AtFlags :: AT_FDCWD . bits ( ) , path, flags, mode, follow_symlink) ;
252
+ let path = check_and_clone_cstr ( path, Some ( MAX_PATHLEN ) ) ?;
253
+ let open_flags: FileMode = FileMode :: from_bits ( o_flags) . ok_or ( SystemError :: EINVAL ) ?;
254
+ let mode = ModeType :: from_bits ( mode as u32 ) . ok_or ( SystemError :: EINVAL ) ?;
255
+ return do_sys_open (
256
+ AtFlags :: AT_FDCWD . bits ( ) ,
257
+ & path,
258
+ open_flags,
259
+ mode,
260
+ follow_symlink,
261
+ ) ;
257
262
}
258
263
259
264
pub fn openat (
260
265
dirfd : i32 ,
261
- path : & str ,
262
- o_flags : FileMode ,
263
- mode : ModeType ,
266
+ path : * const u8 ,
267
+ o_flags : u32 ,
268
+ mode : u32 ,
264
269
follow_symlink : bool ,
265
270
) -> Result < usize , SystemError > {
266
- return do_sys_open ( dirfd, path, o_flags, mode, follow_symlink) ;
271
+ let path = check_and_clone_cstr ( path, Some ( MAX_PATHLEN ) ) ?;
272
+ let open_flags: FileMode = FileMode :: from_bits ( o_flags) . ok_or ( SystemError :: EINVAL ) ?;
273
+ let mode = ModeType :: from_bits ( mode as u32 ) . ok_or ( SystemError :: EINVAL ) ?;
274
+ return do_sys_open ( dirfd, & path, open_flags, mode, follow_symlink) ;
267
275
}
268
276
269
277
/// @brief 关闭文件
@@ -351,7 +359,15 @@ impl Syscall {
351
359
///
352
360
/// @return Ok(usize) 调整后,文件访问指针相对于文件头部的偏移量
353
361
/// @return Err(SystemError) 调整失败,返回posix错误码
354
- pub fn lseek ( fd : i32 , seek : SeekFrom ) -> Result < usize , SystemError > {
362
+ pub fn lseek ( fd : i32 , offset : i64 , seek : u32 ) -> Result < usize , SystemError > {
363
+ let seek = match seek {
364
+ SEEK_SET => Ok ( SeekFrom :: SeekSet ( offset) ) ,
365
+ SEEK_CUR => Ok ( SeekFrom :: SeekCurrent ( offset) ) ,
366
+ SEEK_END => Ok ( SeekFrom :: SeekEnd ( offset) ) ,
367
+ SEEK_MAX => Ok ( SeekFrom :: SeekEnd ( 0 ) ) ,
368
+ _ => Err ( SystemError :: EINVAL ) ,
369
+ } ?;
370
+
355
371
let binding = ProcessManager :: current_pcb ( ) . fd_table ( ) ;
356
372
let fd_table_guard = binding. read ( ) ;
357
373
let file = fd_table_guard
@@ -429,10 +445,14 @@ impl Syscall {
429
445
/// EFAULT | 错误的地址
430
446
///
431
447
/// ENAMETOOLONG | 路径过长
432
- pub fn chdir ( dest_path : & str ) -> Result < usize , SystemError > {
448
+ pub fn chdir ( path : * const u8 ) -> Result < usize , SystemError > {
449
+ if path. is_null ( ) {
450
+ return Err ( SystemError :: EFAULT ) ;
451
+ }
452
+
453
+ let path = check_and_clone_cstr ( path, Some ( MAX_PATHLEN ) ) ?;
433
454
let proc = ProcessManager :: current_pcb ( ) ;
434
455
// Copy path to kernel space to avoid some security issues
435
- let path = dest_path. to_string ( ) ;
436
456
let mut new_path = String :: from ( "" ) ;
437
457
if path. len ( ) > 0 {
438
458
let cwd = match path. as_bytes ( ) [ 0 ] {
@@ -461,8 +481,7 @@ impl Syscall {
461
481
}
462
482
let inode =
463
483
match ROOT_INODE ( ) . lookup_follow_symlink ( & new_path, VFS_MAX_FOLLOW_SYMLINK_TIMES ) {
464
- Err ( e) => {
465
- kerror ! ( "Change Directory Failed, Error = {:?}" , e) ;
484
+ Err ( _) => {
466
485
return Err ( SystemError :: ENOENT ) ;
467
486
}
468
487
Ok ( i) => i,
@@ -534,8 +553,9 @@ impl Syscall {
534
553
/// @param path(r8) 路径 / mode(r9) 模式
535
554
///
536
555
/// @return uint64_t 负数错误码 / 0表示成功
537
- pub fn mkdir ( path : & str , mode : usize ) -> Result < usize , SystemError > {
538
- return do_mkdir ( path, FileMode :: from_bits_truncate ( mode as u32 ) ) . map ( |x| x as usize ) ;
556
+ pub fn mkdir ( path : * const u8 , mode : usize ) -> Result < usize , SystemError > {
557
+ let path = check_and_clone_cstr ( path, Some ( MAX_PATHLEN ) ) ?;
558
+ return do_mkdir ( & path, FileMode :: from_bits_truncate ( mode as u32 ) ) . map ( |x| x as usize ) ;
539
559
}
540
560
541
561
/// **删除文件夹、取消文件的链接、删除文件的系统调用**
@@ -547,14 +567,15 @@ impl Syscall {
547
567
/// - `flags`:标志位
548
568
///
549
569
///
550
- pub fn unlinkat ( dirfd : i32 , pathname : & str , flags : u32 ) -> Result < usize , SystemError > {
570
+ pub fn unlinkat ( dirfd : i32 , path : * const u8 , flags : u32 ) -> Result < usize , SystemError > {
551
571
let flags = AtFlags :: from_bits ( flags as i32 ) . ok_or ( SystemError :: EINVAL ) ?;
552
572
573
+ let path = check_and_clone_cstr ( path, Some ( MAX_PATHLEN ) ) ?;
574
+
553
575
if flags. contains ( AtFlags :: AT_REMOVEDIR ) {
554
576
// kdebug!("rmdir");
555
- match do_remove_dir ( dirfd, & pathname ) {
577
+ match do_remove_dir ( dirfd, & path ) {
556
578
Err ( err) => {
557
- kerror ! ( "Failed to Remove Directory, Error Code = {:?}" , err) ;
558
579
return Err ( err) ;
559
580
}
560
581
Ok ( _) => {
@@ -563,9 +584,8 @@ impl Syscall {
563
584
}
564
585
}
565
586
566
- match do_unlink_at ( dirfd, & pathname ) {
587
+ match do_unlink_at ( dirfd, & path ) {
567
588
Err ( err) => {
568
- kerror ! ( "Failed to Remove Directory, Error Code = {:?}" , err) ;
569
589
return Err ( err) ;
570
590
}
571
591
Ok ( _) => {
@@ -574,32 +594,14 @@ impl Syscall {
574
594
}
575
595
}
576
596
577
- pub fn rmdir ( pathname : * const u8 ) -> Result < usize , SystemError > {
578
- let pathname: String = check_and_clone_cstr ( pathname, Some ( MAX_PATHLEN ) ) ?;
579
- if pathname. len ( ) >= MAX_PATHLEN {
580
- return Err ( SystemError :: ENAMETOOLONG ) ;
581
- }
582
- let pathname = pathname. as_str ( ) . trim ( ) ;
583
- return do_remove_dir ( AtFlags :: AT_FDCWD . bits ( ) , pathname) . map ( |v| v as usize ) ;
597
+ pub fn rmdir ( path : * const u8 ) -> Result < usize , SystemError > {
598
+ let path = check_and_clone_cstr ( path, Some ( MAX_PATHLEN ) ) ?;
599
+ return do_remove_dir ( AtFlags :: AT_FDCWD . bits ( ) , & path) . map ( |v| v as usize ) ;
584
600
}
585
601
586
- pub fn unlink ( pathname : * const u8 ) -> Result < usize , SystemError > {
587
- if pathname. is_null ( ) {
588
- return Err ( SystemError :: EFAULT ) ;
589
- }
590
- let ureader = UserBufferReader :: new ( pathname, MAX_PATHLEN , true ) ?;
591
-
592
- let buf: & [ u8 ] = ureader. buffer ( 0 ) . unwrap ( ) ;
593
-
594
- let pathname: & CStr = CStr :: from_bytes_until_nul ( buf) . map_err ( |_| SystemError :: EINVAL ) ?;
595
-
596
- let pathname: & str = pathname. to_str ( ) . map_err ( |_| SystemError :: EINVAL ) ?;
597
- if pathname. len ( ) >= MAX_PATHLEN {
598
- return Err ( SystemError :: ENAMETOOLONG ) ;
599
- }
600
- let pathname = pathname. trim ( ) ;
601
-
602
- return do_unlink_at ( AtFlags :: AT_FDCWD . bits ( ) , pathname) . map ( |v| v as usize ) ;
602
+ pub fn unlink ( path : * const u8 ) -> Result < usize , SystemError > {
603
+ let path = check_and_clone_cstr ( path, Some ( MAX_PATHLEN ) ) ?;
604
+ return do_unlink_at ( AtFlags :: AT_FDCWD . bits ( ) , & path) . map ( |v| v as usize ) ;
603
605
}
604
606
605
607
/// # 修改文件名
@@ -892,45 +894,44 @@ impl Syscall {
892
894
}
893
895
894
896
pub fn fstat ( fd : i32 , usr_kstat : * mut PosixKstat ) -> Result < usize , SystemError > {
897
+ let mut writer = UserBufferWriter :: new ( usr_kstat, size_of :: < PosixKstat > ( ) , true ) ?;
895
898
let kstat = Self :: do_fstat ( fd) ?;
896
- if usr_kstat. is_null ( ) {
897
- return Err ( SystemError :: EFAULT ) ;
898
- }
899
- unsafe {
900
- * usr_kstat = kstat;
901
- }
899
+
900
+ writer. copy_one_to_user ( & kstat, 0 ) ?;
902
901
return Ok ( 0 ) ;
903
902
}
904
903
905
- pub fn stat ( path : & str , user_kstat : * mut PosixKstat ) -> Result < usize , SystemError > {
906
- let fd = Self :: open ( path, FileMode :: O_RDONLY , ModeType :: empty ( ) , true ) ?;
904
+ pub fn stat ( path : * const u8 , user_kstat : * mut PosixKstat ) -> Result < usize , SystemError > {
905
+ let fd = Self :: open (
906
+ path,
907
+ FileMode :: O_RDONLY . bits ( ) ,
908
+ ModeType :: empty ( ) . bits ( ) ,
909
+ true ,
910
+ ) ?;
907
911
let r = Self :: fstat ( fd as i32 , user_kstat) ;
908
912
Self :: close ( fd) . ok ( ) ;
909
913
return r;
910
914
}
911
915
912
- pub fn lstat ( path : & str , user_kstat : * mut PosixKstat ) -> Result < usize , SystemError > {
913
- let fd = Self :: open ( path, FileMode :: O_RDONLY , ModeType :: empty ( ) , false ) ?;
916
+ pub fn lstat ( path : * const u8 , user_kstat : * mut PosixKstat ) -> Result < usize , SystemError > {
917
+ let fd = Self :: open (
918
+ path,
919
+ FileMode :: O_RDONLY . bits ( ) ,
920
+ ModeType :: empty ( ) . bits ( ) ,
921
+ false ,
922
+ ) ?;
914
923
let r = Self :: fstat ( fd as i32 , user_kstat) ;
915
924
Self :: close ( fd) . ok ( ) ;
916
925
return r;
917
926
}
918
927
919
928
pub fn mknod (
920
- path_ptr : * const i8 ,
929
+ path : * const u8 ,
921
930
mode : ModeType ,
922
931
dev_t : DeviceNumber ,
923
932
) -> Result < usize , SystemError > {
924
- // 安全检验
925
- let len = unsafe { CStr :: from_ptr ( path_ptr) . to_bytes ( ) . len ( ) } ;
926
- let user_buffer = UserBufferReader :: new ( path_ptr, len, true ) ?;
927
- let buf = user_buffer. read_from_user :: < u8 > ( 0 ) ?;
928
- let path = core:: str:: from_utf8 ( buf) . map_err ( |_| SystemError :: EINVAL ) ?;
929
-
930
- // 文件名过长
931
- if path. len ( ) > MAX_PATHLEN as usize {
932
- return Err ( SystemError :: ENAMETOOLONG ) ;
933
- }
933
+ let path = check_and_clone_cstr ( path, Some ( MAX_PATHLEN ) ) ?;
934
+ let path = path. as_str ( ) . trim ( ) ;
934
935
935
936
let inode: Result < Arc < dyn IndexNode > , SystemError > =
936
937
ROOT_INODE ( ) . lookup_follow_symlink ( path, VFS_MAX_FOLLOW_SYMLINK_TIMES ) ;
@@ -980,12 +981,9 @@ impl Syscall {
980
981
buf_size : usize ,
981
982
) -> Result < usize , SystemError > {
982
983
let path = check_and_clone_cstr ( path, Some ( MAX_PATHLEN ) ) ?;
984
+ let path = path. as_str ( ) . trim ( ) ;
983
985
let mut user_buf = UserBufferWriter :: new ( user_buf, buf_size, true ) ?;
984
986
985
- if path. len ( ) == 0 {
986
- return Err ( SystemError :: EINVAL ) ;
987
- }
988
-
989
987
let ( inode, path) = user_path_at ( & ProcessManager :: current_pcb ( ) , dirfd, & path) ?;
990
988
991
989
let inode = inode. lookup ( path. as_str ( ) ) ?;
0 commit comments