LCOV - code coverage report
Current view: top level - builtins - exec.def (source / functions) Hit Total Coverage
Test: cov-sh.info Lines: 0 84 0.0 %
Date: 2020-10-29 14:49:55 Functions: 0 2 0.0 %

          Line data    Source code
       1             : This file is exec.def, from which is created exec.c.
       2             : It implements the builtin "exec" in Bash.
       3             : 
       4             : Copyright (C) 1987-2015 Free Software Foundation, Inc.
       5             : 
       6             : This file is part of GNU Bash, the Bourne Again SHell.
       7             : 
       8             : Bash is free software: you can redistribute it and/or modify
       9             : it under the terms of the GNU General Public License as published by
      10             : the Free Software Foundation, either version 3 of the License, or
      11             : (at your option) any later version.
      12             : 
      13             : Bash is distributed in the hope that it will be useful,
      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             : GNU General Public License for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with Bash.  If not, see <http://www.gnu.org/licenses/>.
      20             : 
      21             : $PRODUCES exec.c
      22             : 
      23             : $BUILTIN exec
      24             : $FUNCTION exec_builtin
      25             : $SHORT_DOC exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
      26             : Replace the shell with the given command.
      27             : 
      28             : Execute COMMAND, replacing this shell with the specified program.
      29             : ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
      30             : any redirections take effect in the current shell.
      31             : 
      32             : Options:
      33             :   -a name       pass NAME as the zeroth argument to COMMAND
      34             :   -c    execute COMMAND with an empty environment
      35             :   -l    place a dash in the zeroth argument to COMMAND
      36             : 
      37             : If the command cannot be executed, a non-interactive shell exits, unless
      38             : the shell option `execfail' is set.
      39             : 
      40             : Exit Status:
      41             : Returns success unless COMMAND is not found or a redirection error occurs.
      42             : $END
      43             : 
      44             : #include <config.h>
      45             : 
      46             : #include "../bashtypes.h"
      47             : #include "posixstat.h"
      48             : #include <signal.h>
      49             : #include <errno.h>
      50             : 
      51             : #if defined (HAVE_UNISTD_H)
      52             : #  include <unistd.h>
      53             : #endif
      54             : 
      55             : #include "../bashansi.h"
      56             : #include "../bashintl.h"
      57             : 
      58             : #include "../shell.h"
      59             : #include "../execute_cmd.h"
      60             : #include "../findcmd.h"
      61             : #if defined (JOB_CONTROL)
      62             : #  include "../jobs.h"
      63             : #endif
      64             : #include "../flags.h"
      65             : #include "../trap.h"
      66             : #if defined (HISTORY)
      67             : #  include "../bashhist.h"
      68             : #endif
      69             : #include "common.h"
      70             : #include "bashgetopt.h"
      71             : 
      72             : /* Not all systems declare ERRNO in errno.h... and some systems #define it! */
      73             : #if !defined (errno)
      74             : extern int errno;
      75             : #endif /* !errno */
      76             : 
      77             : extern int subshell_environment;
      78             : extern REDIRECT *redirection_undo_list;
      79             : extern char *exec_argv0;
      80             : 
      81             : int no_exit_on_failed_exec;
      82             : 
      83             : /* If the user wants this to look like a login shell, then
      84             :    prepend a `-' onto NAME and return the new name. */
      85             : static char *
      86           0 : mkdashname (name)
      87             :      char *name;
      88             : {
      89           0 :   char *ret;
      90             : 
      91           0 :   ret = (char *)xmalloc (2 + strlen (name));
      92           0 :   ret[0] = '-';
      93           0 :   strcpy (ret + 1, name);
      94           0 :   return ret;
      95             : }
      96             : 
      97             : int
      98           0 : exec_builtin (list)
      99             :      WORD_LIST *list;
     100             : {
     101           0 :   int exit_value = EXECUTION_FAILURE;
     102           0 :   int cleanenv, login, opt;
     103           0 :   char *argv0, *command, **args, **env, *newname, *com2;
     104             : 
     105           0 :   cleanenv = login = 0;
     106           0 :   exec_argv0 = argv0 = (char *)NULL;
     107             : 
     108           0 :   reset_internal_getopt ();
     109           0 :   while ((opt = internal_getopt (list, "cla:")) != -1)
     110             :     {
     111           0 :       switch (opt)
     112             :         {
     113             :         case 'c':
     114             :           cleanenv = 1;
     115             :           break;
     116           0 :         case 'l':
     117           0 :           login = 1;
     118           0 :           break;
     119           0 :         case 'a':
     120           0 :           argv0 = list_optarg;
     121           0 :           break;
     122           0 :         CASE_HELPOPT;
     123           0 :         default:
     124           0 :           builtin_usage ();
     125           0 :           return (EX_USAGE);
     126             :         }
     127             :     }
     128           0 :   list = loptend;
     129             : 
     130             :   /* First, let the redirections remain. */
     131           0 :   dispose_redirects (redirection_undo_list);
     132           0 :   redirection_undo_list = (REDIRECT *)NULL;
     133             : 
     134           0 :   if (list == 0)
     135             :     return (EXECUTION_SUCCESS);
     136             : 
     137             : #if defined (RESTRICTED_SHELL)
     138             :   if (restricted)
     139             :     {
     140             :       sh_restricted ((char *)NULL);
     141             :       return (EXECUTION_FAILURE);
     142             :     }
     143             : #endif /* RESTRICTED_SHELL */
     144             : 
     145           0 :   args = strvec_from_word_list (list, 1, 0, (int *)NULL);
     146           0 :   env = (char **)0;
     147             : 
     148             :   /* A command with a slash anywhere in its name is not looked up in $PATH. */
     149           0 :   command = absolute_program (args[0]) ? args[0] : search_for_command (args[0], 1);
     150             : 
     151           0 :   if (command == 0)
     152             :     {
     153           0 :       if (file_isdir (args[0]))
     154             :         {
     155             : #if defined (EISDIR)
     156           0 :           builtin_error (_("%s: cannot execute: %s"), args[0], strerror (EISDIR));
     157             : #else
     158             :           builtin_error (_("%s: cannot execute: %s"), args[0], strerror (errno));
     159             : #endif
     160           0 :           exit_value = EX_NOEXEC;
     161             :         }
     162             :       else
     163             :         {
     164           0 :           sh_notfound (args[0]);
     165           0 :           exit_value = EX_NOTFOUND;     /* As per Posix.2, 3.14.6 */
     166             :         }
     167           0 :       goto failed_exec;
     168             :     }
     169             : 
     170           0 :   com2 = full_pathname (command);
     171           0 :   if (com2)
     172             :     {
     173           0 :       if (command != args[0])
     174           0 :         free (command);
     175             :       command = com2;
     176             :     }
     177             : 
     178           0 :   if (argv0)
     179             :     {
     180           0 :       free (args[0]);
     181           0 :       args[0] = login ? mkdashname (argv0) : savestring (argv0);
     182           0 :       exec_argv0 = savestring (args[0]);
     183             :     }
     184           0 :   else if (login)
     185             :     {
     186           0 :       newname = mkdashname (args[0]);
     187           0 :       free (args[0]);
     188           0 :       args[0] = newname;
     189             :     }
     190             : 
     191             :   /* Decrement SHLVL by 1 so a new shell started here has the same value,
     192             :      preserving the appearance.  After we do that, we need to change the
     193             :      exported environment to include the new value. */
     194           0 :   if (cleanenv == 0)
     195           0 :     adjust_shell_level (-1);
     196             : 
     197           0 :   if (cleanenv)
     198             :     {
     199           0 :       env = strvec_create (1);
     200           0 :       env[0] = (char *)0;
     201             :     }
     202             :   else
     203             :     {   
     204           0 :       maybe_make_export_env ();
     205           0 :       env = export_env;
     206             :     }
     207             : 
     208             : #if defined (HISTORY)
     209             :   if (interactive_shell && subshell_environment == 0)
     210             :     maybe_save_shell_history ();
     211             : #endif /* HISTORY */
     212             : 
     213           0 :   restore_original_signals ();
     214             : 
     215             : #if defined (JOB_CONTROL)
     216           0 :   if (subshell_environment == 0)
     217           0 :     end_job_control ();
     218           0 :   if (interactive || job_control)
     219           0 :     default_tty_job_signals ();         /* undo initialize_job_signals */
     220             : #endif /* JOB_CONTROL */
     221             : 
     222           0 :   exit_value = shell_execve (command, args, env);
     223             : 
     224             :   /* We have to set this to NULL because shell_execve has called realloc()
     225             :      to stuff more items at the front of the array, which may have caused
     226             :      the memory to be freed by realloc().  We don't want to free it twice. */
     227           0 :   args = (char **)NULL;
     228           0 :   if (cleanenv == 0)
     229           0 :     adjust_shell_level (1);
     230             : 
     231           0 :   if (exit_value == EX_NOTFOUND)        /* no duplicate error message */
     232             :     goto failed_exec;
     233           0 :   else if (executable_file (command) == 0)
     234             :     {
     235           0 :       builtin_error (_("%s: cannot execute: %s"), command, strerror (errno));
     236           0 :       exit_value = EX_NOEXEC;   /* As per Posix.2, 3.14.6 */
     237             :     }
     238             :   else
     239           0 :     file_error (command);
     240             : 
     241           0 : failed_exec:
     242           0 :   FREE (command);
     243             : 
     244           0 :   if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
     245           0 :     exit_shell (exit_value);
     246             : 
     247           0 :   if (args)
     248           0 :     strvec_dispose (args);
     249             : 
     250           0 :   if (env && env != export_env)
     251           0 :     strvec_dispose (env);
     252             : 
     253           0 :   initialize_traps ();
     254           0 :   initialize_signals (1);
     255             : 
     256             : #if defined (JOB_CONTROL)
     257           0 :   if (interactive_shell || job_control)
     258           0 :     restart_job_control ();
     259             : #endif /* JOB_CONTROL */
     260             : 
     261             :   return (exit_value);
     262             : }

Generated by: LCOV version 1.14.0.6.4058