home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / DMAKE35X.ZIP / RUNARGV.C < prev    next >
C/C++ Source or Header  |  1990-08-15  |  7KB  |  311 lines

  1. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/unix/RCS/runargv.c,v 1.1 90/07/20 16:54:53 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) 1990 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  90/07/20  16:54:53  dvadura
  31.  * Initial Revision of Version 3.5
  32.  *
  33. */
  34.  
  35. #include <process.h>
  36. #include <stdlib.h>
  37. #include <signal.h>
  38. #include "extern.h"
  39. #include "sysintf.h"
  40. #include "alloc.h"
  41.  
  42. #define INCL_NOPM
  43. #define INCL_DOSPROCESS
  44. #include <os2.h>
  45.  
  46. typedef struct prp {
  47.    char *prp_cmd;
  48.    int   prp_group;
  49.    int   prp_ignore;
  50.    int   prp_last;
  51.    struct prp *prp_next;
  52.    char  *prp_dir;
  53. } RCP, *RCPPTR;
  54.  
  55. typedef struct pr {
  56.    int        pr_valid;
  57.    int        pr_pid;
  58.    CELLPTR    pr_target;
  59.    HOWPTR    pr_how;
  60.    int        pr_ignore;
  61.    int        pr_last;
  62.    RCPPTR      pr_recipe;
  63.    RCPPTR      pr_recipe_end;
  64. } PR;
  65.  
  66. static PR  *_procs    = NIL(PR);
  67. static int  _proc_cnt = 0;
  68. static int  _abort_flg= FALSE;
  69. static int  _use_i    = -1;
  70. static int  _do_upd   = 0;
  71.  
  72. static  void    _add_child ANSI((int, CELLPTR, HOWPTR, int, int));
  73. static  void    _attach_cmd ANSI((char *, int, int, CELLPTR, HOWPTR, int));
  74. static  void    _finished_child ANSI((int, int));
  75. static  int     _running ANSI((CELLPTR, HOWPTR));
  76.  
  77. int
  78. runargv(target, how, ignore, group, last, cmd)
  79. CELLPTR target;
  80. HOWPTR  how;
  81. int     ignore;
  82. int    group;
  83. int    last;
  84. char    *cmd;
  85. {
  86.    int          pid;
  87.    char         *argv[MAXARGV];
  88.  
  89.    if( _running(target, how) /*&& Max_proc != 1*/ ) {
  90.       /* The command will be executed when the previous recipe
  91.        * line completes. */
  92.       _attach_cmd( cmd, group, ignore, target, how, last );
  93.       return(1);
  94.    }
  95.  
  96.    Pack_argv( argv, MAXARGV, group, cmd );
  97.  
  98.    while( _proc_cnt == Max_proc )
  99.       if( Wait_for_child(FALSE, -1) == -1 )  Fatal( "Lost a child" );
  100.  
  101.    if ( (pid = spawnvp((_osmode == DOS_MODE) ? P_WAIT : P_NOWAIT, argv[0], argv)) == -1 )
  102.    {
  103.       Error("%s: %s", argv[0], sys_errlist[errno]);
  104.       Handle_result(-1, ignore, _abort_flg, target);
  105.       return(-1);
  106.    }
  107.    else
  108.       if ( _osmode == DOS_MODE )
  109.       {
  110.         _add_child(4711, target, how, ignore, last);
  111.         _finished_child(4711, pid);
  112.       }
  113.       else
  114.         _add_child(pid, target, how, ignore, last);
  115.  
  116.    return(1);
  117. }
  118.  
  119.  
  120. int
  121. Wait_for_child( abort_flg, pid )
  122. int abort_flg;
  123. int pid;
  124. {
  125.    int wid;
  126.    int status;
  127.    int waitchild;
  128.  
  129.    if ( _osmode == DOS_MODE )
  130.      return(1);
  131.  
  132.    waitchild = (pid == -1)? FALSE : Wait_for_completion;
  133.  
  134.    do {
  135.       if( (wid = wait(&status)) == -1 ) return(-1);
  136.  
  137.       _abort_flg = abort_flg;
  138.       _finished_child(wid, status);
  139.       _abort_flg = FALSE;
  140.    }
  141.    while( waitchild && pid != wid );
  142.  
  143.    return(0);
  144. }
  145.  
  146.  
  147. void
  148. Clean_up_processes()
  149. {
  150.    register int i;
  151.  
  152.    if ( _osmode == DOS_MODE )
  153.    {
  154.      _abort_flg = TRUE;
  155.      _finished_child(4711, -1);
  156.      return;
  157.    }
  158.  
  159.    if( _procs != NIL(PR) ) {
  160.       for( i=0; i<Max_proc; i++ )
  161.      if( _procs[i].pr_valid )
  162.         /* kill(_procs[i].pr_pid, SIGTERM); */
  163.             DosKillProcess(DKP_PROCESSTREE, _procs[i].pr_pid);
  164.  
  165.       while( Wait_for_child(TRUE, -1) != -1 );
  166.    }
  167. }
  168.  
  169.  
  170. static void
  171. _add_child( pid, target, how, ignore, last )
  172. int    pid;
  173. CELLPTR target;
  174. HOWPTR  how;
  175. int    ignore;
  176. int     last;
  177. {
  178.    register int i;
  179.    register PR *pp;
  180.  
  181.    if( _procs == NIL(PR) ) {
  182.       TALLOC( _procs, Max_proc, PR );
  183.    }
  184.  
  185.    if( (i = _use_i) == -1 )
  186.       for( i=0; i<Max_proc; i++ )
  187.      if( !_procs[i].pr_valid )
  188.         break;
  189.  
  190.    pp = _procs+i;
  191.  
  192.    pp->pr_valid  = 1;
  193.    pp->pr_pid    = pid;
  194.    pp->pr_target = target;
  195.    pp->pr_how    = how;
  196.    pp->pr_ignore = ignore;
  197.    pp->pr_last   = last;
  198.  
  199.    Current_target = NIL(HOW);
  200.  
  201.    _proc_cnt++;
  202.  
  203.    if( Wait_for_completion ) Wait_for_child( FALSE, pid );
  204. }
  205.  
  206.  
  207. static void
  208. _finished_child(pid, status)
  209. int    pid;
  210. int    status;
  211. {
  212.    register int i;
  213.    register PR *pp;
  214.  
  215.    if( _procs == NIL(PR) )
  216.      return;
  217.  
  218.    for( i=0; i<Max_proc; i++ )
  219.       if( _procs[i].pr_valid && _procs[i].pr_pid == pid )
  220.      break;
  221.  
  222.    _procs[i].pr_valid = 0;
  223.    _proc_cnt--;
  224.  
  225.    if( _procs[i].pr_recipe != NIL(RCP) && !_abort_flg ) {
  226.       RCPPTR rp = _procs[i].pr_recipe;
  227.       char   *dir;
  228.  
  229.       Current_target = _procs[i].pr_how;
  230.       Handle_result( status, _procs[i].pr_ignore, FALSE, _procs[i].pr_target );
  231.       Current_target = NIL(HOW);
  232.  
  233.       _procs[i].pr_recipe = rp->prp_next;
  234.  
  235.       _use_i = i;
  236.       dir = _strdup(Get_current_dir());
  237.       Set_dir( rp->prp_dir );
  238.       runargv( _procs[i].pr_target, _procs[i].pr_how, rp->prp_ignore,
  239.                  rp->prp_group, rp->prp_last, rp->prp_cmd );
  240.       Set_dir(dir);
  241.       FREE(dir);
  242.       FREE(rp->prp_dir);
  243.       _use_i = -1;
  244.  
  245.       FREE( rp->prp_cmd );
  246.       FREE( rp );
  247.  
  248.       if( _proc_cnt == Max_proc ) Wait_for_child( FALSE, -1 );
  249.    }
  250.    else {
  251.       Unlink_temp_files( _procs[i].pr_how );
  252.       Handle_result(status,_procs[i].pr_ignore,_abort_flg,_procs[i].pr_target);
  253.  
  254.       if( _procs[i].pr_last && !Doing_bang )
  255.      Update_time_stamp( _procs[i].pr_target, _procs[i].pr_how );
  256.    }
  257. }
  258.  
  259.  
  260. static int
  261. _running( cp, how )
  262. CELLPTR cp;
  263. HOWPTR  how;
  264. {
  265.    register int i;
  266.  
  267.    if( !_procs ) return(FALSE);
  268.  
  269.    for( i=0; i<Max_proc; i++ )
  270.       if( _procs[i].pr_valid &&
  271.       _procs[i].pr_how == how &&
  272.       _procs[i].pr_target == cp  )
  273.      break;
  274.  
  275.    return( i != Max_proc );
  276. }
  277.  
  278.  
  279. static void
  280. _attach_cmd( cmd, group, ignore, cp, how, last )
  281. char    *cmd;
  282. int    group;
  283. int     ignore;
  284. CELLPTR cp;
  285. HOWPTR  how;
  286. int     last;
  287. {
  288.    register int i;
  289.    RCPPTR rp;
  290.  
  291.    for( i=0; i<Max_proc; i++ )
  292.       if( _procs[i].pr_valid &&
  293.       _procs[i].pr_how == how &&
  294.       _procs[i].pr_target == cp  )
  295.      break;
  296.  
  297.    TALLOC( rp, 1, RCP );
  298.    rp->prp_cmd   = _strdup(cmd);
  299.    rp->prp_group = group;
  300.    rp->prp_ignore= ignore;
  301.    rp->prp_last  = last;
  302.    rp->prp_dir   = _strdup(Get_current_dir());
  303.  
  304.    if( _procs[i].pr_recipe == NIL(RCP) )
  305.       _procs[i].pr_recipe = _procs[i].pr_recipe_end = rp;
  306.    else {
  307.       _procs[i].pr_recipe_end->prp_next = rp;
  308.       _procs[i].pr_recipe_end = rp;
  309.    }
  310. }
  311.