diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2019-01-31 23:46:56 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2019-02-01 12:50:29 -0500 |
commit | aa5f0f5745e4e7392c078d1fe28825c941f52f7c (patch) | |
tree | 897376cebf759a6e90c4b94f7b3dd5fe3a42025a /main.c | |
parent | 02132c2efb6daa213aa07b805ccb0c20241ca2f7 (diff) | |
download | bfs-aa5f0f5745e4e7392c078d1fe28825c941f52f7c.tar.xz |
main: Fix closed standard stream handling
bfs >&- should complain about a missing file descriptor, rather than
silently succeeding.
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 40 |
1 files changed, 25 insertions, 15 deletions
@@ -1,6 +1,6 @@ /**************************************************************************** * bfs * - * Copyright (C) 2015-2017 Tavian Barnes <tavianator@tavianator.com> * + * Copyright (C) 2015-2019 Tavian Barnes <tavianator@tavianator.com> * * * * Permission to use, copy, modify, and/or distribute this software for any * * purpose with or without fee is hereby granted. * @@ -24,16 +24,31 @@ #include <unistd.h> /** - * Ensure that a file descriptor is open. + * Make sure the standard streams std{in,out,err} are open. If they are not, + * future open() calls may use those file descriptors, and std{in,out,err} will + * use them unintentionally. */ -static int ensure_fd_open(int fd, int flags) { - if (isopen(fd)) { - return 0; - } else if (redirect(fd, "/dev/null", flags) >= 0) { - return 0; - } else { +static int open_std_streams() { +#ifdef O_PATH + const int inflags = O_PATH, outflags = O_PATH; +#else + // These are intentionally backwards so that bfs >&- still fails with EBADF + const int inflags = O_WRONLY, outflags = O_RDONLY; +#endif + + if (!isopen(STDERR_FILENO) && redirect(STDERR_FILENO, "/dev/null", outflags) < 0) { + return -1; + } + if (!isopen(STDOUT_FILENO) && redirect(STDOUT_FILENO, "/dev/null", outflags) < 0) { + perror("redirect()"); + return -1; + } + if (!isopen(STDIN_FILENO) && redirect(STDIN_FILENO, "/dev/null", inflags) < 0) { + perror("redirect()"); return -1; } + + return 0; } /** @@ -42,13 +57,8 @@ static int ensure_fd_open(int fd, int flags) { int main(int argc, char *argv[]) { int ret = EXIT_FAILURE; - if (ensure_fd_open(STDIN_FILENO, O_RDONLY) != 0) { - goto done; - } - if (ensure_fd_open(STDOUT_FILENO, O_WRONLY) != 0) { - goto done; - } - if (ensure_fd_open(STDERR_FILENO, O_WRONLY) != 0) { + // Make sure the standard streams are open + if (open_std_streams() != 0) { goto done; } |