OSDN Git Service

* ps.cc (prog_name): New global variable.
[pf3gnuchains/pf3gnuchains4x.git] / utils / amd-udi / udi / udr.c
1 /******************************************************************************
2 * Copyright 1991 Advanced Micro Devices, Inc.
3 *
4 * This software is the property of Advanced Micro Devices, Inc  (AMD)  which
5 * specifically  grants the user the right to modify, use and distribute this
6 * software provided this notice is not removed or altered.  All other rights
7 * are reserved by AMD.
8 *
9 * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
10 * SOFTWARE.  IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
11 * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
12 * USE OF THIS SOFTWARE.
13 *
14 * So that all may benefit from your experience, please report  any  problems
15 * or  suggestions about this software to the 29K Technical Support Center at
16 * 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131  in  the  UK,  or
17 * 0031-11-1129 in Japan, toll free.  The direct dial number is 512-462-4118.
18 *
19 * Advanced Micro Devices, Inc.
20 * 29K Support Products
21 * Mail Stop 573
22 * 5900 E. Ben White Blvd.
23 * Austin, TX 78741
24 * 800-292-9263
25 *****************************************************************************
26 */
27 static char udr_c[] = "@(#)udr.c        2.8  Daniel Mann";
28 static char udr_c_AMD[] = "@(#)udr.c    2.3, AMD";
29 /*
30 *       This module supports sending and receiving
31 *       data objects over a socket conection.
32 *       All data is serialised into a character stream,
33 *       and de-serialised back into the approproiate objects.
34 ********************************************************************** HISTORY
35 */
36 #include <stdio.h>
37 #include <sys/fcntl.h>
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include "udiproc.h"
41 #include "udisoc.h"
42
43 extern int errno;
44 extern char *malloc ();
45
46 /* local type decs. and macro defs. not in a .h  file ************* MACRO/TYPE
47 */
48
49 /* global dec/defs. which are not in a .h   file ************* EXPORT DEC/DEFS
50 */
51 int udr_errno;                  /* error occurs during UDR service */
52
53 /* local dec/defs. which are not in a .h   file *************** LOCAL DEC/DEFS
54 */
55
56 /****************************************************************** UDR_CREATE
57 * Build UDR structure for character stream processing.
58 */
59 int 
60 udr_create (udrs, sd, size)
61      UDR *udrs;
62      int sd;
63      int size;
64 {
65   udrs->sd = sd;
66   if (!udrs->buff)
67     udrs->buff = malloc (size);
68   udrs->getbytes = udrs->buff;  /* set the buffer to the start */
69   udrs->putbytes = udrs->buff;
70   udrs->putend = udrs->buff;
71   udrs->udr_op = -1;            /* don't know the direction */
72   udrs->previous_op = -1;       /* don't know the direction */
73   udrs->bufsize = size;
74   return 0;
75 }
76
77 /******************************************************************** UDR_FREE
78 * Free USR structure and close socket.
79 */
80 int 
81 udr_free (udrs)
82      UDR *udrs;
83 {
84   close (udrs->sd);
85   free (udrs->buff);
86   return 0;
87 }
88
89 /****************************************************************** UDR_SIGNAL
90 * Send a signal to the process at the other end of the socket,
91 * indicating that it should expect to recieve a new message shortly.
92 */
93 int 
94 udr_signal (udrs)
95      UDR *udrs;
96 {
97   if (send (udrs->sd, "I", 1, MSG_OOB) == -1)
98     {
99       perror ("ERROR, udr_signal(), send(...MSG_OOB)");
100       udr_errno = UDIErrorIPCInternal;
101       return -1;                /* return error code */
102     }
103   return 0;
104 }
105
106 /***************************************************************** UDR_SENDNOW
107 * used to flush the current character stream buffer to
108 * the associated socket.  */
109 int 
110 udr_sendnow (udrs)
111      UDR *udrs;
112 {
113   int size = (UDIUInt32) (udrs->putend) - (UDIUInt32) (udrs->buff);
114   if (udrs->previous_op == 0)
115     {
116       udr_errno = UDIErrorIPCInternal;
117       return -1;
118     }
119   udrs->putbytes = udrs->buff;
120   udrs->putend = udrs->buff;
121   if (write (udrs->sd, udrs->buff, size) == -1)
122     {
123       perror ("ERROR, udr_sendnow(), write() call: ");
124       udr_errno = UDIErrorIPCInternal;
125       return -1;                /* return error code */
126     }
127   return 0;
128 }
129
130 /******************************************************************** UDR_WORK
131 * Function to send or recieve data from the buffers supporting
132 * socket communication. The buffer contains serialised objects
133 * sent/recieved over a socket connection.
134 */
135 int 
136 udr_work (udrs, object_p, size)
137      UDR *udrs;
138      void *object_p;
139      int size;
140 {
141   int cnt, remain;
142
143   if (udrs->udr_op != udrs->previous_op)
144     {
145       if (udrs->previous_op == 0)
146         {
147           udr_errno = UDIErrorIPCInternal;
148           return -1;
149         }
150       udrs->previous_op = udrs->udr_op;
151       udrs->putbytes = udrs->buff;
152       udrs->getbytes = udrs->buff;
153     }
154
155   if (udrs->udr_op == UDR_ENCODE)
156     {                           /* write data into character stream buffer */
157       if ((UDIUInt32) (udrs->putbytes) + size >
158           (UDIUInt32) (udrs->buff) + (UDIUInt32) (udrs->bufsize))
159         {
160           udr_errno = UDIErrorIPCInternal;
161           return -1;
162         }
163       bcopy ((char *) object_p, udrs->putbytes, size);
164       udrs->putbytes += size;
165       if (udrs->putbytes > udrs->putend)
166         udrs->putend = udrs->putbytes;
167     }
168   else if (udrs->udr_op == UDR_DECODE)
169     {
170       if ((UDIUInt32) (udrs->putbytes) - (UDIUInt32) (udrs->getbytes) < size)
171         {                       /* need more data in character stream buffer */
172           remain = (UDIUInt32) (udrs->bufsize) -
173             ((UDIUInt32) (udrs->putbytes) - (UDIUInt32) (udrs->buff));
174           if (((UDIUInt32) (udrs->bufsize) + (UDIUInt32) (udrs->buff)
175                - (UDIUInt32) (udrs->getbytes)) < size)
176             {
177               udr_errno = UDIErrorIPCInternal;
178               return -1;
179             }
180           cnt = read (udrs->sd, (char *) udrs->putbytes, remain);
181           if (cnt == -1)
182             perror ("ERROR udr_work(),  read() failure: ");
183           udrs->putbytes += cnt;
184           if ((UDIUInt32) (udrs->putbytes) - (UDIUInt32) (udrs->getbytes) < size)
185             {
186               udr_errno = UDIErrorIPCInternal;
187               return -1;        /* return error code */
188             }
189         }                       /* read data from character stream buffer */
190       bcopy (udrs->getbytes, (char *) object_p, size);
191       udrs->getbytes += size;
192     }
193   else
194     {
195       udr_errno = UDIErrorIPCInternal;
196       return -1;
197     }
198   return 0;
199 }
200
201 /************************************************************* UDR_UDIResource
202 */
203 int 
204 udr_UDIResource (udrs, object_p)
205      UDR *udrs;
206      UDIResource *object_p;
207 {
208   int retval;
209
210   retval = udr_CPUSpace (udrs, &object_p->Space);
211   retval = retval | udr_CPUOffset (udrs, &object_p->Offset);
212   return retval;
213 }
214
215 /**************************************************************** UDR_UDIRange
216 */
217 int 
218 udr_UDIRange (udrs, object_p)
219      UDR *udrs;
220      UDIRange *object_p;
221 {
222   int retval;
223
224   retval = udr_CPUOffset (udrs, &object_p->Low);
225   retval = retval | udr_CPUOffset (udrs, &object_p->High);
226   return retval;
227 }
228
229 /********************************************************** UDR_UDIMemoryRange
230 */
231 int 
232 udr_UDIMemoryRange (udrs, object_p)
233      UDR *udrs;
234      UDIMemoryRange *object_p;
235 {
236   int retval;
237
238   retval = udr_CPUSpace (udrs, &object_p->Space);
239   retval = retval | udr_CPUOffset (udrs, &object_p->Offset);
240   retval = retval | udr_CPUSizeT (udrs, &object_p->Size);
241   return retval;
242 }
243
244 /****************************************************************** UDR_string
245 */
246 int 
247 udr_string (udrs, sp)
248      UDR *udrs;
249      char *sp;
250 {
251   int len, retval;
252
253   if (udrs->udr_op == UDR_ENCODE)
254     {
255       if (sp)
256         {
257           len = strlen (sp) + 1;
258           retval = udr_UDIInt32 (udrs, &len);
259           retval = retval | udr_work (udrs, sp, len);
260         }
261       else
262         /* deal with NULL pointer */
263         {
264           len = 0;
265           retval = udr_UDIInt32 (udrs, &len);
266         }
267     }
268   else if (udrs->udr_op == UDR_DECODE)
269     {
270       retval = udr_UDIInt32 (udrs, &len);
271       if (len)
272         retval = retval | udr_work (udrs, sp, len);
273       else
274         *sp = '\0';             /* terminate string */
275     }
276   else
277     {
278       udr_errno = UDIErrorIPCInternal;
279       return -1;
280     }
281   return retval;
282 }
283
284 /******************************************************************* UDR_BYTES
285 */
286 int 
287 udr_bytes (udrs, ptr, len)
288      UDR *udrs;
289      char *ptr;
290      int len;
291 {
292   return udr_work (udrs, ptr, len);
293 }
294
295 /********************************************************************* UDR_INT
296 */
297 int 
298 udr_int (udrs, int_p)
299      UDR *udrs;
300      int *int_p;
301 {
302   int ret_val;
303   UDIInt32 udr_obj;             /* object of know size */
304
305   if (udrs->udr_op == UDR_ENCODE)
306     {
307       udr_obj = *int_p;         /* copy into know object size */
308       return udr_UDIInt32 (udrs, &udr_obj);
309     }
310   else if (udrs->udr_op == UDR_DECODE)
311     {
312       ret_val = udr_UDIInt32 (udrs, &udr_obj);  /* get object of known size */
313       *int_p = udr_obj;
314       return ret_val;
315     }
316   else
317     {
318       udr_errno = UDIErrorIPCInternal;
319       return -1;
320     }
321 }
322
323 /****************************************************************** UDR_INLINE
324 */
325 char *
326 udr_inline (udrs, size)
327      UDR *udrs;
328      int size;
329 {
330   if (udrs->udr_op != udrs->previous_op)
331     {
332       if (udrs->previous_op == 0)
333         {
334           udr_errno = UDIErrorIPCInternal;
335           return 0;
336         }
337       udrs->previous_op = udrs->udr_op;
338       udrs->putbytes = udrs->buff;
339       udrs->getbytes = udrs->buff;
340     }
341   if (udrs->udr_op == UDR_ENCODE)
342     {
343       if (udrs->putbytes + size > udrs->bufsize + udrs->buff)
344         return 0;
345       udrs->putbytes += size;
346       return udrs->putbytes - size;
347     }
348   else if (udrs->udr_op == UDR_DECODE)
349     {
350       if (udrs->getbytes + size > udrs->bufsize + udrs->buff)
351         return 0;
352       udrs->getbytes += size;
353       return udrs->getbytes - size;
354     }
355   else
356     {
357       udr_errno = UDIErrorIPCInternal;
358       return 0;
359     }
360 }
361
362 /****************************************************************** UDR_GETPOS
363 */
364 char *
365 udr_getpos (udrs)
366      UDR *udrs;
367 {
368   if (udrs->udr_op == UDR_ENCODE)
369     {
370       return udrs->putbytes;
371     }
372   else if (udrs->udr_op == UDR_DECODE)
373     {
374       return udrs->getbytes;
375     }
376   else
377     {
378       udr_errno = UDIErrorIPCInternal;
379       return 0;
380     }
381 }
382
383 /****************************************************************** UDR_SETPOS
384 */
385 int 
386 udr_setpos (udrs, pos)
387      UDR *udrs;
388      char *pos;
389 {
390   if (((UDIUInt32) pos > (UDIUInt32) (udrs->buff) + (UDIUInt32) (udrs->bufsize))
391       || ((UDIUInt32) pos < (UDIUInt32) (udrs->buff)))
392     {
393       udr_errno = UDIErrorIPCInternal;
394       return 0;
395     }
396   if (udrs->udr_op == UDR_ENCODE)
397     {
398       udrs->putbytes = pos;
399       return 1;
400     }
401   else if (udrs->udr_op == UDR_DECODE)
402     {
403       udrs->getbytes = pos;
404       return 1;
405     }
406   else
407     {
408       udr_errno = UDIErrorIPCInternal;
409       return 0;
410     }
411 }
412
413 /***************************************************************** UDR_READNOW
414 * Try and ensure "size" bytes are available in the
415 * receive buffer character stream.
416 */
417 int 
418 udr_readnow (udrs, size)
419      UDR *udrs;
420      int size;
421 {
422   int cnt, remain;
423
424   if (udrs->udr_op == UDR_ENCODE)
425     {
426       udr_errno = UDIErrorIPCInternal;
427       return -1;
428     }
429   else if (udrs->udr_op == UDR_DECODE)
430     {
431       if ((UDIUInt32) (udrs->putbytes) - (UDIUInt32) (udrs->getbytes) < size)
432         {                       /* need more data in character stream buffer */
433           remain = (UDIUInt32) (udrs->bufsize) -
434             ((UDIUInt32) (udrs->putbytes) - (UDIUInt32) (udrs->buff));
435           cnt = read (udrs->sd, (char *) udrs->putbytes, remain);
436           if (cnt == -1)
437             perror ("ERROR udr_work(),  read() failure: ");
438           udrs->putbytes += cnt;
439           if ((UDIUInt32) (udrs->putbytes) - (UDIUInt32) (udrs->getbytes) < size)
440             {
441               fprintf (stderr, "ERROR, udr_readnow() too few bytes in stream\n");
442               return -1;        /* return error code */
443             }
444         }
445     }
446   else
447     {
448       udr_errno = UDIErrorIPCInternal;
449       return -1;
450     }
451   return 0;
452 }
453
454 /******************************************************************* UDR_ALIGN
455 */
456 int 
457 udr_align (udrs, size)
458      UDR *udrs;
459      int size;
460 {
461   char *align;
462   int offset;
463
464   align = udr_getpos (udrs);
465   offset = size - ((int) align & (size - 1));
466   offset = offset & (size - 1);
467   if (offset)
468     udr_setpos (udrs, align + offset);
469 }