Annotation of 43BSDReno/contrib/emacs-18.55/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:                       NO WARRANTY
                      8: 
                      9:   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
                     10: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
                     11: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
                     12: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
                     13: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
                     14: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
                     15: FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
                     16: AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
                     17: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
                     18: CORRECTION.
                     19: 
                     20:  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
                     21: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
                     22: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
                     23: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
                     24: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
                     25: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
                     26: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
                     27: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
                     28: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
                     29: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
                     30: 
                     31:                GENERAL PUBLIC LICENSE TO COPY
                     32: 
                     33:   1. You may copy and distribute verbatim copies of this source file
                     34: as you receive it, in any medium, provided that you conspicuously
                     35: and appropriately publish on each copy a valid copyright notice
                     36: "Copyright (C) 1986 Free Software Foundation, Inc.", and include
                     37: following the copyright notice a verbatim copy of the above disclaimer
                     38: of warranty and of this License.
                     39: 
                     40:   2. You may modify your copy or copies of this source file or
                     41: any portion of it, and copy and distribute such modifications under
                     42: the terms of Paragraph 1 above, provided that you also do the following:
                     43: 
                     44:     a) cause the modified files to carry prominent notices stating
                     45:     that you changed the files and the date of any change; and
                     46: 
                     47:     b) cause the whole of any work that you distribute or publish,
                     48:     that in whole or in part contains or is a derivative of this
                     49:     program or any part thereof, to be licensed at no charge to all
                     50:     third parties on terms identical to those contained in this
                     51:     License Agreement (except that you may choose to grant more extensive
                     52:     warranty protection to some or all third parties, at your option).
                     53: 
                     54:     c) You may charge a distribution fee for the physical act of
                     55:     transferring a copy, and you may at your option offer warranty
                     56:     protection in exchange for a fee.
                     57: 
                     58: Mere aggregation of another unrelated program with this program (or its
                     59: derivative) on a volume of a storage or distribution medium does not bring
                     60: the other program under the scope of these terms.
                     61: 
                     62:   3. You may copy and distribute this program (or a portion or derivative
                     63: of it, under Paragraph 2) in object code or executable form under the terms
                     64: of Paragraphs 1 and 2 above provided that you also do one of the following:
                     65: 
                     66:     a) accompany it with the complete corresponding machine-readable
                     67:     source code, which must be distributed under the terms of
                     68:     Paragraphs 1 and 2 above; or,
                     69: 
                     70:     b) accompany it with a written offer, valid for at least three
                     71:     years, to give any third party free (except for a nominal
                     72:     shipping charge) a complete machine-readable copy of the
                     73:     corresponding source code, to be distributed under the terms of
                     74:     Paragraphs 1 and 2 above; or,
                     75: 
                     76:     c) accompany it with the information you received as to where the
                     77:     corresponding source code may be obtained.  (This alternative is
                     78:     allowed only for noncommercial distribution and only if you
                     79:     received the program in object code or executable form alone.)
                     80: 
                     81: For an executable file, complete source code means all the source code for
                     82: all modules it contains; but, as a special exception, it need not include
                     83: source code for modules which are standard libraries that accompany the
                     84: operating system on which the executable file runs.
                     85: 
                     86:   4. You may not copy, sublicense, distribute or transfer this program
                     87: except as expressly provided under this License Agreement.  Any attempt
                     88: otherwise to copy, sublicense, distribute or transfer this program is void and
                     89: your rights to use the program under this License agreement shall be
                     90: automatically terminated.  However, parties who have received computer
                     91: software programs from you with this License Agreement will not have
                     92: their licenses terminated so long as such parties remain in full compliance.
                     93: 
                     94:   5. If you wish to incorporate parts of this program into other free
                     95: programs whose distribution conditions are different, write to the Free
                     96: Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
                     97: worked out a simple rule that can be stated here, but we will often permit
                     98: this.  We will be guided by the two goals of preserving the free status of
                     99: all derivatives of our free software and of promoting the sharing and reuse of
                    100: software.
                    101: 
                    102:  In other words, you are welcome to use, share and improve this program.
                    103:  You are forbidden to forbid anyone else to use, share and improve
                    104:  what you give them.   Help stamp out software-hoarding!  */
                    105: 
                    106: /* 
                    107: 
                    108:    If first argument is "-", then a new environment is constructed
                    109:    from scratch; otherwise the environment is inherited from the parent
                    110:    process, except as modified by other options.
                    111:    
                    112:    So, "env - foo" will invoke the "foo" program in a null environment,
                    113:    whereas "env foo" would invoke "foo" in the same environment as that
                    114:    passed to "env" itself.
                    115: 
                    116:    Subsequent arguments are interpreted as follows:
                    117:    
                    118:    * "variable=value" (ie an arg containing a "=" character)
                    119:      means to set the specified environment variable to that value.
                    120:      `value' may be of zero length ("variable=").  Note that setting
                    121:      a variable to a zero-length value is different from unsetting it.
                    122: 
                    123:    * "-u variable" or "-unset variable"
                    124:      means to unset that variable
                    125:      If that variable isn't set, does nothing.
                    126: 
                    127:    * "-s variable value" or "-set variable value"
                    128:      same as "variable=value"
                    129: 
                    130:    * "-" or "--"
                    131:      are used to indicate that the following argument is the program
                    132:      to invoke.  This is only necessary when the program's name
                    133:      begins with "-" or contains a "="
                    134: 
                    135:    * anything else
                    136:      The first remaining argument specifies a program to invoke
                    137:      (it is searched for according to the specification of the PATH
                    138:      environment variable) and any arguments following that are
                    139:      passed as arguments to that program
                    140: 
                    141:      If no program-name is specified following the environment
                    142:      specifications the the resulting environment is printed
                    143:      (The is like specifying a program-name of "printenv")
                    144: 
                    145:    Examples:
                    146:      If the environment passed to "env" is
                    147:      { USER=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
                    148: 
                    149:      * "env DISPLAY=gnu:0 nemacs"
                    150:         calls "nemacs" in the envionment
                    151:        { EDITOR=emacs USER=rms DISPLAY=gnu }
                    152: 
                    153:      * "env - USER=foo /hacks/hack bar baz"
                    154:        will call the "hack" program on arguments "bar" and "baz"
                    155:        in an environment in which the only variable is "USER"
                    156:        Note that the "-" option will clear out the PATH variable,
                    157:        so one should be careful to specify in which directory
                    158:        to find the program to call
                    159:        
                    160:      * "env -u EDITOR USER=foo PATH=/energy -- e=mc2 bar baz"
                    161:        The program "/energy/e=mc2" is called with environment
                    162:        { USER=foo PATH=/energy }
                    163: 
                    164: */
                    165: 
                    166: #ifdef EMACS
                    167: #define NO_SHORTNAMES
                    168: #include "../src/config.h"
                    169: #endif /* EMACS */
                    170: 
                    171: #include <stdio.h>
                    172: 
                    173: extern int execvp ();
                    174: extern char *index ();
                    175: 
                    176: char *xmalloc (), *xrealloc ();
                    177: char *concat ();
                    178: 
                    179: extern char **environ;
                    180: 
                    181: char **nenv;
                    182: int nenv_size;
                    183: 
                    184: char *progname;
                    185: void setenv ();
                    186: void fatal ();
                    187: 
                    188: main (argc, argv, envp)
                    189:      register int argc;
                    190:      register char **argv;
                    191:      char **envp;
                    192: {
                    193:   register char *tem;
                    194: 
                    195:   progname = argv[0];
                    196:   argc--;
                    197:   argv++;
                    198: 
                    199:   nenv_size = 100;
                    200:   nenv = (char **) xmalloc (nenv_size * sizeof (char *));
                    201:   *nenv = (char *) 0;
                    202: 
                    203:   /* "-" flag means to not inherit parent's environment */
                    204:   if (argc && !strcmp (*argv, "-"))
                    205:     {
                    206:       argc--;
                    207:       argv++;
                    208:     }
                    209:   else
                    210:     /* Else pass on existing env vars. */
                    211:     for (; *envp; envp++)
                    212:       {
                    213:        tem = index (*envp, '=');
                    214:        if (tem)
                    215:          {
                    216:            *tem = '\000';
                    217:            setenv (*envp, tem + 1);
                    218:          }
                    219:      }
                    220: 
                    221:   while (argc > 0)
                    222:     {
                    223:       tem = index (*argv, '=');
                    224:       if (tem)
                    225:        /* If arg contains a "=" it specifies to set a variable */
                    226:        {
                    227:          *tem = '\000';
                    228:          setenv (*argv, tem + 1);
                    229:          argc--; argv++;
                    230:          continue;
                    231:        }
                    232:       
                    233:       if (**argv != '-')
                    234:        /* Remaining args are program name and args to pass it */
                    235:        break;
                    236: 
                    237:       if (argc < 2)
                    238:        fatal ("No argument following \"%s\" switch", *argv);
                    239:        if (!strcmp (*argv, "-u") ||
                    240:               !strcmp (*argv, "-unset"))
                    241:        /* Unset a variable */
                    242:        {
                    243:          argc--; argv++;
                    244:          setenv (*argv, 0);
                    245:          argc--; argv++;
                    246:        }
                    247:       else if (!strcmp (*argv, "-s") ||
                    248:               !strcmp (*argv, "-set"))
                    249:        /* Set a variable */
                    250:        {
                    251:          argc--; argv++;
                    252:          tem = *argv;
                    253:          if (argc < 2)
                    254:            fatal ("No value specified for variable \"%s\"",
                    255:                   tem);
                    256:          argc--; argv++;
                    257:          setenv (tem, *argv);
                    258:          argc--; argv++;
                    259:        }
                    260:       else if (!strcmp (*argv, "-") || !strcmp (*argv, "--"))
                    261:        {
                    262:          argc--; argv++;
                    263:          break;
                    264:        }
                    265:       else
                    266:        {
                    267:          fatal ("unknown switch \"%s\"", *argv);
                    268:        }
                    269:     }
                    270: 
                    271:   /* If no program specified print the environment and exit */
                    272:   if (argc <= 0)
                    273:     {
                    274:       while (*nenv)
                    275:        printf ("%s\n", *nenv++);
                    276:       exit (0);
                    277:     }
                    278:   else
                    279:     {
                    280:       extern int errno, sys_nerr;
                    281:       extern char *sys_errlist[];
                    282: 
                    283:       environ = nenv;
                    284:       (void) execvp (*argv, argv);
                    285: 
                    286:       fprintf (stderr, "%s: Cannot execute \"%s\"",
                    287:               progname, *argv);
                    288:       if (errno < sys_nerr)
                    289:        fprintf (stderr, ": %s\n" , sys_errlist[errno]);
                    290:       else
                    291:        putc ('\n', stderr);
                    292:       exit (errno != 0 ? errno : 1);
                    293:     }
                    294: }
                    295: 
                    296: void
                    297: setenv (var, val)
                    298:   register char *var, *val;
                    299: {
                    300:   register char **e;
                    301:   int len = strlen (var);
                    302: 
                    303:   {
                    304:     register char *tem = index (var, '=');
                    305:     if (tem)
                    306:       fatal ("Environment variable names may not contain \"=\": %s",
                    307:             var);
                    308:     else if (*var == '\000')
                    309:       fatal ("Zero-length environment variable name specified.");
                    310:   }
                    311: 
                    312:   for (e = nenv; *e; e++)
                    313:     if (!strncmp (var, *e, len) &&
                    314:        (*e)[len] == '=')
                    315:       {
                    316:        if (val)
                    317:          goto set;
                    318:        else
                    319:          do { *e = *(e + 1); } while (*e++);
                    320:        return;
                    321:       }
                    322: 
                    323:   if (!val)
                    324:     return; /* Nothing to unset */
                    325: 
                    326:   len = e - nenv;
                    327:   if (len + 1 >= nenv_size)
                    328:     {
                    329:       nenv_size += 100;
                    330:       nenv = (char **) xrealloc (nenv, nenv_size * sizeof (char *));
                    331:       e = nenv + len;
                    332:     }
                    333: 
                    334:  set:
                    335:   val = concat (var, "=", val);
                    336:   if (*e)
                    337:     free (*e);
                    338:   else
                    339:     *(e + 1) = (char *) 0;
                    340:   *e = val;
                    341:   return;
                    342: }
                    343: 
                    344: void
                    345: fatal (msg, arg1, arg2)
                    346:      char *msg, *arg1, *arg2;
                    347: {
                    348:   fprintf (stderr, "%s: ", progname);
                    349:   fprintf (stderr, msg, arg1, arg2);
                    350:   putc ('\n', stderr);
                    351:   exit (1);
                    352: }
                    353: 
                    354: 
                    355: extern char *malloc (), *realloc ();
                    356: 
                    357: void
                    358: memory_fatal ()
                    359: {
                    360:   fatal ("Out of memory");
                    361: }
                    362: 
                    363: char *
                    364: xmalloc (size)
                    365:      int size;
                    366: {
                    367:   register char *value;
                    368:   value = (char *) malloc (size);
                    369:   if (!value) memory_fatal ();
                    370:   return (value);
                    371: }
                    372: 
                    373: char *
                    374: xrealloc (ptr, size)
                    375:      char *ptr;
                    376:      int size;
                    377: {
                    378:   register char *value;
                    379:   value = (char *) realloc (ptr, size);
                    380:   if (!value) memory_fatal ();
                    381:   return (value);
                    382: }
                    383: 
                    384: /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3.  */
                    385: 
                    386: char *
                    387: concat (s1, s2, s3)
                    388:      char *s1, *s2, *s3;
                    389: {
                    390:   int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
                    391:   char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
                    392: 
                    393:   strcpy (result, s1);
                    394:   strcpy (result + len1, s2);
                    395:   strcpy (result + len1 + len2, s3);
                    396:   *(result + len1 + len2 + len3) = 0;
                    397: 
                    398:   return result;
                    399: }
                    400: 
                    401: 
                    402: /*
                    403:  * Local variables:
                    404:  * compile-command: "cc -g -o env env.c"
                    405:  * end:
                    406:  */

unix.superglobalmegacorp.com

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