LCOV - code coverage report
Current view: top level - src - env.c (source / functions) Hit Total Coverage
Test: coreutils.info Lines: 48 48 100.0 %
Date: 2018-01-30 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* env - run a program in a modified environment
       2             :    Copyright (C) 1986, 1991-2005, 2007 Free Software Foundation, Inc.
       3             : 
       4             :    This program is free software: you can redistribute it and/or modify
       5             :    it under the terms of the GNU General Public License as published by
       6             :    the Free Software Foundation, either version 3 of the License, or
       7             :    (at your option) any later version.
       8             : 
       9             :    This program is distributed in the hope that it will be useful,
      10             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :    GNU General Public License for more details.
      13             : 
      14             :    You should have received a copy of the GNU General Public License
      15             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
      16             : 
      17             : /* Richard Mlynarik and David MacKenzie */
      18             : 
      19             : /* Options:
      20             :    -
      21             :    -i
      22             :    --ignore-environment
      23             :         Construct a new environment from scratch; normally the
      24             :         environment is inherited from the parent process, except as
      25             :         modified by other options.
      26             : 
      27             :    -u variable
      28             :    --unset=variable
      29             :         Unset variable VARIABLE (remove it from the environment).
      30             :         If VARIABLE was not set, does nothing.
      31             : 
      32             :    variable=value (an arg containing a "=" character)
      33             :         Set the environment variable VARIABLE to value VALUE.  VALUE
      34             :         may be of zero length ("variable=").  Setting a variable to a
      35             :         zero-length value is different from unsetting it.
      36             : 
      37             :    --
      38             :         Indicate that the following argument is the program
      39             :         to invoke.  This is necessary when the program's name
      40             :         begins with "-" or contains a "=".
      41             : 
      42             :    The first remaining argument specifies a program to invoke;
      43             :    it is searched for according to the specification of the PATH
      44             :    environment variable.  Any arguments following that are
      45             :    passed as arguments to that program.
      46             : 
      47             :    If no command name is specified following the environment
      48             :    specifications, the resulting environment is printed.
      49             :    This is like specifying a command name of "printenv".
      50             : 
      51             :    Examples:
      52             : 
      53             :    If the environment passed to "env" is
      54             :         { LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
      55             : 
      56             :    env - foo
      57             :         runs "foo" in a null environment.
      58             : 
      59             :    env foo
      60             :         runs "foo" in the environment
      61             :         { LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
      62             : 
      63             :    env DISPLAY=gnu:0 nemacs
      64             :         runs "nemacs" in the environment
      65             :         { LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks DISPLAY=gnu:0 }
      66             : 
      67             :    env - LOGNAME=foo /hacks/hack bar baz
      68             :         runs the "hack" program on arguments "bar" and "baz" in an
      69             :         environment in which the only variable is "LOGNAME".  Note that
      70             :         the "-" option clears out the PATH variable, so one should be
      71             :         careful to specify in which directory to find the program to
      72             :         call.
      73             : 
      74             :    env -u EDITOR LOGNAME=foo PATH=/energy -- e=mc2 bar baz
      75             :         runs the program "/energy/e=mc2" with environment
      76             :         { LOGNAME=foo PATH=/energy }
      77             : */
      78             : 
      79             : #include <config.h>
      80             : #include <stdio.h>
      81             : #include <getopt.h>
      82             : #include <sys/types.h>
      83             : #include <getopt.h>
      84             : 
      85             : #include "system.h"
      86             : #include "error.h"
      87             : 
      88             : /* The official name of this program (e.g., no `g' prefix).  */
      89             : #define PROGRAM_NAME "env"
      90             : 
      91             : #define AUTHORS "Richard Mlynarik", "David MacKenzie"
      92             : 
      93             : int putenv ();
      94             : 
      95             : extern char **environ;
      96             : 
      97             : /* The name by which this program was run. */
      98             : char *program_name;
      99             : 
     100             : static struct option const longopts[] =
     101             : {
     102             :   {"ignore-environment", no_argument, NULL, 'i'},
     103             :   {"unset", required_argument, NULL, 'u'},
     104             :   {GETOPT_HELP_OPTION_DECL},
     105             :   {GETOPT_VERSION_OPTION_DECL},
     106             :   {NULL, 0, NULL, 0}
     107             : };
     108             : 
     109             : void
     110           9 : usage (int status)
     111             : {
     112           9 :   if (status != EXIT_SUCCESS)
     113           7 :     fprintf (stderr, _("Try `%s --help' for more information.\n"),
     114             :              program_name);
     115             :   else
     116             :     {
     117           2 :       printf (_("\
     118             : Usage: %s [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]\n"),
     119             :               program_name);
     120           2 :       fputs (_("\
     121             : Set each NAME to VALUE in the environment and run COMMAND.\n\
     122             : \n\
     123             :   -i, --ignore-environment   start with an empty environment\n\
     124             :   -u, --unset=NAME           remove variable from the environment\n\
     125             : "), stdout);
     126           2 :       fputs (HELP_OPTION_DESCRIPTION, stdout);
     127           2 :       fputs (VERSION_OPTION_DESCRIPTION, stdout);
     128           2 :       fputs (_("\
     129             : \n\
     130             : A mere - implies -i.  If no COMMAND, print the resulting environment.\n\
     131             : "), stdout);
     132           2 :       emit_bug_reporting_address ();
     133             :     }
     134           9 :   exit (status);
     135             : }
     136             : 
     137             : int
     138          39 : main (int argc, char **argv)
     139             : {
     140             :   int optc;
     141          39 :   bool ignore_environment = false;
     142             : 
     143             :   initialize_main (&argc, &argv);
     144          39 :   program_name = argv[0];
     145          39 :   setlocale (LC_ALL, "");
     146             :   bindtextdomain (PACKAGE, LOCALEDIR);
     147             :   textdomain (PACKAGE);
     148             : 
     149          39 :   initialize_exit_failure (EXIT_FAILURE);
     150          39 :   atexit (close_stdout);
     151             : 
     152          95 :   while ((optc = getopt_long (argc, argv, "+iu:", longopts, NULL)) != -1)
     153             :     {
     154          27 :       switch (optc)
     155             :         {
     156           7 :         case 'i':
     157           7 :           ignore_environment = true;
     158           7 :           break;
     159          10 :         case 'u':
     160          10 :           break;
     161           2 :         case_GETOPT_HELP_CHAR;
     162           1 :         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
     163           7 :         default:
     164           7 :           usage (EXIT_FAILURE);
     165             :         }
     166             :     }
     167             : 
     168          29 :   if (optind < argc && STREQ (argv[optind], "-"))
     169           7 :     ignore_environment = true;
     170             : 
     171          29 :   if (ignore_environment)
     172             :     {
     173             :       static char *dummy_environ[] = { NULL };
     174          13 :       environ = dummy_environ;
     175             :     }
     176             : 
     177          29 :   optind = 0;                   /* Force GNU getopt to re-initialize. */
     178          74 :   while ((optc = getopt_long (argc, argv, "+iu:", longopts, NULL)) != -1)
     179          16 :     if (optc == 'u')
     180          10 :       putenv (optarg);          /* Requires GNU putenv. */
     181             : 
     182          29 :   if (optind < argc && STREQ (argv[optind], "-"))
     183           7 :     ++optind;
     184             : 
     185          73 :   while (optind < argc && strchr (argv[optind], '='))
     186          15 :     putenv (argv[optind++]);
     187             : 
     188             :   /* If no program is specified, print the environment and exit. */
     189          29 :   if (argc <= optind)
     190             :     {
     191          23 :       char *const *e = environ;
     192         407 :       while (*e)
     193         361 :         puts (*e++);
     194          23 :       exit (EXIT_SUCCESS);
     195             :     }
     196             : 
     197           6 :   execvp (argv[optind], &argv[optind]);
     198             : 
     199             :   {
     200           6 :     int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
     201           6 :     error (0, errno, "%s", argv[optind]);
     202           6 :     exit (exit_status);
     203             :   }
     204             : }

Generated by: LCOV version 1.10