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 /* 27 * dosys.cc 28 * 29 * Execute one commandline 30 */ 31 32 /* 33 * Included files 34 */ 35 #include <fcntl.h> /* open() */ 36 #include <mk/defs.h> 37 #include <mksh/dosys.h> /* doshell(), doexec() */ 38 #include <mksh/misc.h> /* getmem() */ 39 #include <sys/stat.h> /* open() */ 40 #include <unistd.h> /* getpid() */ 41 42 /* 43 * Defined macros 44 */ 45 46 /* 47 * typedefs & structs 48 */ 49 50 /* 51 * Static variables 52 */ 53 static int filter_file; 54 static char *filter_file_name; 55 56 /* 57 * File table of contents 58 */ 59 static void redirect_stderr(void); 60 61 /* 62 * dosys(command, ignore_error, call_make, silent_error, target) 63 * 64 * Check if command string contains meta chars and dispatch to 65 * the proper routine for executing one command line. 66 * 67 * Return value: 68 * Indicates if the command execution failed 69 * 70 * Parameters: 71 * command The command to run 72 * ignore_error Should make abort when an error is seen? 73 * call_make Did command reference $(MAKE) ? 74 * silent_error Should error messages be suppressed for pmake? 75 * target Target we are building 76 * 77 * Global variables used: 78 * do_not_exec_rule Is -n on? 79 * working_on_targets We started processing real targets 80 */ 81 Doname 82 dosys(register Name command, register Boolean ignore_error, register Boolean call_make, Boolean silent_error, Boolean always_exec, Name target, Boolean redirect_out_err) 83 { 84 timestruc_t before; 85 register int length = command->hash.length; 86 Wstring wcb(command); 87 register wchar_t *p = wcb.get_string(); 88 register wchar_t *q; 89 Doname result; 90 91 /* Strip spaces from head of command string */ 92 while (iswspace(*p)) { 93 p++, length--; 94 } 95 if (*p == (int) nul_char) { 96 return build_failed; 97 } 98 /* If we are faking it we just return */ 99 if (do_not_exec_rule && 100 working_on_targets && 101 !call_make && 102 !always_exec) { 103 return build_ok; 104 } 105 /* no_action_was_taken is used to print special message */ 106 no_action_was_taken = false; 107 108 /* Copy string to make it OK to write it. */ 109 q = ALLOC_WC(length + 1); 110 (void) wscpy(q, p); 111 /* Write the state file iff this command uses make. */ 112 if (call_make && command_changed) { 113 write_state_file(0, false); 114 } 115 make_state->stat.time = file_no_time; 116 (void)exists(make_state); 117 before = make_state->stat.time; 118 /* 119 * Run command directly if it contains no shell meta chars, 120 * else run it using the shell. 121 */ 122 if (await(ignore_error, 123 silent_error, 124 target, 125 wcb.get_string(), 126 command->meta ? 127 doshell(q, ignore_error, redirect_out_err, 128 stdout_file, stderr_file, 0) : 129 doexec(q, ignore_error, redirect_out_err, 130 stdout_file, stderr_file, 131 vroot_path, 0), 132 send_mtool_msgs, 133 NULL, 134 -1 135 )) { 136 result = build_ok; 137 } else { 138 result = build_failed; 139 } 140 retmem(q); 141 142 if ((report_dependencies_level == 0) && 143 call_make) { 144 make_state->stat.time = file_no_time; 145 (void)exists(make_state); 146 if (before == make_state->stat.time) { 147 return result; 148 } 149 makefile_type = reading_statefile; 150 if (read_trace_level > 1) { 151 trace_reader = true; 152 } 153 temp_file_number++; 154 (void) read_simple_file(make_state, 155 false, 156 false, 157 false, 158 false, 159 false, 160 true); 161 trace_reader = false; 162 } 163 return result; 164 }