4 * Copyright (C) 1991, 1992 Linus Torvalds
7 #include <linux/sched.h>
8 #include <linux/kernel.h>
9 #include <linux/errno.h>
10 #include <linux/stat.h>
11 #include <linux/fcntl.h>
12 #include <linux/file.h>
13 #include <linux/string.h>
15 #include <linux/smp.h>
16 #include <linux/smp_lock.h>
18 #include <asm/bitops.h>
19 #include <asm/uaccess.h>
21 extern int sock_fcntl (struct file
*, unsigned int cmd
, unsigned long arg
);
23 static inline int dupfd(unsigned int fd
, unsigned int arg
)
25 struct files_struct
* files
= current
->files
;
39 arg
= find_next_zero_bit(&files
->open_fds
, NR_OPEN
, arg
);
40 if (arg
>= current
->rlim
[RLIMIT_NOFILE
].rlim_cur
)
42 FD_SET(arg
, &files
->open_fds
);
43 FD_CLR(arg
, &files
->close_on_exec
);
44 fd_install(arg
, file
);
54 asmlinkage
int sys_dup2(unsigned int oldfd
, unsigned int newfd
)
66 goto out
; /* following POSIX.1 6.2.1 */
69 err
= dupfd(oldfd
, newfd
);
75 asmlinkage
int sys_dup(unsigned int fildes
)
80 ret
= dupfd(fildes
, 0);
85 #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC)
87 static int setfl(struct file
* filp
, unsigned long arg
)
89 struct inode
* inode
= filp
->f_dentry
->d_inode
;
92 * In the case of an append-only file, O_APPEND
95 if (!(arg
& O_APPEND
) && IS_APPEND(inode
))
98 /* Did FASYNC state change? */
99 if ((arg
^ filp
->f_flags
) & FASYNC
) {
100 if (filp
->f_op
->fasync
)
101 filp
->f_op
->fasync(filp
, (arg
& FASYNC
) != 0);
104 /* required for strict SunOS emulation */
105 if (O_NONBLOCK
!= O_NDELAY
)
109 filp
->f_flags
= (arg
& SETFL_MASK
) | (filp
->f_flags
& ~SETFL_MASK
);
113 asmlinkage
long sys_fcntl(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
125 err
= dupfd(fd
, arg
);
128 err
= FD_ISSET(fd
, ¤t
->files
->close_on_exec
);
132 FD_SET(fd
, ¤t
->files
->close_on_exec
);
134 FD_CLR(fd
, ¤t
->files
->close_on_exec
);
140 err
= setfl(filp
, arg
);
143 err
= fcntl_getlk(fd
, (struct flock
*) arg
);
146 err
= fcntl_setlk(fd
, cmd
, (struct flock
*) arg
);
149 err
= fcntl_setlk(fd
, cmd
, (struct flock
*) arg
);
153 * XXX If f_owner is a process group, the
154 * negative return value will get converted
155 * into an error. Oops. If we keep the
156 * current syscall conventions, the only way
157 * to fix this will be in libc.
159 err
= filp
->f_owner
.pid
;
163 filp
->f_owner
.pid
= arg
;
164 filp
->f_owner
.uid
= current
->uid
;
165 filp
->f_owner
.euid
= current
->euid
;
166 if (S_ISSOCK (filp
->f_dentry
->d_inode
->i_mode
))
167 err
= sock_fcntl (filp
, F_SETOWN
, arg
);
170 /* sockets need a few special fcntls. */
171 if (S_ISSOCK (filp
->f_dentry
->d_inode
->i_mode
))
172 err
= sock_fcntl (filp
, cmd
, arg
);
183 static void send_sigio(int pid
, uid_t uid
, uid_t euid
)
185 struct task_struct
* p
;
187 read_lock(&tasklist_lock
);
195 (euid
^ p
->suid
) && (euid
^ p
->uid
) &&
196 (uid
^ p
->suid
) && (uid
^ p
->uid
))
198 send_sig(SIGIO
, p
, 1);
199 if (p
->state
== TASK_INTERRUPTIBLE
&& signal_pending(p
))
202 read_unlock(&tasklist_lock
);
205 void kill_fasync(struct fasync_struct
*fa
, int sig
)
208 struct fown_struct
* fown
;
209 if (fa
->magic
!= FASYNC_MAGIC
) {
210 printk("kill_fasync: bad magic number in "
214 fown
= &fa
->fa_file
->f_owner
;
216 send_sigio(fown
->pid
, fown
->uid
, fown
->euid
);