1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % File: PXK:PIPE-S.C
5 % Description: pipe, slave mode
6 % Author:
7 % Created:
8 % Modified:
9 % Mode: Text
10 % Package:
11 % Status: Open Source: BSD License
12 %
13 % Redistribution and use in source and binary forms, with or without
14 % modification, are permitted provided that the following conditions are met:
15 %
16 % * Redistributions of source code must retain the relevant copyright
17 % notice, this list of conditions and the following disclaimer.
18 % * Redistributions in binary form must reproduce the above copyright
19 % notice, this list of conditions and the following disclaimer in the
20 % documentation and/or other materials provided with the distribution.
21 %
22 % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 % AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 % THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 % PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR
26 % CONTRIBUTORS
27 % BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 % CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 % SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 % POSSIBILITY OF SUCH DAMAGE.
34 %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 */
37
38 #define _CRT_SECURE_NO_WARNINGS
39
40 #include <windows.h>
41 #include <string.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45
46 #ifdef ALPHA
47 #define LONG __int64
48 #else
49 #define LONG long
50 #endif
51
52
53 #ifdef TEST
54 #define TEST_PRINT(fmt,p1,p2) pmelden(fmt,p1,p2)
55 #else
56 #define TEST_PRINT(fmt,p1,p2)
57 #endif
58
59 HANDLE fe2lisp_read,fe2lisp_write, lisp2fe_read, lisp2fe_write;
60 static int slave_mode = 1;
61
62 void my_popen_slave(int n);
63
64 extern void my_puts(char *);
65 extern int my_psend(char,char *,int);
66 extern int my_preceive(char,char *,int);
67 extern int myWriteToNamedPipe(char *,int);
68 extern int myReadFromNamedPipe(char *,int);
69 extern void local_puts(char *);
70 extern int my_plocalcall(char *,int);
71
72 extern LONG bruch_bruch;
73
74
75 //protocol:
76 // c: remote procedure call
77 // a: answer to rpc
78 // r: read request
79 // d: data reply to 'r'
80 // b: break
81 // x: exit
82 // w: write (data)
83 // k: ack to w
84
85 void my_peek();
86
who()87 char * who()
88 {
89 if(slave_mode) return("slave"); else return("master");
90 }
91
pmelden(char * fmt,char * p1,char * p2)92 pmelden(char * fmt,char * p1, char * p2)
93 {
94 char str[100];
95 sprintf(str,fmt,who(),p1,p2);
96 if(slave_mode) puts(str); else my_puts(str);
97 }
98
my_rpc(char * buf,int len)99 my_rpc(char * buf, int len)
100 {
101 TEST_PRINT("%s RPC call\n %s\n",buf,"");
102 my_psend('c',buf,len);
103 return(my_preceive('a',buf,len));
104 }
105
my_popen_slave(int n)106 void my_popen_slave(int n)
107 {
108 char lbuf[10];
109 // transfer address of break control to master
110 sprintf(lbuf,"%lx",&bruch_bruch);
111 printf("adr bruch %s\n",lbuf);
112 my_psend('b',lbuf,strlen(lbuf));
113 }
114
my_pexit()115 my_pexit()
116 {
117 char lbuf[8];
118 my_psend('x',lbuf,0);
119 //myDeleteNamedPipe();
120 }
121
my_pwrite(char * buf,int len)122 my_pwrite(char * buf, int len)
123 {
124 int i,j; char lbuf[100];
125
126 if((int)strlen(buf) > len) buf[len] = '\0';
127 printf("%s",buf);
128 j = my_psend('w',buf,len);
129 i = my_preceive('k',lbuf,100);
130 return(j);
131 }
132
my_pread(char * buf,int len)133 my_pread(char * buf, int len)
134 {
135 int i;
136 my_psend('r',"",0);
137 i = my_preceive('d',buf, len);
138 buf[i] = '\0';
139 printf("%s\n",buf);
140 return(i);
141 }
142
my_psend(char type,char * buf,int len)143 my_psend(char type, char * buf, int len)
144 {
145 int ret;
146 char lbuf[600];
147
148 strncpy(lbuf,buf,len);
149
150 lbuf[len] = type;
151 TEST_PRINT("%s sends: %s\n",lbuf,"");
152 ret=myWriteToNamedPipe(lbuf,len+1);
153 my_peek();
154 return(ret);
155 }
156
my_preceive(char type,char * buf,int len)157 my_preceive(char type, char * buf, int len)
158 {
159 int ret,t,llen;
160 char lbuf[600];
161
162 TEST_PRINT("%s waits for %s\n",(char*)&type,"");
163 next:
164 llen = myReadFromNamedPipe(lbuf, 600);
165 llen -- ; t = lbuf[llen]; lbuf[llen] = '\0';
166
167 if (t == type)
168 {
169 strncpy(buf,lbuf,llen);
170 TEST_PRINT("%s received %s\n",&type,"");
171 return(llen);
172 };
173
174 TEST_PRINT("%s received %s\n",(char*)&t,"");
175 if(t == 'x') // exit
176 exit(0);
177 else if(t == 'w')
178 {
179 local_puts(lbuf);
180 }
181 else if(t == 'c') // remote procedure call
182 {
183 ////printf("%s received RPC %s\n",lbuf,"");
184 TEST_PRINT("%s received RPC %s\n",lbuf,"");
185 ret=my_plocalcall(lbuf,llen); // call local procedure
186 ////printf("%s returns from RPC %d\n","",ret);
187 TEST_PRINT("%s returns from RPC\n","","");
188 my_psend('a',lbuf,ret); // result return
189 }
190 else
191 {
192 sprintf(lbuf," error: unexpected message >%c< instead of >%c<\n",t,type);
193 pmelden("%s %s\n",lbuf,"");
194 }
195 goto next;
196 }
197
my_peek()198 void my_peek()
199 {
200 // handle messages with may come asynchronously
201
202 int ret,t,llen;
203 char lbuf[600];
204
205 if (1) // (!PeekNamedPipe(the_named_pipe,lbuf,600,&llen,&l1,&l2)
206 //|| llen<1)
207 {
208 TEST_PRINT("%s peek empty\n","","");
209 return;
210 }
211
212 llen -- ; t = lbuf[llen]; lbuf[llen] = '\0';
213
214 TEST_PRINT("%s peek sees message %s\n",(char*)&t, "");
215
216 if (!(t == 'x' || t == 'c' || t == 'b' || (t == 'w' && ! slave_mode))) return;
217
218 TEST_PRINT("%s peek processes message %s\n",(char*)&t, "");
219
220 llen = myReadFromNamedPipe(lbuf, 600);
221
222 if(t == 'x') // exit
223 exit(0);
224 else if(t == 'c') // remote procedure call
225 {
226 ret=my_plocalcall(lbuf,llen); // call local procedure
227 my_psend('a',lbuf,ret); // result return
228 }
229 else if(t == 'b')
230 bruch_bruch--;
231 else if(t == 'w')
232 {
233 local_puts(lbuf);
234 }
235 }
236
237
myWriteToNamedPipe(char * buf,int bytes)238 myWriteToNamedPipe(char * buf, int bytes)
239 {
240 DWORD retCode;
241 DWORD bytesWritten;
242
243 retCode = WriteFile (lisp2fe_write, buf, bytes,
244 &bytesWritten, (LPOVERLAPPED)NULL);
245 FlushFileBuffers(lisp2fe_write);
246
247 return((int)bytesWritten);
248 }
249
myReadFromNamedPipe(char * buf,int bytes)250 myReadFromNamedPipe(char * buf, int bytes)
251 {
252
253 DWORD retCode;
254 DWORD bytesRead;
255
256 while(!(retCode = ReadFile (fe2lisp_read, buf, bytes,
257 &bytesRead, (LPOVERLAPPED)NULL))) Sleep(500);
258
259 return((int) bytesRead);
260 }
261