diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-03-18 17:17:51 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-03-18 17:17:51 +0000 |
commit | f1382dc4850bb459d24a81c6cb0ef93ea7bd4a79 (patch) | |
tree | 225271a3d5dcd4e9dea5ee393556abd754c964b1 /fs/fcntl.c | |
parent | 135b00fc2e90e605ac2a96b20b0ebd93851a3f89 (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.c | 39 |
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, ¤t->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; |