From 027a73a903af306449710ce12bc09e0e3550c6c9 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 4 Aug 2016 10:16:59 -0500 Subject: Make xopen() skip stdin/stdout/stderr, add xopen_stdio() if you want stdout, add xopenro() that takes one argument and understands "-" means stdin, and switch over lots of users. --- lib/lib.c | 2 +- lib/lib.h | 3 +++ lib/password.c | 2 +- lib/xwrap.c | 42 +++++++++++++++++++++++++++++++++++++++--- toys/android/load_policy.c | 5 ++--- toys/net/rfkill.c | 2 +- toys/other/blockdev.c | 2 +- toys/other/fsfreeze.c | 2 +- toys/other/insmod.c | 2 +- toys/other/makedevs.c | 2 +- toys/other/nsenter.c | 3 +-- toys/other/oneit.c | 6 +++--- toys/other/shred.c | 2 +- toys/other/sysctl.c | 2 +- toys/pending/arp.c | 2 +- toys/pending/crond.c | 5 +++-- toys/pending/crontab.c | 9 ++++----- toys/pending/dd.c | 17 ++--------------- toys/pending/dhcp.c | 4 +++- toys/pending/dumpleases.c | 2 +- toys/pending/getty.c | 2 +- toys/pending/klogd.c | 2 +- toys/pending/last.c | 2 +- toys/pending/mdev.c | 2 +- toys/pending/modprobe.c | 4 +++- toys/pending/openvt.c | 2 +- toys/pending/sulogin.c | 2 +- toys/pending/tftp.c | 2 +- toys/posix/comm.c | 3 +-- toys/posix/cut.c | 8 ++++---- toys/posix/find.c | 2 +- toys/posix/grep.c | 2 +- toys/posix/nohup.c | 2 +- toys/posix/patch.c | 4 ++-- toys/posix/sed.c | 3 +-- toys/posix/uudecode.c | 2 +- toys/posix/uuencode.c | 2 +- 37 files changed, 94 insertions(+), 68 deletions(-) diff --git a/lib/lib.c b/lib/lib.c index 5c7696d0..718ea3ac 100644 --- a/lib/lib.c +++ b/lib/lib.c @@ -1008,7 +1008,7 @@ int qstrcmp(const void *a, const void *b) void create_uuid(char *uuid) { // Read 128 random bits - int fd = xopen("/dev/urandom", O_RDONLY); + int fd = xopenro("/dev/urandom"); xreadall(fd, uuid, 16); close(fd); diff --git a/lib/lib.h b/lib/lib.h index c3aa7e72..520a5ed6 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -130,6 +130,9 @@ void xaccess(char *path, int flags); void xunlink(char *path); int xcreate(char *path, int flags, int mode); int xopen(char *path, int flags); +int xcreate_stdio(char *path, int flags, int mode); +int xopen_stdio(char *path, int flags); +int xopenro(char *path); void xpipe(int *pp); void xclose(int fd); int xdup(int fd); diff --git a/lib/password.c b/lib/password.c index bf13c441..eab2d669 100644 --- a/lib/password.c +++ b/lib/password.c @@ -24,7 +24,7 @@ int get_salt(char *salt, char *algo) if (al[i].id) s += sprintf(s, "$%c$", '0'+al[i].id); // Read appropriate number of random bytes for salt - i = xopen("/dev/urandom", O_RDONLY); + i = xopenro("/dev/urandom"); xreadall(i, libbuf, ((len*6)+7)/8); close(i); diff --git a/lib/xwrap.c b/lib/xwrap.c index 7176aae1..a7b7bfcb 100644 --- a/lib/xwrap.c +++ b/lib/xwrap.c @@ -318,17 +318,18 @@ void xunlink(char *path) } // Die unless we can open/create a file, returning file descriptor. -int xcreate(char *path, int flags, int mode) +int xcreate_stdio(char *path, int flags, int mode) { int fd = open(path, flags^O_CLOEXEC, mode); + if (fd == -1) perror_exit_raw(path); return fd; } // Die unless we can open a file, returning file descriptor. -int xopen(char *path, int flags) +int xopen_stdio(char *path, int flags) { - return xcreate(path, flags, 0); + return xcreate_stdio(path, flags, 0); } void xpipe(int *pp) @@ -350,6 +351,41 @@ int xdup(int fd) return fd; } +// Move file descriptor above stdin/stdout/stderr, using /dev/null to consume +// old one. (We should never be called with stdin/stdout/stderr closed, but...) +int notstdio(int fd) +{ + while (fd<3) { + int fd2 = xdup(fd); + + close(fd); + xopen_stdio("/dev/null", O_RDWR); + fd = fd2; + } + + return fd; +} + +// Create a file but don't return stdin/stdout/stderr +int xcreate(char *path, int flags, int mode) +{ + return notstdio(xcreate_stdio(path, flags, mode)); +} + +// Open a file descriptor NOT in stdin/stdout/stderr +int xopen(char *path, int flags) +{ + return notstdio(xopen_stdio(path, flags)); +} + +// Open read only, treating "-" as a synonym for stdin. +int xopenro(char *path) +{ + if (!strcmp(path, "-")) return 0; + + return xopen(path, O_RDONLY); +} + FILE *xfdopen(int fd, char *mode) { FILE *f = fdopen(fd, mode); diff --git a/toys/android/load_policy.c b/toys/android/load_policy.c index 84967360..d9ff1486 100644 --- a/toys/android/load_policy.c +++ b/toys/android/load_policy.c @@ -19,14 +19,13 @@ config LOAD_POLICY void load_policy_main(void) { - char *path = *toys.optargs; - int fd = xopen(path, O_RDONLY); + int fd = xopenro(*toys.optargs); off_t policy_len = fdlength(fd); char *policy_data = mmap(0, policy_len, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); if (!policy_data || security_load_policy(policy_data, policy_len) < 0) - perror_exit("Couldn't %s %s", policy_data ? "load" : "read", path); + perror_exit("Couldn't %s %s", policy_data ? "load" : "read", *toys.optargs); munmap(policy_data, policy_len); } diff --git a/toys/net/rfkill.c b/toys/net/rfkill.c index 36fe320d..56e57687 100644 --- a/toys/net/rfkill.c +++ b/toys/net/rfkill.c @@ -80,7 +80,7 @@ void rfkill_main(void) continue; sprintf(toybuf, "/sys/class/rfkill/rfkill%u/uevent", rfevent.idx); - tvar = xopen(toybuf, O_RDONLY); + tvar = xopenro(toybuf); while ((line = get_line(tvar))) { char *s = line; diff --git a/toys/other/blockdev.c b/toys/other/blockdev.c index e5a504e6..38e09935 100644 --- a/toys/other/blockdev.c +++ b/toys/other/blockdev.c @@ -46,7 +46,7 @@ void blockdev_main(void) if (!toys.optflags) help_exit("need --option"); for (ss = toys.optargs; *ss; ss++) { - int fd = xopen(*ss, O_RDONLY), i; + int fd = xopenro(*ss), i; // Command line order discarded so perform multiple operations in flag order for (i = 0; i < 32; i++) { diff --git a/toys/other/fsfreeze.c b/toys/other/fsfreeze.c index e169554e..dfe17fb9 100644 --- a/toys/other/fsfreeze.c +++ b/toys/other/fsfreeze.c @@ -23,7 +23,7 @@ config FSFREEZE void fsfreeze_main(void) { - int fd = xopen(*toys.optargs, O_RDONLY); + int fd = xopenro(*toys.optargs); long p = 1; xioctl(fd, (toys.optflags & FLAG_f) ? FIFREEZE : FITHAW, &p); diff --git a/toys/other/insmod.c b/toys/other/insmod.c index 18ac9176..9a3f5958 100644 --- a/toys/other/insmod.c +++ b/toys/other/insmod.c @@ -25,7 +25,7 @@ config INSMOD void insmod_main(void) { - int fd = !strcmp(*toys.optargs, "-") ? 0 : xopen(*toys.optargs, O_RDONLY); + int fd = xopenro(*toys.optargs); int i, rc; i = 1; diff --git a/toys/other/makedevs.c b/toys/other/makedevs.c index 0f79b25f..ed91fd93 100644 --- a/toys/other/makedevs.c +++ b/toys/other/makedevs.c @@ -47,7 +47,7 @@ void makedevs_main() // Open file and chdir, verbosely xprintf("rootdir = %s\n", *toys.optargs); if (toys.optflags & FLAG_d && strcmp(TT.fname, "-")) { - fd = xopen(TT.fname, O_RDONLY); + fd = xopenro(TT.fname); xprintf("table = %s\n", TT.fname); } else xprintf("table = \n"); xchdir(*toys.optargs); diff --git a/toys/other/nsenter.c b/toys/other/nsenter.c index 13757280..78a9d91a 100644 --- a/toys/other/nsenter.c +++ b/toys/other/nsenter.c @@ -152,8 +152,7 @@ void unshare_main(void) filename = toybuf; } - if (setns(fd = xopen(filename, O_RDONLY), flags[i])) - perror_exit("setns"); + if (setns(fd = xopenro(filename), flags[i])) perror_exit("setns"); close(fd); } nsnames += strlen(nsnames)+1; diff --git a/toys/other/oneit.c b/toys/other/oneit.c index 0e95a104..9be67c05 100644 --- a/toys/other/oneit.c +++ b/toys/other/oneit.c @@ -68,11 +68,11 @@ void oneit_main(void) for (i = 0; i=0 && fd != 2) { + if (fd==-1) perror_msg("'%s", TT.logfile); + else { dup2(fd, 2); close(fd); - } else if (fd < 0) perror_msg("'%s", TT.logfile); + } } used = vsnprintf(NULL, 0, msg, d); smsg = xzalloc(++used); diff --git a/toys/pending/crontab.c b/toys/pending/crontab.c index 80a881d7..0b1c47db 100644 --- a/toys/pending/crontab.c +++ b/toys/pending/crontab.c @@ -114,7 +114,7 @@ static int validate_component(int min, int max, char *src) static int parse_crontab(char *fname) { char *line; - int lno, fd = xopen(fname, O_RDONLY); + int lno, fd = xopenro(fname); long plen = 0; for (lno = 1; (line = get_rawline(fd, &plen, '\n')); lno++,free(line)) { @@ -214,8 +214,7 @@ static void do_list(char *name) int fdin; snprintf(toybuf, sizeof(toybuf), "%s%s", TT.cdir, name); - if ((fdin = open(toybuf, O_RDONLY)) == -1) - error_exit("No crontab for '%s'", name); + fdin = xopenro(toybuf); xsendfile(fdin, 1); xclose(fdin); } @@ -233,7 +232,7 @@ static void update_crontab(char *src, char *dest) snprintf(toybuf, sizeof(toybuf), "%s%s", TT.cdir, dest); fdout = xcreate(toybuf, O_WRONLY|O_CREAT|O_TRUNC, 0600); - fdin = xopen(src, O_RDONLY); + fdin = xopenro(src); xsendfile(fdin, fdout); xclose(fdin); @@ -277,7 +276,7 @@ static void do_edit(struct passwd *pwd) if (!stat(toybuf, &sb)) { // file exists and have some content. if (sb.st_size) { - srcfd = xopen(toybuf, O_RDONLY); + srcfd = xopenro(toybuf); xsendfile(srcfd, destfd); xclose(srcfd); } diff --git a/toys/pending/dd.c b/toys/pending/dd.c index 9990a0f4..b09a7dfe 100644 --- a/toys/pending/dd.c +++ b/toys/pending/dd.c @@ -143,16 +143,6 @@ static void status() } } -static int xmove_fd(int fd) -{ - int newfd; - - if (fd > STDERR_FILENO) return fd; - if ((newfd = fcntl(fd, F_DUPFD, 3) < 0)) perror_exit("dupfd IO"); - close(fd); - return newfd; -} - static void setup_inout() { /* for C_BS, in/out is done as it is. so only in.sz is enough. @@ -164,10 +154,8 @@ static void setup_inout() if (!TT.in.name) { TT.in.name = "stdin"; TT.in.fd = STDIN_FILENO; - } else { - TT.in.fd = xopen(TT.in.name, O_RDONLY); - TT.in.fd = xmove_fd(TT.in.fd); - } + } else TT.in.fd = xopenro(TT.in.name); + //setup outout if (!TT.out.name) { TT.out.name = "stdout"; @@ -176,7 +164,6 @@ static void setup_inout() int flags = O_WRONLY|O_CREAT; if (!(toys.optflags&C_NOTRUNC)) flags |= O_TRUNC; TT.out.fd = xcreate(TT.out.name, flags, 0666); - TT.out.fd = xmove_fd(TT.out.fd); } if (TT.in.offset) { diff --git a/toys/pending/dhcp.c b/toys/pending/dhcp.c index cb9d15a1..b99bb4c0 100644 --- a/toys/pending/dhcp.c +++ b/toys/pending/dhcp.c @@ -566,7 +566,9 @@ static void run_script(dhcpc_result_t *res, char *name) static uint32_t getxid(void) { uint32_t randnum; - int fd = xopen("/dev/urandom", O_RDONLY); + int fd = xopenro("/dev/urandom"); + +// TODO xreadfile xreadall(fd, &randnum, sizeof(randnum)); xclose(fd); return randnum; diff --git a/toys/pending/dumpleases.c b/toys/pending/dumpleases.c index 86cb4e76..ef17aab4 100644 --- a/toys/pending/dumpleases.c +++ b/toys/pending/dumpleases.c @@ -42,7 +42,7 @@ void dumpleases_main(void) int i, fd; if(!(toys.optflags & FLAG_f)) TT.file = "/var/lib/misc/dhcpd.leases"; //DEF_LEASE_FILE - fd = xopen(TT.file, O_RDONLY); + fd = xopenro(TT.file); xprintf("Mac Address IP Address Host Name Expires %s\n", (toys.optflags & FLAG_a) ? "at" : "in"); xread(fd, &written_time, sizeof(written_time)); current_time = time(NULL); diff --git a/toys/pending/getty.c b/toys/pending/getty.c index c7376288..25d04eaa 100644 --- a/toys/pending/getty.c +++ b/toys/pending/getty.c @@ -128,7 +128,7 @@ static void open_tty(void) if ((setsid() < 0) && (getpid() != getsid(0))) perror_exit("setsid"); xclose(0); - xopen(TT.tty_name, O_RDWR|O_NDELAY|O_CLOEXEC); + xopen_stdio(TT.tty_name, O_RDWR|O_NDELAY|O_CLOEXEC); fcntl(0, F_SETFL, fcntl(0, F_GETFL) & ~O_NONBLOCK); // Block read dup2(0, 1); dup2(0, 2); diff --git a/toys/pending/klogd.c b/toys/pending/klogd.c index 2c842889..d950981d 100644 --- a/toys/pending/klogd.c +++ b/toys/pending/klogd.c @@ -74,7 +74,7 @@ void klogd_main(void) syslog(LOG_NOTICE, "KLOGD: started with Kernel ring buffer as log source\n"); klogctl(1, NULL, 0); } else { - TT.fd = xopen("/proc/kmsg", O_RDONLY); //_PATH_KLOG in paths.h + TT.fd = xopenro("/proc/kmsg"); //_PATH_KLOG in paths.h syslog(LOG_NOTICE, "KLOGD: started with /proc/kmsg as log source\n"); } openlog("Kernel", 0, LOG_KERN); //open connection to system logger.. diff --git a/toys/pending/last.c b/toys/pending/last.c index b207afef..4b7b472e 100644 --- a/toys/pending/last.c +++ b/toys/pending/last.c @@ -96,7 +96,7 @@ void last_main(void) pwidth = (toys.optflags & FLAG_W) ? 46 : 16; *tm = time(tm+1); - fd = xopen(file, O_RDONLY); + fd = xopenro(file); loc = xlseek(fd, 0, SEEK_END); // Loop through file structures in reverse order. diff --git a/toys/pending/mdev.c b/toys/pending/mdev.c index 975d31da..2688cf35 100644 --- a/toys/pending/mdev.c +++ b/toys/pending/mdev.c @@ -40,8 +40,8 @@ static void make_device(char *path) gid_t gid = 0; if (path) { - // Try to read major/minor string + // Try to read major/minor string, returning if we can't temp = strrchr(path, '/'); fd = open(path, O_RDONLY); *temp = 0; diff --git a/toys/pending/modprobe.c b/toys/pending/modprobe.c index 7a35c186..ebf17a0e 100644 --- a/toys/pending/modprobe.c +++ b/toys/pending/modprobe.c @@ -367,7 +367,9 @@ static int ins_mod(char *modules, char *flags) { char *buf = NULL; int len, res; - int fd = xopen(modules, O_RDONLY); + int fd = xopenro(modules); + + // TODO xreadfile() len = fdlength(fd); buf = xmalloc(len); diff --git a/toys/pending/openvt.c b/toys/pending/openvt.c index 042b897c..29f8a174 100644 --- a/toys/pending/openvt.c +++ b/toys/pending/openvt.c @@ -100,7 +100,7 @@ void openvt_main(void) xioctl(fd, VT_GETSTATE, &vstate); close(0); //new vt becomes stdin - vt_fd = xopen(toybuf, O_RDWR); + vt_fd = xopen_stdio(toybuf, O_RDWR); if (toys.optflags & FLAG_s) { ioctl(vt_fd, VT_ACTIVATE, TT.vt_num); ioctl(vt_fd, VT_WAITACTIVE, TT.vt_num); diff --git a/toys/pending/sulogin.c b/toys/pending/sulogin.c index e6cb8314..bc3638e3 100644 --- a/toys/pending/sulogin.c +++ b/toys/pending/sulogin.c @@ -88,7 +88,7 @@ void sulogin_main(void) if (toys.optargs[0]) { int fd; - dup2((fd = xopen(toys.optargs[0], O_RDWR)), 0); + dup2((fd = xopen_stdin(toys.optargs[0], O_RDWR)), 0); if (!isatty(0)) error_exit("%s: it is not a tty", toys.optargs[0]); dup2( fd, 1); dup2( fd, 2); diff --git a/toys/pending/tftp.c b/toys/pending/tftp.c index 60d5f172..1c6fe9e6 100644 --- a/toys/pending/tftp.c +++ b/toys/pending/tftp.c @@ -381,7 +381,7 @@ int file_put(void) sd = init_tftp(&server); packet = (uint8_t*)xzalloc(TFTP_IOBUFSIZE); - fd = xopen(TT.local_file, O_RDONLY); + fd = xopenro(TT.local_file); for (;;) { //first loop for request send and confirmation from server. packetlen = mkpkt_request(packet, TFTP_OP_WRQ, TT.remote_file, 1); diff --git a/toys/posix/comm.c b/toys/posix/comm.c index 6c726cf6..ded262f5 100644 --- a/toys/posix/comm.c +++ b/toys/posix/comm.c @@ -48,8 +48,7 @@ void comm_main(void) if (toys.optflags == 7) return; for (i = 0; i < 2; i++) { - file[i] = strcmp("-", toys.optargs[i]) - ? xopen(toys.optargs[i], O_RDONLY) : 0; + file[i] = xopenro(toys.optargs[i]); line[i] = get_line(file[i]); } diff --git a/toys/posix/cut.c b/toys/posix/cut.c index 1acefe2b..13be5e74 100644 --- a/toys/posix/cut.c +++ b/toys/posix/cut.c @@ -77,13 +77,13 @@ static void parse_list(char *list) if (!ctoken) break; if (!*ctoken) continue; - //Get start position. + // Get start position. if (*(dtoken = strsep(&ctoken, "-"))) { start = atolx_range(dtoken, 0, INT_MAX); start = (start?(start-1):start); } - //Get end position. + // Get end position. if (!ctoken) end = -1; //case e.g. 1,2,3 else if (*ctoken) {//case e.g. N-M end = atolx_range(ctoken, 0, INT_MAX); @@ -94,7 +94,7 @@ static void parse_list(char *list) add_to_list(start, end); TT.nelem++; } - //if list is missing in command line. + // if list is missing in command line. if (!TT.nelem) error_exit("missing positions list"); } @@ -112,7 +112,7 @@ static void get_data(void) if(strcmp(*argv, "-") == 0) TT.do_cut(0); //for stdin else { int fd = open(*argv, O_RDONLY, 0); - if(fd < 0) {//if file not present then continue with other files. + if (fd < 0) {//if file not present then continue with other files. perror_msg_raw(*argv); continue; } diff --git a/toys/posix/find.c b/toys/posix/find.c index a1821ca3..02f7702d 100644 --- a/toys/posix/find.c +++ b/toys/posix/find.c @@ -454,7 +454,7 @@ static int do_find(struct dirtree *new) ss += len; aa->arglen = len; aa->dir = !!strchr(s, 'd'); - if (TT.topdir == -1) TT.topdir = xopen(".", 0); + if (TT.topdir == -1) TT.topdir = xopenro("."); // collect names and execute commands } else { diff --git a/toys/posix/grep.c b/toys/posix/grep.c index 9e50a7ca..6423ea6b 100644 --- a/toys/posix/grep.c +++ b/toys/posix/grep.c @@ -359,7 +359,7 @@ void grep_main(void) toys.exitval = 1; if (toys.optflags & FLAG_s) { close(2); - xopen("/dev/null", O_RDWR); + xopen_stdio("/dev/null", O_RDWR); } if (toys.optflags & FLAG_r) { diff --git a/toys/posix/nohup.c b/toys/posix/nohup.c index 4d6d59f6..b302cbe4 100644 --- a/toys/posix/nohup.c +++ b/toys/posix/nohup.c @@ -36,7 +36,7 @@ void nohup_main(void) } if (isatty(0)) { close(0); - open("/dev/null", O_RDONLY); + xopen_stdio("/dev/null", O_RDONLY); } xexec(toys.optargs); } diff --git a/toys/posix/patch.c b/toys/posix/patch.c index 2c73d958..fbad1fb9 100644 --- a/toys/posix/patch.c +++ b/toys/posix/patch.c @@ -265,7 +265,7 @@ void patch_main(void) strip = 0; char *oldname = NULL, *newname = NULL; - if (TT.infile) TT.filepatch = xopen(TT.infile, O_RDONLY); + if (TT.infile) TT.filepatch = xopenro(TT.infile); TT.filein = TT.fileout = -1; if (TT.dir) xchdir(TT.dir); @@ -402,7 +402,7 @@ void patch_main(void) TT.filein = xcreate(name, O_CREAT|O_EXCL|O_RDWR, 0666); } else { printf("patching %s\n", name); - TT.filein = xopen(name, O_RDONLY); + TT.filein = xopenro(name); } if (toys.optflags & FLAG_dry_run) TT.fileout = xopen("/dev/null", O_RDWR); diff --git a/toys/posix/sed.c b/toys/posix/sed.c index 063c20c3..71988248 100644 --- a/toys/posix/sed.c +++ b/toys/posix/sed.c @@ -1026,8 +1026,7 @@ void sed_main(void) // so handle all -e, then all -f. (At least the behavior's consistent.) for (al = TT.e; al; al = al->next) parse_pattern(&al->arg, strlen(al->arg)); - for (al = TT.f; al; al = al->next) - do_lines(strcmp(al->arg, "-") ? xopen(al->arg, O_RDONLY) : 0,parse_pattern); + for (al = TT.f; al; al = al->next) do_lines(xopenro(al->arg), parse_pattern); parse_pattern(0, 0); dlist_terminate(TT.pattern); if (TT.nextlen) error_exit("no }"); diff --git a/toys/posix/uudecode.c b/toys/posix/uudecode.c index fd557eca..238e27e9 100644 --- a/toys/posix/uudecode.c +++ b/toys/posix/uudecode.c @@ -30,7 +30,7 @@ void uudecode_main(void) char *line = 0, mode[16], *class[] = {"begin%*[ ]%15s%*[ ]%n", "begin-base64%*[ ]%15s%*[ ]%n"}; - if (toys.optc) ifd = xopen(*toys.optargs, O_RDONLY); + if (toys.optc) ifd = xopenro(*toys.optargs); while (!idx) { free(line); diff --git a/toys/posix/uuencode.c b/toys/posix/uuencode.c index 34ca7013..06709d5e 100644 --- a/toys/posix/uuencode.c +++ b/toys/posix/uuencode.c @@ -26,7 +26,7 @@ void uuencode_main(void) int i, m = toys.optflags & FLAG_m, fd = 0; - if (toys.optc > 1) fd = xopen(toys.optargs[0], O_RDONLY); + if (toys.optc > 1) fd = xopenro(toys.optargs[0]); base64_init(toybuf); -- cgit v1.2.3