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 }