This source file includes following definitions.
- dupfd
- sys_dup2
- sys_dup
- sys_fcntl
- kill_fasync
1
2
3
4
5
6
7 #include <asm/segment.h>
8
9 #include <linux/sched.h>
10 #include <linux/kernel.h>
11 #include <linux/errno.h>
12 #include <linux/stat.h>
13 #include <linux/fcntl.h>
14 #include <linux/string.h>
15
16 extern int fcntl_getlk(unsigned int, struct flock *);
17 extern int fcntl_setlk(unsigned int, unsigned int, struct flock *);
18 extern int sock_fcntl (struct file *, unsigned int cmd, unsigned long arg);
19
20 static inline int dupfd(unsigned int fd, unsigned int arg)
21 {
22 if (fd >= NR_OPEN || !current->files->fd[fd])
23 return -EBADF;
24 if (arg >= NR_OPEN)
25 return -EINVAL;
26 while (arg < NR_OPEN)
27 if (current->files->fd[arg])
28 arg++;
29 else
30 break;
31 if (arg >= NR_OPEN)
32 return -EMFILE;
33 FD_CLR(arg, ¤t->files->close_on_exec);
34 (current->files->fd[arg] = current->files->fd[fd])->f_count++;
35 return arg;
36 }
37
38 asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
39 {
40 if (oldfd >= NR_OPEN || !current->files->fd[oldfd])
41 return -EBADF;
42 if (newfd == oldfd)
43 return newfd;
44 if (newfd >= NR_OPEN)
45 return -EBADF;
46
47 sys_close(newfd);
48 return dupfd(oldfd,newfd);
49 }
50
51 asmlinkage int sys_dup(unsigned int fildes)
52 {
53 return dupfd(fildes,0);
54 }
55
56 asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
57 {
58 struct file * filp;
59 struct task_struct *p;
60 int task_found = 0;
61
62 if (fd >= NR_OPEN || !(filp = current->files->fd[fd]))
63 return -EBADF;
64 switch (cmd) {
65 case F_DUPFD:
66 return dupfd(fd,arg);
67 case F_GETFD:
68 return FD_ISSET(fd, ¤t->files->close_on_exec);
69 case F_SETFD:
70 if (arg&1)
71 FD_SET(fd, ¤t->files->close_on_exec);
72 else
73 FD_CLR(fd, ¤t->files->close_on_exec);
74 return 0;
75 case F_GETFL:
76 return filp->f_flags;
77 case F_SETFL:
78
79
80
81
82 if (IS_APPEND(filp->f_inode) && !(arg & O_APPEND))
83 return -EPERM;
84 if ((arg & FASYNC) && !(filp->f_flags & FASYNC) &&
85 filp->f_op->fasync)
86 filp->f_op->fasync(filp->f_inode, filp, 1);
87 if (!(arg & FASYNC) && (filp->f_flags & FASYNC) &&
88 filp->f_op->fasync)
89 filp->f_op->fasync(filp->f_inode, filp, 0);
90 filp->f_flags &= ~(O_APPEND | O_NONBLOCK | FASYNC);
91 filp->f_flags |= arg & (O_APPEND | O_NONBLOCK |
92 FASYNC);
93 return 0;
94 case F_GETLK:
95 return fcntl_getlk(fd, (struct flock *) arg);
96 case F_SETLK:
97 return fcntl_setlk(fd, cmd, (struct flock *) arg);
98 case F_SETLKW:
99 return fcntl_setlk(fd, cmd, (struct flock *) arg);
100 case F_GETOWN:
101
102
103
104
105
106
107
108 return filp->f_owner;
109 case F_SETOWN:
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132 if (current->pgrp == -arg || current->pid == arg)
133 goto fasync_ok;
134
135 for_each_task(p) {
136 if ((p->pid == arg) || (p->pid == -arg) ||
137 (p->pgrp == -arg)) {
138 task_found++;
139 if ((p->session != current->session) &&
140 (p->uid != current->uid) &&
141 (p->euid != current->euid) &&
142 !suser())
143 return -EPERM;
144 break;
145 }
146 }
147 if ((task_found == 0) && !suser())
148 return -EINVAL;
149 fasync_ok:
150 filp->f_owner = arg;
151 if (S_ISSOCK (filp->f_inode->i_mode))
152 sock_fcntl (filp, F_SETOWN, arg);
153 return 0;
154 default:
155
156 if (S_ISSOCK (filp->f_inode->i_mode))
157 {
158 return (sock_fcntl (filp, cmd, arg));
159 }
160 return -EINVAL;
161 }
162 }
163
164 void kill_fasync(struct fasync_struct *fa, int sig)
165 {
166 while (fa) {
167 if (fa->magic != FASYNC_MAGIC) {
168 printk("kill_fasync: bad magic number in "
169 "fasync_struct!\n");
170 return;
171 }
172 if (fa->fa_file->f_owner > 0)
173 kill_proc(fa->fa_file->f_owner, sig, 1);
174 else
175 kill_pg(-fa->fa_file->f_owner, sig, 1);
176 fa = fa->fa_next;
177 }
178 }