1 /******************************************************************************
2 * Copyright 1991 Advanced Micro Devices, Inc.
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
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.
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.
19 * Advanced Micro Devices, Inc.
20 * 29K Support Products
22 * 5900 E. Ben White Blvd.
25 *****************************************************************************
27 static char udr_c[] = "@(#)udr.c 2.8 Daniel Mann";
28 static char udr_c_AMD[] = "@(#)udr.c 2.3, AMD";
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
37 #include <sys/fcntl.h>
38 #include <sys/types.h>
39 #include <sys/socket.h>
44 extern char *malloc ();
46 /* local type decs. and macro defs. not in a .h file ************* MACRO/TYPE
49 /* global dec/defs. which are not in a .h file ************* EXPORT DEC/DEFS
51 int udr_errno; /* error occurs during UDR service */
53 /* local dec/defs. which are not in a .h file *************** LOCAL DEC/DEFS
56 /****************************************************************** UDR_CREATE
57 * Build UDR structure for character stream processing.
60 udr_create (udrs, sd, size)
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 */
77 /******************************************************************** UDR_FREE
78 * Free USR structure and close socket.
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.
97 if (send (udrs->sd, "I", 1, MSG_OOB) == -1)
99 perror ("ERROR, udr_signal(), send(...MSG_OOB)");
100 udr_errno = UDIErrorIPCInternal;
101 return -1; /* return error code */
106 /***************************************************************** UDR_SENDNOW
107 * used to flush the current character stream buffer to
108 * the associated socket. */
113 int size = (UDIUInt32) (udrs->putend) - (UDIUInt32) (udrs->buff);
114 if (udrs->previous_op == 0)
116 udr_errno = UDIErrorIPCInternal;
119 udrs->putbytes = udrs->buff;
120 udrs->putend = udrs->buff;
121 if (write (udrs->sd, udrs->buff, size) == -1)
123 perror ("ERROR, udr_sendnow(), write() call: ");
124 udr_errno = UDIErrorIPCInternal;
125 return -1; /* return error code */
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.
136 udr_work (udrs, object_p, size)
143 if (udrs->udr_op != udrs->previous_op)
145 if (udrs->previous_op == 0)
147 udr_errno = UDIErrorIPCInternal;
150 udrs->previous_op = udrs->udr_op;
151 udrs->putbytes = udrs->buff;
152 udrs->getbytes = udrs->buff;
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))
160 udr_errno = UDIErrorIPCInternal;
163 bcopy ((char *) object_p, udrs->putbytes, size);
164 udrs->putbytes += size;
165 if (udrs->putbytes > udrs->putend)
166 udrs->putend = udrs->putbytes;
168 else if (udrs->udr_op == UDR_DECODE)
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)
177 udr_errno = UDIErrorIPCInternal;
180 cnt = read (udrs->sd, (char *) udrs->putbytes, remain);
182 perror ("ERROR udr_work(), read() failure: ");
183 udrs->putbytes += cnt;
184 if ((UDIUInt32) (udrs->putbytes) - (UDIUInt32) (udrs->getbytes) < size)
186 udr_errno = UDIErrorIPCInternal;
187 return -1; /* return error code */
189 } /* read data from character stream buffer */
190 bcopy (udrs->getbytes, (char *) object_p, size);
191 udrs->getbytes += size;
195 udr_errno = UDIErrorIPCInternal;
201 /************************************************************* UDR_UDIResource
204 udr_UDIResource (udrs, object_p)
206 UDIResource *object_p;
210 retval = udr_CPUSpace (udrs, &object_p->Space);
211 retval = retval | udr_CPUOffset (udrs, &object_p->Offset);
215 /**************************************************************** UDR_UDIRange
218 udr_UDIRange (udrs, object_p)
224 retval = udr_CPUOffset (udrs, &object_p->Low);
225 retval = retval | udr_CPUOffset (udrs, &object_p->High);
229 /********************************************************** UDR_UDIMemoryRange
232 udr_UDIMemoryRange (udrs, object_p)
234 UDIMemoryRange *object_p;
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);
244 /****************************************************************** UDR_string
247 udr_string (udrs, sp)
253 if (udrs->udr_op == UDR_ENCODE)
257 len = strlen (sp) + 1;
258 retval = udr_UDIInt32 (udrs, &len);
259 retval = retval | udr_work (udrs, sp, len);
262 /* deal with NULL pointer */
265 retval = udr_UDIInt32 (udrs, &len);
268 else if (udrs->udr_op == UDR_DECODE)
270 retval = udr_UDIInt32 (udrs, &len);
272 retval = retval | udr_work (udrs, sp, len);
274 *sp = '\0'; /* terminate string */
278 udr_errno = UDIErrorIPCInternal;
284 /******************************************************************* UDR_BYTES
287 udr_bytes (udrs, ptr, len)
292 return udr_work (udrs, ptr, len);
295 /********************************************************************* UDR_INT
298 udr_int (udrs, int_p)
303 UDIInt32 udr_obj; /* object of know size */
305 if (udrs->udr_op == UDR_ENCODE)
307 udr_obj = *int_p; /* copy into know object size */
308 return udr_UDIInt32 (udrs, &udr_obj);
310 else if (udrs->udr_op == UDR_DECODE)
312 ret_val = udr_UDIInt32 (udrs, &udr_obj); /* get object of known size */
318 udr_errno = UDIErrorIPCInternal;
323 /****************************************************************** UDR_INLINE
326 udr_inline (udrs, size)
330 if (udrs->udr_op != udrs->previous_op)
332 if (udrs->previous_op == 0)
334 udr_errno = UDIErrorIPCInternal;
337 udrs->previous_op = udrs->udr_op;
338 udrs->putbytes = udrs->buff;
339 udrs->getbytes = udrs->buff;
341 if (udrs->udr_op == UDR_ENCODE)
343 if (udrs->putbytes + size > udrs->bufsize + udrs->buff)
345 udrs->putbytes += size;
346 return udrs->putbytes - size;
348 else if (udrs->udr_op == UDR_DECODE)
350 if (udrs->getbytes + size > udrs->bufsize + udrs->buff)
352 udrs->getbytes += size;
353 return udrs->getbytes - size;
357 udr_errno = UDIErrorIPCInternal;
362 /****************************************************************** UDR_GETPOS
368 if (udrs->udr_op == UDR_ENCODE)
370 return udrs->putbytes;
372 else if (udrs->udr_op == UDR_DECODE)
374 return udrs->getbytes;
378 udr_errno = UDIErrorIPCInternal;
383 /****************************************************************** UDR_SETPOS
386 udr_setpos (udrs, pos)
390 if (((UDIUInt32) pos > (UDIUInt32) (udrs->buff) + (UDIUInt32) (udrs->bufsize))
391 || ((UDIUInt32) pos < (UDIUInt32) (udrs->buff)))
393 udr_errno = UDIErrorIPCInternal;
396 if (udrs->udr_op == UDR_ENCODE)
398 udrs->putbytes = pos;
401 else if (udrs->udr_op == UDR_DECODE)
403 udrs->getbytes = pos;
408 udr_errno = UDIErrorIPCInternal;
413 /***************************************************************** UDR_READNOW
414 * Try and ensure "size" bytes are available in the
415 * receive buffer character stream.
418 udr_readnow (udrs, size)
424 if (udrs->udr_op == UDR_ENCODE)
426 udr_errno = UDIErrorIPCInternal;
429 else if (udrs->udr_op == UDR_DECODE)
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);
437 perror ("ERROR udr_work(), read() failure: ");
438 udrs->putbytes += cnt;
439 if ((UDIUInt32) (udrs->putbytes) - (UDIUInt32) (udrs->getbytes) < size)
441 fprintf (stderr, "ERROR, udr_readnow() too few bytes in stream\n");
442 return -1; /* return error code */
448 udr_errno = UDIErrorIPCInternal;
454 /******************************************************************* UDR_ALIGN
457 udr_align (udrs, size)
464 align = udr_getpos (udrs);
465 offset = size - ((int) align & (size - 1));
466 offset = offset & (size - 1);
468 udr_setpos (udrs, align + offset);