summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2016-11-13 15:08:33 -0500
committerTavian Barnes <tavianator@tavianator.com>2016-11-13 15:44:48 -0500
commit58b4741d3d8eb50bd265e0aa5603923c1e3c04c4 (patch)
tree8ac8a78995df61d92359e33f5fcbc9a8299e9546 /util.c
parent1c5168342e5248983d3a7929abaebe16ca3640a3 (diff)
downloadbfs-58b4741d3d8eb50bd265e0aa5603923c1e3c04c4.tar.xz
Redirect stdin from /dev/null for -ok and -okdir.
Diffstat (limited to 'util.c')
-rw-r--r--util.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..e0f6177
--- /dev/null
+++ b/util.c
@@ -0,0 +1,50 @@
+/*********************************************************************
+ * bfs *
+ * Copyright (C) 2016 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This program is free software. It comes without any warranty, to *
+ * the extent permitted by applicable law. You can redistribute it *
+ * and/or modify it under the terms of the Do What The Fuck You Want *
+ * To Public License, Version 2, as published by Sam Hocevar. See *
+ * the COPYING file or http://www.wtfpl.net/ for more details. *
+ *********************************************************************/
+
+#include "util.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+bool isopen(int fd) {
+ return fcntl(fd, F_GETFD) >= 0 || errno != EBADF;
+}
+
+int redirect(int fd, const char *path, int flags, ...) {
+ close(fd);
+
+ mode_t mode = 0;
+ if (flags & O_CREAT) {
+ va_list args;
+ va_start(args, flags);
+
+ // Use int rather than mode_t, because va_arg must receive a
+ // fully-promoted type
+ mode = va_arg(args, int);
+
+ va_end(args);
+ }
+
+ int ret = open(path, flags, mode);
+
+ if (ret >= 0 && ret != fd) {
+ int other = ret;
+ ret = dup2(other, fd);
+ if (close(other) != 0) {
+ ret = -1;
+ }
+ }
+
+ return ret;
+}