123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- /* env.c - manipulate environment and execute a program
- in that environment
- Mly 861126 */
- /* Copyright (C) 1986, Free Software Foundation, Inc.
- NO WARRANTY
- BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
- NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
- WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
- RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
- WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
- AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
- DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
- CORRECTION.
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
- STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
- WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
- LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
- OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
- USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
- DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
- A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
- PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
- DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
- GENERAL PUBLIC LICENSE TO COPY
- 1. You may copy and distribute verbatim copies of this source file
- as you receive it, in any medium, provided that you conspicuously
- and appropriately publish on each copy a valid copyright notice
- "Copyright (C) 1986 Free Software Foundation"; and include
- following the copyright notice a verbatim copy of the above disclaimer
- of warranty and of this License.
- 2. You may modify your copy or copies of this source file or
- any portion of it, and copy and distribute such modifications under
- the terms of Paragraph 1 above, provided that you also do the following:
- a) cause the modified files to carry prominent notices stating
- that you changed the files and the date of any change; and
- b) cause the whole of any work that you distribute or publish,
- that in whole or in part contains or is a derivative of this
- program or any part thereof, to be freely distributed
- and licensed to all third parties on terms identical to those
- contained in this License Agreement (except that you may choose
- to grant more extensive warranty protection to third parties,
- at your option).
- 3. You may copy and distribute this program or any portion of it in
- compiled, executable or object code form under the terms of Paragraphs
- 1 and 2 above provided that you do the following:
- a) cause each such copy to be accompanied by the
- corresponding machine-readable source code, which must
- be distributed under the terms of Paragraphs 1 and 2 above; or,
- b) cause each such copy to be accompanied by a
- written offer, with no time limit, to give any third party
- free (except for a nominal shipping charge) a machine readable
- copy of the corresponding source code, to be distributed
- under the terms of Paragraphs 1 and 2 above; or,
- c) in the case of a recipient of this program in compiled, executable
- or object code form (without the corresponding source code) you
- shall cause copies you distribute to be accompanied by a copy
- of the written offer of source code which you received along
- with the copy you received.
- 4. You may not copy, sublicense, distribute or transfer this program
- except as expressly provided under this License Agreement. Any attempt
- otherwise to copy, sublicense, distribute or transfer this program is void and
- your rights to use the program under this License agreement shall be
- automatically terminated. However, parties who have received computer
- software programs from you with this License Agreement will not have
- their licenses terminated so long as such parties remain in full compliance.
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding! */
- /*
- If first argument is "-", then a new environment is constructed
- from scratch; otherwise the environment is inherited from the parent
- process, except as modified by other options.
-
- So, "env - foo" will invoke the "foo" program in a null environment,
- whereas "env foo" would invoke "foo" in the same environment as that
- passed to "env" itself.
- Subsequent arguments are interpreted as follows:
-
- * "variable=value" (ie an arg containing a "=" character)
- means to set the specified environment variable to that value.
- `value' may be of zero length ("variable="). Note that setting
- a variable to a zero-length value is different from unsetting it.
- * "-u variable" or "-unset variable"
- means to unset that variable
- If that variable isn't set, does nothing.
- * "-s variable value" or "-set variable value"
- same as "variable=value"
- * "-" or "--"
- are used to indicate that the following argument is the program
- to invoke. This is only necessary when the program's name
- begins with "-" or contains a "="
- * anything else
- The first remaining argument specifies a program to invoke
- (it is searched for according to the specification of the PATH
- environment variable) and any arguments following that are
- passed as arguments to that program
- If no program-name is specified following the environment
- specifications the the resulting environment is printed
- (The is like specifying a program-name of "printenv")
- Examples:
- If the environment passed to "env" is
- { USER=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
- * "env DISPLAY=gnu:0 nemacs"
- calls "nemacs" in the envionment
- { EDITOR=emacs USER=rms DISPLAY=gnu }
- * "env - USER=foo /hacks/hack bar baz"
- will call the "hack" program on arguments "bar" and "baz"
- in an environment in which the only variable is "USER"
- Note that the "-" option will clear out the PATH variable,
- so one should be careful to specify in which directory
- to find the program to call
-
- * "env -u EDITOR USER=foo PATH=/energy -- e=mc2 bar baz"
- The program "/energy/e=mc2" is called with environment
- { USER=foo PATH=/energy }
- */
- #ifdef EMACS
- #define NO_SHORTNAMES
- #include "../src/config.h"
- #endif /* EMACS */
- #include <stdio.h>
- extern int execvp ();
- extern char *index ();
- char *xmalloc (), *xrealloc ();
- char *concat ();
- extern char **environ;
- char **nenv;
- int nenv_size;
- char *progname;
- void setenv ();
- void fatal ();
- main (argc, argv, envp)
- register int argc;
- register char **argv;
- char **envp;
- {
- register char *tem;
- progname = argv[0];
- argc--;
- argv++;
- nenv_size = 100;
- nenv = (char **) xmalloc (nenv_size * sizeof (char *));
- *nenv = (char *) 0;
- /* "-" flag means to not inherit parent's environment */
- if (argc && !strcmp (*argv, "-"))
- {
- argc--;
- argv++;
- }
- else
- /* Else pass on existing env vars. */
- for (; *envp; envp++)
- {
- tem = index (*envp, '=');
- if (tem)
- {
- *tem = '\000';
- setenv (*envp, tem + 1);
- }
- }
- while (argc > 0)
- {
- tem = index (*argv, '=');
- if (tem)
- /* If arg contains a "=" it specifies to set a variable */
- {
- *tem = '\000';
- setenv (*argv, tem + 1);
- argc--; argv++;
- continue;
- }
-
- if (**argv != '-')
- /* Remaining args are program name and args to pass it */
- break;
- if (argc < 2)
- fatal ("No argument following \"%s\" switch", *argv);
- if (!strcmp (*argv, "-u") ||
- !strcmp (*argv, "-unset"))
- /* Unset a variable */
- {
- argc--; argv++;
- setenv (*argv, 0);
- argc--; argv++;
- }
- else if (!strcmp (*argv, "-s") ||
- !strcmp (*argv, "-set"))
- /* Set a variable */
- {
- argc--; argv++;
- tem = *argv;
- if (argc < 2)
- fatal ("No value specified for variable \"%s\"",
- tem);
- argc--; argv++;
- setenv (tem, *argv);
- argc--; argv++;
- }
- else if (!strcmp (*argv, "-") || !strcmp (*argv, "--"))
- {
- argc--; argv++;
- break;
- }
- else
- {
- fatal ("unknown switch \"%s\"", *argv);
- }
- }
- /* If no program specified print the environment and exit */
- if (argc <= 0)
- {
- while (*nenv)
- printf ("%s\n", *nenv++);
- exit (0);
- }
- else
- {
- extern int errno, sys_nerr;
- extern char *sys_errlist[];
- environ = nenv;
- (void) execvp (*argv, argv);
- fprintf (stderr, "%s: Cannot execute \"%s\"",
- progname, *argv);
- if (errno < sys_nerr)
- fprintf (stderr, ": %s\n" , sys_errlist[errno]);
- else
- putc ('\n', stderr);
- exit (errno != 0 ? errno : 1);
- }
- }
- void
- setenv (var, val)
- register char *var, *val;
- {
- register char **e;
- int len = strlen (var);
- {
- register char *tem = index (var, '=');
- if (tem)
- fatal ("Environment variable names may not contain \"=\": %s",
- var);
- else if (*var == '\000')
- fatal ("Zero-length environment variable name specified.");
- }
- for (e = nenv; *e; e++)
- if (!strncmp (var, *e, len) &&
- (*e)[len] == '=')
- {
- if (val)
- goto set;
- else
- do { *e = *(e + 1); } while (*e++);
- return;
- }
- if (!val)
- return; /* Nothing to unset */
- len = e - nenv;
- if (len + 1 >= nenv_size)
- {
- nenv_size += 100;
- nenv = (char **) xrealloc (nenv, nenv_size * sizeof (char *));
- e = nenv + len;
- }
- set:
- val = concat (var, "=", val);
- if (*e)
- free (*e);
- else
- *(e + 1) = (char *) 0;
- *e = val;
- return;
- }
- void
- fatal (msg, arg1, arg2)
- char *msg, *arg1, *arg2;
- {
- fprintf (stderr, "%s: ", progname);
- fprintf (stderr, msg, arg1, arg2);
- putc ('\n', stderr);
- exit (1);
- }
- extern char *malloc (), *realloc ();
- void
- memory_fatal ()
- {
- fatal ("Out of memory");
- }
- char *
- xmalloc (size)
- int size;
- {
- register char *value;
- value = (char *) malloc (size);
- if (!value) memory_fatal ();
- return (value);
- }
- char *
- xrealloc (ptr, size)
- char *ptr;
- int size;
- {
- register char *value;
- value = (char *) realloc (ptr, size);
- if (!value) memory_fatal ();
- return (value);
- }
- /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */
- char *
- concat (s1, s2, s3)
- char *s1, *s2, *s3;
- {
- int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
- char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
- strcpy (result, s1);
- strcpy (result + len1, s2);
- strcpy (result + len1 + len2, s3);
- *(result + len1 + len2 + len3) = 0;
- return result;
- }
- /*
- * Local variables:
- * compile-command: "cc -g -o env env.c"
- * end:
- */
|