@@ -7,6 +7,7 @@ use crate::{
7
7
io:: SeekFrom ,
8
8
kerror,
9
9
syscall:: { Syscall , SystemError } ,
10
+ time:: TimeSpec ,
10
11
} ;
11
12
12
13
use super :: {
@@ -22,6 +23,102 @@ pub const SEEK_CUR: u32 = 1;
22
23
pub const SEEK_END : u32 = 2 ;
23
24
pub const SEEK_MAX : u32 = 3 ;
24
25
26
+ bitflags ! {
27
+ /// 文件类型和权限
28
+ pub struct ModeType : u32 {
29
+ /// 掩码
30
+ const S_IFMT = 0o0_170_000 ;
31
+ /// 文件类型
32
+ const S_IFSOCK = 0o140000 ;
33
+ const S_IFLNK = 0o120000 ;
34
+ const S_IFREG = 0o100000 ;
35
+ const S_IFBLK = 0o060000 ;
36
+ const S_IFDIR = 0o040000 ;
37
+ const S_IFCHR = 0o020000 ;
38
+ const S_IFIFO = 0o010000 ;
39
+
40
+ const S_ISUID = 0o004000 ;
41
+ const S_ISGID = 0o002000 ;
42
+ const S_ISVTX = 0o001000 ;
43
+ /// 文件用户权限
44
+ const S_IRWXU = 0o0700 ;
45
+ const S_IRUSR = 0o0400 ;
46
+ const S_IWUSR = 0o0200 ;
47
+ const S_IXUSR = 0o0100 ;
48
+ /// 文件组权限
49
+ const S_IRWXG = 0o0070 ;
50
+ const S_IRGRP = 0o0040 ;
51
+ const S_IWGRP = 0o0020 ;
52
+ const S_IXGRP = 0o0010 ;
53
+ /// 文件其他用户权限
54
+ const S_IRWXO = 0o0007 ;
55
+ const S_IROTH = 0o0004 ;
56
+ const S_IWOTH = 0o0002 ;
57
+ const S_IXOTH = 0o0001 ;
58
+ }
59
+ }
60
+
61
+ #[ repr( C ) ]
62
+ /// # 文件信息结构体
63
+ pub struct PosixKstat {
64
+ /// 硬件设备ID
65
+ dev_id : u64 ,
66
+ /// inode号
67
+ inode : u64 ,
68
+ /// 硬链接数
69
+ nlink : u64 ,
70
+ /// 文件权限
71
+ mode : ModeType ,
72
+ /// 所有者用户ID
73
+ uid : i32 ,
74
+ /// 所有者组ID
75
+ gid : i32 ,
76
+ /// 设备ID
77
+ rdev : i64 ,
78
+ /// 文件大小
79
+ size : i64 ,
80
+ /// 文件系统块大小
81
+ blcok_size : i64 ,
82
+ /// 分配的512B块数
83
+ blocks : u64 ,
84
+ /// 最后访问时间
85
+ atime : TimeSpec ,
86
+ /// 最后修改时间
87
+ mtime : TimeSpec ,
88
+ /// 最后状态变化时间
89
+ ctime : TimeSpec ,
90
+ /// 用于填充结构体大小的空白数据
91
+ pub _pad : [ i8 ; 24 ] ,
92
+ }
93
+ impl PosixKstat {
94
+ fn new ( ) -> Self {
95
+ Self {
96
+ inode : 0 ,
97
+ dev_id : 0 ,
98
+ mode : ModeType { bits : 0 } ,
99
+ nlink : 0 ,
100
+ uid : 0 ,
101
+ gid : 0 ,
102
+ rdev : 0 ,
103
+ size : 0 ,
104
+ atime : TimeSpec {
105
+ tv_sec : 0 ,
106
+ tv_nsec : 0 ,
107
+ } ,
108
+ mtime : TimeSpec {
109
+ tv_sec : 0 ,
110
+ tv_nsec : 0 ,
111
+ } ,
112
+ ctime : TimeSpec {
113
+ tv_sec : 0 ,
114
+ tv_nsec : 0 ,
115
+ } ,
116
+ blcok_size : 0 ,
117
+ blocks : 0 ,
118
+ _pad : Default :: default ( ) ,
119
+ }
120
+ }
121
+ }
25
122
impl Syscall {
26
123
/// @brief 为当前进程打开一个文件
27
124
///
@@ -474,6 +571,66 @@ impl Syscall {
474
571
}
475
572
return Err ( SystemError :: EBADF ) ;
476
573
}
574
+ fn do_fstat ( fd : i32 ) -> Result < PosixKstat , SystemError > {
575
+ let cur = current_pcb ( ) ;
576
+ match cur. get_file_ref_by_fd ( fd) {
577
+ Some ( file) => {
578
+ let mut kstat = PosixKstat :: new ( ) ;
579
+ // 获取文件信息
580
+ match file. metadata ( ) {
581
+ Ok ( metadata) => {
582
+ kstat. size = metadata. size as i64 ;
583
+ kstat. dev_id = metadata. dev_id as u64 ;
584
+ kstat. inode = metadata. inode_id as u64 ;
585
+ kstat. blcok_size = metadata. blk_size as i64 ;
586
+ kstat. blocks = metadata. blocks as u64 ;
587
+
588
+ kstat. atime . tv_sec = metadata. atime . tv_sec ;
589
+ kstat. atime . tv_nsec = metadata. atime . tv_nsec ;
590
+ kstat. mtime . tv_sec = metadata. mtime . tv_sec ;
591
+ kstat. mtime . tv_nsec = metadata. mtime . tv_nsec ;
592
+ kstat. ctime . tv_sec = metadata. ctime . tv_sec ;
593
+ kstat. ctime . tv_nsec = metadata. ctime . tv_nsec ;
594
+
595
+ kstat. nlink = metadata. nlinks as u64 ;
596
+ kstat. uid = metadata. uid as i32 ;
597
+ kstat. gid = metadata. gid as i32 ;
598
+ kstat. rdev = metadata. raw_dev as i64 ;
599
+ kstat. mode . bits = metadata. mode ;
600
+ match file. file_type ( ) {
601
+ FileType :: File => kstat. mode . insert ( ModeType :: S_IFMT ) ,
602
+ FileType :: Dir => kstat. mode . insert ( ModeType :: S_IFDIR ) ,
603
+ FileType :: BlockDevice => kstat. mode . insert ( ModeType :: S_IFBLK ) ,
604
+ FileType :: CharDevice => kstat. mode . insert ( ModeType :: S_IFCHR ) ,
605
+ FileType :: SymLink => kstat. mode . insert ( ModeType :: S_IFLNK ) ,
606
+ FileType :: Socket => kstat. mode . insert ( ModeType :: S_IFSOCK ) ,
607
+ FileType :: Pipe => kstat. mode . insert ( ModeType :: S_IFIFO ) ,
608
+ }
609
+ }
610
+ Err ( e) => return Err ( e) ,
611
+ }
612
+
613
+ return Ok ( kstat) ;
614
+ }
615
+ None => {
616
+ return Err ( SystemError :: EINVAL ) ;
617
+ }
618
+ }
619
+ }
620
+ pub fn fstat ( fd : i32 , usr_kstat : * mut PosixKstat ) -> Result < usize , SystemError > {
621
+ match Self :: do_fstat ( fd) {
622
+ Ok ( kstat) => {
623
+ if usr_kstat. is_null ( ) {
624
+ return Err ( SystemError :: EFAULT ) ;
625
+ }
626
+ unsafe {
627
+ * usr_kstat = kstat;
628
+ }
629
+ return Ok ( 0 ) ;
630
+ }
631
+ Err ( e) => return Err ( e) ,
632
+ }
633
+ }
477
634
}
478
635
479
636
#[ repr( C ) ]
0 commit comments