OSDN Git Service

Make xopen() skip stdin/stdout/stderr, add xopen_stdio() if you want stdout,
authorRob Landley <rob@landley.net>
Thu, 4 Aug 2016 15:16:59 +0000 (10:16 -0500)
committerRob Landley <rob@landley.net>
Thu, 4 Aug 2016 15:16:59 +0000 (10:16 -0500)
add xopenro() that takes one argument and understands "-" means stdin,
and switch over lots of users.

37 files changed:
lib/lib.c
lib/lib.h
lib/password.c
lib/xwrap.c
toys/android/load_policy.c
toys/net/rfkill.c
toys/other/blockdev.c
toys/other/fsfreeze.c
toys/other/insmod.c
toys/other/makedevs.c
toys/other/nsenter.c
toys/other/oneit.c
toys/other/shred.c
toys/other/sysctl.c
toys/pending/arp.c
toys/pending/crond.c
toys/pending/crontab.c
toys/pending/dd.c
toys/pending/dhcp.c
toys/pending/dumpleases.c
toys/pending/getty.c
toys/pending/klogd.c
toys/pending/last.c
toys/pending/mdev.c
toys/pending/modprobe.c
toys/pending/openvt.c
toys/pending/sulogin.c
toys/pending/tftp.c
toys/posix/comm.c
toys/posix/cut.c
toys/posix/find.c
toys/posix/grep.c
toys/posix/nohup.c
toys/posix/patch.c
toys/posix/sed.c
toys/posix/uudecode.c
toys/posix/uuencode.c

index 5c7696d..718ea3a 100644 (file)
--- 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);
 
index c3aa7e7..520a5ed 100644 (file)
--- 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);
index bf13c44..eab2d66 100644 (file)
@@ -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);
 
index 7176aae..a7b7bfc 100644 (file)
@@ -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);
index 8496736..d9ff148 100644 (file)
@@ -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);
 }
index 36fe320..56e5768 100644 (file)
@@ -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;
 
index e5a504e..38e0993 100644 (file)
@@ -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++) {
index e169554..dfe17fb 100644 (file)
@@ -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);
index 18ac917..9a3f595 100644 (file)
@@ -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;
index 0f79b25..ed91fd9 100644 (file)
@@ -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 = <stdin>\n");
   xchdir(*toys.optargs);
index 1375728..78a9d91 100644 (file)
@@ -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;
index 0e95a10..9be67c0 100644 (file)
@@ -68,11 +68,11 @@ void oneit_main(void)
   for (i = 0; i<ARRAY_LEN(pipes); i++) xsignal(pipes[i], oneit_signaled);
 
   if (toys.optflags & FLAG_3) {
-    // Ensure next available filehandle is #3
-    while (open("/", 0) < 3);
+    // Ensure next available filehandles are #3 and #4
+    while (xopen_stdio("/", 0) < 3);
     close(3);
     close(4);
-    if (pipe(pipes)) perror_exit("pipe");
+    xpipe(pipes);
     fcntl(4, F_SETFD, FD_CLOEXEC);
   }
 
index 5b018ea..30b5e7d 100644 (file)
@@ -42,7 +42,7 @@ void shred_main(void)
   char **try;
 
   if (!(toys.optflags & FLAG_n)) TT.iterations++;
-  TT.ufd = xopen("/dev/urandom", O_RDONLY);
+  TT.ufd = xopenro("/dev/urandom");
 
   // We don't use loopfiles() here because "-" isn't stdin, and want to
   // respond to files we can't open via chmod.
index a123110..ad643c9 100644 (file)
@@ -50,7 +50,7 @@ static void key_error(char *key)
 
 static int write_key(char *path, char *key, char *value)
 {
-  int fd = open(path, O_WRONLY);;
+  int fd = open(path, O_WRONLY);
 
   if (fd < 0) {
     key_error(key);
index e725112..6b57c3c 100644 (file)
@@ -245,7 +245,7 @@ void arp_main(void)
   if ((toys.optflags & FLAG_d) && !delete_entry()) return; 
 
   //show arp chache
-  fd = xopen("/proc/net/arp", O_RDONLY);
+  fd = xopenro("/proc/net/arp");
   buf = get_line(fd);
   free(buf); //skip first line
 
index 1b5e419..df8b5f1 100644 (file)
@@ -79,10 +79,11 @@ static void loginfo(uint8_t loglevel, char *msg, ...)
 
     if (!TT.flagd && TT.logfile) {
       int fd = open(TT.logfile, O_WRONLY | O_CREAT | O_APPEND, 0666);
-      if (fd >=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);
index 80a881d..0b1c47d 100644 (file)
@@ -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);
     }
index 9990a0f..b09a7df 100644 (file)
@@ -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) {
index cb9d15a..b99bb4c 100644 (file)
@@ -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;
index 86cb4e7..ef17aab 100644 (file)
@@ -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);
index c737628..25d04ea 100644 (file)
@@ -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);
index 2c84288..d950981 100644 (file)
@@ -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..
index b207afe..4b7b472 100644 (file)
@@ -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.
index 975d31d..2688cf3 100644 (file)
@@ -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;
index 7a35c18..ebf17a0 100644 (file)
@@ -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);
index 042b897..29f8a17 100644 (file)
@@ -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);
index e6cb831..bc3638e 100644 (file)
@@ -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);
index 60d5f17..1c6fe9e 100644 (file)
@@ -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);
index 6c726cf..ded262f 100644 (file)
@@ -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]);
   }
 
index 1acefe2..13be5e7 100644 (file)
@@ -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;
         }
index a1821ca..02f7702 100644 (file)
@@ -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 {
index 9e50a7c..6423ea6 100644 (file)
@@ -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) {
index 4d6d59f..b302cbe 100644 (file)
@@ -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);
 }
index 2c73d95..fbad1fb 100644 (file)
@@ -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);
index 063c20c..7198824 100644 (file)
@@ -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 }");  
index fd557ec..238e27e 100644 (file)
@@ -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);
index 34ca701..06709d5 100644 (file)
@@ -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);