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
- close_fp
- 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 #include <linux/tty.h>
18 #include <asm/segment.h>
19
20 extern void fcntl_remove_locks(struct task_struct *, struct file *);
21
22 struct file_operations * chrdev_fops[MAX_CHRDEV] = {
23 NULL,
24 };
25
26 struct file_operations * blkdev_fops[MAX_BLKDEV] = {
27 NULL,
28 };
29
30 int sys_ustat(int dev, struct ustat * ubuf)
31 {
32 return -ENOSYS;
33 }
34
35 int sys_statfs(const char * path, struct statfs * buf)
36 {
37 struct inode * inode;
38 int error;
39
40 verify_area(buf, sizeof(struct statfs));
41 error = namei(path,&inode);
42 if (error)
43 return error;
44 if (!inode->i_sb->s_op->statfs) {
45 iput(inode);
46 return -ENOSYS;
47 }
48 inode->i_sb->s_op->statfs(inode->i_sb, buf);
49 iput(inode);
50 return 0;
51 }
52
53 int sys_fstatfs(unsigned int fd, struct statfs * buf)
54 {
55 struct inode * inode;
56 struct file * file;
57
58 verify_area(buf, sizeof(struct statfs));
59 if (fd >= NR_OPEN || !(file = current->filp[fd]))
60 return -EBADF;
61 if (!(inode = file->f_inode))
62 return -ENOENT;
63 if (!inode->i_sb->s_op->statfs)
64 return -ENOSYS;
65 inode->i_sb->s_op->statfs(inode->i_sb, buf);
66 return 0;
67 }
68
69 int sys_truncate(const char * path, unsigned int length)
70 {
71 struct inode * inode;
72 int error;
73
74 error = namei(path,&inode);
75 if (error)
76 return error;
77 if (S_ISDIR(inode->i_mode) || !permission(inode,MAY_WRITE)) {
78 iput(inode);
79 return -EACCES;
80 }
81 if (IS_RDONLY(inode)) {
82 iput(inode);
83 return -EROFS;
84 }
85 inode->i_size = length;
86 if (inode->i_op && inode->i_op->truncate)
87 inode->i_op->truncate(inode);
88 inode->i_atime = inode->i_mtime = CURRENT_TIME;
89 inode->i_dirt = 1;
90 iput(inode);
91 return 0;
92 }
93
94 int sys_ftruncate(unsigned int fd, unsigned int length)
95 {
96 struct inode * inode;
97 struct file * file;
98
99 if (fd >= NR_OPEN || !(file = current->filp[fd]))
100 return -EBADF;
101 if (!(inode = file->f_inode))
102 return -ENOENT;
103 if (S_ISDIR(inode->i_mode) || !(file->f_mode & 2))
104 return -EACCES;
105 inode->i_size = length;
106 if (inode->i_op && inode->i_op->truncate)
107 inode->i_op->truncate(inode);
108 inode->i_atime = inode->i_mtime = CURRENT_TIME;
109 inode->i_dirt = 1;
110 return 0;
111 }
112
113
114
115
116
117 int sys_utime(char * filename, struct utimbuf * times)
118 {
119 struct inode * inode;
120 long actime,modtime;
121 int error;
122
123 error = namei(filename,&inode);
124 if (error)
125 return error;
126 if (IS_RDONLY(inode)) {
127 iput(inode);
128 return -EROFS;
129 }
130 if (times) {
131 if ((current->euid != inode->i_uid) && !suser()) {
132 iput(inode);
133 return -EPERM;
134 }
135 actime = get_fs_long((unsigned long *) ×->actime);
136 modtime = get_fs_long((unsigned long *) ×->modtime);
137 } else {
138 if ((current->euid != inode->i_uid) &&
139 !permission(inode,MAY_WRITE)) {
140 iput(inode);
141 return -EACCES;
142 }
143 actime = modtime = CURRENT_TIME;
144 }
145 inode->i_atime = actime;
146 inode->i_mtime = modtime;
147 inode->i_dirt = 1;
148 iput(inode);
149 return 0;
150 }
151
152
153
154
155
156 int sys_access(const char * filename,int mode)
157 {
158 struct inode * inode;
159 int res, i_mode;
160
161 mode &= 0007;
162 res = namei(filename,&inode);
163 if (res)
164 return res;
165 i_mode = res = inode->i_mode & 0777;
166 iput(inode);
167 if (current->uid == inode->i_uid)
168 res >>= 6;
169 else if (in_group_p(inode->i_gid))
170 res >>= 3;
171 if ((res & 0007 & mode) == mode)
172 return 0;
173
174
175
176
177
178
179 if ((!current->uid) &&
180 (!(mode & 1) || (i_mode & 0111)))
181 return 0;
182 return -EACCES;
183 }
184
185 int sys_chdir(const char * filename)
186 {
187 struct inode * inode;
188 int error;
189
190 error = namei(filename,&inode);
191 if (error)
192 return error;
193 if (!S_ISDIR(inode->i_mode)) {
194 iput(inode);
195 return -ENOTDIR;
196 }
197 if (!permission(inode,MAY_EXEC)) {
198 iput(inode);
199 return -EACCES;
200 }
201 iput(current->pwd);
202 current->pwd = inode;
203 return (0);
204 }
205
206 int sys_chroot(const char * filename)
207 {
208 struct inode * inode;
209 int error;
210
211 error = namei(filename,&inode);
212 if (error)
213 return error;
214 if (!S_ISDIR(inode->i_mode)) {
215 iput(inode);
216 return -ENOTDIR;
217 }
218 if (!suser()) {
219 iput(inode);
220 return -EPERM;
221 }
222 iput(current->root);
223 current->root = inode;
224 return (0);
225 }
226
227 int sys_fchmod(unsigned int fd, mode_t mode)
228 {
229 struct inode * inode;
230 struct file * file;
231
232 if (fd >= NR_OPEN || !(file = current->filp[fd]))
233 return -EBADF;
234 if (!(inode = file->f_inode))
235 return -ENOENT;
236 if ((current->euid != inode->i_uid) && !suser())
237 return -EPERM;
238 if (IS_RDONLY(inode))
239 return -EROFS;
240 inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
241 inode->i_dirt = 1;
242 return 0;
243 }
244
245 int sys_chmod(const char * filename, mode_t mode)
246 {
247 struct inode * inode;
248 int error;
249
250 error = namei(filename,&inode);
251 if (error)
252 return error;
253 if ((current->euid != inode->i_uid) && !suser()) {
254 iput(inode);
255 return -EPERM;
256 }
257 if (IS_RDONLY(inode)) {
258 iput(inode);
259 return -EROFS;
260 }
261 inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
262 inode->i_dirt = 1;
263 iput(inode);
264 return 0;
265 }
266
267 int sys_fchown(unsigned int fd, uid_t user, gid_t group)
268 {
269 struct inode * inode;
270 struct file * file;
271
272 if (fd >= NR_OPEN || !(file = current->filp[fd]))
273 return -EBADF;
274 if (!(inode = file->f_inode))
275 return -ENOENT;
276 if (IS_RDONLY(inode))
277 return -EROFS;
278 if ((current->euid == inode->i_uid && user == inode->i_uid &&
279 (in_group_p(group) || group == inode->i_gid)) ||
280 suser()) {
281 inode->i_uid = user;
282 inode->i_gid = group;
283 inode->i_dirt=1;
284 return 0;
285 }
286 return -EPERM;
287 }
288
289 int sys_chown(const char * filename, uid_t user, gid_t group)
290 {
291 struct inode * inode;
292 int error;
293
294 error = lnamei(filename,&inode);
295 if (error)
296 return error;
297 if (IS_RDONLY(inode)) {
298 iput(inode);
299 return -EROFS;
300 }
301 if ((current->euid == inode->i_uid && user == inode->i_uid &&
302 (in_group_p(group) || group == inode->i_gid)) ||
303 suser()) {
304 inode->i_uid = user;
305 inode->i_gid = group;
306 inode->i_dirt=1;
307 iput(inode);
308 return 0;
309 }
310 iput(inode);
311 return -EPERM;
312 }
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328 int sys_open(const char * filename,int flag,int mode)
329 {
330 struct inode * inode;
331 struct file * f;
332 int i,fd;
333
334 for(fd=0 ; fd<NR_OPEN ; fd++)
335 if (!current->filp[fd])
336 break;
337 if (fd>=NR_OPEN)
338 return -EMFILE;
339 current->close_on_exec &= ~(1<<fd);
340 f = get_empty_filp();
341 if (!f)
342 return -ENFILE;
343 current->filp[fd] = f;
344 f->f_flags = flag;
345 if (f->f_mode = (flag+1) & O_ACCMODE)
346 flag++;
347 if (flag & (O_TRUNC | O_CREAT))
348 flag |= 2;
349 i = open_namei(filename,flag,mode,&inode,NULL);
350 if (i) {
351 current->filp[fd]=NULL;
352 f->f_count--;
353 return i;
354 }
355 if (flag & O_TRUNC)
356 if (inode->i_op && inode->i_op->truncate) {
357 inode->i_size = 0;
358 inode->i_op->truncate(inode);
359 }
360 if (!IS_RDONLY(inode)) {
361 inode->i_atime = CURRENT_TIME;
362 inode->i_dirt = 1;
363 }
364 f->f_inode = inode;
365 f->f_pos = 0;
366 f->f_reada = 0;
367 f->f_op = NULL;
368 if (inode->i_op)
369 f->f_op = inode->i_op->default_file_ops;
370 if (f->f_op && f->f_op->open)
371 if (i = f->f_op->open(inode,f)) {
372 iput(inode);
373 f->f_count--;
374 current->filp[fd]=NULL;
375 return i;
376 }
377 return (fd);
378 }
379
380 int sys_creat(const char * pathname, int mode)
381 {
382 return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
383 }
384
385 static int close_fp(struct file *filp)
386 {
387 struct inode *inode;
388
389 if (filp->f_count == 0) {
390 printk("Close: file count is 0\n");
391 return 0;
392 }
393 inode = filp->f_inode;
394 if (S_ISREG(inode->i_mode))
395 fcntl_remove_locks(current, filp);
396 if (filp->f_count > 1) {
397 filp->f_count--;
398 return 0;
399 }
400 if (filp->f_op && filp->f_op->release)
401 filp->f_op->release(inode,filp);
402 filp->f_count--;
403 filp->f_inode = NULL;
404 iput(inode);
405 return 0;
406 }
407
408 int sys_close(unsigned int fd)
409 {
410 struct file * filp;
411
412 if (fd >= NR_OPEN)
413 return -EINVAL;
414 current->close_on_exec &= ~(1<<fd);
415 if (!(filp = current->filp[fd]))
416 return -EINVAL;
417 current->filp[fd] = NULL;
418 return (close_fp (filp));
419 }
420
421
422
423
424
425
426
427
428
429
430
431 int sys_vhangup(void)
432 {
433 int i,j;
434 struct file *filep;
435 struct tty_struct *tty;
436 extern void kill_wait (struct wait_queue **q, int signal);
437 extern int kill_pg (int pgrp, int sig, int priv);
438
439 if (!suser())
440 return -EPERM;
441
442 kill_pg(current->pgrp, SIGHUP, 0);
443
444 if (current->tty < 0)
445 return 0;
446
447 for (i = 0; i < NR_TASKS; i++) {
448 if (task[i] == NULL)
449 continue;
450 for (j = 0; j < NR_OPEN; j++) {
451 filep = task[i]->filp[j];
452 if (!filep)
453 continue;
454 if (!S_ISCHR(filep->f_inode->i_mode))
455 continue;
456 if ((MAJOR(filep->f_inode->i_rdev) == 5 ||
457 MAJOR(filep->f_inode->i_rdev) == 4 ) &&
458 (MAJOR(filep->f_rdev) == 4 &&
459 MINOR(filep->f_rdev) == MINOR (current->tty))) {
460
461
462
463 task[i]->filp[j] = NULL;
464 kill_wait (&filep->f_inode->i_wait, SIGKILL);
465
466
467
468
469 wake_up (&filep->f_inode->i_wait);
470
471
472
473 current->close_on_exec &= ~(1<<j);
474 close_fp (filep);
475 }
476 }
477
478
479
480
481 if (task[i]->tty == current->tty && task[i] != current) {
482 task[i]->tty = -1;
483 }
484 }
485
486 tty = TTY_TABLE(MINOR(current->tty));
487 tty->session = 0;
488 tty->pgrp = -1;
489 current->tty = -1;
490 return 0;
491 }
492