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