t19.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "a.h"
  2. /*
  3. * 19. Input/output file switching.
  4. */
  5. /* .so - push new source file */
  6. void
  7. r_so(int argc, Rune **argv)
  8. {
  9. USED(argc);
  10. pushinputfile(argv[1]);
  11. }
  12. /* .nx - end this file, switch to arg */
  13. void
  14. r_nx(int argc, Rune **argv)
  15. {
  16. int n;
  17. if(argc == 1){
  18. while(popinput())
  19. ;
  20. }else{
  21. if(argc > 2)
  22. warn("too many arguments for .nx");
  23. while((n=popinput()) && n != 2)
  24. ;
  25. pushinputfile(argv[1]);
  26. }
  27. }
  28. /* .sy - system: run string */
  29. void
  30. r_sy(Rune *name)
  31. {
  32. USED(name);
  33. warn(".sy not implemented");
  34. }
  35. /* .pi - pipe output to string */
  36. void
  37. r_pi(Rune *name)
  38. {
  39. USED(name);
  40. warn(".pi not implemented");
  41. }
  42. /* .cf - copy contents of filename to output */
  43. void
  44. r_cf(int argc, Rune **argv)
  45. {
  46. int c;
  47. char *p;
  48. Biobuf *b;
  49. USED(argc);
  50. p = esmprint("%S", argv[1]);
  51. if((b = Bopen(p, OREAD)) == nil){
  52. fprint(2, "%L: open %s: %r\n", p);
  53. free(p);
  54. return;
  55. }
  56. free(p);
  57. while((c = Bgetrune(b)) >= 0)
  58. outrune(c);
  59. Bterm(b);
  60. }
  61. void
  62. r_inputpipe(Rune *name)
  63. {
  64. Rune *cmd, *stop, *line;
  65. int n, pid, p[2], len;
  66. Waitmsg *w;
  67. USED(name);
  68. if(pipe(p) < 0){
  69. warn("pipe: %r");
  70. return;
  71. }
  72. stop = copyarg();
  73. cmd = readline(CopyMode);
  74. pid = fork();
  75. switch(pid){
  76. case 0:
  77. if(p[0] != 0){
  78. dup(p[0], 0);
  79. close(p[0]);
  80. }
  81. close(p[1]);
  82. execl("/bin/rc", "rc", "-c", esmprint("%S", cmd), nil);
  83. warn("%Cdp %S: %r", dot, cmd);
  84. _exits(nil);
  85. case -1:
  86. warn("fork: %r");
  87. default:
  88. close(p[0]);
  89. len = runestrlen(stop);
  90. fprint(p[1], ".ps %d\n", getnr(L(".s")));
  91. fprint(p[1], ".vs %du\n", getnr(L(".v")));
  92. fprint(p[1], ".ft %d\n", getnr(L(".f")));
  93. fprint(p[1], ".ll 8i\n");
  94. fprint(p[1], ".pl 30i\n");
  95. while((line = readline(~0)) != nil){
  96. if(runestrncmp(line, stop, len) == 0
  97. && (line[len]==' ' || line[len]==0 || line[len]=='\t'
  98. || (line[len]=='\\' && line[len+1]=='}')))
  99. break;
  100. n = runestrlen(line);
  101. line[n] = '\n';
  102. fprint(p[1], "%.*S", n+1, line);
  103. free(line);
  104. }
  105. free(stop);
  106. close(p[1]);
  107. w = wait();
  108. if(w == nil){
  109. warn("wait: %r");
  110. return;
  111. }
  112. if(w->msg[0])
  113. sysfatal("%C%S %S: %s", dot, name, cmd, w->msg);
  114. free(cmd);
  115. free(w);
  116. }
  117. }
  118. void
  119. t19init(void)
  120. {
  121. addreq(L("so"), r_so, 1);
  122. addreq(L("nx"), r_nx, -1);
  123. addraw(L("sy"), r_sy);
  124. addraw(L("inputpipe"), r_inputpipe);
  125. addraw(L("pi"), r_pi);
  126. addreq(L("cf"), r_cf, 1);
  127. nr(L("$$"), getpid());
  128. }