aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-07-26 13:38:19 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2008-07-26 20:53:44 -0400
commit6c5d0512a091480c9f981162227fdb1c9d70e555 (patch)
treed9706cc3c26beacd588a9b976bb4384369a2b86d
parent4cc38a1b383f0c6c65a3fef4ff8144e8000e4ec3 (diff)
[PATCH] get rid of corner case in dup3() entirely
Since Ulrich is OK with getting rid of dup3(fd, fd, flags) completely, to hell the damn thing goes. Corner case for dup2() is handled in sys_dup2() (complete with -EBADF if dup2(fd, fd) is called with fd that is not open), the rest is done in dup3(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/fcntl.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c
index ce12a6885115..3deec9887089 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -135,18 +135,12 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
135 if ((flags & ~O_CLOEXEC) != 0) 135 if ((flags & ~O_CLOEXEC) != 0)
136 return -EINVAL; 136 return -EINVAL;
137 137
138 if (unlikely(oldfd == newfd))
139 return -EINVAL;
140
138 spin_lock(&files->file_lock); 141 spin_lock(&files->file_lock);
139 if (!(file = fcheck(oldfd))) 142 if (!(file = fcheck(oldfd)))
140 goto out_unlock; 143 goto out_unlock;
141 err = newfd;
142 if (unlikely(newfd == oldfd)) {
143 if (flags & O_CLOEXEC) {
144 fdt = files_fdtable(files);
145 FD_SET(newfd, fdt->close_on_exec);
146 }
147 goto out_unlock;
148 }
149 err = -EBADF;
150 if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) 144 if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
151 goto out_unlock; 145 goto out_unlock;
152 get_file(file); /* We are now finished with oldfd */ 146 get_file(file); /* We are now finished with oldfd */
@@ -194,6 +188,14 @@ out_fput:
194 188
195asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd) 189asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
196{ 190{
191 if (unlikely(newfd == oldfd)) { /* corner case */
192 struct files_struct *files = current->files;
193 rcu_read_lock();
194 if (!fcheck_files(files, oldfd))
195 oldfd = -EBADF;
196 rcu_read_unlock();
197 return oldfd;
198 }
197 return sys_dup3(oldfd, newfd, 0); 199 return sys_dup3(oldfd, newfd, 0);
198} 200}
199 201