Annotation of GNUtools/emacs/etc/env.c, revision 1.1.1.1

1.1       root        1: /* env.c - manipulate environment and execute a program
                      2:    in that environment
                      3:    Mly 861126
                      4: 
                      5:    Copyright (C) 1986 Free Software Foundation, Inc.
                      6: 
                      7:     This program is free software; you can redistribute it and/or modify
                      8:     it under the terms of the GNU General Public License as published by
                      9:     the Free Software Foundation; either version 1, or (at your option)
                     10:     any later version.
                     11: 
                     12:     This program is distributed in the hope that it will be useful,
                     13:     but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15:     GNU General Public License for more details.
                     16: 
                     17:     You should have received a copy of the GNU General Public License
                     18:     along with this program; if not, write to the Free Software
                     19:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     20: 
                     21:  In other words, you are welcome to use, share and improve this program.
                     22:  You are forbidden to forbid anyone else to use, share and improve
                     23:  what you give them.   Help stamp out software-hoarding!  */
                     24: 
                     25: /* 
                     26: 
                     27:    If first argument is "-", then a new environment is constructed
                     28:    from scratch; otherwise the environment is inherited from the parent
                     29:    process, except as modified by other options.
                     30:    
                     31:    So, "env - foo" will invoke the "foo" program in a null environment,
                     32:    whereas "env foo" would invoke "foo" in the same environment as that
                     33:    passed to "env" itself.
                     34: 
                     35:    Subsequent arguments are interpreted as follows:
                     36:    
                     37:    * "variable=value" (ie an arg containing a "=" character)
                     38:      means to set the specified environment variable to that value.
                     39:      `value' may be of zero length ("variable=").  Note that setting
                     40:      a variable to a zero-length value is different from unsetting it.
                     41: 
                     42:    * "-u variable" or "-unset variable"
                     43:      means to unset that variable
                     44:      If that variable isn't set, does nothing.
                     45: 
                     46:    * "-s variable value" or "-set variable value"
                     47:      same as "variable=value"
                     48: 
                     49:    * "-" or "--"
                     50:      are used to indicate that the following argument is the program
                     51:      to invoke.  This is only necessary when the program's name
                     52:      begins with "-" or contains a "="
                     53: 
                     54:    * anything else
                     55:      The first remaining argument specifies a program to invoke
                     56:      (it is searched for according to the specification of the PATH
                     57:      environment variable) and any arguments following that are
                     58:      passed as arguments to that program
                     59: 
                     60:      If no program-name is specified following the environment
                     61:      specifications the the resulting environment is printed
                     62:      (The is like specifying a program-name of "printenv")
                     63: 
                     64:    Examples:
                     65:      If the environment passed to "env" is
                     66:      { USER=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
                     67: 
                     68:      * "env DISPLAY=gnu:0 nemacs"
                     69:         calls "nemacs" in the envionment
                     70:        { EDITOR=emacs USER=rms DISPLAY=gnu }
                     71: 
                     72:      * "env - USER=foo /hacks/hack bar baz"
                     73:        will call the "hack" program on arguments "bar" and "baz"
                     74:        in an environment in which the only variable is "USER"
                     75:        Note that the "-" option will clear out the PATH variable,
                     76:        so one should be careful to specify in which directory
                     77:        to find the program to call
                     78:        
                     79:      * "env -u EDITOR USER=foo PATH=/energy -- e=mc2 bar baz"
                     80:        The program "/energy/e=mc2" is called with environment
                     81:        { USER=foo PATH=/energy }
                     82: 
                     83: */
                     84: 
                     85: #ifdef EMACS
                     86: #define NO_SHORTNAMES
                     87: #include "../src/config.h"
                     88: #endif /* EMACS */
                     89: 
                     90: #include <stdio.h>
                     91: #include <errno.h>
                     92: 
                     93: extern int execvp ();
                     94: extern char *index ();
                     95: 
                     96: char *xmalloc (), *xrealloc ();
                     97: char *concat ();
                     98: 
                     99: extern char **environ;
                    100: 
                    101: char **nenv;
                    102: int nenv_size;
                    103: 
                    104: char *progname;
                    105: void setenv ();
                    106: void fatal ();
                    107: 
                    108: main (argc, argv, envp)
                    109:      register int argc;
                    110:      register char **argv;
                    111:      char **envp;
                    112: {
                    113:   register char *tem;
                    114: 
                    115:   progname = argv[0];
                    116:   argc--;
                    117:   argv++;
                    118: 
                    119:   nenv_size = 100;
                    120:   nenv = (char **) xmalloc (nenv_size * sizeof (char *));
                    121:   *nenv = (char *) 0;
                    122: 
                    123:   /* "-" flag means to not inherit parent's environment */
                    124:   if (argc && !strcmp (*argv, "-"))
                    125:     {
                    126:       argc--;
                    127:       argv++;
                    128:     }
                    129:   else
                    130:     /* Else pass on existing env vars. */
                    131:     for (; *envp; envp++)
                    132:       {
                    133:        tem = index (*envp, '=');
                    134:        if (tem)
                    135:          {
                    136:            *tem = '\000';
                    137:            setenv (*envp, tem + 1);
                    138:          }
                    139:      }
                    140: 
                    141:   while (argc > 0)
                    142:     {
                    143:       tem = index (*argv, '=');
                    144:       if (tem)
                    145:        /* If arg contains a "=" it specifies to set a variable */
                    146:        {
                    147:          *tem = '\000';
                    148:          setenv (*argv, tem + 1);
                    149:          argc--; argv++;
                    150:          continue;
                    151:        }
                    152:       
                    153:       if (**argv != '-')
                    154:        /* Remaining args are program name and args to pass it */
                    155:        break;
                    156: 
                    157:       if (argc < 2)
                    158:        fatal ("No argument following \"%s\" switch", *argv);
                    159:        if (!strcmp (*argv, "-u") ||
                    160:               !strcmp (*argv, "-unset"))
                    161:        /* Unset a variable */
                    162:        {
                    163:          argc--; argv++;
                    164:          setenv (*argv, 0);
                    165:          argc--; argv++;
                    166:        }
                    167:       else if (!strcmp (*argv, "-s") ||
                    168:               !strcmp (*argv, "-set"))
                    169:        /* Set a variable */
                    170:        {
                    171:          argc--; argv++;
                    172:          tem = *argv;
                    173:          if (argc < 2)
                    174:            fatal ("No value specified for variable \"%s\"",
                    175:                   tem);
                    176:          argc--; argv++;
                    177:          setenv (tem, *argv);
                    178:          argc--; argv++;
                    179:        }
                    180:       else if (!strcmp (*argv, "-") || !strcmp (*argv, "--"))
                    181:        {
                    182:          argc--; argv++;
                    183:          break;
                    184:        }
                    185:       else
                    186:        {
                    187:          fatal ("unknown switch \"%s\"", *argv);
                    188:        }
                    189:     }
                    190: 
                    191:   /* If no program specified print the environment and exit */
                    192:   if (argc <= 0)
                    193:     {
                    194:       while (*nenv)
                    195:        printf ("%s\n", *nenv++);
                    196:       exit (0);
                    197:     }
                    198:   else
                    199:     {
                    200:       extern int errno, sys_nerr;
                    201:       extern char *sys_errlist[];
                    202: 
                    203:       environ = nenv;
                    204:       (void) execvp (*argv, argv);
                    205: 
                    206:       fprintf (stderr, "%s: Cannot execute \"%s\"",
                    207:               progname, *argv);
                    208:       if (errno < sys_nerr)
                    209:        fprintf (stderr, ": %s\n" , sys_errlist[errno]);
                    210:       else
                    211:        putc ('\n', stderr);
                    212:       exit (errno != 0 ? errno : 1);
                    213:     }
                    214: }
                    215: 
                    216: void
                    217: setenv (var, val)
                    218:   register char *var, *val;
                    219: {
                    220:   register char **e;
                    221:   int len = strlen (var);
                    222: 
                    223:   {
                    224:     register char *tem = index (var, '=');
                    225:     if (tem)
                    226:       fatal ("Environment variable names may not contain \"=\": %s",
                    227:             var);
                    228:     else if (*var == '\000')
                    229:       fatal ("Zero-length environment variable name specified.");
                    230:   }
                    231: 
                    232:   for (e = nenv; *e; e++)
                    233:     if (!strncmp (var, *e, len) &&
                    234:        (*e)[len] == '=')
                    235:       {
                    236:        if (val)
                    237:          goto set;
                    238:        else
                    239:          do { *e = *(e + 1); } while (*e++);
                    240:        return;
                    241:       }
                    242: 
                    243:   if (!val)
                    244:     return; /* Nothing to unset */
                    245: 
                    246:   len = e - nenv;
                    247:   if (len + 1 >= nenv_size)
                    248:     {
                    249:       nenv_size += 100;
                    250:       nenv = (char **) xrealloc (nenv, nenv_size * sizeof (char *));
                    251:       e = nenv + len;
                    252:     }
                    253: 
                    254:  set:
                    255:   val = concat (var, "=", val);
                    256:   if (*e)
                    257:     free (*e);
                    258:   else
                    259:     *(e + 1) = (char *) 0;
                    260:   *e = val;
                    261:   return;
                    262: }
                    263: 
                    264: void
                    265: fatal (msg, arg1, arg2)
                    266:      char *msg, *arg1, *arg2;
                    267: {
                    268:   fprintf (stderr, "%s: ", progname);
                    269:   fprintf (stderr, msg, arg1, arg2);
                    270:   putc ('\n', stderr);
                    271:   exit (1);
                    272: }
                    273: 
                    274: 
                    275: extern char *malloc (), *realloc ();
                    276: 
                    277: void
                    278: memory_fatal ()
                    279: {
                    280:   fatal ("Out of memory");
                    281: }
                    282: 
                    283: char *
                    284: xmalloc (size)
                    285:      int size;
                    286: {
                    287:   register char *value;
                    288:   value = (char *) malloc (size);
                    289:   if (!value) memory_fatal ();
                    290:   return (value);
                    291: }
                    292: 
                    293: char *
                    294: xrealloc (ptr, size)
                    295:      char *ptr;
                    296:      int size;
                    297: {
                    298:   register char *value;
                    299:   value = (char *) realloc (ptr, size);
                    300:   if (!value) memory_fatal ();
                    301:   return (value);
                    302: }
                    303: 
                    304: /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3.  */
                    305: 
                    306: char *
                    307: concat (s1, s2, s3)
                    308:      char *s1, *s2, *s3;
                    309: {
                    310:   int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
                    311:   char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
                    312: 
                    313:   strcpy (result, s1);
                    314:   strcpy (result + len1, s2);
                    315:   strcpy (result + len1 + len2, s3);
                    316:   *(result + len1 + len2 + len3) = 0;
                    317: 
                    318:   return result;
                    319: }
                    320: 
                    321: 
                    322: /*
                    323:  * Local variables:
                    324:  * compile-command: "cc -g -o env env.c"
                    325:  * end:
                    326:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.