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