t19.c 2.7 KB

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