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