1 /* RCS $Id: runargv.c,v 1.6 2008-03-05 18:35:53 kz Exp $
7 -- Use spawn to run a subprocess.
10 -- Dennis Vadura, dvadura@dmake.wticorp.com
13 -- http://dmake.wticorp.com/
16 -- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
18 -- This program is NOT free software; you can redistribute it and/or
19 -- modify it under the terms of the Software License Agreement Provided
20 -- in the file <distribution-root>/readme/license.txt.
23 -- Use cvs log to obtain detailed change logs.
26 #if defined(USE_CREATEPROCESS)
27 /* MSVC6.0 and newer and MinGW use the parallel build enabled runargv(). */
28 Force a compile
-time blowup
.
29 This file should
not be used
, use unix
/runargv
.c instead
.
37 static int _abort_flg
= FALSE
;
38 static void _add_child
ANSI((CELLPTR
, int));
39 static void _finished_child
ANSI((int));
42 runargv(target
, group
, last
, cmnd_attr
, cmd
)
46 t_attr cmnd_attr
; /* Attributes for current cmnd. */
47 char **cmd
; /* Simulate a reference to *cmd. */
49 int ignore
= (cmnd_attr
& A_IGNORE
)!= 0; /* Ignore errors ('-'). */
50 int shell
= (cmnd_attr
& A_SHELL
) != 0; /* Use shell ('+'). */
51 int mute
= (cmnd_attr
& A_MUTE
) != 0; /* Mute output ('@@'). */
52 #if ! defined(_MSC_VER)
53 #if defined(__BORLANDC__) && __BORLANDC__ >= 0x500
54 extern char ** _RTLENTRY _EXPDATA environ
;
56 extern char **environ
;
61 int old_stdout
= -1; /* For redirecting shell escapes */
62 int old_stderr
= -1; /* and silencing @@-recipes */
63 char *tcmd
= *cmd
; /* For saver/easier string arithmetic on *cmd. */
65 if( Measure
& M_RECIPE
)
66 Do_profile_output( "s", M_RECIPE
, target
);
68 _add_child(target
, ignore
);
70 /* redirect output for _exec_shell / @@-recipes. */
72 /* Add error checking? */
74 dup2( fileno(stdout_redir
), 1 );
80 if( !Is_exec_shell
) {
86 /* Return immediately for empty line or noop command. */
87 if ( !*tcmd
|| /* empty line */
88 ( strncmp(tcmd
, "noop", 4) == 0 && /* noop command */
89 (iswhite(tcmd
[4]) || tcmd
[4] == '\0')) ) {
92 else if( !shell
&& /* internal echo only if not in shell */
93 strncmp(tcmd
, "echo", 4) == 0 &&
94 (iswhite(tcmd
[4]) || tcmd
[4] == '\0') ) {
99 while( iswhite(*tcmd
) ) ++tcmd
;
100 if ( strncmp(tcmd
,"-n",2 ) == 0) {
103 while( iswhite(*tcmd
) ) ++tcmd
;
105 printf("%s%s", tcmd
, nl
? "\n" : "");
110 argv
= Pack_argv( group
, shell
, cmd
);
111 Packed_shell
= shell
||group
;
113 /* The last two arguments would need (const char *const *) casts
114 * to silence the warning when building with MinGW. */
115 status
= spawnvpe(P_WAIT
, *argv
, argv
, environ
);
118 /* Restore stdout/stderr if needed. */
119 if( old_stdout
!= -1 ) {
121 if( old_stderr
!= -1 )
126 /* spawnvpe failed */
127 fprintf(stderr
, "%s: Error executing '%s': %s",
128 Pname
, argv
[0], strerror(errno
) );
129 if( ignore
||Continue
) {
130 fprintf(stderr
, " (Ignored)" );
132 fprintf(stderr
, "\n");
135 if( Measure
& M_RECIPE
)
136 Do_profile_output( "e", M_RECIPE
, target
);
138 _finished_child(status
);
139 if( last
&& !Doing_bang
) Update_time_stamp( target
);
154 Wait_for_child( abort_flg
, pid
)
158 /* There is currently no parallel processing for this OS, always
159 * return -1 indicating that there was nothing to wait for. */
164 static int _valid
= -1;
169 _add_child( target
, ignore
)
177 Current_target
= NIL(CELL
);
182 _finished_child(status
)
185 if( _valid
== -1 ) return;
187 Handle_result( status
, _ignore
, _abort_flg
, _tg
);