This source file includes following definitions.
- sys_ustat
- sys_statfs
- sys_fstatfs
- sys_truncate
- sys_ftruncate
- sys_utime
- sys_access
- sys_chdir
- sys_chroot
- sys_fchmod
- sys_chmod
- sys_fchown
- sys_chown
- sys_open
- sys_creat
- sys_close
- sys_vhangup
1
2
3
4
5
6
7 #include <linux/vfs.h>
8 #include <linux/types.h>
9 #include <linux/utime.h>
10 #include <linux/errno.h>
11 #include <linux/fcntl.h>
12 #include <linux/stat.h>
13 #include <linux/string.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/signal.h>
17
18 #include <asm/segment.h>
19
20 struct file_operations * chrdev_fops[MAX_CHRDEV] = {
21 NULL,
22 };
23
24 struct file_operations * blkdev_fops[MAX_BLKDEV] = {
25 NULL,
26 };
27
28 int sys_ustat(int dev, struct ustat * ubuf)
29 {
30 return -ENOSYS;
31 }
32
33 int sys_statfs(const char * path, struct statfs * buf)
34 {
35 struct inode * inode;
36
37 verify_area(buf, sizeof(struct statfs));
38 if (!(inode = namei(path)))
39 return -ENOENT;
40 if (!inode->i_sb->s_op->statfs) {
41 iput(inode);
42 return -ENOSYS;
43 }
44 inode->i_sb->s_op->statfs(inode->i_sb, buf);
45 iput(inode);
46 return 0;
47 }
48
49 int sys_fstatfs(unsigned int fd, struct statfs * buf)
50 {
51 struct inode * inode;
52 struct file * file;
53
54 verify_area(buf, sizeof(struct statfs));
55 if (fd >= NR_OPEN || !(file = current->filp[fd]))
56 return -EBADF;
57 if (!(inode = file->f_inode))
58 return -ENOENT;
59 if (!inode->i_sb->s_op->statfs)
60 return -ENOSYS;
61 inode->i_sb->s_op->statfs(inode->i_sb, buf);
62 return 0;
63 }
64
65 int sys_truncate(const char * path, unsigned int length)
66 {
67 struct inode * inode;
68
69 if (!(inode = namei(path)))
70 return -ENOENT;
71 if (S_ISDIR(inode->i_mode) || !permission(inode,MAY_WRITE)) {
72 iput(inode);
73 return -EACCES;
74 }
75 if (IS_RDONLY(inode)) {
76 iput(inode);
77 return -EROFS;
78 }
79 inode->i_size = length;
80 if (inode->i_op && inode->i_op->truncate)
81 inode->i_op->truncate(inode);
82 inode->i_atime = inode->i_mtime = CURRENT_TIME;
83 inode->i_dirt = 1;
84 iput(inode);
85 return 0;
86 }
87
88 int sys_ftruncate(unsigned int fd, unsigned int length)
89 {
90 struct inode * inode;
91 struct file * file;
92
93 if (fd >= NR_OPEN || !(file = current->filp[fd]))
94 return -EBADF;
95 if (!(inode = file->f_inode))
96 return -ENOENT;
97 if (S_ISDIR(inode->i_mode) || !(file->f_mode & 2))
98 return -EACCES;
99 inode->i_size = length;
100 if (inode->i_op && inode->i_op->truncate)
101 inode->i_op->truncate(inode);
102 inode->i_atime = inode->i_mtime = CURRENT_TIME;
103 inode->i_dirt = 1;
104 return 0;
105 }
106
107
108
109
110
111 int sys_utime(char * filename, struct utimbuf * times)
112 {
113 struct inode * inode;
114 long actime,modtime;
115
116 if (!(inode=namei(filename)))
117 return -ENOENT;
118 if (IS_RDONLY(inode)) {
119 iput(inode);
120 return -EROFS;
121 }
122 if (times) {
123 if ((current->euid != inode->i_uid) && !suser()) {
124 iput(inode);
125 return -EPERM;
126 }
127 actime = get_fs_long((unsigned long *) ×->actime);
128 modtime = get_fs_long((unsigned long *) ×->modtime);
129 } else {
130 if ((current->euid != inode->i_uid) &&
131 !permission(inode,MAY_WRITE)) {
132 iput(inode);
133 return -EACCES;
134 }
135 actime = modtime = CURRENT_TIME;
136 }
137 inode->i_atime = actime;
138 inode->i_mtime = modtime;
139 inode->i_dirt = 1;
140 iput(inode);
141 return 0;
142 }
143
144
145
146
147
148 int sys_access(const char * filename,int mode)
149 {
150 struct inode * inode;
151 int res, i_mode;
152
153 mode &= 0007;
154 if (!(inode=namei(filename)))
155 return -EACCES;
156 i_mode = res = inode->i_mode & 0777;
157 iput(inode);
158 if (current->uid == inode->i_uid)
159 res >>= 6;
160 else if (in_group_p(inode->i_gid))
161 res >>= 3;
162 if ((res & 0007 & mode) == mode)
163 return 0;
164
165
166
167
168
169
170 if ((!current->uid) &&
171 (!(mode & 1) || (i_mode & 0111)))
172 return 0;
173 return -EACCES;
174 }
175
176 int sys_chdir(const char * filename)
177 {
178 struct inode * inode;
179
180 if (!(inode = namei(filename)))
181 return -ENOENT;
182 if (!S_ISDIR(inode->i_mode)) {
183 iput(inode);
184 return -ENOTDIR;
185 }
186 if (!permission(inode,MAY_EXEC)) {
187 iput(inode);
188 return -EACCES;
189 }
190 iput(current->pwd);
191 current->pwd = inode;
192 return (0);
193 }
194
195 int sys_chroot(const char * filename)
196 {
197 struct inode * inode;
198
199 if (!(inode=namei(filename)))
200 return -ENOENT;
201 if (!S_ISDIR(inode->i_mode)) {
202 iput(inode);
203 return -ENOTDIR;
204 }
205 if (!suser()) {
206 iput(inode);
207 return -EPERM;
208 }
209 iput(current->root);
210 current->root = inode;
211 return (0);
212 }
213
214 int sys_fchmod(unsigned int fd, mode_t mode)
215 {
216 struct inode * inode;
217 struct file * file;
218
219 if (fd >= NR_OPEN || !(file = current->filp[fd]))
220 return -EBADF;
221 if (!(inode = file->f_inode))
222 return -ENOENT;
223 if ((current->euid != inode->i_uid) && !suser())
224 return -EPERM;
225 if (IS_RDONLY(inode))
226 return -EROFS;
227 inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
228 inode->i_dirt = 1;
229 return 0;
230 }
231
232 int sys_chmod(const char * filename, mode_t mode)
233 {
234 struct inode * inode;
235
236 if (!(inode = namei(filename)))
237 return -ENOENT;
238 if ((current->euid != inode->i_uid) && !suser()) {
239 iput(inode);
240 return -EPERM;
241 }
242 if (IS_RDONLY(inode)) {
243 iput(inode);
244 return -EROFS;
245 }
246 inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
247 inode->i_dirt = 1;
248 iput(inode);
249 return 0;
250 }
251
252 int sys_fchown(unsigned int fd, uid_t user, gid_t group)
253 {
254 struct inode * inode;
255 struct file * file;
256
257 if (fd >= NR_OPEN || !(file = current->filp[fd]))
258 return -EBADF;
259 if (!(inode = file->f_inode))
260 return -ENOENT;
261 if (IS_RDONLY(inode))
262 return -EROFS;
263 if ((current->euid == inode->i_uid && user == inode->i_uid &&
264 (in_group_p(group) || group == inode->i_gid)) ||
265 suser()) {
266 inode->i_uid = user;
267 inode->i_gid = group;
268 inode->i_dirt=1;
269 return 0;
270 }
271 return -EPERM;
272 }
273
274 int sys_chown(const char * filename, uid_t user, gid_t group)
275 {
276 struct inode * inode;
277
278 if (!(inode = lnamei(filename)))
279 return -ENOENT;
280 if (IS_RDONLY(inode)) {
281 iput(inode);
282 return -EROFS;
283 }
284 if ((current->euid == inode->i_uid && user == inode->i_uid &&
285 (in_group_p(group) || group == inode->i_gid)) ||
286 suser()) {
287 inode->i_uid = user;
288 inode->i_gid = group;
289 inode->i_dirt=1;
290 iput(inode);
291 return 0;
292 }
293 iput(inode);
294 return -EPERM;
295 }
296
297 int sys_open(const char * filename,int flag,int mode)
298 {
299 struct inode * inode;
300 struct file * f;
301 int i,fd;
302
303 for(fd=0 ; fd<NR_OPEN ; fd++)
304 if (!current->filp[fd])
305 break;
306 if (fd>=NR_OPEN)
307 return -EMFILE;
308 current->close_on_exec &= ~(1<<fd);
309 f = get_empty_filp();
310 if (!f)
311 return -ENFILE;
312 current->filp[fd] = f;
313 if ((i = open_namei(filename,flag,mode,&inode))<0) {
314 current->filp[fd]=NULL;
315 f->f_count--;
316 return i;
317 }
318 f->f_mode = "\001\002\003\000"[flag & O_ACCMODE];
319 f->f_flags = flag;
320 f->f_inode = inode;
321 f->f_pos = 0;
322 f->f_reada = 0;
323 f->f_op = NULL;
324 if (inode->i_op)
325 f->f_op = inode->i_op->default_file_ops;
326 if (f->f_op && f->f_op->open)
327 if (i = f->f_op->open(inode,f)) {
328 iput(inode);
329 f->f_count--;
330 current->filp[fd]=NULL;
331 return i;
332 }
333 return (fd);
334 }
335
336 int sys_creat(const char * pathname, int mode)
337 {
338 return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
339 }
340
341 int sys_close(unsigned int fd)
342 {
343 struct file * filp;
344 struct inode * inode;
345
346 if (fd >= NR_OPEN)
347 return -EINVAL;
348 current->close_on_exec &= ~(1<<fd);
349 if (!(filp = current->filp[fd]))
350 return -EINVAL;
351 current->filp[fd] = NULL;
352 if (filp->f_count == 0) {
353 printk("Close: file count is 0\n");
354 return 0;
355 }
356 if (filp->f_count > 1) {
357 filp->f_count--;
358 return 0;
359 }
360 inode = filp->f_inode;
361 if (filp->f_op && filp->f_op->release)
362 filp->f_op->release(inode,filp);
363 filp->f_count--;
364 filp->f_inode = NULL;
365 iput(inode);
366 return 0;
367 }
368
369 int sys_vhangup(void)
370 {
371 return -ENOSYS;
372 }