|
|
1.1.1.2 root 1: /*
2: * linux/fs/fcntl.c
3: *
4: * (C) 1991 Linus Torvalds
5: */
6:
1.1 root 7: #include <string.h>
8: #include <errno.h>
9: #include <linux/sched.h>
10: #include <linux/kernel.h>
11: #include <asm/segment.h>
12:
13: #include <fcntl.h>
14: #include <sys/stat.h>
15:
16: extern int sys_close(int fd);
17:
18: static int dupfd(unsigned int fd, unsigned int arg)
19: {
20: if (fd >= NR_OPEN || !current->filp[fd])
21: return -EBADF;
22: if (arg >= NR_OPEN)
23: return -EINVAL;
24: while (arg < NR_OPEN)
25: if (current->filp[arg])
26: arg++;
27: else
28: break;
29: if (arg >= NR_OPEN)
30: return -EMFILE;
31: current->close_on_exec &= ~(1<<arg);
32: (current->filp[arg] = current->filp[fd])->f_count++;
33: return arg;
34: }
35:
36: int sys_dup2(unsigned int oldfd, unsigned int newfd)
37: {
1.1.1.3 ! root 38: if (newfd == oldfd)
! 39: return newfd;
1.1 root 40: sys_close(newfd);
41: return dupfd(oldfd,newfd);
42: }
43:
44: int sys_dup(unsigned int fildes)
45: {
46: return dupfd(fildes,0);
47: }
48:
49: int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
50: {
51: struct file * filp;
52:
53: if (fd >= NR_OPEN || !(filp = current->filp[fd]))
54: return -EBADF;
55: switch (cmd) {
56: case F_DUPFD:
57: return dupfd(fd,arg);
58: case F_GETFD:
59: return (current->close_on_exec>>fd)&1;
60: case F_SETFD:
61: if (arg&1)
62: current->close_on_exec |= (1<<fd);
63: else
64: current->close_on_exec &= ~(1<<fd);
65: return 0;
66: case F_GETFL:
67: return filp->f_flags;
68: case F_SETFL:
69: filp->f_flags &= ~(O_APPEND | O_NONBLOCK);
70: filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);
71: return 0;
72: case F_GETLK: case F_SETLK: case F_SETLKW:
1.1.1.3 ! root 73: return -ENOSYS;
1.1 root 74: default:
1.1.1.3 ! root 75: return -EINVAL;
1.1 root 76: }
77: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.