summaryrefslogtreecommitdiffstats
path: root/fs/fcntl.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-03-18 17:17:51 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-03-18 17:17:51 +0000
commitf1382dc4850bb459d24a81c6cb0ef93ea7bd4a79 (patch)
tree225271a3d5dcd4e9dea5ee393556abd754c964b1 /fs/fcntl.c
parent135b00fc2e90e605ac2a96b20b0ebd93851a3f89 (diff)
o Merge with Linux 2.1.90.
o Divide L1 cache sizes by 1024 before printing, makes the numbers a bit more credible ...
Diffstat (limited to 'fs/fcntl.c')
-rw-r--r--fs/fcntl.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 8743916ee..5cfeb3658 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -9,6 +9,7 @@
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
+#include <linux/file.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
@@ -22,18 +23,32 @@ extern int sock_fcntl (struct file *, unsigned int cmd, unsigned long arg);
static inline int dupfd(unsigned int fd, unsigned int arg)
{
struct files_struct * files = current->files;
+ struct file * file;
+ int error;
- if (fd >= NR_OPEN || !files->fd[fd])
- return -EBADF;
+ error = -EINVAL;
if (arg >= NR_OPEN)
- return -EINVAL;
+ goto out;
+
+ error = -EBADF;
+ file = fget(fd);
+ if (!file)
+ goto out;
+
+ error = -EMFILE;
arg = find_next_zero_bit(&files->open_fds, NR_OPEN, arg);
if (arg >= current->rlim[RLIMIT_NOFILE].rlim_cur)
- return -EMFILE;
+ goto out_putf;
FD_SET(arg, &files->open_fds);
FD_CLR(arg, &files->close_on_exec);
- (files->fd[arg] = files->fd[fd])->f_count++;
- return arg;
+ fd_install(arg, file);
+ error = arg;
+out:
+ return error;
+
+out_putf:
+ fput(file);
+ goto out;
}
asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
@@ -41,7 +56,7 @@ asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
int err = -EBADF;
lock_kernel();
- if (oldfd >= NR_OPEN || !current->files->fd[oldfd])
+ if (!fcheck(oldfd))
goto out;
err = newfd;
if (newfd == oldfd)
@@ -51,7 +66,7 @@ asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
goto out; /* following POSIX.1 6.2.1 */
sys_close(newfd);
- err = dupfd(oldfd,newfd);
+ err = dupfd(oldfd, newfd);
out:
unlock_kernel();
return err;
@@ -62,7 +77,7 @@ asmlinkage int sys_dup(unsigned int fildes)
int ret;
lock_kernel();
- ret = dupfd(fildes,0);
+ ret = dupfd(fildes, 0);
unlock_kernel();
return ret;
}
@@ -101,12 +116,13 @@ asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
long err = -EBADF;
lock_kernel();
- if (fd >= NR_OPEN || !(filp = current->files->fd[fd]))
+ filp = fget(fd);
+ if (!filp)
goto out;
err = 0;
switch (cmd) {
case F_DUPFD:
- err = dupfd(fd,arg);
+ err = dupfd(fd, arg);
break;
case F_GETFD:
err = FD_ISSET(fd, &current->files->close_on_exec);
@@ -158,6 +174,7 @@ asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
err = -EINVAL;
break;
}
+ fput(filp);
out:
unlock_kernel();
return err;