run.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. */
  6. #include <stdlib.h>
  7. #include "ack.h"
  8. #include "list.h"
  9. #include "trans.h"
  10. #include "grows.h"
  11. #include "data.h"
  12. #include <signal.h>
  13. #ifndef NORCSID
  14. static char rcs_id[] = "$Id$" ;
  15. #endif
  16. #define ARG_MORE 40 /* The size of args chunks to allocate */
  17. extern growstring scanvars();
  18. static char **arglist ; /* The first argument */
  19. static unsigned argcount ; /* The current number of arguments */
  20. static unsigned argmax; /* The maximum number of arguments so far */
  21. int runphase(phase) register trf *phase ; {
  22. register list_elem *elem ;
  23. char *prog ; int result ;
  24. growstring bline ;
  25. bline=scanvars(phase->t_prog) ;
  26. prog=gr_final(&bline) ;
  27. if ( v_flag || debug ) {
  28. if ( v_flag==1 && !debug ) {
  29. vprint("%s",phase->t_name) ;
  30. if ( !phase->t_combine ) {
  31. vprint(" %s%s\n",p_basename,
  32. strrchr(in.p_path,SUFCHAR) ) ;
  33. } else {
  34. scanlist(l_first(phase->t_inputs), elem) {
  35. vprint(" %s",p_cont(*elem)->p_path);
  36. }
  37. vprint("\n") ;
  38. }
  39. } else {
  40. /* list all args */
  41. vprint("%s",prog) ;
  42. scanlist(l_first(phase->t_flags), elem) {
  43. vprint(" %s",l_content(*elem)) ;
  44. }
  45. scanlist(l_first(phase->t_args), elem) {
  46. vprint(" %s",l_content(*elem)) ;
  47. }
  48. vprint("\n") ;
  49. }
  50. }
  51. argcount=0 ;
  52. x_arg(phase->t_name) ;
  53. scanlist(l_first(phase->t_flags), elem) {
  54. x_arg(l_content(*elem)) ;
  55. }
  56. scanlist(l_first(phase->t_args), elem) {
  57. x_arg(l_content(*elem)) ;
  58. }
  59. x_arg( (char *)0 ) ;
  60. result=run_exec(phase,prog) ;
  61. throws(prog) ;
  62. return result ;
  63. }
  64. int run_exec(phase,prog) trf *phase ; char *prog ; {
  65. int status, child, waitchild ;
  66. do_flush();
  67. while ( (child=fork())== -1 ) ;
  68. if ( child ) {
  69. /* The parent */
  70. do {
  71. waitchild= wait(&status) ;
  72. if ( waitchild== -1 ) {
  73. fatal("missing child") ;
  74. }
  75. } while ( waitchild!=child) ;
  76. if ( status ) {
  77. if ( status&0200 && (status&0177)!=SIGQUIT &&
  78. t_flag<=1 ) unlink("core") ;
  79. switch ( status&0177 ) {
  80. case 0 :
  81. break ;
  82. case SIGHUP:
  83. case SIGINT:
  84. case SIGQUIT:
  85. case SIGTERM:
  86. quit(-5) ;
  87. default:
  88. error("%s died with signal %d",
  89. prog,status&0177) ;
  90. }
  91. /* The assumption is that processes voluntarely
  92. dying with a non-zero status already produced
  93. some sort of error message to the outside world.
  94. */
  95. n_error++ ;
  96. return 0 ;
  97. }
  98. return 1 ; /* From the parent */
  99. }
  100. /* The child */
  101. if ( phase->t_stdin ) {
  102. if ( !in.p_path ) {
  103. fatal("no input file for %s",phase->t_name) ;
  104. }
  105. close(0) ;
  106. if ( open(in.p_path,0)!=0 ) {
  107. error("cannot open %s",in.p_path) ;
  108. exit(1) ;
  109. }
  110. }
  111. if ( phase->t_stdout ) {
  112. if ( !out.p_path ) {
  113. fatal("no output file for %s",phase->t_name) ;
  114. }
  115. close(1) ;
  116. if ( creat(out.p_path,0666)!=1 ) {
  117. close(1); dup(2);
  118. error("cannot create %s",out.p_path) ;
  119. exit(1) ;
  120. }
  121. }
  122. execv(prog,arglist) ;
  123. if ( phase->t_stdout ) { close(1) ; dup(2) ; }
  124. error("Cannot execute %s",prog) ;
  125. exit(1) ;
  126. /*NOTREACHED*/
  127. }
  128. x_arg(string) char *string ; {
  129. /* Add one execute argument to the argument vector */
  130. if ( argcount==argmax ) {
  131. if ( argmax==0 ) {
  132. argmax= 2*ARG_MORE ;
  133. arglist= (char **)getcore(argmax*sizeof (char *)) ;
  134. } else {
  135. argmax += ARG_MORE ;
  136. arglist= (char **)changecore((char *)arglist,
  137. argmax*sizeof (char *)) ;
  138. }
  139. }
  140. *(arglist+argcount++) = string ;
  141. }