]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/29k-share/udi/udr.c
Initial creation of sourceware repository
[thirdparty/binutils-gdb.git] / gdb / 29k-share / udi / udr.c
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__ */