toybox/toys/posix/env.c
<<
>>
Prefs
   1/* env.c - Set the environment for command invocation.
   2 *
   3 * Copyright 2012 Tryn Mirell <tryn@mirell.org>
   4 *
   5 * http://opengroup.org/onlinepubs/9699919799/utilities/env.html
   6 *
   7 * Note: env bypasses shell builtins, so don't xexec().
   8 *
   9 * Deviations from posix: "-" argument and -0
  10
  11USE_ENV(NEWTOY(env, "^i0u*", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(125)))
  12
  13config ENV
  14  bool "env"
  15  default y
  16  help
  17    usage: env [-i] [-u NAME] [NAME=VALUE...] [COMMAND...]
  18
  19    Set the environment for command invocation, or list environment variables.
  20
  21    -i  Clear existing environment
  22    -u NAME     Remove NAME from the environment
  23    -0  Use null instead of newline in output
  24*/
  25
  26#define FOR_env
  27#include "toys.h"
  28
  29GLOBALS(
  30  struct arg_list *u;
  31)
  32
  33void env_main(void)
  34{
  35  char **ev = toys.optargs, **ee = 0, **set QUIET, *path = getenv("PATH");
  36  struct string_list *sl = 0;
  37  struct arg_list *u;
  38
  39  // If first nonoption argument is "-" treat it as -i
  40  if (*ev && **ev == '-' && !(*ev)[1]) {
  41    toys.optflags |= FLAG_i;
  42    ev++;
  43  }
  44
  45  if (FLAG(i)) ee = set = xzalloc(sizeof(void *)*(toys.optc+1));
  46  else for (u = TT.u; u; u = u->next) xunsetenv(u->arg);
  47
  48  for (; *ev; ev++) {
  49    if (strchr(*ev, '=')) {
  50      if (FLAG(i)) *set++ = *ev;
  51      else xsetenv(xstrdup(*ev), 0);
  52      if (!strncmp(*ev, "PATH=", 5)) path=(*ev)+5;
  53    } else {
  54      // unfortunately, posix has no exec combining p and e, so do p ourselves
  55      if (!strchr(*ev, '/') && path) {
  56         errno = ENOENT;
  57         for (sl = find_in_path(path, *ev); sl; sl = sl->next)
  58           execve(sl->str, ev, ee ? : environ);
  59      } else execve(*ev, ev, ee ? : environ);
  60      perror_msg("exec %s", *ev);
  61      _exit(126+(errno == ENOENT));
  62    }
  63  }
  64
  65  for (ev = ee ? : environ; *ev; ev++) xprintf("%s%c", *ev, '\n'*!FLAG(0));
  66}
  67