pipe.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <fcall.h>
  4. #include <thread.h>
  5. #include <9p.h>
  6. #include "dat.h"
  7. typedef struct Wpid Wpid;
  8. struct Wpid
  9. {
  10. int pid;
  11. Window *w;
  12. Wpid *next;
  13. };
  14. void pipectl(void*);
  15. int pipefd;
  16. Wpid *wpid;
  17. int snarffd;
  18. Channel *newpipechan;
  19. int
  20. newpipewin(int pid, char *p)
  21. {
  22. int id;
  23. Window *w;
  24. Wpid *wp;
  25. w = newwindow();
  26. winname(w, p);
  27. wintagwrite(w, "Send ", 5);
  28. wp = emalloc(sizeof(Wpid));
  29. wp->pid = pid;
  30. wp->w = w;
  31. wp->next = wpid; /* BUG: this happens in fsread proc (we don't use wpid, so it's okay) */
  32. wpid = wp;
  33. id = w->id;
  34. sendp(newpipechan, w);
  35. return id;
  36. }
  37. int
  38. pipecommand(Window *w, char *s)
  39. {
  40. ulong q0, q1;
  41. char tmp[32], *t;
  42. int n, k;
  43. while(*s==' ' || *s=='\t' || *s=='\n')
  44. s++;
  45. if(strcmp(s, "Delete")==0){
  46. windel(w, 1);
  47. threadexits(nil);
  48. return 1;
  49. }
  50. if(strcmp(s, "Del")==0){
  51. if(windel(w, 0))
  52. threadexits(nil);
  53. return 1;
  54. }
  55. if(strcmp(s, "Send") == 0){
  56. if(w->addr < 0)
  57. w->addr = winopenfile(w, "addr");
  58. ctlprint(w->ctl, "addr=dot\n");
  59. seek(w->addr, 0UL, 0);
  60. if(read(w->addr, tmp, 2*12) == 2*12){
  61. q0 = atol(tmp+0*12);
  62. q1 = atol(tmp+1*12);
  63. if(q0 == q1){
  64. t = nil;
  65. k = 0;
  66. if(snarffd > 0){
  67. seek(0, snarffd, 0);
  68. for(;;){
  69. t = realloc(t, k+8192+2);
  70. if(t == nil)
  71. error("win: alloc failed: %r\n");
  72. n = read(snarffd, t+k, 8192);
  73. if(n <= 0)
  74. break;
  75. k += n;
  76. }
  77. t[k] = 0;
  78. }
  79. }else{
  80. t = emalloc((q1-q0)*UTFmax+2);
  81. winread(w, q0, q1, t);
  82. k = strlen(t);
  83. }
  84. if(t!=nil && t[0]!='\0'){
  85. if(t[k-1]!='\n' && t[k-1]!='\004'){
  86. t[k++] = '\n';
  87. t[k] = '\0';
  88. }
  89. sendit(t);
  90. }
  91. free(t);
  92. }
  93. return 1;
  94. }
  95. return 0;
  96. }
  97. void
  98. pipectl(void *v)
  99. {
  100. Window *w;
  101. Event *e;
  102. w = v;
  103. proccreate(wineventproc, w, STACK);
  104. windormant(w);
  105. winsetaddr(w, "0", 0);
  106. for(;;){
  107. e = recvp(w->cevent);
  108. switch(e->c1){
  109. default:
  110. Unknown:
  111. fprint(2, "unknown message %c%c\n", e->c1, e->c2);
  112. break;
  113. case 'E': /* write to body; can't affect us */
  114. break;
  115. case 'F': /* generated by our actions; ignore */
  116. break;
  117. case 'K': /* ignore */
  118. break;
  119. case 'M':
  120. switch(e->c2){
  121. case 'x':
  122. case 'X':
  123. execevent(w, e, pipecommand);
  124. break;
  125. case 'l': /* reflect all searches back to acme */
  126. case 'L':
  127. if(e->flag & 2)
  128. recvp(w->cevent);
  129. winwriteevent(w, e);
  130. break;
  131. case 'I': /* modify away; we don't care */
  132. case 'i':
  133. case 'D':
  134. case 'd':
  135. break;
  136. default:
  137. goto Unknown;
  138. }
  139. }
  140. }
  141. }
  142. void
  143. newpipethread(void*)
  144. {
  145. Window *w;
  146. while(w = recvp(newpipechan))
  147. threadcreate(pipectl, w, STACK);
  148. }
  149. void
  150. startpipe(void)
  151. {
  152. newpipechan = chancreate(sizeof(Window*), 0);
  153. threadcreate(newpipethread, nil, STACK);
  154. snarffd = open("/dev/snarf", OREAD|OCEXEC);
  155. }