diff options
author | Eric Blake <ebb9@byu.net> | 2009-08-31 14:20:03 -0600 |
---|---|---|
committer | Eric Blake <ebb9@byu.net> | 2009-09-02 19:14:43 -0600 |
commit | 4475e25b6a19e31e5783781f2132cdbd05bcf7c4 (patch) | |
tree | 8e8a8793c084d0e534a75896602a77b0218fa079 /lib/dup2.c | |
parent | 5578788cdb078c97988eb445c2bd848081679e4c (diff) | |
download | gnulib-4475e25b6a19e31e5783781f2132cdbd05bcf7c4.tar.gz |
fchdir: simplify error handling, and support dup3
* modules/fchdir (Depends-on): Use strdup-posix, not strdup. Add
stdbool, malloc-posix, realloc-posix.
* lib/fchdir.c (struct dir_info_t): Delete saved_errno.
(ensure_dirs_slot): Return false on allocation failure.
(rpl_dup2): Delete.
(_gl_register_dup): New function.
(_gl_unregister_fd, rpl_opendir, rpl_dup): Update callers.
(_gl_register_fd): Close fd on allocation failure.
* lib/fcntl.in.h (_gl_register_fd): Update signature.
* lib/unistd.in.h (_gl_register_dup) [FCHDIR_REPLACEMENT]: New
prototype.
(rpl_dup2_fchdir): Delete prototype.
* lib/open.c (open): Update caller.
* lib/dup2.c (dup2): Track fchdir metadata.
* lib/dup3.c (dup3): Likewise.
* m4/dup2.m4 (gl_REPLACE_DUP2): New macro.
* m4/fchdir.m4 (gl_FUNC_FCHDIR): Use it.
Signed-off-by: Eric Blake <ebb9@byu.net>
Diffstat (limited to 'lib/dup2.c')
-rw-r--r-- | lib/dup2.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/dup2.c b/lib/dup2.c index fb3ffb0df0..a513e5bfea 100644 --- a/lib/dup2.c +++ b/lib/dup2.c @@ -70,6 +70,10 @@ rpl_dup2 (int fd, int desired_fd) /* Correct a cygwin 1.5.x errno value. */ else if (result == -1 && errno == EMFILE) errno = EBADF; +#ifdef FCHDIR_REPLACEMENT + if (fd != desired_fd && result == desired_fd) + result = _gl_register_dup (fd, desired_fd); +#endif return result; } @@ -98,13 +102,19 @@ dupfd (int fd, int desired_fd) int dup2 (int fd, int desired_fd) { + int result; if (fd == desired_fd) - return fd; + return fcntl (fd, F_GETFL) < 0 ? -1 : fd; close (desired_fd); # ifdef F_DUPFD - return fcntl (fd, F_DUPFD, desired_fd); + result = fcntl (fd, F_DUPFD, desired_fd); # else - return dupfd (fd, desired_fd); + result = dupfd (fd, desired_fd); # endif +#ifdef FCHDIR_REPLACEMENT + if (0 <= result) + result = _gl_register_dup (fd, desired_fd); +#endif + return result; } #endif /* !REPLACE_DUP2 */ |