xref: /illumos-gate/usr/src/cmd/make/bin/dosys.cc (revision c9ffe217655ce62448bdb45d6f113f43b4dfcc54)
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)
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) wcscpy(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,
128 			    stdout_file, stderr_file, 0) :
129 	            doexec(q, ignore_error,
130 			   stdout_file, stderr_file,
131 	                   vroot_path, 0),
132                   NULL,
133                   -1
134 	          )) {
135 		result = build_ok;
136 	} else {
137 		result = build_failed;
138 	}
139 	retmem(q);
140 
141 	if ((report_dependencies_level == 0) &&
142 	    call_make) {
143 		make_state->stat.time = file_no_time;
144 		(void)exists(make_state);
145 		if (before == make_state->stat.time) {
146 			return result;
147 		}
148 		makefile_type = reading_statefile;
149 		if (read_trace_level > 1) {
150 			trace_reader = true;
151 		}
152 		temp_file_number++;
153 		(void) read_simple_file(make_state,
154 					false,
155 					false,
156 					false,
157 					false,
158 					false,
159 					true);
160 		trace_reader = false;
161 	}
162 	return result;
163 }
164