about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/envfile.html11
-rw-r--r--src/execline/envfile.c50
2 files changed, 51 insertions, 10 deletions
diff --git a/doc/envfile.html b/doc/envfile.html
index 713b6ae..62b9669 100644
--- a/doc/envfile.html
+++ b/doc/envfile.html
@@ -26,7 +26,7 @@ adds the variables to the environment, then executes a program.
 <h2> Interface </h2>
 
 <pre>
-     envfile <em>file</em> <em>prog...</em>
+     envfile [ -i | -I ] <em>file</em> <em>prog...</em>
 </pre>
 
 <p>
@@ -51,6 +51,15 @@ with the modified environment.
 it execs into <em>prog</em>.
 </p>
 
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-i</tt>&nbsp;: strict. If <em>file</em> does not exist, exit 111 with an
+error message. This is the default. </li>
+ <li> <tt>-I</tt>&nbsp;: loose. If <em>file</em> does not exist, exec into
+<em>prog</em> without modifying the environment. </li>
+</ul>
+
 <h2> File syntax </h2>
 
 <p>
diff --git a/src/execline/envfile.c b/src/execline/envfile.c
index 18a175b..aff5964 100644
--- a/src/execline/envfile.c
+++ b/src/execline/envfile.c
@@ -2,17 +2,19 @@
 
 #include <stdint.h>
 #include <string.h>
+#include <errno.h>
 
 #include <skalibs/bytestr.h>
 #include <skalibs/types.h>
 #include <skalibs/buffer.h>
 #include <skalibs/strerr2.h>
+#include <skalibs/sgetopt.h>
 #include <skalibs/fmtscan.h>
 #include <skalibs/env.h>
 #include <skalibs/stralloc.h>
 #include <skalibs/djbunix.h>
 
-#define USAGE "envfile file prog..."
+#define USAGE "envfile [ -i | -I ] file prog..."
 #define dieusage() strerr_dieusage(100, USAGE)
 #define dienomem() strerr_diefu1sys(111, "stralloc_catb")
 
@@ -126,26 +128,56 @@ static inline void parse_config (char const *file, buffer *b, stralloc *sa)
   {
     char fmt[UINT_FMT] ;
     fmt[uint_fmt(fmt, line)] = 0 ;
-    strerr_dief4x(1, "syntax error line ", fmt, " while parsing ", file) ;
+    strerr_dief4x(1, "in ", file, ": syntax error line ", fmt) ;
   }
 }
 
 int main (int argc, char const *const *argv, char const *const *envp)
 {
   stralloc modif = STRALLOC_ZERO ;
+  int fd ;
+  char const *name ;
+  int strict = 1 ;
   PROG = "envfile" ;
-  if (argc < 3) dieusage() ;
-  if (!strcmp(argv[1], "-"))
-    parse_config("standard input", buffer_0, &modif) ;
+  {
+    subgetopt_t l = SUBGETOPT_ZERO ;
+    for (;;)
+    {
+      int opt = subgetopt_r(argc, argv, "iI", &l) ;
+      if (opt == -1) break ;
+      switch (opt)
+      {
+        case 'i' : strict = 1 ; break ;
+        case 'I' : strict = 0 ; break ;
+        default : dieusage() ;
+      }
+    }
+    argc -= l.ind ; argv += l.ind ;
+  }
+
+  if (argc < 2) dieusage() ;
+  if (strcmp(argv[0], "-"))
+  {
+    fd = open_readb(argv[0]) ;
+    name = argv[0] ;
+  }
+  else
+  {
+    fd = 0 ;
+    name = "standard input" ;
+  }
+  if (fd == -1)
+  {
+    if (strict || errno != ENOENT)
+      strerr_diefu2sys(111, "open ", name) ;
+  }
   else
   {
     buffer b ;
     char buf[BUFFER_INSIZE] ;
-    int fd = open_readb(argv[1]) ;
-    if (fd == -1) strerr_diefu2sys(111, "open ", argv[1]) ;
     buffer_init(&b, &buffer_read, fd, buf, BUFFER_INSIZE) ;
-    parse_config(argv[1], &b, &modif) ;
+    parse_config(name, &b, &modif) ;
     fd_close(fd) ;
   }
-  xpathexec_r(argv + 2, envp, env_len(envp), modif.s, modif.len) ;
+  xpathexec_r(argv + 1, envp, env_len(envp), modif.s, modif.len) ;
 }