Commit | Line | Data |
---|---|---|
c906108c SS |
1 | /* This module supports sending and receiving data objects over a |
2 | socket conection. | |
3 | ||
4 | Copyright 1993 Free Software Foundation, Inc. | |
5 | ||
6 | This file is part of GDB. | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2 of the License, or | |
11 | (at your option) any later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program; if not, write to the Free Software | |
20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
21 | ||
22 | static char udr_c[]="@(#)udr.c 2.8 Daniel Mann"; | |
23 | static char udr_c_AMD[]="@(#)udr.c 2.3, AMD"; | |
24 | /* | |
25 | * All data is serialised into a character stream, | |
26 | * and de-serialised back into the approproiate objects. | |
27 | ********************************************************************** HISTORY | |
28 | */ | |
29 | /* This is all unneeded on DOS machines. */ | |
30 | #ifndef __GO32__ | |
31 | ||
32 | #include <stdio.h> | |
33 | #include <sys/types.h> | |
34 | ||
35 | /* This used to say sys/fcntl.h, but the only systems I know of that | |
36 | require that are old (pre-4.3, at least) BSD systems, which we | |
37 | probably don't need to worry about. */ | |
38 | #include <fcntl.h> | |
39 | ||
40 | #include <sys/socket.h> | |
41 | #include "udiproc.h" | |
42 | #include "udisoc.h" | |
43 | ||
44 | extern int errno; | |
45 | extern char* malloc(); | |
46 | ||
47 | /* local type decs. and macro defs. not in a .h file ************* MACRO/TYPE | |
48 | */ | |
49 | ||
50 | /* global dec/defs. which are not in a .h file ************* EXPORT DEC/DEFS | |
51 | */ | |
52 | int udr_errno; /* error occurs during UDR service */ | |
53 | ||
54 | /* local dec/defs. which are not in a .h file *************** LOCAL DEC/DEFS | |
55 | */ | |
56 | ||
57 | /****************************************************************** UDR_CREATE | |
58 | * Build UDR structure for character stream processing. | |
59 | */ | |
60 | int udr_create(udrs, sd, size) | |
61 | UDR* udrs; | |
62 | int sd; | |
63 | int size; | |
64 | { | |
65 | udrs->sd = sd; | |
66 | if(!udrs->buff) udrs->buff = malloc(size); | |
67 | udrs->getbytes = udrs->buff; /* set the buffer to the start */ | |
68 | udrs->putbytes = udrs->buff; | |
69 | udrs->putend = udrs->buff; | |
70 | udrs->udr_op = -1; /* don't know the direction */ | |
71 | udrs->previous_op = -1; /* don't know the direction */ | |
72 | udrs->bufsize = size; | |
73 | return 0; | |
74 | } | |
75 | ||
76 | /******************************************************************** UDR_FREE | |
77 | * Free USR structure and close socket. | |
78 | */ | |
79 | int udr_free(udrs) | |
80 | UDR* udrs; | |
81 | { | |
82 | close(udrs->sd); | |
83 | free(udrs->buff); | |
84 | return 0; | |
85 | } | |
86 | ||
87 | /****************************************************************** UDR_SIGNAL | |
88 | * Send a signal to the process at the other end of the socket, | |
89 | * indicating that it should expect to recieve a new message shortly. | |
90 | */ | |
91 | int udr_signal(udrs) | |
92 | UDR* udrs; | |
93 | { | |
94 | if(send(udrs->sd, "I", 1, MSG_OOB) == -1) | |
95 | { perror("ERROR, udr_signal(), send(...MSG_OOB)"); | |
96 | udr_errno = UDIErrorIPCInternal; | |
97 | return -1; /* return error code */ | |
98 | } | |
99 | return 0; | |
100 | } | |
101 | ||
102 | /***************************************************************** UDR_SENDNOW | |
103 | * used to flush the current character stream buffer to | |
104 | * the associated socket. */ | |
105 | int udr_sendnow(udrs) | |
106 | UDR* udrs; | |
107 | { | |
108 | int size = (UDIUInt32)(udrs->putend) - (UDIUInt32)(udrs->buff); | |
109 | if(udrs->previous_op == 0) | |
110 | { udr_errno = UDIErrorIPCInternal; | |
111 | return -1; | |
112 | } | |
113 | udrs->putbytes = udrs->buff; | |
114 | udrs->putend = udrs->buff; | |
115 | if (write(udrs->sd, udrs->buff, size) == -1) | |
116 | { perror("ERROR, udr_sendnow(), write() call: "); | |
117 | udr_errno = UDIErrorIPCInternal; | |
118 | return -1; /* return error code */ | |
119 | } | |
120 | return 0; | |
121 | } | |
122 | ||
123 | /******************************************************************** UDR_WORK | |
124 | * Function to send or recieve data from the buffers supporting | |
125 | * socket communication. The buffer contains serialised objects | |
126 | * sent/recieved over a socket connection. | |
127 | */ | |
128 | int udr_work(udrs, object_p, size) | |
129 | UDR* udrs; | |
130 | void* object_p; | |
131 | int size; | |
132 | { | |
133 | int cnt, remain; | |
134 | ||
135 | if(udrs->udr_op != udrs->previous_op) | |
136 | { if(udrs->previous_op == 0) | |
137 | { udr_errno = UDIErrorIPCInternal; | |
138 | return -1; | |
139 | } | |
140 | udrs->previous_op= udrs->udr_op; | |
141 | udrs->putbytes = udrs->buff; | |
142 | udrs->getbytes = udrs->buff; | |
143 | } | |
144 | ||
145 | if(udrs->udr_op == UDR_ENCODE) | |
146 | { /* write data into character stream buffer */ | |
147 | if( (UDIUInt32)(udrs->putbytes) + size > | |
148 | (UDIUInt32)(udrs->buff) + (UDIUInt32)(udrs->bufsize) ) | |
149 | { udr_errno = UDIErrorIPCInternal; | |
150 | return -1; | |
151 | } | |
152 | memcpy(udrs->putbytes, (char*)object_p, size); | |
153 | udrs->putbytes += size; | |
154 | if(udrs->putbytes > udrs->putend) udrs->putend = udrs->putbytes; | |
155 | } | |
156 | else if(udrs->udr_op == UDR_DECODE) | |
157 | { | |
158 | if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size ) | |
159 | { /* need more data in character stream buffer */ | |
160 | remain = (UDIUInt32)(udrs->bufsize) - | |
161 | ( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->buff) ); | |
162 | if( ((UDIUInt32)(udrs->bufsize) + (UDIUInt32)(udrs->buff) | |
163 | - (UDIUInt32)(udrs->getbytes)) < size) | |
164 | { udr_errno = UDIErrorIPCInternal; | |
165 | return -1; | |
166 | } | |
167 | cnt = read(udrs->sd, (char*)udrs->putbytes, remain); | |
168 | if(cnt == -1) perror("ERROR udr_work(), read() failure: "); | |
169 | udrs->putbytes += cnt; | |
170 | if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size ) | |
171 | { udr_errno = UDIErrorIPCInternal; | |
172 | return -1; /* return error code */ | |
173 | } | |
174 | } /* read data from character stream buffer */ | |
175 | memcpy((char*)object_p, udrs->getbytes, size); | |
176 | udrs->getbytes += size; | |
177 | } | |
178 | else | |
179 | { udr_errno = UDIErrorIPCInternal; | |
180 | return -1; | |
181 | } | |
182 | return 0; | |
183 | } | |
184 | ||
185 | /************************************************************* UDR_UDIResource | |
186 | */ | |
187 | int udr_UDIResource(udrs, object_p) | |
188 | UDR* udrs; | |
189 | UDIResource* object_p; | |
190 | { | |
191 | int retval; | |
192 | ||
193 | retval = udr_CPUSpace(udrs, &object_p->Space); | |
194 | retval = retval | udr_CPUOffset(udrs, &object_p->Offset); | |
195 | return retval; | |
196 | } | |
197 | ||
198 | /**************************************************************** UDR_UDIRange | |
199 | */ | |
200 | int udr_UDIRange(udrs, object_p) | |
201 | UDR* udrs; | |
202 | UDIRange* object_p; | |
203 | { | |
204 | int retval; | |
205 | ||
206 | retval = udr_CPUOffset(udrs, &object_p->Low); | |
207 | retval = retval | udr_CPUOffset(udrs, &object_p->High); | |
208 | return retval; | |
209 | } | |
210 | ||
211 | /********************************************************** UDR_UDIMemoryRange | |
212 | */ | |
213 | int udr_UDIMemoryRange(udrs, object_p) | |
214 | UDR* udrs; | |
215 | UDIMemoryRange* object_p; | |
216 | { | |
217 | int retval; | |
218 | ||
219 | retval = udr_CPUSpace(udrs, &object_p->Space); | |
220 | retval = retval | udr_CPUOffset(udrs, &object_p->Offset); | |
221 | retval = retval | udr_CPUSizeT(udrs, &object_p->Size); | |
222 | return retval; | |
223 | } | |
224 | ||
225 | /****************************************************************** UDR_string | |
226 | */ | |
227 | int udr_string(udrs, sp) | |
228 | UDR* udrs; | |
229 | char* sp; | |
230 | { | |
231 | int len, retval; | |
232 | ||
233 | if(udrs->udr_op == UDR_ENCODE) | |
234 | { | |
235 | if(sp) | |
236 | { len = strlen(sp) + 1; | |
237 | retval = udr_UDIInt32(udrs, &len); | |
238 | retval = retval | udr_work(udrs, sp, len); | |
239 | } | |
240 | else /* deal with NULL pointer */ | |
241 | { len = 0; | |
242 | retval = udr_UDIInt32(udrs, &len); | |
243 | } | |
244 | } | |
245 | else if(udrs->udr_op == UDR_DECODE) | |
246 | { | |
247 | retval = udr_UDIInt32(udrs, &len); | |
248 | if(len) | |
249 | retval = retval | udr_work(udrs, sp, len); | |
250 | else *sp = '\0'; /* terminate string */ | |
251 | } | |
252 | else | |
253 | { udr_errno = UDIErrorIPCInternal; | |
254 | return -1; | |
255 | } | |
256 | return retval; | |
257 | } | |
258 | ||
259 | /******************************************************************* UDR_BYTES | |
260 | */ | |
261 | int udr_bytes(udrs, ptr, len) | |
262 | UDR* udrs; | |
263 | char* ptr; | |
264 | int len; | |
265 | { | |
266 | return udr_work(udrs, ptr, len); | |
267 | } | |
268 | ||
269 | /********************************************************************* UDR_INT | |
270 | */ | |
271 | int udr_int(udrs, int_p) | |
272 | UDR* udrs; | |
273 | int* int_p; | |
274 | { | |
275 | int ret_val; | |
276 | UDIInt32 udr_obj; /* object of know size */ | |
277 | ||
278 | if(udrs->udr_op == UDR_ENCODE) | |
279 | { | |
280 | udr_obj = *int_p; /* copy into know object size */ | |
281 | return udr_UDIInt32(udrs, &udr_obj); | |
282 | } | |
283 | else if(udrs->udr_op == UDR_DECODE) | |
284 | { | |
285 | ret_val = udr_UDIInt32(udrs, &udr_obj); /* get object of known size */ | |
286 | *int_p = udr_obj; | |
287 | return ret_val; | |
288 | } | |
289 | else | |
290 | { udr_errno = UDIErrorIPCInternal; | |
291 | return -1; | |
292 | } | |
293 | } | |
294 | ||
295 | /****************************************************************** UDR_INLINE | |
296 | */ | |
297 | char* udr_inline(udrs, size) | |
298 | UDR* udrs; | |
299 | int size; | |
300 | { | |
301 | if(udrs->udr_op != udrs->previous_op) | |
302 | { if(udrs->previous_op == 0) | |
303 | { udr_errno = UDIErrorIPCInternal; | |
304 | return 0; | |
305 | } | |
306 | udrs->previous_op= udrs->udr_op; | |
307 | udrs->putbytes = udrs->buff; | |
308 | udrs->getbytes = udrs->buff; | |
309 | } | |
310 | if(udrs->udr_op == UDR_ENCODE) | |
311 | { | |
312 | if(udrs->putbytes + size > udrs->bufsize + udrs->buff) | |
313 | return 0; | |
314 | udrs->putbytes += size; | |
315 | return udrs->putbytes - size; | |
316 | } | |
317 | else if(udrs->udr_op == UDR_DECODE) | |
318 | { | |
319 | if(udrs->getbytes + size > udrs->bufsize + udrs->buff) | |
320 | return 0; | |
321 | udrs->getbytes += size; | |
322 | return udrs->getbytes - size; | |
323 | } | |
324 | else | |
325 | { udr_errno = UDIErrorIPCInternal; | |
326 | return 0; | |
327 | } | |
328 | } | |
329 | ||
330 | /****************************************************************** UDR_GETPOS | |
331 | */ | |
332 | char* udr_getpos(udrs) | |
333 | UDR* udrs; | |
334 | { | |
335 | if(udrs->udr_op == UDR_ENCODE) | |
336 | { | |
337 | return udrs->putbytes; | |
338 | } | |
339 | else if(udrs->udr_op == UDR_DECODE) | |
340 | { | |
341 | return udrs->getbytes; | |
342 | } | |
343 | else | |
344 | { udr_errno = UDIErrorIPCInternal; | |
345 | return 0; | |
346 | } | |
347 | } | |
348 | ||
349 | /****************************************************************** UDR_SETPOS | |
350 | */ | |
351 | int udr_setpos(udrs, pos) | |
352 | UDR* udrs; | |
353 | char* pos; | |
354 | { | |
355 | if( ((UDIUInt32)pos > (UDIUInt32)(udrs->buff) + (UDIUInt32)(udrs->bufsize)) | |
356 | || ((UDIUInt32)pos < (UDIUInt32)(udrs->buff) ) ) | |
357 | { udr_errno = UDIErrorIPCInternal; | |
358 | return 0; | |
359 | } | |
360 | if(udrs->udr_op == UDR_ENCODE) | |
361 | { | |
362 | udrs->putbytes = pos; | |
363 | return 1; | |
364 | } | |
365 | else if(udrs->udr_op == UDR_DECODE) | |
366 | { | |
367 | udrs->getbytes = pos; | |
368 | return 1; | |
369 | } | |
370 | else | |
371 | { udr_errno = UDIErrorIPCInternal; | |
372 | return 0; | |
373 | } | |
374 | } | |
375 | ||
376 | /***************************************************************** UDR_READNOW | |
377 | * Try and ensure "size" bytes are available in the | |
378 | * receive buffer character stream. | |
379 | */ | |
380 | int udr_readnow(udrs, size) | |
381 | UDR* udrs; | |
382 | int size; | |
383 | { | |
384 | int cnt, remain; | |
385 | ||
386 | if(udrs->udr_op == UDR_ENCODE) | |
387 | { | |
388 | udr_errno = UDIErrorIPCInternal; | |
389 | return -1; | |
390 | } | |
391 | else if(udrs->udr_op == UDR_DECODE) | |
392 | { | |
393 | if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size ) | |
394 | { /* need more data in character stream buffer */ | |
395 | remain = (UDIUInt32)(udrs->bufsize) - | |
396 | ( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->buff) ); | |
397 | cnt = read(udrs->sd, (char*)udrs->putbytes, remain); | |
398 | if(cnt == -1) perror("ERROR udr_work(), read() failure: "); | |
399 | udrs->putbytes += cnt; | |
400 | if( (UDIUInt32)(udrs->putbytes)-(UDIUInt32)(udrs->getbytes) < size ) | |
401 | { fprintf(stderr,"ERROR, udr_readnow() too few bytes in stream\n"); | |
402 | return -1; /* return error code */ | |
403 | } | |
404 | } | |
405 | } | |
406 | else | |
407 | { udr_errno = UDIErrorIPCInternal; | |
408 | return -1; | |
409 | } | |
410 | return 0; | |
411 | } | |
412 | ||
413 | /******************************************************************* UDR_ALIGN | |
414 | */ | |
415 | int udr_align(udrs, size) | |
416 | UDR* udrs; | |
417 | int size; | |
418 | { | |
419 | char* align; | |
420 | int offset; | |
421 | ||
422 | align = udr_getpos(udrs); | |
423 | offset = size - ((int)align & (size -1)); | |
424 | offset = offset & (size -1); | |
425 | if(offset) udr_setpos(udrs, align + offset); | |
426 | } | |
427 | #endif /* __GO32__ */ |