4 * Copyright (C) 1991, 1992 Linus Torvalds
8 #include <linux/file.h>
9 #include <linux/smp_lock.h>
11 #include <asm/uaccess.h>
13 extern int sock_fcntl (struct file
*, unsigned int cmd
, unsigned long arg
);
16 * locate_fd finds a free file descriptor in the open_fds fdset,
17 * expanding the fd arrays if necessary. The files write lock will be
18 * held on exit to ensure that the fd can be entered atomically.
21 static inline int locate_fd(struct files_struct
*files
,
22 struct file
*file
, int start
)
27 write_lock(&files
->file_lock
);
31 if (start
< files
->next_fd
)
32 start
= files
->next_fd
;
33 if (start
>= files
->max_fdset
) {
35 error
= expand_files(files
, start
);
41 newfd
= find_next_zero_bit(files
->open_fds
->fds_bits
,
42 files
->max_fdset
, start
);
45 if (newfd
>= current
->rlim
[RLIMIT_NOFILE
].rlim_cur
)
47 if (newfd
>= files
->max_fdset
)
50 error
= expand_files(files
, newfd
);
53 if (error
) /* If we might have blocked, try again. */
56 if (start
<= files
->next_fd
)
57 files
->next_fd
= newfd
+ 1;
65 static inline void allocate_fd(struct files_struct
*files
,
66 struct file
*file
, int fd
)
68 FD_SET(fd
, files
->open_fds
);
69 FD_CLR(fd
, files
->close_on_exec
);
70 write_unlock(&files
->file_lock
);
74 static int dupfd(struct file
*file
, int start
)
76 struct files_struct
* files
= current
->files
;
79 ret
= locate_fd(files
, file
, start
);
82 allocate_fd(files
, file
, ret
);
86 write_unlock(&files
->file_lock
);
91 asmlinkage
int sys_dup2(unsigned int oldfd
, unsigned int newfd
)
95 struct files_struct
* files
= current
->files
;
97 write_lock(¤t
->files
->file_lock
);
98 if (!(file
= fcheck(oldfd
)))
104 if (newfd
>= NR_OPEN
)
105 goto out_unlock
; /* following POSIX.1 6.2.1 */
106 get_file(file
); /* We are now finished with oldfd */
108 err
= expand_files(files
, newfd
);
110 write_unlock(&files
->file_lock
);
115 /* To avoid races with open() and dup(), we will mark the fd as
116 * in-use in the open-file bitmap throughout the entire dup2()
117 * process. This is quite safe: do_close() uses the fd array
118 * entry, not the bitmap, to decide what work needs to be
120 FD_SET(newfd
, files
->open_fds
);
121 write_unlock(&files
->file_lock
);
125 write_lock(&files
->file_lock
);
126 allocate_fd(files
, file
, newfd
);
132 write_unlock(¤t
->files
->file_lock
);
136 asmlinkage
int sys_dup(unsigned int fildes
)
139 struct file
* file
= fget(fildes
);
142 ret
= dupfd(file
, 0);
146 #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC)
148 static int setfl(int fd
, struct file
* filp
, unsigned long arg
)
150 struct inode
* inode
= filp
->f_dentry
->d_inode
;
153 * In the case of an append-only file, O_APPEND
156 if (!(arg
& O_APPEND
) && IS_APPEND(inode
))
159 /* Did FASYNC state change? */
160 if ((arg
^ filp
->f_flags
) & FASYNC
) {
161 if (filp
->f_op
&& filp
->f_op
->fasync
)
162 filp
->f_op
->fasync(fd
, filp
, (arg
& FASYNC
) != 0);
165 /* required for strict SunOS emulation */
166 if (O_NONBLOCK
!= O_NDELAY
)
170 filp
->f_flags
= (arg
& SETFL_MASK
) | (filp
->f_flags
& ~SETFL_MASK
);
174 asmlinkage
long sys_fcntl(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
189 err
= dupfd(filp
, arg
);
193 err
= FD_ISSET(fd
, current
->files
->close_on_exec
);
197 FD_SET(fd
, current
->files
->close_on_exec
);
199 FD_CLR(fd
, current
->files
->close_on_exec
);
205 err
= setfl(fd
, filp
, arg
);
208 err
= fcntl_getlk(fd
, (struct flock
*) arg
);
211 err
= fcntl_setlk(fd
, cmd
, (struct flock
*) arg
);
214 err
= fcntl_setlk(fd
, cmd
, (struct flock
*) arg
);
218 * XXX If f_owner is a process group, the
219 * negative return value will get converted
220 * into an error. Oops. If we keep the
221 * current syscall conventions, the only way
222 * to fix this will be in libc.
224 err
= filp
->f_owner
.pid
;
227 filp
->f_owner
.pid
= arg
;
228 filp
->f_owner
.uid
= current
->uid
;
229 filp
->f_owner
.euid
= current
->euid
;
230 if (S_ISSOCK (filp
->f_dentry
->d_inode
->i_mode
))
231 err
= sock_fcntl (filp
, F_SETOWN
, arg
);
234 err
= filp
->f_owner
.signum
;
237 if (arg
<= 0 || arg
> _NSIG
) {
242 filp
->f_owner
.signum
= arg
;
245 /* sockets need a few special fcntls. */
247 if (S_ISSOCK (filp
->f_dentry
->d_inode
->i_mode
))
248 err
= sock_fcntl (filp
, cmd
, arg
);
257 static void send_sigio_to_task(struct task_struct
*p
,
258 struct fown_struct
*fown
, struct fasync_struct
*fa
)
260 if ((fown
->euid
!= 0) &&
261 (fown
->euid
^ p
->suid
) && (fown
->euid
^ p
->uid
) &&
262 (fown
->uid
^ p
->suid
) && (fown
->uid
^ p
->uid
))
264 switch (fown
->signum
) {
267 /* Queue a rt signal with the appropriate fd as its
268 value. We use SI_SIGIO as the source, not
269 SI_KERNEL, since kernel signals always get
270 delivered even if we can't queue. Failure to
271 queue in this case _should_ be reported; we fall
272 back to SIGIO in that case. --sct */
273 si
.si_signo
= fown
->signum
;
275 si
.si_code
= SI_SIGIO
;
276 si
.si_pid
= fown
->pid
;
277 si
.si_uid
= fown
->uid
;
278 si
.si_fd
= fa
->fa_fd
;
279 if (!send_sig_info(fown
->signum
, &si
, p
))
281 /* fall-through: fall back on the old plain SIGIO signal */
283 send_sig(SIGIO
, p
, 1);
287 static void send_sigio(struct fown_struct
*fown
, struct fasync_struct
*fa
)
289 struct task_struct
* p
;
292 read_lock(&tasklist_lock
);
293 if ( (pid
> 0) && (p
= find_task_by_pid(pid
)) ) {
294 send_sigio_to_task(p
, fown
, fa
);
303 send_sigio_to_task(p
, fown
, fa
);
306 read_unlock(&tasklist_lock
);
309 void kill_fasync(struct fasync_struct
*fa
, int sig
)
312 struct fown_struct
* fown
;
313 if (fa
->magic
!= FASYNC_MAGIC
) {
314 printk("kill_fasync: bad magic number in "
318 fown
= &fa
->fa_file
->f_owner
;
320 send_sigio(fown
, fa
);