summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2019-01-31 23:46:56 -0500
committerTavian Barnes <tavianator@tavianator.com>2019-02-01 12:50:29 -0500
commitaa5f0f5745e4e7392c078d1fe28825c941f52f7c (patch)
tree897376cebf759a6e90c4b94f7b3dd5fe3a42025a /main.c
parent02132c2efb6daa213aa07b805ccb0c20241ca2f7 (diff)
downloadbfs-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.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/main.c b/main.c
index 2734aaf..3c19092 100644
--- a/main.c
+++ b/main.c
@@ -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;
}