diff options
author | Marius Halden <marius.h@lden.org> | 2016-11-04 14:30:03 +0100 |
---|---|---|
committer | Marius Halden <marius.h@lden.org> | 2016-11-04 14:30:03 +0100 |
commit | dca237d41e42bf82ca9871ca87666bcf73bce6cf (patch) | |
tree | 19e00448218655403090f54285741d0d00239499 | |
parent | aa5e98bba336c7eb75325b4e0bdb68a6a4c61c4f (diff) | |
download | runq-dca237d41e42bf82ca9871ca87666bcf73bce6cf.tar.gz runq-dca237d41e42bf82ca9871ca87666bcf73bce6cf.tar.bz2 runq-dca237d41e42bf82ca9871ca87666bcf73bce6cf.tar.xz |
Allow setting fd through argv[1] and set O_CLOEXEC if file does not start with #!
-rw-r--r-- | runfd.c | 32 |
1 files changed, 29 insertions, 3 deletions
@@ -1,7 +1,10 @@ #include <stdio.h> +#include <stdlib.h> #include <err.h> #include <unistd.h> #include <fcntl.h> +#include <errno.h> +#include <string.h> /** * NOTE: requires fdescfs to be mounted to run interpreted files (starting with #!) @@ -10,10 +13,33 @@ char *args[] = { "batchrun", NULL }; int -main() +main(int argc, char **argv) { - //fcntl(3, F_SETFD, FD_CLOEXEC); + char buf[2]; + ssize_t ret; + int tries = 0; + int fd = 3; - fexecve(3, args, NULL); + if (argc > 1) { + fd = atoi(argv[1]); + } + +retry: + if (tries++ >= 3) + errx(1, "Failed to read file header"); + + ret = pread(fd, buf, sizeof(buf), 0); + if (ret == 2) { + if (strncmp(buf, "#!", 2) != 0) { + fcntl(3, F_SETFD, FD_CLOEXEC); + } + } else if (ret == -1) { + if (errno == EINTR) + goto retry; + } else if (ret != 0) { + goto retry; + } + + fexecve(fd, args, NULL); err(1, "fexecve()"); } |