diff options
author | Ulrich Drepper <drepper@redhat.com> | 2008-07-25 22:32:13 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-26 20:53:39 -0400 |
commit | 3c333937ee3be114b181c4861188cfe8f6a59697 (patch) | |
tree | fda3bb122bb4c9c180ef41e5d142ac315dc7a576 /fs | |
parent | 58ec42b061bf5dad8fa0370a19966cfd96eaf80c (diff) |
[PATCH] dup3 fix
Al Viro notice one cornercase that the new dup3() code. The dup2()
function, as a special case, handles dup-ing to the same file
descriptor. In this case the current dup3() code does nothing at
all. I.e., it ingnores the flags parameter. This shouldn't happen,
the close-on-exec flag should be set if requested.
In case the O_CLOEXEC bit in the flags parameter is not set the
dup3() function should behave in this respect identical to dup2().
This means dup3(fd, fd, 0) should not actively reset the c-o-e
flag.
The patch below implements this minor change.
[AV: credits to Artur Grabowski for bringing that up as potential subtle point
in dup2() behaviour]
Signed-off-by: Ulrich Drepper <drepper@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fcntl.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c index 9679fcbdeaa0..ce12a6885115 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -139,8 +139,13 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags) | |||
139 | if (!(file = fcheck(oldfd))) | 139 | if (!(file = fcheck(oldfd))) |
140 | goto out_unlock; | 140 | goto out_unlock; |
141 | err = newfd; | 141 | err = newfd; |
142 | if (newfd == oldfd) | 142 | if (unlikely(newfd == oldfd)) { |
143 | if (flags & O_CLOEXEC) { | ||
144 | fdt = files_fdtable(files); | ||
145 | FD_SET(newfd, fdt->close_on_exec); | ||
146 | } | ||
143 | goto out_unlock; | 147 | goto out_unlock; |
148 | } | ||
144 | err = -EBADF; | 149 | err = -EBADF; |
145 | if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) | 150 | if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) |
146 | goto out_unlock; | 151 | goto out_unlock; |