195 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
INTRODUCTION
 | 
						|
======================
 | 
						|
This directory contains a port of eXternal Data Representation
 | 
						|
(XDR) code from SunRPC (derived from the relicensed -- to
 | 
						|
3-clause BSD -- implementation in Fedora 11's libtirpc package
 | 
						|
version 0.1.10-7). It has been adapted for newlib in the
 | 
						|
following ways:
 | 
						|
 | 
						|
1) xdr_* functions for fixed-width integral types have been
 | 
						|
   added, such as xdr_int32_t() and similar. The implementation
 | 
						|
   of stream-specific x_putlong() and x_getlong() functions
 | 
						|
   has been modified to work properly whenever possible, even
 | 
						|
   if sizeof(long) > 32bits -- and to correctly report failure
 | 
						|
   when that is not possible.
 | 
						|
2) Use of DEFUN(), EXFUN(), and various other portability
 | 
						|
   macros.
 | 
						|
3) Uses of 64bit types, such as xdr_hyper, xdr_u_longlong_t,
 | 
						|
   and xdr_int64_t, as well as the xdr-specific typedefs
 | 
						|
   quad_t and u_quad_t, are guarded by ___int64_t_defined.
 | 
						|
4) Out-of-memory conditions are indicated by returning FALSE
 | 
						|
   and setting errno = ENOMEM, rather than by printing error
 | 
						|
   messages to stderr. (See #8, below).
 | 
						|
5) Only xdrstdio.c requires stdio support, and it is only
 | 
						|
   compiled if the target supports stdio (see stdio_dir in
 | 
						|
   configure.host)
 | 
						|
6) Uses a local implementation of ntohl/htonl, rather than
 | 
						|
   one provided elsewhere. No dependency on any networking
 | 
						|
   functions.
 | 
						|
7) Floating point support refactored. Currently supports
 | 
						|
   IEEE single and double precision, and VAX single and
 | 
						|
   double precision.
 | 
						|
   a) Those platforms which use float to represent double
 | 
						|
      do not provide xdr_double().
 | 
						|
8) Error reporting can be customized using a private hook.
 | 
						|
   This is described below.
 | 
						|
 | 
						|
xdr is compiled and supported only for those platforms which
 | 
						|
set xdr_dir nonempty in configure.host. At present, the list
 | 
						|
of platforms which do this is:
 | 
						|
   cygwin
 | 
						|
 | 
						|
 | 
						|
PORTING
 | 
						|
======================
 | 
						|
To port XDR to a new newlib target, first enable building it
 | 
						|
by modifying configure.host.  Search for the 'case' statement
 | 
						|
where various *_dir= variables are set, and look for your
 | 
						|
target's entry (or add one if not present).  Set xdr_dir:
 | 
						|
 | 
						|
  *-*-myplatform*)
 | 
						|
        xdr_dir=xdr
 | 
						|
	;;
 | 
						|
 | 
						|
If your platform does not use IEEE754 standard formats for
 | 
						|
floating point values (floats, doubles) you may need to add
 | 
						|
a new xdr_float_*.c implementation, and modify the bottom of
 | 
						|
xdr_float.c:
 | 
						|
 | 
						|
  ...
 | 
						|
  #elif defined(__vax__)
 | 
						|
  #include "xdr_float_vax.c"
 | 
						|
 +#elif defined(__my_platform__)
 | 
						|
 +#include "xdr_float_my_platform.c"
 | 
						|
  #endif
 | 
						|
 | 
						|
You may want to customize your platform's startup objects to set
 | 
						|
the error reporting callback for xdr (not likely, but see ERROR
 | 
						|
MESSAGES section). 
 | 
						|
 | 
						|
You may also want to customize the memory allocation semantics
 | 
						|
employed by the xdr routines.  As stated in the xdr.h header:
 | 
						|
 | 
						|
  XDR_DECODE may allocate space if the pointer [to the location
 | 
						|
  at which the decoded data is to be stored] is NULL. This
 | 
						|
  data can be freed with the XDR_FREE operation.
 | 
						|
 | 
						|
The default implementation defines the following macros in
 | 
						|
rpc/types.h, used throughout xdr/ to deal with memory
 | 
						|
allocation:
 | 
						|
 | 
						|
  #ifndef mem_alloc
 | 
						|
  #define mem_alloc(bsize)        calloc(1, bsize)
 | 
						|
  #endif
 | 
						|
  #ifndef mem_free
 | 
						|
  #define mem_free(ptr, bsize)    free(ptr)
 | 
						|
  #endif
 | 
						|
 | 
						|
By arranging that these symbols are #defined to some other
 | 
						|
memory allocation functions, different memory semantics can be
 | 
						|
imposed. To disallow memory allocation entirely, use the
 | 
						|
following:
 | 
						|
 | 
						|
  -D'mem_alloc(a)'=NULL -D'mem_free(a,b)'='do { ; } while(0)'
 | 
						|
 | 
						|
In this case, any operations which would otherwise require
 | 
						|
memory to be allocated, will instead fail (return FALSE),
 | 
						|
and set errno=ENOMEM.
 | 
						|
 | 
						|
 | 
						|
ERROR MESSAGES
 | 
						|
======================
 | 
						|
This implementation of xdr provides a special hook, so that
 | 
						|
error messages generated by xdr may be captured by a user-
 | 
						|
defined facility. For certain error conditions, the internal
 | 
						|
printf-like function
 | 
						|
  xdr_warnx (fmt, ...)
 | 
						|
is called.  However, that function simply delegates to an
 | 
						|
internal function pointer to a callback function if set;
 | 
						|
otherwise, xdr_warnx does nothing.
 | 
						|
 | 
						|
By setting this function pointer to a user-defined callback,
 | 
						|
the user can enable these messages to go to a syslog, stderr,
 | 
						|
or some other facility.  The function should match the
 | 
						|
following typedef (see xdr_private.h):
 | 
						|
 | 
						|
  typedef void (* xdr_vprintf_t) (const char *, va_list);
 | 
						|
 | 
						|
The desired callback can be registered by calling:
 | 
						|
 | 
						|
  xdr_vprintf_t xdr_set_vprintf (xdr_vprintf_t fnptr);
 | 
						|
 | 
						|
The return value is the "old" function pointer, which may
 | 
						|
be NULL.
 | 
						|
 | 
						|
However, neither the typedef nor the registration function
 | 
						|
are declared in the public headers. Clients wishing to use
 | 
						|
them must either declare the necessary symbols manually,
 | 
						|
or #include "xdr_private.h". More on this point, below.
 | 
						|
 | 
						|
For instance:
 | 
						|
  #include <stdarg.h>
 | 
						|
  #include <stdio.h>
 | 
						|
  typedef void (* xdr_vprintf_t) (const char *, va_list);
 | 
						|
  xdr_vprintf_t xdr_set_vprintf (xdr_vprintf_t fnptr);
 | 
						|
 | 
						|
  void my_vwarnx (const char * fmt, va_list ap)
 | 
						|
  {
 | 
						|
    (void) fprintf (stderr, fmt, ap);
 | 
						|
  }
 | 
						|
  
 | 
						|
  main()
 | 
						|
  {
 | 
						|
    (void) xdr_set_vprintf (&my_vwarnx);
 | 
						|
    ...
 | 
						|
  }
 | 
						|
 | 
						|
will cause xdr-generated error messages to go to stderr.
 | 
						|
 | 
						|
It is not expected that end-user applications will make use
 | 
						|
of this facility.  Rather, it is expected that IF certain
 | 
						|
*platforms* desire that these error messages be recorded,
 | 
						|
instead of expecting client apps to print error messages as
 | 
						|
necessary (*), then those platforms will, in their startup
 | 
						|
objects or static initialization, direct these messages to
 | 
						|
a logging facility, strace debug facility, etc.
 | 
						|
 | 
						|
Therefore, the platform startup code, if part of newlib, can
 | 
						|
#include "xdr_private.h", or simply copy the two declarations
 | 
						|
from that file.
 | 
						|
 | 
						|
However, most newlib targets will probably be satisfied with
 | 
						|
the default (silent) behavior. Note that the original Sun RPC
 | 
						|
implementation of XDR, as well as the glibc implementation,
 | 
						|
print these error messages to stderr.  Cygwin, for greater
 | 
						|
similarity to glibc, registers an error message handler similar
 | 
						|
to the example above, within its startup code.
 | 
						|
 | 
						|
(*) Client apps should already check for FALSE return values.
 | 
						|
    In this case when xdr function return FALSE, the client
 | 
						|
    app would then check errno and act appropriately.
 | 
						|
 | 
						|
 | 
						|
LICENSING AND PEDIGREE
 | 
						|
======================
 | 
						|
For years, the Sun RPC code, and the XDR implementation, was in
 | 
						|
legal license limbo
 | 
						|
  http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=181493
 | 
						|
as its license terms, while open, were of debatable compatibility
 | 
						|
with the GPL. In February of 2009, that changed:
 | 
						|
  http://blogs.sun.com/webmink/entry/old_code_and_old_licenses
 | 
						|
  http://lwn.net/Articles/319648/
 | 
						|
 | 
						|
As documented in the libtirpc rpm.spec file from Fedora 11:
 | 
						|
* Tue May 19 2009 Tom "spot" Callaway <xxxx@redhat.com> 0.1.10-7
 | 
						|
  - Replace the Sun RPC license with the BSD license, with the
 | 
						|
    explicit permission of Sun Microsystems
 | 
						|
 | 
						|
So, in the XDR implementation from Fedora 11's libtirpc package,
 | 
						|
after the modification above by Tom Callaway, each file carries
 | 
						|
the 3-clause BSD license and not the so-called "SunRPC" license.
 | 
						|
It is from this version that the newlib implementation here was
 | 
						|
derived, with the modifications described in the introduction,
 | 
						|
above.
 | 
						|
 |