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

  1. /* RCS      -- $Header: /u5/dvadura/src/public/dmake/src/os2/RCS/runargv.c,v 1.1 1994/10/06 17:42:41 dvadura Exp $
  2. -- SYNOPSIS -- invoke a sub process, modified unix/runargv.c for OS/2.
  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:42:41  dvadura
  31.  * dmake Release Version 4.0, Initial revision
  32.  *
  33. */
  34.  
  35. #define INCL_DOSPROCESS
  36. #include <os2.h>
  37.  
  38. #include <process.h>
  39. #include <stdlib.h>
  40. #include <signal.h>
  41. #include "extern.h"
  42. #include "sysintf.h"
  43.  
  44. typedef struct prp {
  45.    char *prp_cmd;
  46.    int   prp_group;
  47.    int   prp_ignore;
  48.    int   prp_last;
  49.    int     prp_shell;
  50.    struct prp *prp_next;
  51. } RCP, *RCPPTR;
  52.  
  53. typedef struct pr {
  54.    int        pr_valid;
  55.    int        pr_pid;
  56.    CELLPTR    pr_target;
  57.    int        pr_ignore;
  58.    int        pr_last;
  59.    RCPPTR      pr_recipe;
  60.    RCPPTR      pr_recipe_end;
  61.    char        *pr_dir;
  62. } PR;
  63.  
  64. static PR  *_procs    = NIL(PR);
  65. static int  _proc_cnt = 0;
  66. static int  _abort_flg= FALSE;
  67. static int  _use_i    = -1;
  68. static int  _do_upd   = 0;
  69.  
  70. extern unsigned int _far _pascal DosSmSetTitle(char _far *s);
  71. static  void    SetSessionTitle (char *s);
  72. static  void    _add_child ANSI((int, CELLPTR, int, int));
  73. static  void    _attach_cmd ANSI((char *, int, int, CELLPTR, int, int));
  74. static  void    _finished_child ANSI((int, int));
  75. static  int     _running ANSI((CELLPTR));
  76.  
  77. PUBLIC int
  78. runargv(target, ignore, group, last, shell, cmd)
  79. CELLPTR target;
  80. int     ignore;
  81. int    group;
  82. int    last;
  83. int     shell;
  84. char    *cmd;
  85. {
  86.    int          pid;
  87.    char         **argv;
  88.  
  89.    if( _running(target) /*&& Max_proc != 1*/ ) {
  90.       /* The command will be executed when the previous recipe
  91.        * line completes. */
  92.       _attach_cmd( cmd, group, ignore, target, last, shell );
  93.       return(1);
  94.    }
  95.  
  96.    while( _proc_cnt == Max_proc )
  97.       if( Wait_for_child(FALSE, -1) == -1 )  Fatal( "Lost a child" );
  98.  
  99. #ifdef SESSTITLE
  100.    SetSessionTitle(target->CE_NAME);
  101. #endif
  102.    argv = Pack_argv( group, shell, cmd );
  103.  
  104.    if((pid=spawnvp((_osmode == DOS_MODE)?P_WAIT:P_NOWAIT,argv[0],argv)) == -1){
  105.       Error("%s: %s", argv[0], sys_errlist[errno]);
  106.       Handle_result(-1, ignore, _abort_flg, target);
  107.       return(-1);
  108.    }
  109.    else if( _osmode == DOS_MODE ) {
  110.      _add_child(4711, target, ignore, last);
  111.      _finished_child(4711, pid);
  112.    }
  113.    else
  114.      _add_child(pid, target, ignore, last);
  115.  
  116.    return(1);
  117. }
  118.  
  119.  
  120. #ifdef SESSTITLE
  121. /* N.B. The system call used below is undocumented and therefore possibly
  122.  * subject to change. It sets the session title even from a full screen
  123.  * session, so you can see which target is being built.
  124.  * If dubious about undocumented calls simply remove it.
  125.  */
  126. PUBLIC void
  127. SetSessionTitle(char *s)
  128. {
  129.    char buff[128];
  130.    strncpy(buff, Pname, sizeof(buff));
  131.    buff[sizeof(buff)-1] = 0;
  132.    strncat(buff, " - ", sizeof(buff));
  133.    strncat(buff, s, sizeof(buff));
  134.    buff[sizeof(buff)-1] = 0;
  135.    DosSmSetTitle(buff);
  136. }
  137. #endif
  138.  
  139.  
  140. PUBLIC int
  141. Wait_for_child( abort_flg, pid )
  142. int abort_flg;
  143. int pid;
  144. {
  145.    int wid;
  146.    int status;
  147.    int waitchild;
  148.  
  149.    if( _osmode == DOS_MODE ) return(1);
  150.  
  151.    waitchild = (pid == -1)? FALSE : Wait_for_completion;
  152.  
  153.    do {
  154.       if( (wid = wait(&status)) == -1 ) return(-1);
  155.  
  156.       _abort_flg = abort_flg;
  157.       _finished_child(wid, status);
  158.       _abort_flg = FALSE;
  159.    }
  160.    while( waitchild && pid != wid );
  161.  
  162.    return(0);
  163. }
  164.  
  165.  
  166. PUBLIC void
  167. Clean_up_processes()
  168. {
  169.    register int i;
  170.  
  171.    if( _osmode == DOS_MODE ) {
  172.       _abort_flg = TRUE;
  173.       _finished_child(4711, -1);
  174.       return;
  175.    }
  176.  
  177.    if( _procs != NIL(PR) ) {
  178.       for( i=0; i<Max_proc; i++ )
  179.      if( _procs[i].pr_valid )
  180.         DosKillProcess(DKP_PROCESSTREE, _procs[i].pr_pid);
  181.  
  182.       while( Wait_for_child(TRUE, -1) != -1 );
  183.    }
  184. }
  185.  
  186.  
  187. static void
  188. _add_child( pid, target, ignore, last )
  189. int    pid;
  190. CELLPTR target;
  191. int    ignore;
  192. int     last;
  193. {
  194.    register int i;
  195.    register PR *pp;
  196.  
  197.    if( _procs == NIL(PR) ) {
  198.       TALLOC( _procs, Max_proc, PR );
  199.    }
  200.  
  201.    if( (i = _use_i) == -1 )
  202.       for( i=0; i<Max_proc; i++ )
  203.      if( !_procs[i].pr_valid )
  204.         break;
  205.  
  206.    pp = _procs+i;
  207.  
  208.    pp->pr_valid  = 1;
  209.    pp->pr_pid    = pid;
  210.    pp->pr_target = target;
  211.    pp->pr_ignore = ignore;
  212.    pp->pr_last   = last;
  213.    pp->pr_dir    = DmStrDup(Get_current_dir());
  214.  
  215.    Current_target = NIL(CELL);
  216.  
  217.    _proc_cnt++;
  218.  
  219.    if( Wait_for_completion ) Wait_for_child( FALSE, pid );
  220. }
  221.  
  222.  
  223. static void
  224. _finished_child(pid, status)
  225. int    pid;
  226. int    status;
  227. {
  228.    register int i;
  229.    register PR *pp;
  230.    char     *dir;
  231.  
  232.    for( i=0; i<Max_proc; i++ )
  233.       if( _procs[i].pr_valid && _procs[i].pr_pid == pid )
  234.      break;
  235.  
  236.    /* Some children we didn't make esp true if using /bin/sh to execute a
  237.     * a pipe and feed the output as a makefile into dmake. */
  238.    if( i == Max_proc ) return;
  239.    _procs[i].pr_valid = 0;
  240.    _proc_cnt--;
  241.    dir = DmStrDup(Get_current_dir());
  242.    Set_dir( _procs[i].pr_dir );
  243.  
  244.    if( _procs[i].pr_recipe != NIL(RCP) && !_abort_flg ) {
  245.       RCPPTR rp = _procs[i].pr_recipe;
  246.  
  247.  
  248.       Current_target = _procs[i].pr_target;
  249.       Handle_result( status, _procs[i].pr_ignore, FALSE, _procs[i].pr_target );
  250.       Current_target = NIL(CELL);
  251.  
  252.       if ( _procs[i].pr_target->ce_attr & A_ERROR ) {
  253.      Unlink_temp_files( _procs[i].pr_target );
  254.      _procs[i].pr_last = TRUE;
  255.      goto ABORT_REMAINDER_OF_RECIPE;
  256.       }
  257.  
  258.       _procs[i].pr_recipe = rp->prp_next;
  259.  
  260.       _use_i = i;
  261.       runargv( _procs[i].pr_target, rp->prp_ignore, rp->prp_group,
  262.            rp->prp_last, rp->prp_shell, rp->prp_cmd );
  263.       _use_i = -1;
  264.  
  265.       FREE( rp->prp_cmd );
  266.       FREE( rp );
  267.  
  268.       if( _proc_cnt == Max_proc ) Wait_for_child( FALSE, -1 );
  269.    }
  270.    else {
  271.       Unlink_temp_files( _procs[i].pr_target );
  272.       Handle_result(status,_procs[i].pr_ignore,_abort_flg,_procs[i].pr_target);
  273.  
  274.  ABORT_REMAINDER_OF_RECIPE:
  275.       if( _procs[i].pr_last ) {
  276.      FREE(_procs[i].pr_dir );
  277.  
  278.      if( !Doing_bang ) Update_time_stamp( _procs[i].pr_target );
  279.       }
  280.    }
  281.  
  282.    Set_dir(dir);
  283.    FREE(dir);
  284. }
  285.  
  286.  
  287. static int
  288. _running( cp )
  289. CELLPTR cp;
  290. {
  291.    register int i;
  292.  
  293.    if( !_procs ) return(FALSE);
  294.  
  295.    for( i=0; i<Max_proc; i++ )
  296.       if( _procs[i].pr_valid &&
  297.       _procs[i].pr_target == cp  )
  298.      break;
  299.      
  300.    return( i != Max_proc );
  301. }
  302.  
  303.  
  304. static void
  305. _attach_cmd( cmd, group, ignore, cp, last, shell )
  306. char    *cmd;
  307. int    group;
  308. int     ignore;
  309. CELLPTR cp;
  310. int     last;
  311. int     shell;
  312. {
  313.    register int i;
  314.    RCPPTR rp;
  315.  
  316.    for( i=0; i<Max_proc; i++ )
  317.       if( _procs[i].pr_valid &&
  318.       _procs[i].pr_target == cp  )
  319.      break;
  320.  
  321.    TALLOC( rp, 1, RCP );
  322.    rp->prp_cmd   = DmStrDup(cmd);
  323.    rp->prp_group = group;
  324.    rp->prp_ignore= ignore;
  325.    rp->prp_last  = last;
  326.    rp->prp_shell = shell;
  327.  
  328.    if( _procs[i].pr_recipe == NIL(RCP) )
  329.       _procs[i].pr_recipe = _procs[i].pr_recipe_end = rp;
  330.    else {
  331.       _procs[i].pr_recipe_end->prp_next = rp;
  332.       _procs[i].pr_recipe_end = rp;
  333.    }
  334. }
  335.