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

(-)dmake/dmake.c (+1 lines)
Lines 169-174 Link Here
169
   m_export  = FALSE;
169
   m_export  = FALSE;
170
   cmdmacs   = NIL(char);
170
   cmdmacs   = NIL(char);
171
   targets   = NIL(char);
171
   targets   = NIL(char);
172
   Is_shell_exec = FALSE;
172
173
173
   Verbose     = V_NOFLAG;
174
   Verbose     = V_NOFLAG;
174
   Transitive  = TRUE;
175
   Transitive  = TRUE;
(-)dmake/function.c (-1 / +17 lines)
Lines 507-513 Link Here
507
507
508
508
509
static char *
509
static char *
510
_exec_shell( data, mod1 )
510
_exec_shell( data, mod1 )/*
511
===========================
512
   Capture the stdout of an execuded command. */
511
char *data;
513
char *data;
512
char *mod1;
514
char *mod1;
513
{
515
{
Lines 520-525 Link Here
520
   static FILE *tmp;
522
   static FILE *tmp;
521
523
522
   int wait     = Wait_for_completion;
524
   int wait     = Wait_for_completion;
525
   int old_is_shell_exec = Is_shell_exec;
523
   uint16 vflag = Verbose;
526
   uint16 vflag = Verbose;
524
   int tflag    = Trace;
527
   int tflag    = Trace;
525
   char *res    = NIL(char);
528
   char *res    = NIL(char);
Lines 556-561 Link Here
556
      fflush(stdout);
559
      fflush(stdout);
557
   }
560
   }
558
561
562
   /* FIXME: This doesn't look right. Instead of using nestlevel and
563
    * org_out as static variables this should be done as normal function
564
    * calls that save and restore stdout. */
559
   if( nestlevel == 0 ) {
565
   if( nestlevel == 0 ) {
560
      org_out = dup(1);
566
      org_out = dup(1);
561
567
Lines 569-575 Link Here
569
      buffer = MALLOC(bsize,char);
575
      buffer = MALLOC(bsize,char);
570
   }
576
   }
571
577
578
   /* As this function redirects the output of stdout we have to make sure
579
    * that only this single command is executed. With Is_shell_exec and
580
    * Wait_for_completion set this is realized. This is obviously a design
581
    * weakness, if the client process would do the redirection the additional
582
    * global variable would not be needed. */
572
   Wait_for_completion = TRUE;
583
   Wait_for_completion = TRUE;
584
   Is_shell_exec = TRUE;
573
   Verbose &= V_LEAVE_TMP;
585
   Verbose &= V_LEAVE_TMP;
574
   Trace   = FALSE;
586
   Trace   = FALSE;
575
   nestlevel++;
587
   nestlevel++;
Lines 579-584 Link Here
579
   Trace   = tflag;
591
   Trace   = tflag;
580
   Verbose = vflag;
592
   Verbose = vflag;
581
   Wait_for_completion = wait;
593
   Wait_for_completion = wait;
594
   Is_shell_exec = old_is_shell_exec;
582
595
583
   /* Now we have to read the temporary file, get the tokens and return them
596
   /* Now we have to read the temporary file, get the tokens and return them
584
    * as a string. */
597
    * as a string. */
Lines 590-595 Link Here
590
	 res = DmStrJoin(res,buffer,-1,TRUE);
603
	 res = DmStrJoin(res,buffer,-1,TRUE);
591
      else {
604
      else {
592
	 *p = '\0';
605
	 *p = '\0';
606
	 /* You might encounter '\r\n' on windows, handle it. */
607
	 if( p > buffer && *(p-1) == '\r')
608
	    *(p-1) = '\0';
593
         res = DmStrApp(res,buffer);
609
         res = DmStrApp(res,buffer);
594
      }
610
      }
595
   }
611
   }
(-)dmake/sysintf.c (+1 lines)
Lines 214-219 Link Here
214
   if( Max_proc == 1 ) Wait_for_completion = TRUE;
214
   if( Max_proc == 1 ) Wait_for_completion = TRUE;
215
215
216
   if( (i = runargv(target, ignore, group, last, shell, cmd)) == -1 )
216
   if( (i = runargv(target, ignore, group, last, shell, cmd)) == -1 )
217
      /* Only fails for failed spawn. (Spawn is disabled ATM.) */
217
      Quit();
218
      Quit();
218
219
219
   /* NOTE:  runargv must return either 0 or 1, 0 ==> command executed, and
220
   /* NOTE:  runargv must return either 0 or 1, 0 ==> command executed, and
(-)dmake/vextern.h (-1 / +2 lines)
Lines 74-80 Link Here
74
EXTERN  CELLPTR Targets;	/* Targets in makefile 			  */
74
EXTERN  CELLPTR Targets;	/* Targets in makefile 			  */
75
 
75
 
76
EXTERN  CELLPTR Current_target; /* cell of current target being made      */
76
EXTERN  CELLPTR Current_target; /* cell of current target being made      */
77
EXTERN  int	Wait_for_completion;
77
EXTERN  int	Wait_for_completion; /* Wait for subprocess to finish     */
78
EXTERN  int	Is_shell_exec;  /* Enable special child process handling  */
78
EXTERN  int	Doing_bang;
79
EXTERN  int	Doing_bang;
79
EXTERN  int	Packed_shell;	/* TRUE if packed args to use a shell	  */
80
EXTERN  int	Packed_shell;	/* TRUE if packed args to use a shell	  */
80
EXTERN  int	Swap_on_exec;	/* TRUE if going to swap on exec call     */
81
EXTERN  int	Swap_on_exec;	/* TRUE if going to swap on exec call     */
(-)dmake/unix/runargv.c (-1 / +46 lines)
Lines 24-29 Link Here
24
-- LOG
24
-- LOG
25
--      Use cvs log to obtain detailed change logs.
25
--      Use cvs log to obtain detailed change logs.
26
*/
26
*/
27
/*
28
This file (runargv.c) provides all the parallel process handling routines
29
for dmake on unix like operating systems. The following text briefly
30
describes the process flow.
31
32
Exec_commands() [make.c] builds the recipes associated to the given target.
33
  They are build sequentially in a loop that calls Do_cmnd() for each of them.
34
35
Do_cmnd() [sysintf.c] feeds the given command or command group to runargv().
36
37
runargv() [unix/runargv] The actual child processes are started in this
38
  function, even in non parallel builds (MAXPROCESS==1) child processes are
39
  created.
40
  If recipes for a target are currently running attach them to the process
41
  queue (_procs[i]) of that target and return.
42
  If the maximum number of running process queues is reached
43
  Wait_for_child(?, -1) is used to wait for one to be available.
44
  New child processes are started using:
45
    spawn:       currently disabled, see line 40.
46
    fork/execvp: Create a client process with fork and run the command with
47
                 execvp.
48
  The parent calls _add_child() to track the child.
49
50
_add_child() [unix/runargv] creates a new process queue and enters the child
51
  parameters.
52
  If Wait_for_completion (global variable) is set the function calls
53
  Wait_for_child to waits for the new process queue to be finished.
54
55
Wait_for_child(?, pid) [unix/runargv] waits for process queues to finish.
56
  All finished processes are handled by calling _finished_child() for each
57
  of them.
58
  If pid = -1 wait for the next child process to finish.
59
  If Wait_for_completion is set handle all finished processes until the
60
  process with the given pid is reached.
61
  If Is_shell_exec (global variable) is set wait and handle only the given
62
  pid.
63
64
_finished_child(pid, ?) [unix/runargv] removes the finished child from its
65
  process queue. If there are more commands in this queue start the next
66
  with runargv().
67
*/
27
68
28
#include <signal.h>
69
#include <signal.h>
29
#ifdef HAVE_WAIT_H
70
#ifdef HAVE_WAIT_H
Lines 185-191 Link Here
185
   waitchild = (pid == -1)? FALSE : Wait_for_completion;
226
   waitchild = (pid == -1)? FALSE : Wait_for_completion;
186
227
187
   do {
228
   do {
188
      wid = wait(&status);
229
      if( Is_shell_exec ) /* For pid == -1 waitpid behaves like wait. */
230
         wid = waitpid(pid, &status, 0);
231
      else
232
         wid = wait(&status);
233
189
      if( wid  == -1 )
234
      if( wid  == -1 )
190
		 return(-1);
235
		 return(-1);
191
236

Return to issue 53148