* better
[mascara-docs.git] / i386 / linux-2.3.21 / fs / fcntl.c
blob255267da8f2f5e6946bcf8930bc7e153de01074d
1 /*
2 * linux/fs/fcntl.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
7 #include <linux/mm.h>
8 #include <linux/file.h>
9 #include <linux/smp_lock.h>
11 #include <asm/poll.h>
12 #include <asm/siginfo.h>
13 #include <asm/uaccess.h>
15 extern int sock_fcntl (struct file *, unsigned int cmd, unsigned long arg);
18 * locate_fd finds a free file descriptor in the open_fds fdset,
19 * expanding the fd arrays if necessary. The files write lock will be
20 * held on exit to ensure that the fd can be entered atomically.
23 static inline int locate_fd(struct files_struct *files,
24 struct file *file, int start)
26 unsigned int newfd;
27 int error;
29 write_lock(&files->file_lock);
31 repeat:
32 error = -EMFILE;
33 if (start < files->next_fd)
34 start = files->next_fd;
35 if (start >= files->max_fdset) {
36 expand:
37 error = expand_files(files, start);
38 if (error < 0)
39 goto out;
40 goto repeat;
43 newfd = find_next_zero_bit(files->open_fds->fds_bits,
44 files->max_fdset, start);
46 error = -EMFILE;
47 if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
48 goto out;
49 if (newfd >= files->max_fdset)
50 goto expand;
52 error = expand_files(files, newfd);
53 if (error < 0)
54 goto out;
55 if (error) /* If we might have blocked, try again. */
56 goto repeat;
58 if (start <= files->next_fd)
59 files->next_fd = newfd + 1;
61 error = newfd;
63 out:
64 return error;
67 static inline void allocate_fd(struct files_struct *files,
68 struct file *file, int fd)
70 FD_SET(fd, files->open_fds);
71 FD_CLR(fd, files->close_on_exec);
72 write_unlock(&files->file_lock);
73 fd_install(fd, file);
76 static int dupfd(struct file *file, int start)
78 struct files_struct * files = current->files;
79 int ret;
81 ret = locate_fd(files, file, start);
82 if (ret < 0)
83 goto out_putf;
84 allocate_fd(files, file, ret);
85 return ret;
87 out_putf:
88 write_unlock(&files->file_lock);
89 fput(file);
90 return ret;
93 asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
95 int err = -EBADF;
96 struct file * file;
97 struct files_struct * files = current->files;
99 write_lock(&current->files->file_lock);
100 if (!(file = fcheck(oldfd)))
101 goto out_unlock;
102 err = newfd;
103 if (newfd == oldfd)
104 goto out_unlock;
105 err = -EBADF;
106 if (newfd >= NR_OPEN)
107 goto out_unlock; /* following POSIX.1 6.2.1 */
108 get_file(file); /* We are now finished with oldfd */
110 err = expand_files(files, newfd);
111 if (err < 0) {
112 write_unlock(&files->file_lock);
113 fput(file);
114 goto out;
117 /* To avoid races with open() and dup(), we will mark the fd as
118 * in-use in the open-file bitmap throughout the entire dup2()
119 * process. This is quite safe: do_close() uses the fd array
120 * entry, not the bitmap, to decide what work needs to be
121 * done. --sct */
122 FD_SET(newfd, files->open_fds);
123 write_unlock(&files->file_lock);
125 do_close(newfd, 0);
127 write_lock(&files->file_lock);
128 allocate_fd(files, file, newfd);
129 err = newfd;
131 out:
132 return err;
133 out_unlock:
134 write_unlock(&current->files->file_lock);
135 goto out;
138 asmlinkage long sys_dup(unsigned int fildes)
140 int ret = -EBADF;
141 struct file * file = fget(fildes);
143 if (file)
144 ret = dupfd(file, 0);
145 return ret;
148 #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC)
150 static int setfl(int fd, struct file * filp, unsigned long arg)
152 struct inode * inode = filp->f_dentry->d_inode;
155 * In the case of an append-only file, O_APPEND
156 * cannot be cleared
158 if (!(arg & O_APPEND) && IS_APPEND(inode))
159 return -EPERM;
161 /* Did FASYNC state change? */
162 if ((arg ^ filp->f_flags) & FASYNC) {
163 if (filp->f_op && filp->f_op->fasync)
164 filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
167 /* required for strict SunOS emulation */
168 if (O_NONBLOCK != O_NDELAY)
169 if (arg & O_NDELAY)
170 arg |= O_NONBLOCK;
172 filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
173 return 0;
176 asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
178 struct file * filp;
179 long err = -EBADF;
181 filp = fget(fd);
182 if (!filp)
183 goto out;
184 err = 0;
185 lock_kernel();
186 switch (cmd) {
187 case F_DUPFD:
188 err = -EINVAL;
189 if (arg < NR_OPEN) {
190 get_file(filp);
191 err = dupfd(filp, arg);
193 break;
194 case F_GETFD:
195 err = FD_ISSET(fd, current->files->close_on_exec);
196 break;
197 case F_SETFD:
198 if (arg&1)
199 FD_SET(fd, current->files->close_on_exec);
200 else
201 FD_CLR(fd, current->files->close_on_exec);
202 break;
203 case F_GETFL:
204 err = filp->f_flags;
205 break;
206 case F_SETFL:
207 err = setfl(fd, filp, arg);
208 break;
209 case F_GETLK:
210 err = fcntl_getlk(fd, (struct flock *) arg);
211 break;
212 case F_SETLK:
213 err = fcntl_setlk(fd, cmd, (struct flock *) arg);
214 break;
215 case F_SETLKW:
216 err = fcntl_setlk(fd, cmd, (struct flock *) arg);
217 break;
218 case F_GETOWN:
220 * XXX If f_owner is a process group, the
221 * negative return value will get converted
222 * into an error. Oops. If we keep the
223 * current syscall conventions, the only way
224 * to fix this will be in libc.
226 err = filp->f_owner.pid;
227 break;
228 case F_SETOWN:
229 filp->f_owner.pid = arg;
230 filp->f_owner.uid = current->uid;
231 filp->f_owner.euid = current->euid;
232 if (S_ISSOCK (filp->f_dentry->d_inode->i_mode))
233 err = sock_fcntl (filp, F_SETOWN, arg);
234 break;
235 case F_GETSIG:
236 err = filp->f_owner.signum;
237 break;
238 case F_SETSIG:
239 /* arg == 0 restores default behaviour. */
240 if (arg < 0 || arg > _NSIG) {
241 err = -EINVAL;
242 break;
244 err = 0;
245 filp->f_owner.signum = arg;
246 break;
247 default:
248 /* sockets need a few special fcntls. */
249 err = -EINVAL;
250 if (S_ISSOCK (filp->f_dentry->d_inode->i_mode))
251 err = sock_fcntl (filp, cmd, arg);
252 break;
254 fput(filp);
255 unlock_kernel();
256 out:
257 return err;
260 /* Table to convert sigio signal codes into poll band bitmaps */
262 static int band_table[NSIGPOLL+1] = {
264 POLLIN | POLLRDNORM, /* POLL_IN */
265 POLLOUT | POLLWRNORM | POLLWRBAND, /* POLL_OUT */
266 POLLIN | POLLRDNORM | POLLMSG, /* POLL_MSG */
267 POLLERR, /* POLL_ERR */
268 POLLPRI | POLLRDBAND, /* POLL_PRI */
269 POLLHUP | POLLERR /* POLL_HUP */
272 static void send_sigio_to_task(struct task_struct *p,
273 struct fown_struct *fown,
274 struct fasync_struct *fa,
275 int reason)
277 if ((fown->euid != 0) &&
278 (fown->euid ^ p->suid) && (fown->euid ^ p->uid) &&
279 (fown->uid ^ p->suid) && (fown->uid ^ p->uid))
280 return;
281 switch (fown->signum) {
282 siginfo_t si;
283 default:
284 /* Queue a rt signal with the appropriate fd as its
285 value. We use SI_SIGIO as the source, not
286 SI_KERNEL, since kernel signals always get
287 delivered even if we can't queue. Failure to
288 queue in this case _should_ be reported; we fall
289 back to SIGIO in that case. --sct */
290 si.si_signo = fown->signum;
291 si.si_errno = 0;
292 si.si_code = reason;
293 if (reason < 0 || reason > NSIGPOLL)
294 si.si_band = ~0;
295 else
296 si.si_band = band_table[reason];
297 si.si_fd = fa->fa_fd;
298 if (!send_sig_info(fown->signum, &si, p))
299 break;
300 /* fall-through: fall back on the old plain SIGIO signal */
301 case 0:
302 send_sig(SIGIO, p, 1);
306 static void send_sigio(struct fown_struct *fown, struct fasync_struct *fa,
307 int band)
309 struct task_struct * p;
310 int pid = fown->pid;
312 read_lock(&tasklist_lock);
313 if ( (pid > 0) && (p = find_task_by_pid(pid)) ) {
314 send_sigio_to_task(p, fown, fa, band);
315 goto out;
317 for_each_task(p) {
318 int match = p->pid;
319 if (pid < 0)
320 match = -p->pgrp;
321 if (pid != match)
322 continue;
323 send_sigio_to_task(p, fown, fa, band);
325 out:
326 read_unlock(&tasklist_lock);
329 void kill_fasync(struct fasync_struct *fa, int sig, int band)
331 while (fa) {
332 struct fown_struct * fown;
333 if (fa->magic != FASYNC_MAGIC) {
334 printk("kill_fasync: bad magic number in "
335 "fasync_struct!\n");
336 return;
338 fown = &fa->fa_file->f_owner;
339 /* Don't send SIGURG to processes which have not set a
340 queued signum: SIGURG has its own default signalling
341 mechanism. */
342 if (fown->pid && !(sig == SIGURG && fown->signum == 0))
343 send_sigio(fown, fa, band);
344 fa = fa->fa_next;