home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dmake40.zip / qnx / runargv.c < prev    next >
C/C++ Source or Header  |  1994-10-23  |  7KB  |  306 lines

  1. /* RCS      -- $Header: /u5/dvadura/src/public/dmake/src/qnx/RCS/runargv.c,v 1.1 1994/10/06 17:43:22 dvadura Exp $
  2. -- SYNOPSIS -- invoke a sub process.
  3. -- 
  4. -- DESCRIPTION
  5. --     Use the standard methods of executing a sub process.
  6. --
  7. -- AUTHOR
  8. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  9. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  10. --
  11. -- COPYRIGHT
  12. --      Copyright (c) 1992,1994 by Dennis Vadura.  All rights reserved.
  13. -- 
  14. --      This program is free software; you can redistribute it and/or
  15. --      modify it under the terms of the GNU General Public License
  16. --      (version 1), as published by the Free Software Foundation, and
  17. --      found in the file 'LICENSE' included with this distribution.
  18. -- 
  19. --      This program is distributed in the hope that it will be useful,
  20. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  21. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22. --      GNU General Public License for more details.
  23. -- 
  24. --      You should have received a copy of the GNU General Public License
  25. --      along with this program;  if not, write to the Free Software
  26. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27. --
  28. -- LOG
  29. --     $Log: runargv.c,v $
  30.  * Revision 1.1  1994/10/06  17:43:22  dvadura
  31.  * dmake Release Version 4.0, Initial revision
  32.  *
  33. */
  34.  
  35. #include <signal.h>
  36. #include "extern.h"
  37. #include "sysintf.h"
  38.  
  39. typedef struct prp {
  40.    char *prp_cmd;
  41.    int   prp_group;
  42.    int   prp_ignore;
  43.    int   prp_last;
  44.    int     prp_shell;
  45.    struct prp *prp_next;
  46. } RCP, *RCPPTR;
  47.  
  48. typedef struct pr {
  49.    int        pr_valid;
  50.    int        pr_pid;
  51.    CELLPTR    pr_target;
  52.    int        pr_ignore;
  53.    int        pr_last;
  54.    RCPPTR      pr_recipe;
  55.    RCPPTR      pr_recipe_end;
  56.    char        *pr_dir;
  57. } PR;
  58.  
  59. static PR  *_procs    = NIL(PR);
  60. static int  _proc_cnt = 0;
  61. static int  _abort_flg= FALSE;
  62. static int  _use_i    = -1;
  63. static int  _do_upd   = 0;
  64.  
  65. static  void    _add_child ANSI((int, CELLPTR, int, int));
  66. static  void    _attach_cmd ANSI((char *, int, int, CELLPTR, int, int));
  67. static  void    _finished_child ANSI((int, int));
  68. static  int     _running ANSI((CELLPTR));
  69.  
  70. PUBLIC int
  71. runargv(target, ignore, group, last, shell, cmd)
  72. CELLPTR target;
  73. int     ignore;
  74. int    group;
  75. int    last;
  76. int     shell;
  77. char    *cmd;
  78. {
  79.    extern  int  errno;
  80.    int          pid;
  81.    char         **argv;
  82.  
  83.    if( _running(target) /*&& Max_proc != 1*/ ) {
  84.       /* The command will be executed when the previous recipe
  85.        * line completes. */
  86.       _attach_cmd( cmd, group, ignore, target, last, shell );
  87.       return(1);
  88.    }
  89.  
  90.    while( _proc_cnt == Max_proc )
  91.       if( Wait_for_child(FALSE, -1) == -1 )  Fatal( "Lost a child %d", errno );
  92.  
  93.    argv = Pack_argv( group, shell, cmd );
  94.  
  95.    switch( pid=fork() ){
  96.       int   wid;
  97.       int   status;
  98.  
  99.    case -1: /* fork failed */
  100.       Error("%s: %s", argv[0], strerror(errno));
  101.       Handle_result(-1, ignore, _abort_flg, target);
  102.       return(-1);
  103.  
  104.    case 0:  /* child */
  105.       execvp(argv[0], argv);
  106.       Continue = TRUE;   /* survive error message */
  107.       Error("%s: %s", argv[0], strerror(errno));
  108.       kill(getpid(), SIGTERM);
  109.       /*NOTREACHED*/
  110.  
  111.    default: /* parent */
  112.       _add_child(pid, target, ignore, last);
  113.    }
  114.  
  115.    return(1);
  116. }
  117.  
  118.  
  119. PUBLIC int
  120. Wait_for_child( abort_flg, pid )
  121. int abort_flg;
  122. int pid;
  123. {
  124.    int wid;
  125.    int status;
  126.    int waitchild;
  127.  
  128.    waitchild = (pid == -1)? FALSE : Wait_for_completion;
  129.  
  130.    do {
  131.       if( (wid = wait(&status)) == -1 ) return(-1);
  132.  
  133.       _abort_flg = abort_flg;
  134.       _finished_child(wid, status);
  135.       _abort_flg = FALSE;
  136.    }
  137.    while( waitchild && pid != wid );
  138.  
  139.    return(0);
  140. }
  141.  
  142.  
  143. PUBLIC void
  144. Clean_up_processes()
  145. {
  146.    register int i;
  147.  
  148.    if( _procs != NIL(PR) ) {
  149.       for( i=0; i<Max_proc; i++ )
  150.      if( _procs[i].pr_valid )
  151.         kill(_procs[i].pr_pid, SIGTERM);
  152.  
  153.       while( Wait_for_child(TRUE, -1) != -1 );
  154.    }
  155. }
  156.  
  157.  
  158. static void
  159. _add_child( pid, target, ignore, last )
  160. int    pid;
  161. CELLPTR target;
  162. int    ignore;
  163. int     last;
  164. {
  165.    register int i;
  166.    register PR *pp;
  167.  
  168.    if( _procs == NIL(PR) ) {
  169.       TALLOC( _procs, Max_proc, PR );
  170.    }
  171.  
  172.    if( (i = _use_i) == -1 )
  173.       for( i=0; i<Max_proc; i++ )
  174.      if( !_procs[i].pr_valid )
  175.         break;
  176.  
  177.    pp = _procs+i;
  178.  
  179.    pp->pr_valid  = 1;
  180.    pp->pr_pid    = pid;
  181.    pp->pr_target = target;
  182.    pp->pr_ignore = ignore;
  183.    pp->pr_last   = last;
  184.    pp->pr_dir    = DmStrDup(Get_current_dir());
  185.  
  186.    Current_target = NIL(CELL);
  187.  
  188.    _proc_cnt++;
  189.  
  190.    if( Wait_for_completion ) Wait_for_child( FALSE, pid );
  191. }
  192.  
  193.  
  194. static void
  195. _finished_child(pid, status)
  196. int    pid;
  197. int    status;
  198. {
  199.    register int i;
  200.    register PR *pp;
  201.    char     *dir;
  202.  
  203.    for( i=0; i<Max_proc; i++ )
  204.       if( _procs[i].pr_valid && _procs[i].pr_pid == pid )
  205.      break;
  206.  
  207.    /* Some children we didn't make esp true if using /bin/sh to execute a
  208.     * a pipe and feed the output as a makefile into dmake. */
  209.    if( i == Max_proc ) return;
  210.    _procs[i].pr_valid = 0;
  211.    _proc_cnt--;
  212.    dir = DmStrDup(Get_current_dir());
  213.    Set_dir( _procs[i].pr_dir );
  214.  
  215.    if( _procs[i].pr_recipe != NIL(RCP) && !_abort_flg ) {
  216.       RCPPTR rp = _procs[i].pr_recipe;
  217.  
  218.  
  219.       Current_target = _procs[i].pr_target;
  220.       Handle_result( status, _procs[i].pr_ignore, FALSE, _procs[i].pr_target );
  221.       Current_target = NIL(CELL);
  222.  
  223.       if ( _procs[i].pr_target->ce_attr & A_ERROR ) {
  224.      Unlink_temp_files( _procs[i].pr_target );
  225.      _procs[i].pr_last = TRUE;
  226.      goto ABORT_REMAINDER_OF_RECIPE;
  227.       }
  228.  
  229.       _procs[i].pr_recipe = rp->prp_next;
  230.  
  231.       _use_i = i;
  232.       runargv( _procs[i].pr_target, rp->prp_ignore, rp->prp_group,
  233.            rp->prp_last, rp->prp_shell, rp->prp_cmd );
  234.       _use_i = -1;
  235.  
  236.       FREE( rp->prp_cmd );
  237.       FREE( rp );
  238.  
  239.       if( _proc_cnt == Max_proc ) Wait_for_child( FALSE, -1 );
  240.    }
  241.    else {
  242.       Unlink_temp_files( _procs[i].pr_target );
  243.       Handle_result(status,_procs[i].pr_ignore,_abort_flg,_procs[i].pr_target);
  244.  
  245.  ABORT_REMAINDER_OF_RECIPE:
  246.       if( _procs[i].pr_last ) {
  247.      FREE(_procs[i].pr_dir );
  248.  
  249.      if( !Doing_bang ) Update_time_stamp( _procs[i].pr_target );
  250.       }
  251.    }
  252.  
  253.    Set_dir(dir);
  254.    FREE(dir);
  255. }
  256.  
  257.  
  258. static int
  259. _running( cp )
  260. CELLPTR cp;
  261. {
  262.    register int i;
  263.  
  264.    if( !_procs ) return(FALSE);
  265.  
  266.    for( i=0; i<Max_proc; i++ )
  267.       if( _procs[i].pr_valid &&
  268.       _procs[i].pr_target == cp  )
  269.      break;
  270.      
  271.    return( i != Max_proc );
  272. }
  273.  
  274.  
  275. static void
  276. _attach_cmd( cmd, group, ignore, cp, last, shell )
  277. char    *cmd;
  278. int    group;
  279. int     ignore;
  280. CELLPTR cp;
  281. int     last;
  282. int     shell;
  283. {
  284.    register int i;
  285.    RCPPTR rp;
  286.  
  287.    for( i=0; i<Max_proc; i++ )
  288.       if( _procs[i].pr_valid &&
  289.       _procs[i].pr_target == cp  )
  290.      break;
  291.  
  292.    TALLOC( rp, 1, RCP );
  293.    rp->prp_cmd   = DmStrDup(cmd);
  294.    rp->prp_group = group;
  295.    rp->prp_ignore= ignore;
  296.    rp->prp_last  = last;
  297.    rp->prp_shell = shell;
  298.  
  299.    if( _procs[i].pr_recipe == NIL(RCP) )
  300.       _procs[i].pr_recipe = _procs[i].pr_recipe_end = rp;
  301.    else {
  302.       _procs[i].pr_recipe_end->prp_next = rp;
  303.       _procs[i].pr_recipe_end = rp;
  304.    }
  305. }
  306.