Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2380 | konopa | 1 | /* This file contains the code for performing four system calls relating to |
2 | * status and directories. |
||
3 | */ |
||
4 | |||
5 | /* Methods: |
||
6 | * do_chdir: perform the CHDIR system call |
||
7 | * do_stat: perform the STAT system call |
||
8 | * do_fstat: perform the FSTAT system call |
||
9 | */ |
||
10 | |||
11 | |||
12 | #include "fs.h" |
||
13 | #include "stat.h" |
||
14 | #include "file.h" |
||
15 | #include "fproc.h" |
||
16 | #include "inode.h" |
||
17 | #include "param.h" |
||
18 | |||
19 | |||
20 | static int change(inode_t **iip, char *name_ptr, int len); |
||
21 | static int stat_inode(inode_t *rip, filp_t *fil_ptr, char *user_addr); |
||
22 | |||
23 | int do_chdir() |
||
24 | { |
||
25 | |||
26 | /* Perform the chdir(file_name) system call */ |
||
27 | int r; |
||
28 | |||
29 | r = change(&fp->fp_workdir, file_name, strlen(file_name)+1); |
||
30 | |||
31 | return r; |
||
32 | } |
||
33 | |||
34 | int change(inode_t **iip, char *name_ptr, int len) |
||
35 | { |
||
36 | |||
37 | /* |
||
38 | * iip: pointer to the inode pointer for the dir |
||
39 | * name_ptr: pointer to the directory name to change to |
||
40 | * len: length of the directory name string |
||
41 | */ |
||
42 | |||
43 | /* Do the actual work for chdir() and chroot(). */ |
||
44 | |||
45 | inode_t *rip; |
||
46 | register int r; |
||
47 | |||
48 | r = OK; |
||
49 | |||
50 | /* Try to open the new directory. */ |
||
51 | if (fetch_name(name_ptr, len) != OK) |
||
52 | return err_code; |
||
53 | |||
54 | if ((rip = eat_path(user_path)) == NIL_INODE) |
||
55 | return err_code; |
||
56 | |||
57 | /* It must be a directory and also be searchable. */ |
||
58 | if ((rip->i_mode & I_TYPE) != I_DIRECTORY) |
||
59 | r = FS_ENOTDIR; |
||
60 | |||
61 | /* If error, return inode. */ |
||
62 | if (r != OK) { |
||
63 | put_inode(rip); |
||
64 | return r; |
||
65 | } |
||
66 | |||
67 | /* Everything is OK. Make the change. */ |
||
68 | put_inode(*iip); /* release the old directory */ |
||
69 | *iip = rip; /* acquire the new one */ |
||
70 | |||
71 | return OK; |
||
72 | } |
||
73 | |||
74 | int do_stat() |
||
75 | { |
||
76 | |||
77 | /* Perform the stat(name, buf) system call. */ |
||
78 | |||
79 | register inode_t *rip; |
||
80 | register int r; |
||
81 | |||
82 | /* Both stat() and fstat() use the same routine to do the real work. That |
||
83 | * routine expects an inode, so acquire it temporarily. |
||
84 | */ |
||
85 | |||
86 | if (fetch_name(file_name, strlen(file_name)+1) != OK) |
||
87 | return err_code; |
||
88 | |||
89 | if ((rip = eat_path(user_path)) == NIL_INODE) |
||
90 | return err_code; |
||
91 | |||
92 | r = stat_inode(rip, NIL_FILP, fp->buffer); /* actually do the work.*/ |
||
93 | put_inode(rip); /* release the inode */ |
||
94 | |||
95 | return r; |
||
96 | } |
||
97 | |||
98 | int do_fstat() |
||
99 | { |
||
100 | |||
101 | /* Perform the fstat(fd, buf) system call. */ |
||
102 | |||
103 | register filp_t *rfilp; |
||
104 | |||
105 | |||
106 | /* Is the file descriptor valid? */ |
||
107 | if ((rfilp = get_filp(fd)) == NIL_FILP) |
||
108 | return err_code; |
||
109 | |||
110 | if (rfilp->filp_ino == NIL_INODE) |
||
111 | return FS_ENOENT; |
||
112 | |||
113 | return(stat_inode(rfilp->filp_ino, NIL_FILP, fp->buffer)); |
||
114 | } |
||
115 | |||
116 | int stat_inode(register inode_t *rip, filp_t *fil_ptr, char *user_addr) |
||
117 | { |
||
118 | |||
119 | /* |
||
120 | * rip: pointer to inode to stat |
||
121 | * fil_ptr: filp pointer, supplied by 'fstat' |
||
122 | * user_addr: user space address where stat buf goes |
||
123 | */ |
||
124 | |||
125 | /* Common code for stat and fstat system calls. */ |
||
126 | |||
127 | stat_t statbuf; |
||
128 | |||
129 | /* Fill in the statbuf struct. */ |
||
130 | statbuf.st_ino = rip->i_num; |
||
131 | statbuf.st_mode = rip->i_mode; |
||
132 | statbuf.st_nlink = rip->i_nlinks & BYTE; |
||
133 | statbuf.st_size = rip->i_size; |
||
134 | |||
135 | /* Copy infomations to userspace. */ |
||
136 | memcpy(user_addr, &statbuf, sizeof(statbuf)); |
||
137 | |||
138 | return OK; |
||
139 | } |
||
140 |