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 }