110d63b7dSRichard Lowe /*
210d63b7dSRichard Lowe * CDDL HEADER START
310d63b7dSRichard Lowe *
410d63b7dSRichard Lowe * The contents of this file are subject to the terms of the
510d63b7dSRichard Lowe * Common Development and Distribution License (the "License").
610d63b7dSRichard Lowe * You may not use this file except in compliance with the License.
710d63b7dSRichard Lowe *
810d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing.
1010d63b7dSRichard Lowe * See the License for the specific language governing permissions
1110d63b7dSRichard Lowe * and limitations under the License.
1210d63b7dSRichard Lowe *
1310d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
1410d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
1610d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
1710d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
1810d63b7dSRichard Lowe *
1910d63b7dSRichard Lowe * CDDL HEADER END
2010d63b7dSRichard Lowe */
2110d63b7dSRichard Lowe /*
2210d63b7dSRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
2310d63b7dSRichard Lowe * Use is subject to license terms.
2410d63b7dSRichard Lowe */
2510d63b7dSRichard Lowe
2610d63b7dSRichard Lowe /*
2710d63b7dSRichard Lowe * dosys.cc
2810d63b7dSRichard Lowe *
2910d63b7dSRichard Lowe * Execute one commandline
3010d63b7dSRichard Lowe */
3110d63b7dSRichard Lowe
3210d63b7dSRichard Lowe /*
3310d63b7dSRichard Lowe * Included files
3410d63b7dSRichard Lowe */
3510d63b7dSRichard Lowe #include <fcntl.h> /* open() */
3610d63b7dSRichard Lowe #include <mk/defs.h>
3710d63b7dSRichard Lowe #include <mksh/dosys.h> /* doshell(), doexec() */
3810d63b7dSRichard Lowe #include <mksh/misc.h> /* getmem() */
3910d63b7dSRichard Lowe #include <sys/stat.h> /* open() */
4010d63b7dSRichard Lowe #include <unistd.h> /* getpid() */
4110d63b7dSRichard Lowe
4210d63b7dSRichard Lowe /*
4310d63b7dSRichard Lowe * Defined macros
4410d63b7dSRichard Lowe */
4510d63b7dSRichard Lowe
4610d63b7dSRichard Lowe /*
4710d63b7dSRichard Lowe * typedefs & structs
4810d63b7dSRichard Lowe */
4910d63b7dSRichard Lowe
5010d63b7dSRichard Lowe /*
5110d63b7dSRichard Lowe * Static variables
5210d63b7dSRichard Lowe */
5310d63b7dSRichard Lowe static int filter_file;
5410d63b7dSRichard Lowe static char *filter_file_name;
5510d63b7dSRichard Lowe
5610d63b7dSRichard Lowe /*
5710d63b7dSRichard Lowe * File table of contents
5810d63b7dSRichard Lowe */
5910d63b7dSRichard Lowe static void redirect_stderr(void);
6010d63b7dSRichard Lowe
6110d63b7dSRichard Lowe /*
6210d63b7dSRichard Lowe * dosys(command, ignore_error, call_make, silent_error, target)
6310d63b7dSRichard Lowe *
6410d63b7dSRichard Lowe * Check if command string contains meta chars and dispatch to
6510d63b7dSRichard Lowe * the proper routine for executing one command line.
6610d63b7dSRichard Lowe *
6710d63b7dSRichard Lowe * Return value:
6810d63b7dSRichard Lowe * Indicates if the command execution failed
6910d63b7dSRichard Lowe *
7010d63b7dSRichard Lowe * Parameters:
7110d63b7dSRichard Lowe * command The command to run
7210d63b7dSRichard Lowe * ignore_error Should make abort when an error is seen?
7310d63b7dSRichard Lowe * call_make Did command reference $(MAKE) ?
7410d63b7dSRichard Lowe * silent_error Should error messages be suppressed for pmake?
7510d63b7dSRichard Lowe * target Target we are building
7610d63b7dSRichard Lowe *
7710d63b7dSRichard Lowe * Global variables used:
7810d63b7dSRichard Lowe * do_not_exec_rule Is -n on?
7910d63b7dSRichard Lowe * working_on_targets We started processing real targets
8010d63b7dSRichard Lowe */
8110d63b7dSRichard Lowe Doname
dosys(Name command,Boolean ignore_error,Boolean call_make,Boolean silent_error,Boolean always_exec,Name target)82*e7afc443SToomas Soome dosys(Name command, Boolean ignore_error, Boolean call_make, Boolean silent_error, Boolean always_exec, Name target)
8310d63b7dSRichard Lowe {
8410d63b7dSRichard Lowe timestruc_t before;
85*e7afc443SToomas Soome int length = command->hash.length;
8610d63b7dSRichard Lowe Wstring wcb(command);
87*e7afc443SToomas Soome wchar_t *p = wcb.get_string();
88*e7afc443SToomas Soome wchar_t *q;
8910d63b7dSRichard Lowe Doname result;
9010d63b7dSRichard Lowe
9110d63b7dSRichard Lowe /* Strip spaces from head of command string */
9210d63b7dSRichard Lowe while (iswspace(*p)) {
9310d63b7dSRichard Lowe p++, length--;
9410d63b7dSRichard Lowe }
9510d63b7dSRichard Lowe if (*p == (int) nul_char) {
9610d63b7dSRichard Lowe return build_failed;
9710d63b7dSRichard Lowe }
9810d63b7dSRichard Lowe /* If we are faking it we just return */
9910d63b7dSRichard Lowe if (do_not_exec_rule &&
10010d63b7dSRichard Lowe working_on_targets &&
10110d63b7dSRichard Lowe !call_make &&
10210d63b7dSRichard Lowe !always_exec) {
10310d63b7dSRichard Lowe return build_ok;
10410d63b7dSRichard Lowe }
10510d63b7dSRichard Lowe /* no_action_was_taken is used to print special message */
10610d63b7dSRichard Lowe no_action_was_taken = false;
10710d63b7dSRichard Lowe
10810d63b7dSRichard Lowe /* Copy string to make it OK to write it. */
10910d63b7dSRichard Lowe q = ALLOC_WC(length + 1);
11010d63b7dSRichard Lowe (void) wcscpy(q, p);
11110d63b7dSRichard Lowe /* Write the state file iff this command uses make. */
11210d63b7dSRichard Lowe if (call_make && command_changed) {
11310d63b7dSRichard Lowe write_state_file(0, false);
11410d63b7dSRichard Lowe }
11510d63b7dSRichard Lowe make_state->stat.time = file_no_time;
11610d63b7dSRichard Lowe (void)exists(make_state);
11710d63b7dSRichard Lowe before = make_state->stat.time;
11810d63b7dSRichard Lowe /*
11910d63b7dSRichard Lowe * Run command directly if it contains no shell meta chars,
12010d63b7dSRichard Lowe * else run it using the shell.
12110d63b7dSRichard Lowe */
12210d63b7dSRichard Lowe if (await(ignore_error,
12310d63b7dSRichard Lowe silent_error,
12410d63b7dSRichard Lowe target,
12510d63b7dSRichard Lowe wcb.get_string(),
12610d63b7dSRichard Lowe command->meta ?
12710d63b7dSRichard Lowe doshell(q, ignore_error,
12810d63b7dSRichard Lowe stdout_file, stderr_file, 0) :
12910d63b7dSRichard Lowe doexec(q, ignore_error,
13010d63b7dSRichard Lowe stdout_file, stderr_file,
13110d63b7dSRichard Lowe vroot_path, 0),
13210d63b7dSRichard Lowe NULL,
13310d63b7dSRichard Lowe -1
13410d63b7dSRichard Lowe )) {
13510d63b7dSRichard Lowe result = build_ok;
13610d63b7dSRichard Lowe } else {
13710d63b7dSRichard Lowe result = build_failed;
13810d63b7dSRichard Lowe }
13910d63b7dSRichard Lowe retmem(q);
14010d63b7dSRichard Lowe
14110d63b7dSRichard Lowe if ((report_dependencies_level == 0) &&
14210d63b7dSRichard Lowe call_make) {
14310d63b7dSRichard Lowe make_state->stat.time = file_no_time;
14410d63b7dSRichard Lowe (void)exists(make_state);
14510d63b7dSRichard Lowe if (before == make_state->stat.time) {
14610d63b7dSRichard Lowe return result;
14710d63b7dSRichard Lowe }
14810d63b7dSRichard Lowe makefile_type = reading_statefile;
14910d63b7dSRichard Lowe if (read_trace_level > 1) {
15010d63b7dSRichard Lowe trace_reader = true;
15110d63b7dSRichard Lowe }
15210d63b7dSRichard Lowe temp_file_number++;
15310d63b7dSRichard Lowe (void) read_simple_file(make_state,
15410d63b7dSRichard Lowe false,
15510d63b7dSRichard Lowe false,
15610d63b7dSRichard Lowe false,
15710d63b7dSRichard Lowe false,
15810d63b7dSRichard Lowe false,
15910d63b7dSRichard Lowe true);
16010d63b7dSRichard Lowe trace_reader = false;
16110d63b7dSRichard Lowe }
16210d63b7dSRichard Lowe return result;
16310d63b7dSRichard Lowe }
164