diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2016-11-13 15:08:33 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2016-11-13 15:44:48 -0500 |
commit | 58b4741d3d8eb50bd265e0aa5603923c1e3c04c4 (patch) | |
tree | 8ac8a78995df61d92359e33f5fcbc9a8299e9546 /util.c | |
parent | 1c5168342e5248983d3a7929abaebe16ca3640a3 (diff) | |
download | bfs-58b4741d3d8eb50bd265e0aa5603923c1e3c04c4.tar.xz |
Redirect stdin from /dev/null for -ok and -okdir.
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 50 |
1 files changed, 50 insertions, 0 deletions
@@ -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; +} |