Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
1b7e190b
Commit
1b7e190b
authored
Jul 30, 2008
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] clean dup2() up a bit
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
1027abe8
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
27 additions
and
26 deletions
+27
-26
fs/fcntl.c
fs/fcntl.c
+27
-26
No files found.
fs/fcntl.c
View file @
1b7e190b
...
@@ -63,31 +63,35 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
...
@@ -63,31 +63,35 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
return
-
EINVAL
;
return
-
EINVAL
;
spin_lock
(
&
files
->
file_lock
);
spin_lock
(
&
files
->
file_lock
);
if
(
!
(
file
=
fcheck
(
oldfd
)))
goto
out_unlock
;
get_file
(
file
);
/* We are now finished with oldfd */
err
=
expand_files
(
files
,
newfd
);
err
=
expand_files
(
files
,
newfd
);
file
=
fcheck
(
oldfd
);
if
(
unlikely
(
!
file
))
goto
Ebadf
;
if
(
unlikely
(
err
<
0
))
{
if
(
unlikely
(
err
<
0
))
{
if
(
err
==
-
EMFILE
)
if
(
err
==
-
EMFILE
)
err
=
-
EBADF
;
goto
Ebadf
;
goto
out_
fput
;
goto
out_
unlock
;
}
}
/*
/* To avoid races with open() and dup(), we will mark the fd as
* We need to detect attempts to do dup2() over allocated but still
* in-use in the open-file bitmap throughout the entire dup2()
* not finished descriptor. NB: OpenBSD avoids that at the price of
* process. This is quite safe: do_close() uses the fd array
* extra work in their equivalent of fget() - they insert struct
* entry, not the bitmap, to decide what work needs to be
* file immediately after grabbing descriptor, mark it larval if
* done. --sct */
* more work (e.g. actual opening) is needed and make sure that
/* Doesn't work. open() might be there first. --AV */
* fget() treats larval files as absent. Potentially interesting,
* but while extra work in fget() is trivial, locking implications
/* Yes. It's a race. In user space. Nothing sane to do */
* and amount of surgery on open()-related paths in VFS are not.
* FreeBSD fails with -EBADF in the same situation, NetBSD "solution"
* deadlocks in rather amusing ways, AFAICS. All of that is out of
* scope of POSIX or SUS, since neither considers shared descriptor
* tables and this condition does not arise without those.
*/
err
=
-
EBUSY
;
err
=
-
EBUSY
;
fdt
=
files_fdtable
(
files
);
fdt
=
files_fdtable
(
files
);
tofree
=
fdt
->
fd
[
newfd
];
tofree
=
fdt
->
fd
[
newfd
];
if
(
!
tofree
&&
FD_ISSET
(
newfd
,
fdt
->
open_fds
))
if
(
!
tofree
&&
FD_ISSET
(
newfd
,
fdt
->
open_fds
))
goto
out_
fput
;
goto
out_
unlock
;
get_file
(
file
);
rcu_assign_pointer
(
fdt
->
fd
[
newfd
],
file
);
rcu_assign_pointer
(
fdt
->
fd
[
newfd
],
file
);
FD_SET
(
newfd
,
fdt
->
open_fds
);
FD_SET
(
newfd
,
fdt
->
open_fds
);
if
(
flags
&
O_CLOEXEC
)
if
(
flags
&
O_CLOEXEC
)
...
@@ -98,17 +102,14 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
...
@@ -98,17 +102,14 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
if
(
tofree
)
if
(
tofree
)
filp_close
(
tofree
,
files
);
filp_close
(
tofree
,
files
);
err
=
newfd
;
out:
return
err
;
out_unlock:
spin_unlock
(
&
files
->
file_lock
);
goto
out
;
out_fput:
return
newfd
;
Ebadf:
err
=
-
EBADF
;
out_unlock:
spin_unlock
(
&
files
->
file_lock
);
spin_unlock
(
&
files
->
file_lock
);
fput
(
file
);
return
err
;
goto
out
;
}
}
asmlinkage
long
sys_dup2
(
unsigned
int
oldfd
,
unsigned
int
newfd
)
asmlinkage
long
sys_dup2
(
unsigned
int
oldfd
,
unsigned
int
newfd
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment