• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
11 USE_ENV(NEWTOY(env, "^i0u*", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(125)))
12 
13 config 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 
GLOBALS(struct arg_list * u;)29 GLOBALS(
30   struct arg_list *u;
31 )
32 
33 void 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