View | Details | Raw Unified | Return to issue 83540
Collapse All | Expand All

(-)dmake/Makefile.am (-1 / +1 lines)
Lines 61-67 Link Here
61
if OSTYPEWIN32
61
if OSTYPEWIN32
62
dmake_SOURCES += win95/dchdir.c win95/switchar.c \
62
dmake_SOURCES += win95/dchdir.c win95/switchar.c \
63
                 msdos/dstrlwr.c msdos/arlib.c \
63
                 msdos/dstrlwr.c msdos/arlib.c \
64
                 msdos/dirbrk.c msdos/runargv.c \
64
                 msdos/dirbrk.c unix/runargv.c \
65
                 msdos/rmprq.c \
65
                 msdos/rmprq.c \
66
                 win95/microsft/ruletab.c
66
                 win95/microsft/ruletab.c
67
INCLUDES += -I$(top_srcdir)/@OS_TYPE@/@OS_VERSION@ -I$(top_srcdir)/@OS_TYPE@
67
INCLUDES += -I$(top_srcdir)/@OS_TYPE@/@OS_VERSION@ -I$(top_srcdir)/@OS_TYPE@
(-)dmake/Makefile.in (-8 / +3 lines)
Lines 82-88 Link Here
82
82
83
@OSTYPEWIN32_TRUE@am__append_4 = win95/dchdir.c win95/switchar.c \
83
@OSTYPEWIN32_TRUE@am__append_4 = win95/dchdir.c win95/switchar.c \
84
@OSTYPEWIN32_TRUE@                 msdos/dstrlwr.c msdos/arlib.c \
84
@OSTYPEWIN32_TRUE@                 msdos/dstrlwr.c msdos/arlib.c \
85
@OSTYPEWIN32_TRUE@                 msdos/dirbrk.c msdos/runargv.c \
85
@OSTYPEWIN32_TRUE@                 msdos/dirbrk.c unix/runargv.c \
86
@OSTYPEWIN32_TRUE@                 msdos/rmprq.c \
86
@OSTYPEWIN32_TRUE@                 msdos/rmprq.c \
87
@OSTYPEWIN32_TRUE@                 win95/microsft/ruletab.c
87
@OSTYPEWIN32_TRUE@                 win95/microsft/ruletab.c
88
88
Lines 112-118 Link Here
112
	function.c dbug/dbug/dbug.c unix/arlib.c unix/dcache.c \
112
	function.c dbug/dbug/dbug.c unix/arlib.c unix/dcache.c \
113
	unix/dirbrk.c unix/rmprq.c unix/ruletab.c unix/runargv.c \
113
	unix/dirbrk.c unix/rmprq.c unix/ruletab.c unix/runargv.c \
114
	unix/tempnam.c win95/dchdir.c win95/switchar.c msdos/dstrlwr.c \
114
	unix/tempnam.c win95/dchdir.c win95/switchar.c msdos/dstrlwr.c \
115
	msdos/arlib.c msdos/dirbrk.c msdos/runargv.c msdos/rmprq.c \
115
	msdos/arlib.c msdos/dirbrk.c msdos/rmprq.c \
116
	win95/microsft/ruletab.c
116
	win95/microsft/ruletab.c
117
am__dirstamp = $(am__leading_dot)dirstamp
117
am__dirstamp = $(am__leading_dot)dirstamp
118
@DBUG_TRUE@am__objects_1 = dbug/dbug/dbug.$(OBJEXT)
118
@DBUG_TRUE@am__objects_1 = dbug/dbug/dbug.$(OBJEXT)
Lines 124-131 Link Here
124
@OSTYPEWIN32_TRUE@	win95/switchar.$(OBJEXT) \
124
@OSTYPEWIN32_TRUE@	win95/switchar.$(OBJEXT) \
125
@OSTYPEWIN32_TRUE@	msdos/dstrlwr.$(OBJEXT) \
125
@OSTYPEWIN32_TRUE@	msdos/dstrlwr.$(OBJEXT) \
126
@OSTYPEWIN32_TRUE@	msdos/arlib.$(OBJEXT) msdos/dirbrk.$(OBJEXT) \
126
@OSTYPEWIN32_TRUE@	msdos/arlib.$(OBJEXT) msdos/dirbrk.$(OBJEXT) \
127
@OSTYPEWIN32_TRUE@	msdos/runargv.$(OBJEXT) \
127
@OSTYPEWIN32_TRUE@	unix/runargv.$(OBJEXT) msdos/rmprq.$(OBJEXT) \
128
@OSTYPEWIN32_TRUE@	msdos/rmprq.$(OBJEXT) \
129
@OSTYPEWIN32_TRUE@	win95/microsft/ruletab.$(OBJEXT)
128
@OSTYPEWIN32_TRUE@	win95/microsft/ruletab.$(OBJEXT)
130
am_dmake_OBJECTS = infer.$(OBJEXT) make.$(OBJEXT) stat.$(OBJEXT) \
129
am_dmake_OBJECTS = infer.$(OBJEXT) make.$(OBJEXT) stat.$(OBJEXT) \
131
	expand.$(OBJEXT) dmstring.$(OBJEXT) hash.$(OBJEXT) \
130
	expand.$(OBJEXT) dmstring.$(OBJEXT) hash.$(OBJEXT) \
Lines 404-411 Link Here
404
	msdos/$(DEPDIR)/$(am__dirstamp)
403
	msdos/$(DEPDIR)/$(am__dirstamp)
405
msdos/dirbrk.$(OBJEXT): msdos/$(am__dirstamp) \
404
msdos/dirbrk.$(OBJEXT): msdos/$(am__dirstamp) \
406
	msdos/$(DEPDIR)/$(am__dirstamp)
405
	msdos/$(DEPDIR)/$(am__dirstamp)
407
msdos/runargv.$(OBJEXT): msdos/$(am__dirstamp) \
408
	msdos/$(DEPDIR)/$(am__dirstamp)
409
msdos/rmprq.$(OBJEXT): msdos/$(am__dirstamp) \
406
msdos/rmprq.$(OBJEXT): msdos/$(am__dirstamp) \
410
	msdos/$(DEPDIR)/$(am__dirstamp)
407
	msdos/$(DEPDIR)/$(am__dirstamp)
411
win95/microsft/$(am__dirstamp):
408
win95/microsft/$(am__dirstamp):
Lines 427-433 Link Here
427
	-rm -f msdos/dirbrk.$(OBJEXT)
424
	-rm -f msdos/dirbrk.$(OBJEXT)
428
	-rm -f msdos/dstrlwr.$(OBJEXT)
425
	-rm -f msdos/dstrlwr.$(OBJEXT)
429
	-rm -f msdos/rmprq.$(OBJEXT)
426
	-rm -f msdos/rmprq.$(OBJEXT)
430
	-rm -f msdos/runargv.$(OBJEXT)
431
	-rm -f unix/arlib.$(OBJEXT)
427
	-rm -f unix/arlib.$(OBJEXT)
432
	-rm -f unix/dcache.$(OBJEXT)
428
	-rm -f unix/dcache.$(OBJEXT)
433
	-rm -f unix/dirbrk.$(OBJEXT)
429
	-rm -f unix/dirbrk.$(OBJEXT)
Lines 467-473 Link Here
467
@AMDEP_TRUE@@am__include@ @am__quote@msdos/$(DEPDIR)/dirbrk.Po@am__quote@
463
@AMDEP_TRUE@@am__include@ @am__quote@msdos/$(DEPDIR)/dirbrk.Po@am__quote@
468
@AMDEP_TRUE@@am__include@ @am__quote@msdos/$(DEPDIR)/dstrlwr.Po@am__quote@
464
@AMDEP_TRUE@@am__include@ @am__quote@msdos/$(DEPDIR)/dstrlwr.Po@am__quote@
469
@AMDEP_TRUE@@am__include@ @am__quote@msdos/$(DEPDIR)/rmprq.Po@am__quote@
465
@AMDEP_TRUE@@am__include@ @am__quote@msdos/$(DEPDIR)/rmprq.Po@am__quote@
470
@AMDEP_TRUE@@am__include@ @am__quote@msdos/$(DEPDIR)/runargv.Po@am__quote@
471
@AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/arlib.Po@am__quote@
466
@AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/arlib.Po@am__quote@
472
@AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/dcache.Po@am__quote@
467
@AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/dcache.Po@am__quote@
473
@AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/dirbrk.Po@am__quote@
468
@AMDEP_TRUE@@am__include@ @am__quote@unix/$(DEPDIR)/dirbrk.Po@am__quote@
(-)dmake/dag.c (+10 lines)
Lines 28-33 Link Here
28
28
29
#include "extern.h"
29
#include "extern.h"
30
30
31
#if defined(USE_CREATEPROCESS)
32
#include <windows.h>
33
#endif
34
31
35
32
static void
36
static void
33
set_macro_value(hp)/*
37
set_macro_value(hp)/*
Lines 86-91 Link Here
86
         if( hp->MV_IVAR == &Max_proc || hp->MV_IVAR == &Max_proclmt ) {
90
         if( hp->MV_IVAR == &Max_proc || hp->MV_IVAR == &Max_proclmt ) {
87
            if( tvalue < 1 )
91
            if( tvalue < 1 )
88
               Fatal( "Process limit value must be > 1" );
92
               Fatal( "Process limit value must be > 1" );
93
94
#if defined(USE_CREATEPROCESS)
95
            if( Max_proclmt > MAXIMUM_WAIT_OBJECTS )
96
               Fatal( "Specified maximum # of processes (MAXPROCESSLIMIT)"
97
		      " exceeds OS limit of [%d].", MAXIMUM_WAIT_OBJECTS );
98
#endif
89
            
99
            
90
            if( Max_proc > Max_proclmt )
100
            if( Max_proc > Max_proclmt )
91
               Fatal( "Specified # of processes exceeds limit of [%d]",
101
               Fatal( "Specified # of processes exceeds limit of [%d]",
(-)dmake/dmake.c (-1 / +6 lines)
Lines 146-151 Link Here
146
146
147
   /* Initialize Global variables to their default values       */
147
   /* Initialize Global variables to their default values       */
148
   Prolog(argc, argv);
148
   Prolog(argc, argv);
149
   /* Set internal macros to their initial values, some are changed
150
    * later again by Make_rules() that parses the values from ruletab.c. */
149
   Create_macro_vars();
151
   Create_macro_vars();
150
   Catch_signals(Quit);
152
   Catch_signals(Quit);
151
153
Lines 315-322 Link Here
315
	    case 'P':
317
	    case 'P':
316
	       if( p[1] ) {
318
	       if( p[1] ) {
317
		  /* Only set MAXPROCESS if -S flag is *not* used. */
319
		  /* Only set MAXPROCESS if -S flag is *not* used. */
318
		  if( !(Glob_attr & A_SEQ) )
320
		  if( !(Glob_attr & A_SEQ) ) {
319
		     Def_macro( "MAXPROCESS", p+1, M_MULTI|M_EXPANDED );
321
		     Def_macro( "MAXPROCESS", p+1, M_MULTI|M_EXPANDED );
322
		  }
320
		  p += strlen(p)-1;
323
		  p += strlen(p)-1;
321
	       }
324
	       }
322
	       else
325
	       else
Lines 337-342 Link Here
337
      }
340
      }
338
      else if( (q = strchr(p, '=')) != NIL(char) ) {
341
      else if( (q = strchr(p, '=')) != NIL(char) ) {
339
	 cmdmacs = DmStrAdd( cmdmacs, DmStrDup2(p), TRUE );
342
	 cmdmacs = DmStrAdd( cmdmacs, DmStrDup2(p), TRUE );
343
	 /* Macros defined on the command line are marked precious.
344
	  * FIXME: The exception for += appears to be bogus. */
340
	 Parse_macro( p, (q[-1]!='+')?M_PRECIOUS:M_DEFAULT );
345
	 Parse_macro( p, (q[-1]!='+')?M_PRECIOUS:M_DEFAULT );
341
      }
346
      }
342
      else {
347
      else {
(-)dmake/extern.h (+13 lines)
Lines 139-144 Link Here
139
#  define NULLDEV "/dev/null"
139
#  define NULLDEV "/dev/null"
140
#endif
140
#endif
141
141
142
/* For MSVC 6.0 and newer and MinGW use the CreateProcess() function. */
143
#if defined(__MINGW32__) || defined(_MSC_VER) && _MSC_VER >= 1200
144
#  define USE_CREATEPROCESS 1
145
#else
146
/* #undef USE_CREATEPROCESS */
147
#endif
148
149
/*  CreateProcess() is spawn-like. */
150
#if ENABLE_SPAWN && ( HAVE_SPAWN_H || __CYGWIN__ || __EMX__) || defined(USE_CREATEPROCESS)
151
#  define USE_SPAWN 1
152
#else
153
/* #undef USE_SPAWN */
154
#endif
142
155
143
/* Work around some of the functions that may or may not exist */
156
/* Work around some of the functions that may or may not exist */
144
#if ! HAVE_TZSET
157
#if ! HAVE_TZSET
(-)dmake/imacs.c (-2 / +11 lines)
Lines 28-33 Link Here
28
28
29
#include "extern.h"
29
#include "extern.h"
30
30
31
#if defined(USE_CREATEPROCESS)
32
#include <windows.h>
33
#endif
34
31
static	void	_set_int_var ANSI((char *, char *, int, int *));
35
static	void	_set_int_var ANSI((char *, char *, int, int *));
32
static	void	_set_string_var ANSI((char *, char *, int, char **));
36
static	void	_set_string_var ANSI((char *, char *, int, char **));
33
static	void	_set_bit_var ANSI((char *, char *, int));
37
static	void	_set_bit_var ANSI((char *, char *, int));
Lines 137-145 Link Here
137
   _set_int_var( "PREP",          "0", M_DEFAULT, &Prep );
141
   _set_int_var( "PREP",          "0", M_DEFAULT, &Prep );
138
   (void) Def_macro("MAXLINELENGTH", "1024", M_FLAG | M_DEFAULT);
142
   (void) Def_macro("MAXLINELENGTH", "1024", M_FLAG | M_DEFAULT);
139
143
140
   /* set MAXPROCESSLIMIT high initially so that it allows MAXPROCESS to
144
   /* MAXPROCESSLIMIT is overwritten by the ruletab.c settings. Set its
141
    * change from command line. */
145
    * initial value high so that it allows MAXPROCESS to be changed
146
    * from the command line. */
142
   _set_int_var( "MAXPROCESSLIMIT", "100", M_DEFAULT|M_NOEXPORT,&Max_proclmt );
147
   _set_int_var( "MAXPROCESSLIMIT", "100", M_DEFAULT|M_NOEXPORT,&Max_proclmt );
148
#if defined(USE_CREATEPROCESS)
149
   /* Set the OS early enough. */
150
   Max_proclmt = MAXIMUM_WAIT_OBJECTS;
151
#endif
143
   _set_int_var( "MAXPROCESS", "1", M_DEFAULT|M_NOEXPORT, &Max_proc );
152
   _set_int_var( "MAXPROCESS", "1", M_DEFAULT|M_NOEXPORT, &Max_proc );
144
   sprintf(buf,"%d",NAME_MAX);
153
   sprintf(buf,"%d",NAME_MAX);
145
   _set_int_var( "NAMEMAX", buf, M_DEFAULT|M_NOEXPORT, &NameMax);
154
   _set_int_var( "NAMEMAX", buf, M_DEFAULT|M_NOEXPORT, &NameMax);
(-)dmake/sysintf.c (-1 / +26 lines)
Lines 328-333 Link Here
328
   static char **av = NIL(char *);
328
   static char **av = NIL(char *);
329
   static int   avs = 0;
329
   static int   avs = 0;
330
   int i = 0;
330
   int i = 0;
331
   char *s; /* Temporary string pointer. */
331
332
332
   if( av == NIL(char *) ) {
333
   if( av == NIL(char *) ) {
333
      TALLOC(av, MINARGV, char*);
334
      TALLOC(av, MINARGV, char*);
Lines 345-356 Link Here
345
346
346
	    if( shell && Shell_quote && *Shell_quote ) {
347
	    if( shell && Shell_quote && *Shell_quote ) {
347
	       /* Enclose the shell command with SHELLCMDQUOTE. */
348
	       /* Enclose the shell command with SHELLCMDQUOTE. */
348
	       char *s;
349
	       s = DmStrJoin(Shell_quote, *cmd, -1, FALSE);
349
	       s = DmStrJoin(Shell_quote, *cmd, -1, FALSE);
350
	       FREE(*cmd);
350
	       FREE(*cmd);
351
	       *cmd = DmStrJoin(s, Shell_quote, -1, TRUE);
351
	       *cmd = DmStrJoin(s, Shell_quote, -1, TRUE);
352
	    }
352
	    }
353
	    av[i++] = *cmd;
353
	    av[i++] = *cmd;
354
355
#if defined(USE_CREATEPROCESS)
356
	    /* CreateProcess() needs one long command line. */
357
	    av[0] = DmStrAdd(av[0], av[1], FALSE);
358
	    av[1] = NIL(char);
359
	    /* i == 3 means Shell_flags are given. */
360
	    if( i == 3 ) {
361
	       s = av[0];
362
	       av[0] = DmStrAdd(s, av[2], FALSE);
363
	       FREE(s);
364
	       av[2] = NIL(char);
365
	    }
366
	    /* The final free of cmd will free the concated command line. */
367
	    FREE(*cmd);
368
	    *cmd = av[0];
369
#endif
354
	    av[i]   = NIL(char);
370
	    av[i]   = NIL(char);
355
	 }
371
	 }
356
	 else
372
	 else
Lines 359-364 Link Here
359
      else {
375
      else {
360
	 char *tcmd = *cmd;
376
	 char *tcmd = *cmd;
361
377
378
#if defined(USE_CREATEPROCESS)
379
	 /* CreateProcess() needs one long command line, fill *cmd
380
	  * into av[0]. */
381
	 while( iswhite(*tcmd) ) ++tcmd;
382
	 if( *tcmd ) av[i++] = tcmd;
383
#else
384
	 /* All other exec/spawn functions need the parameters separated
385
	  * in the argument vector. */
362
	 do {
386
	 do {
363
	    /* Fill *cmd into av[]. Whitespace is converted into '\0' to
387
	    /* Fill *cmd into av[]. Whitespace is converted into '\0' to
364
	     * terminate each av[] member. */
388
	     * terminate each av[] member. */
Lines 374-379 Link Here
374
	       av = (char **) realloc( av, avs*sizeof(char *) );
398
	       av = (char **) realloc( av, avs*sizeof(char *) );
375
	    }
399
	    }
376
	 } while( *tcmd );
400
	 } while( *tcmd );
401
#endif
377
402
378
	 av[i] = NIL(char);
403
	 av[i] = NIL(char);
379
      }
404
      }
(-)dmake/msdos/runargv.c (+6 lines)
Lines 23-28 Link Here
23
--      Use cvs log to obtain detailed change logs.
23
--      Use cvs log to obtain detailed change logs.
24
*/
24
*/
25
25
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.
30
#endif
31
26
#include <process.h>
32
#include <process.h>
27
#include <errno.h>
33
#include <errno.h>
28
#include "extern.h"
34
#include "extern.h"
(-)dmake/unix/runargv.c (-42 / +310 lines)
Lines 112-117 Link Here
112
112
113
#include "extern.h"
113
#include "extern.h"
114
114
115
#if defined(USE_CREATEPROCESS)
116
#include <windows.h>
117
#endif
118
115
#ifdef HAVE_WAIT_H
119
#ifdef HAVE_WAIT_H
116
#  include <wait.h>
120
#  include <wait.h>
117
#else 
121
#else 
Lines 148-156 Link Here
148
   struct prp *prp_next;
152
   struct prp *prp_next;
149
} RCP, *RCPPTR;
153
} RCP, *RCPPTR;
150
154
155
#if defined(USE_CREATEPROCESS)
156
   /* MS's HANDLE is basically a (void *) (winnt.h). */
157
typedef HANDLE DMHANDLE;
158
#else
159
typedef int DMHANDLE;
160
#endif
161
151
typedef struct pr {
162
typedef struct pr {
152
   int		pr_valid;
163
   int		pr_valid;
153
   int		pr_pid;
164
   DMHANDLE	pr_pid;
165
   DMHANDLE	pr_tid;
154
   CELLPTR	pr_target;
166
   CELLPTR	pr_target;
155
   int		pr_ignore;
167
   int		pr_ignore;
156
   int		pr_last;
168
   int		pr_last;
Lines 160-176 Link Here
160
   char        *pr_dir;
172
   char        *pr_dir;
161
} PR;
173
} PR;
162
174
175
typedef struct tpid {
176
   DMHANDLE pid;
177
   DMHANDLE tid;
178
} TPID;
179
180
const TPID NOPID = { (DMHANDLE)-1, (DMHANDLE)0 };
181
163
static PR  *_procs    = NIL(PR); /* Array to hold concurrent processes. */
182
static PR  *_procs    = NIL(PR); /* Array to hold concurrent processes. */
164
static int  _procs_size = 0;     /* Savegard to find MAXPROCESS changes. */
183
static int  _procs_size = 0;     /* Savegard to find MAXPROCESS changes. */
165
static int  _proc_cnt = 0;       /* Number of running processes. */
184
static int  _proc_cnt = 0;       /* Number of running processes. */
166
static int  _abort_flg= FALSE;
185
static int  _abort_flg= FALSE;
167
static int  _use_i    = -1;
186
static int  _use_i    = -1;
187
#if defined(USE_CREATEPROCESS)
188
static HANDLE *_wpList = NIL(HANDLE); /* Array to hold pids to wait for. */
189
#endif
168
190
169
static  int	_add_child ANSI((int, CELLPTR, int, int, int));
191
static  int	_add_child ANSI((TPID, CELLPTR, int, int, int));
170
static  void	_attach_cmd ANSI((char *, int, CELLPTR, t_attr, int));
192
static  void	_attach_cmd ANSI((char *, int, CELLPTR, t_attr, int));
171
static  void    _finished_child ANSI((int, int));
193
static  void    _finished_child ANSI((DMHANDLE, int));
172
static  int     _running ANSI((CELLPTR));
194
static  int     _running ANSI((CELLPTR));
173
195
196
/* Machine/OS dependent helpers. */
197
static	DMHANDLE	dmwaitnext ANSI((int *));
198
static	DMHANDLE	dmwaitpid ANSI((int, int *));
199
200
#if defined( USE_SPAWN )
201
202
int terrno; /* Temporarily store errno. */
203
204
static	TPID	dmspawn ANSI((char **));
205
206
static TPID
207
dmspawn( argv )
208
   char **argv;
209
{
210
   TPID pid;
211
212
   /* No error output is done here as stdout/stderr might be redirected. */
213
#if defined( __CYGWIN__) || defined( __EMX__)
214
   pid.pid = spawnvp(_P_NOWAIT, argv[0], (const char**) argv);
215
   pid.tid = 0;
216
#elif defined(USE_CREATEPROCESS)
217
   static STARTUPINFO si;
218
   static int initSTARTUPINFO = FALSE;
219
   PROCESS_INFORMATION pi;
220
221
   /* si can be reused. */
222
   if( initSTARTUPINFO == FALSE ) {
223
      initSTARTUPINFO = TRUE;
224
      ZeroMemory( &si, sizeof(si) );
225
      si.cb = sizeof(si);
226
   }
227
   ZeroMemory( &pi, sizeof(pi) );
228
229
   /* Start the child process. CreateProcess() parameters:
230
    * No module name (use command line).
231
    * Command line. This fails if the path to the program contains spaces.
232
    * Process handle not inheritable.
233
    * Thread handle not inheritable.
234
    * Set handle inheritance to FALSE.
235
    * No creation flags.
236
    * Use parent's environment block.
237
    * Use parent's starting directory.
238
    * Pointer to STARTUPINFO structure.
239
    * Pointer to PROCESS_INFORMATION structure. */
240
   if( CreateProcess(NULL, argv[0], NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) ) {
241
      pid.pid = pi.hProcess;
242
      pid.tid = pi.hThread;
243
   } else {
244
      printf( "CreateProcess failed (%d).\n", GetLastError() );
245
      pid.pid = (DMHANDLE)-1;
246
   }
247
#else   /* Non cygwin, OS/2, MinGW and MSC */
248
   int tpid;
249
   if (posix_spawnp (&tpid, argv[0], NULL, NULL, argv, (char *)NULL))
250
      tpid = -1; /* posix_spawn failed */
251
252
   pid.pid = tpid;
253
   pid.tid = 0;
254
#endif  /* __CYGWIN__ */
255
   return pid;
256
}
257
258
#endif /* USE_SPAWN */
259
260
static DMHANDLE
261
dmwaitnext( status )
262
     int *status;
263
     /* return pid we waited for, -1 if there
264
      * was nothing to wait for (ECHILD) and -2 for other errors. */
265
{
266
   DMHANDLE wid;
267
#if !defined(USE_CREATEPROCESS)
268
   /* Here might be the culprit for the famous OOo build hang. If
269
    * cygwin manages to "loose" a process and none else is left the
270
    * wait() will wait forever. */
271
   wid = wait(status);
272
273
   /* If ECHILD is set from waitpid/wait then no child was left. */
274
   if( wid  == -1 ) {
275
      fprintf(stderr, "%s:  Internal Error: wait() failed: %d -  %s\n",
276
	      Pname, errno, strerror(errno) );
277
      if(errno != ECHILD) {
278
	 /* Wait was interrupted or a child was terminated (SIGCHLD) */
279
	 return -2;
280
      } else {
281
	 return -1;
282
      }
283
   }
284
#else
285
   DWORD pEvent;
286
   DWORD dwExitCode = 0;
287
288
   /* Create a list of possible objects to wait for. */
289
   int i;
290
   int numProc = 0;
291
   for( i=0; i<Max_proc; i++ ) {
292
      if(_procs[i].pr_valid) {
293
	 _wpList[numProc++] = _procs[i].pr_pid;
294
      }
295
   }
296
297
   /* Wait ... */
298
   /* number of objects in array, array of objects,
299
    * wait for any object, wait for the next child to finish */
300
   pEvent = WaitForMultipleObjects( numProc, _wpList, FALSE, INFINITE);
301
302
   if( pEvent >= 0 && pEvent < WAIT_OBJECT_0 + numProc ) {
303
      wid =  _wpList[pEvent - WAIT_OBJECT_0];
304
      for( i=0; i<Max_proc && _procs[i].pr_pid != wid; i++ )
305
	 ;
306
      if( i == Max_proc )
307
	 Fatal("Internal Error: Process not in pq !");
308
309
      GetExitCodeProcess(wid, &dwExitCode);
310
      if(dwExitCode == STILL_ACTIVE) {
311
	 /* Process did not terminate -> force it, with exit code 1. */
312
	 TerminateProcess(wid, 1);
313
	 dwExitCode = 1;
314
	 fprintf(stderr, "%s:  Internal Error: Process still running - "
315
		 "terminate it!\n", Pname );
316
      }
317
318
      /* Close process and thread handles. */
319
      CloseHandle( wid );
320
      CloseHandle( _procs[i].pr_tid );
321
   }
322
   else {
323
      int err = GetLastError();
324
      LPVOID lpMsgBuf;
325
      
326
      FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | 
327
		     FORMAT_MESSAGE_FROM_SYSTEM |
328
		     FORMAT_MESSAGE_IGNORE_INSERTS,
329
		     NULL,
330
		     err,
331
		     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
332
		     (LPTSTR) &lpMsgBuf,
333
		     0, NULL );
334
335
      fprintf(stderr, "%s:  Internal Error: WaitForMultipleObjects() failed:"
336
	      " %d -  %s\n", Pname, err, lpMsgBuf);
337
      LocalFree(lpMsgBuf);
338
339
      /* No way to identify something comparable to ECHILD, always return -2.*/
340
      wid = (DMHANDLE)-2;
341
   }
342
343
344
   *status = dwExitCode;
345
#endif
346
   return wid;
347
}
348
349
350
static DMHANDLE
351
dmwaitpid( pqid, status )
352
     int pqid;
353
     int *status;
354
     /* return pid we waited for, 0 if it didn't finish yet, -1 if there
355
      * was nothing to wait for (ECHILD) and -2 for other errors. */
356
{
357
   DMHANDLE wid;
358
359
#if !defined(USE_CREATEPROCESS)
360
   wid = waitpid(_procs[pqid].pr_pid, status, WNOHANG);
361
   /* If ECHILD is set from waitpid/wait then no child was left. */
362
   if( wid  == -1 ) {
363
      fprintf(stderr, "%s:  Internal Error: waitpid() failed: %d -  %s\n",
364
	      Pname, errno, strerror(errno) );
365
      if(errno != ECHILD) {
366
	 /* Wait was interrupted or a child was terminated (SIGCHLD) */
367
	 return -2;
368
      } else {
369
	 return -1;
370
      }
371
   }
372
#else
373
   DWORD pEvent;
374
   DWORD dwExitCode = 0;
375
376
   /* Wait ... (Check status and return) */
377
   pEvent = WaitForSingleObject(_procs[pqid].pr_pid, 0);
378
379
   if( pEvent == WAIT_OBJECT_0 ) {
380
      GetExitCodeProcess(_procs[pqid].pr_pid, &dwExitCode);
381
      if(dwExitCode == STILL_ACTIVE) {
382
	 /* Process did not terminate -> force it, with exit code 1. */
383
	 TerminateProcess(_procs[pqid].pr_pid, 1);
384
	 dwExitCode = 1;
385
	 fprintf(stderr, "%s:  Internal Error: Process still running - "
386
		 "terminate it!\n", Pname );
387
      }
388
389
      /* Close process and thread handles. */
390
      CloseHandle( _procs[pqid].pr_pid );
391
      CloseHandle( _procs[pqid].pr_tid );
392
   }
393
   else if( pEvent == WAIT_TIMEOUT ) {
394
      wid = 0;
395
   }
396
   else {
397
      int err = GetLastError();
398
      LPVOID lpMsgBuf;
399
      
400
      FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | 
401
		     FORMAT_MESSAGE_FROM_SYSTEM |
402
		     FORMAT_MESSAGE_IGNORE_INSERTS,
403
		     NULL,
404
		     err,
405
		     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
406
		     (LPTSTR) &lpMsgBuf,
407
		     0, NULL );
408
409
      fprintf(stderr, "%s:  Internal Error: WaitForSingleObject() failed:"
410
	      " %d -  %s\n", Pname, err, lpMsgBuf);
411
      LocalFree(lpMsgBuf);
412
413
      printf("pEvent:%d:  %d %d\n", pEvent, WAIT_OBJECT_0, WAIT_TIMEOUT);
414
415
      exit(1);
416
417
      /* No way to identify something comparable to ECHILD, always return -2.*/
418
      wid = (DMHANDLE)-2;
419
   }
420
421
   *status = dwExitCode;
422
#endif
423
424
   return wid;
425
}
426
427
174
#if ! HAVE_STRERROR
428
#if ! HAVE_STRERROR
175
static char *
429
static char *
176
private_strerror (errnum)
430
private_strerror (errnum)
Lines 211-217 Link Here
211
   int  mute = (cmnd_attr & A_MUTE) != 0; /* Mute output ('@@'). */
465
   int  mute = (cmnd_attr & A_MUTE) != 0; /* Mute output ('@@'). */
212
   int  wfc = (cmnd_attr & A_WFC) != 0; /* Wait for completion. */
466
   int  wfc = (cmnd_attr & A_WFC) != 0; /* Wait for completion. */
213
467
214
   int  pid;
468
   TPID  pid;
215
   int  st_pq = 0; /* Current _exec_shell target process index */
469
   int  st_pq = 0; /* Current _exec_shell target process index */
216
   char *tcmd = *cmd; /* For saver/easier string arithmetic on *cmd. */
470
   char *tcmd = *cmd; /* For saver/easier string arithmetic on *cmd. */
217
   char         **argv;
471
   char         **argv;
Lines 300-307 Link Here
300
   }
554
   }
301
   if ( internal ) {
555
   if ( internal ) {
302
      /* Use _add_child() / _finished_child() with internal command. */
556
      /* Use _add_child() / _finished_child() with internal command. */
303
      int cur_proc = _add_child(-1, target, ignore, last, FALSE);
557
      int cur_proc = _add_child(NOPID, target, ignore, last, FALSE);
304
      _finished_child(-cur_proc, 0);
558
      _finished_child( (DMHANDLE)-cur_proc, 0 );
305
      DB_RETURN( 0 );
559
      DB_RETURN( 0 );
306
   }
560
   }
307
561
Lines 309-315 Link Here
309
   argv = Pack_argv( group, shell, cmd );
563
   argv = Pack_argv( group, shell, cmd );
310
564
311
   /* Really spawn or fork a child. */
565
   /* Really spawn or fork a child. */
312
#if ENABLE_SPAWN && ( HAVE_SPAWN_H || __CYGWIN__ || __EMX__)
566
#if defined( USE_SPAWN )
313
   /* As no other childs are started while the output is redirected this
567
   /* As no other childs are started while the output is redirected this
314
    * is save. */
568
    * is save. */
315
   if( Is_exec_shell ) {
569
   if( Is_exec_shell ) {
Lines 326-348 Link Here
326
	 dup2( zerofd, 1 );
580
	 dup2( zerofd, 1 );
327
      }
581
      }
328
   }
582
   }
329
#if defined( __CYGWIN__) || defined( __EMX__)
583
330
   pid = spawnvp(_P_NOWAIT, argv[0], (const char**) argv);
584
   pid = dmspawn( argv );
331
#else   /* __CYGWIN__ */
585
   terrno = errno;
332
   if (posix_spawnp (&pid, argv[0], NULL, NULL, argv, (char *)NULL))
586
333
      pid = -1;	/* posix_spawn failed */
334
#endif  /* __CYGWIN__ */
335
   if( old_stdout != -1 ) {
587
   if( old_stdout != -1 ) {
336
      dup2(old_stdout, 1);
588
      dup2(old_stdout, 1);
337
      if( old_stderr != -1 )
589
      if( old_stderr != -1 )
338
	 dup2(old_stderr, 2);
590
	 dup2(old_stderr, 2);
339
   }
591
   }
340
   if(pid == -1) {
592
   if(pid.pid == (DMHANDLE)-1) {
341
      /* spawn failed */
593
      /* spawn failed */
342
      int cur_proc;
594
      int cur_proc;
343
595
344
      fprintf(stderr, "%s:  Error executing '%s': %s",
596
      fprintf(stderr, "%s:  Error executing '%s': %s",
345
	      Pname, argv[0], strerror(errno) );
597
	      Pname, argv[0], strerror(terrno) );
346
      if( ignore||Continue ) {
598
      if( ignore||Continue ) {
347
	 fprintf(stderr, " (Ignored)" );
599
	 fprintf(stderr, " (Ignored)" );
348
      }
600
      }
Lines 350-357 Link Here
350
602
351
      /* Use _add_child() / _finished_child() to treat the failure
603
      /* Use _add_child() / _finished_child() to treat the failure
352
       * gracefully, if so requested. */
604
       * gracefully, if so requested. */
353
      cur_proc = _add_child(-1, target, ignore, last, FALSE);
605
      cur_proc = _add_child(NOPID, target, ignore, last, FALSE);
354
      _finished_child(cur_proc, SIGTERM);
606
      _finished_child((DMHANDLE)cur_proc, SIGTERM);
355
607
356
      /* _finished_child() aborts dmake if we are not told to
608
      /* _finished_child() aborts dmake if we are not told to
357
       * ignore errors. If we reach the this point return 0 as
609
       * ignore errors. If we reach the this point return 0 as
Lines 361-370 Link Here
361
   } else {
613
   } else {
362
      _add_child(pid, target, ignore, last, wfc);
614
      _add_child(pid, target, ignore, last, wfc);
363
   }
615
   }
364
#else  /* ENABLE_SPAWN && ... */
616
#else  /* USE_SPAWN */
365
617
366
   fflush(stdout);
618
   fflush(stdout);
367
   switch( pid=fork() ){
619
   switch( pid.pid = fork() ){
368
620
369
   case -1: /* fork failed */
621
   case -1: /* fork failed */
370
      Fatal("fork failed: %s: %s", argv[0], strerror( errno ));
622
      Fatal("fork failed: %s: %s", argv[0], strerror( errno ));
Lines 408-414 Link Here
408
      _add_child(pid, target, ignore, last, wfc);
660
      _add_child(pid, target, ignore, last, wfc);
409
   }
661
   }
410
662
411
#endif  /* ENABLE_SPAWN && ... */
663
#endif  /* USE_SPAWN */
412
664
413
   DB_RETURN( 1 );
665
   DB_RETURN( 1 );
414
}
666
}
Lines 429-436 Link Here
429
int abort_flg;
681
int abort_flg;
430
int pqid;
682
int pqid;
431
{
683
{
432
   int pid;
684
   DMHANDLE pid;
433
   int wid;
685
   DMHANDLE wid;
434
   int status;
686
   int status;
435
   /* Never wait for internal commands. */
687
   /* Never wait for internal commands. */
436
   int waitchild;
688
   int waitchild;
Lines 452-458 Link Here
452
      if( i == Max_proc )
704
      if( i == Max_proc )
453
	 return(-1);
705
	 return(-1);
454
706
455
      pid = -1;
707
      pid = (DMHANDLE)-1;
456
      waitchild = FALSE;
708
      waitchild = FALSE;
457
   }
709
   }
458
   else {
710
   else {
Lines 477-510 Link Here
477
729
478
   do {
730
   do {
479
      /* Wait for the next process to finish. */
731
      /* Wait for the next process to finish. */
480
      if( (pid != -1) && (wid = waitpid(pid, &status, WNOHANG)) ) {
732
      if( (pid != (DMHANDLE)-1) && (wid = dmwaitpid(pqid, &status)) ) {
481
	 /* if wid is 0 this means that pid didn't finish yet. In this case
733
	 /* if wid is 0 this means that pid didn't finish yet. In this case
482
	  * just handle the next finished process in the following "else". */
734
	  * just handle the next finished process in the following "else". */
483
	 ;
735
	 ;
484
      }
736
      }
485
      else {
737
      else {
486
	 /* Here might be the culprit for the famous OOo build hang. If
738
	 wid = dmwaitnext(&status);
487
	  * cygwin manages to "loose" a process and none else is left the
488
	  * wait() will wait forever. */
489
	 wid = wait(&status);
490
	 /* If we get an error tell the error handling routine below that we
739
	 /* If we get an error tell the error handling routine below that we
491
	  * were not waiting for a specific pid. */
740
	  * were not waiting for a specific pid. */
492
	 if( wid  == -1 )
741
	 if( wid  == (DMHANDLE)-1 )
493
	    pid = -1;
742
	    pid = (DMHANDLE)-1;
494
      }
743
      }
495
 
744
 
496
      /* If ECHILD is set from waitpid/wait then no child was left. */
745
      /* If ECHILD is set from waitpid/wait then no child was left. */
497
      if( wid  == -1 ) {
746
      if( (int)wid  < 0 ) { /* Force int to check for sign. BRRR */
498
	 if(errno != ECHILD) {
747
	 if(wid == (DMHANDLE)-2) {
499
	    /* Wait was interrupted or a child was terminated (SIGCHLD) */
748
	    /* Wait was interrupted or a child was terminated (SIGCHLD) */
500
	    if ( in_quit() ) {
749
	    if ( in_quit() ) {
501
	       /* We're already terminating, just continue. */
750
	       /* We're already terminating, just continue. */
502
	       return 0;
751
	       return 0;
503
	    } else {
752
	    } else {
504
	       Fatal( "dmake was interrupted or a child terminated: %d : %s - stopping all childs ...", errno, strerror( errno ) );
753
	       Fatal( "dmake was interrupted or a child terminated. "
754
		      "Stopping all childs ..." );
505
	    }
755
	    }
506
	 } else {
756
	 } else {
507
	    if( pid != -1 ) {
757
	    /* The child we were waiting for is missing or no child is
758
	     * left to wait for. */
759
	    if( pid != (DMHANDLE)-1 ) {
508
	       /* If we know the pid disable the pq entry. */
760
	       /* If we know the pid disable the pq entry. */
509
	       if( _procs[pqid].pr_valid ) {
761
	       if( _procs[pqid].pr_valid ) {
510
		  _procs[pqid].pr_valid = 0;
762
		  _procs[pqid].pr_valid = 0;
Lines 564-574 Link Here
564
   if( _procs != NIL(PR) ) {
816
   if( _procs != NIL(PR) ) {
565
      for( i=0; i<Max_proc; i++ )
817
      for( i=0; i<Max_proc; i++ )
566
	 if( _procs[i].pr_valid ) {
818
	 if( _procs[i].pr_valid ) {
819
#if !defined(USE_CREATEPROCESS)
567
	    if( (ret = kill(_procs[i].pr_pid, SIGTERM)) ) {
820
	    if( (ret = kill(_procs[i].pr_pid, SIGTERM)) ) {
568
	       fprintf(stderr, "Killing of pid %d from pq[%d] failed with: %s - %d ret: %d\n",
821
	       fprintf(stderr, "Killing of pid %d from pq[%d] failed with: %s - %d ret: %d\n",
569
		       _procs[i].pr_pid, i,
822
		       _procs[i].pr_pid, i,
570
		       strerror(errno), SIGTERM, ret );
823
		       strerror(errno), SIGTERM, ret );
571
	    }
824
	    }
825
#else
826
	 TerminateProcess(_procs[i].pr_pid, 1);
827
#endif
572
	 }
828
	 }
573
   }
829
   }
574
}
830
}
Lines 584-590 Link Here
584
  If wfc (wait for completion) is TRUE the function calls
840
  If wfc (wait for completion) is TRUE the function calls
585
  Wait_for_child to wait for the whole process queue to be finished.
841
  Wait_for_child to wait for the whole process queue to be finished.
586
*/
842
*/
587
int	pid;
843
TPID	pid;
588
CELLPTR target;
844
CELLPTR target;
589
int	ignore;
845
int	ignore;
590
int     last;
846
int     last;
Lines 599-604 Link Here
599
      if( _procs == NIL(PR) ) {
855
      if( _procs == NIL(PR) ) {
600
	 _procs_size = Max_proc;
856
	 _procs_size = Max_proc;
601
	 TALLOC( _procs, Max_proc, PR );
857
	 TALLOC( _procs, Max_proc, PR );
858
#if defined(USE_CREATEPROCESS)
859
	 TALLOC( _wpList, Max_proc, HANDLE );
860
861
	 /* Signed int values are cast to DMHANDLE in various places, use this
862
	  * sanity check to verify that DMHANDLE is large enough. */
863
	 if( sizeof(int) > sizeof(DMHANDLE) )
864
	    Fatal( "Internal Error: Check type of DMHANDLE!" );
865
#endif
602
      }
866
      }
603
      else {
867
      else {
604
	 Fatal( "MAXPROCESS changed from `%d' to `%d' after a command was executed!", _procs_size, Max_proc );
868
	 Fatal( "MAXPROCESS changed from `%d' to `%d' after a command was executed!", _procs_size, Max_proc );
Lines 624-630 Link Here
624
   pp = _procs+i;
888
   pp = _procs+i;
625
889
626
   pp->pr_valid  = 1;
890
   pp->pr_valid  = 1;
627
   pp->pr_pid    = pid;
891
   pp->pr_pid    = pid.pid;
892
   pp->pr_tid    = pid.tid;
628
   pp->pr_target = target;
893
   pp->pr_target = target;
629
   pp->pr_ignore = ignore;
894
   pp->pr_ignore = ignore;
630
   pp->pr_last   = last;
895
   pp->pr_last   = last;
Lines 636-646 Link Here
636
901
637
   _proc_cnt++;
902
   _proc_cnt++;
638
903
639
   if( pid != -1 ) {
904
   if( pid.pid != (DMHANDLE)-1 ) {
640
      /* Wait for each recipe to finish if wfc is TRUE. This
905
      /* Wait for each recipe to finish if wfc is TRUE. This
641
       * basically forces sequential execution. */
906
       * basically forces sequential execution. */
642
      if( wfc )
907
      if( wfc ) {
643
	 Wait_for_child( FALSE, i );
908
	 Wait_for_child( FALSE, i );
909
      }
644
910
645
      return -1;
911
      return -1;
646
   } else
912
   } else
Lines 657-671 Link Here
657
  process and for cid < 1 -cid is used as the process array index of the
923
  process and for cid < 1 -cid is used as the process array index of the
658
  internal command.
924
  internal command.
659
*/
925
*/
660
int	cid;
926
DMHANDLE cid;
661
int	status;
927
int	status;
662
{
928
{
663
   register int i;
929
   register int i;
664
   char     *dir;
930
   char     *dir;
665
931
666
   if(cid < 1) {
932
   if((int)cid < 1) { /* Force int. */
667
      /* internal command */
933
      /* internal command */
668
      i = -cid;
934
      i = -((int)cid);
669
   }
935
   }
670
   else {
936
   else {
671
      for( i=0; i<Max_proc; i++ )
937
      for( i=0; i<Max_proc; i++ )
Lines 718-724 Link Here
718
984
719
      /* If all process queues are used wait for the next process to
985
      /* If all process queues are used wait for the next process to
720
       * finish. Is this really needed here? */
986
       * finish. Is this really needed here? */
721
      if( _proc_cnt == Max_proc ) Wait_for_child( FALSE, -1 );
987
      if( _proc_cnt == Max_proc ) {
988
	 Wait_for_child( FALSE, -1 );
989
      }
722
   }
990
   }
723
   else {
991
   else {
724
      /* empty the queue on abort. */
992
      /* empty the queue on abort. */
(-)dmake/win95/microsft/ruletab.c (-3 / +14 lines)
Lines 29-40 Link Here
29
 * may be overridden inside the .STARTUP makefile, they are here
29
 * may be overridden inside the .STARTUP makefile, they are here
30
 * strictly so that dmake can parse the STARTUP makefile */
30
 * strictly so that dmake can parse the STARTUP makefile */
31
31
32
#include <stdio.h>
32
#include "extern.h"
33
34
#if defined(USE_CREATEPROCESS)
35
#include <windows.h>
36
#endif
37
#if !defined(MAXIMUM_WAIT_OBJECTS)
38
#define MAXIMUM_WAIT_OBJECTS 1
39
#endif
40
41
/* To stringify the result of the expansion of a macro argument
42
 * use two levels of macros. */
43
#define dmstr2(s) dmstr1(s)
44
#define dmstr1(s) #s
33
45
34
static char *_rules[] = {
46
static char *_rules[] = {
35
	"MAXLINELENGTH := 32766",
47
	"MAXLINELENGTH := 32766",
36
	"MAXPROCESSLIMIT := 4",
48
	"MAXPROCESSLIMIT := " dmstr2(MAXIMUM_WAIT_OBJECTS) ,
37
	"MAXPROCESS := 1",
38
	".IMPORT .IGNORE: DMAKEROOT",
49
	".IMPORT .IGNORE: DMAKEROOT",
39
	".MAKEFILES : makefile.mk makefile",
50
	".MAKEFILES : makefile.mk makefile",
40
	".SOURCE    : .NULL",
51
	".SOURCE    : .NULL",

Return to issue 83540