run.c 3.5 KB

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