1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * @(#)dosys.cc 1.45 06/12/12
  27  */
  28 
  29 #pragma ident   "@(#)dosys.cc   1.45    06/12/12"
  30 
  31 /*
  32  *      dosys.cc
  33  *
  34  *      Execute one commandline
  35  */
  36 
  37 /*
  38  * Included files
  39  */
  40 #include <fcntl.h>                /* open() */
  41 #include <mk/defs.h>
  42 #include <mksh/dosys.h>           /* doshell(), doexec() */
  43 #include <mksh/misc.h>            /* getmem() */
  44 #include <sys/stat.h>             /* open() */
  45 #include <unistd.h>               /* getpid() */
  46 
  47 /*
  48  * Defined macros
  49  */
  50 
  51 /*
  52  * typedefs & structs
  53  */
  54 
  55 /*
  56  * Static variables
  57  */
  58 static  int             filter_file;
  59 static  char            *filter_file_name;
  60 
  61 /*
  62  * File table of contents
  63  */
  64 static  void            redirect_stderr(void);
  65 
  66 /*
  67  *      dosys(command, ignore_error, call_make, silent_error, target)
  68  *
  69  *      Check if command string contains meta chars and dispatch to
  70  *      the proper routine for executing one command line.
  71  *
  72  *      Return value:
  73  *                              Indicates if the command execution failed
  74  *
  75  *      Parameters:
  76  *              command         The command to run
  77  *              ignore_error    Should make abort when an error is seen?
  78  *              call_make       Did command reference $(MAKE) ?
  79  *              silent_error    Should error messages be suppressed for pmake?
  80  *              target          Target we are building
  81  *
  82  *      Global variables used:
  83  *              do_not_exec_rule Is -n on?
  84  *              working_on_targets We started processing real targets
  85  */
  86 Doname
  87 dosys(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err)
  88 {
  89         timestruc_t             before;
  90         register int            length = command->hash.length;
  91         Wstring                 wcb(command);
  92         register wchar_t        *p = wcb.get_string();
  93         register wchar_t        *q;
  94         Doname                  result;
  95 
  96         /* Strip spaces from head of command string */
  97         while (iswspace(*p)) {
  98                 p++, length--;
  99         }
 100         if (*p == (int) nul_char) {
 101                 return build_failed;
 102         }
 103         /* If we are faking it we just return */
 104         if (do_not_exec_rule &&
 105             working_on_targets &&
 106             !call_make &&
 107             !always_exec) {
 108                 return build_ok;
 109         }
 110         /* no_action_was_taken is used to print special message */
 111         no_action_was_taken = false;
 112 
 113         /* Copy string to make it OK to write it. */
 114         q = ALLOC_WC(length + 1);
 115         (void) wscpy(q, p);
 116         /* Write the state file iff this command uses make. */
 117         if (call_make && command_changed) {
 118                 write_state_file(0, false);
 119         }
 120         make_state->stat.time = file_no_time;
 121         (void)exists(make_state);
 122         before = make_state->stat.time;
 123         /*
 124          * Run command directly if it contains no shell meta chars,
 125          * else run it using the shell.
 126          */
 127         if (await(ignore_error,
 128                   silent_error,
 129                   target,
 130                   wcb.get_string(),
 131                   command->meta ?
 132                     doshell(q, ignore_error, redirect_out_err,
 133                             stdout_file, stderr_file, 0) :
 134                     doexec(q, ignore_error, redirect_out_err,
 135                            stdout_file, stderr_file,
 136                            vroot_path, 0),
 137                   send_mtool_msgs,
 138 #if defined(DISTRIBUTED) || defined(MAKETOOL) /* tolik */
 139                   get_xdrs_ptr(),
 140                   get_job_msg_id()
 141 #else
 142                   NULL,
 143                   -1
 144 #endif
 145                   )) {
 146                 result = build_ok;
 147         } else {
 148                 result = build_failed;
 149         }
 150         retmem(q);
 151 
 152         if ((report_dependencies_level == 0) &&
 153             call_make) {
 154                 make_state->stat.time = file_no_time;
 155                 (void)exists(make_state);
 156                 if (before == make_state->stat.time) {
 157                         return result;
 158                 }
 159                 makefile_type = reading_statefile;
 160                 if (read_trace_level > 1) {
 161                         trace_reader = true;
 162                 }
 163                 temp_file_number++;
 164                 (void) read_simple_file(make_state,
 165                                         false,
 166                                         false,
 167                                         false,
 168                                         false,
 169                                         false,
 170                                         true);
 171                 trace_reader = false;
 172         }
 173         return result;
 174 }