summaryrefslogtreecommitdiffstats
path: root/src/fs/fcntl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/fcntl.c')
-rw-r--r--src/fs/fcntl.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/fs/fcntl.c b/src/fs/fcntl.c
new file mode 100644
index 0000000..f3a2d29
--- /dev/null
+++ b/src/fs/fcntl.c
@@ -0,0 +1,75 @@
1/*
2 * linux/fs/fcntl.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
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
16extern int sys_close(int fd);
17
18static 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
36int sys_dup2(unsigned int oldfd, unsigned int newfd)
37{
38 sys_close(newfd);
39 return dupfd(oldfd,newfd);
40}
41
42int sys_dup(unsigned int fildes)
43{
44 return dupfd(fildes,0);
45}
46
47int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
48{
49 struct file * filp;
50
51 if (fd >= NR_OPEN || !(filp = current->filp[fd]))
52 return -EBADF;
53 switch (cmd) {
54 case F_DUPFD:
55 return dupfd(fd,arg);
56 case F_GETFD:
57 return (current->close_on_exec>>fd)&1;
58 case F_SETFD:
59 if (arg&1)
60 current->close_on_exec |= (1<<fd);
61 else
62 current->close_on_exec &= ~(1<<fd);
63 return 0;
64 case F_GETFL:
65 return filp->f_flags;
66 case F_SETFL:
67 filp->f_flags &= ~(O_APPEND | O_NONBLOCK);
68 filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);
69 return 0;
70 case F_GETLK: case F_SETLK: case F_SETLKW:
71 return -1;
72 default:
73 return -1;
74 }
75}