[444] | 1 | INTRODUCTION |
---|
| 2 | ====================== |
---|
| 3 | This directory contains a port of eXternal Data Representation |
---|
| 4 | (XDR) code from SunRPC (derived from the relicensed -- to |
---|
| 5 | 3-clause BSD -- implementation in Fedora 11's libtirpc package |
---|
| 6 | version 0.1.10-7). It has been adapted for newlib in the |
---|
| 7 | following ways: |
---|
| 8 | |
---|
| 9 | 1) xdr_* functions for fixed-width integral types have been |
---|
| 10 | added, such as xdr_int32_t() and similar. The implementation |
---|
| 11 | of stream-specific x_putlong() and x_getlong() functions |
---|
| 12 | has been modified to work properly whenever possible, even |
---|
| 13 | if sizeof(long) > 32bits -- and to correctly report failure |
---|
| 14 | when that is not possible. |
---|
| 15 | 2) Use of DEFUN(), EXFUN(), and various other portability |
---|
| 16 | macros. |
---|
| 17 | 3) Uses of 64bit types, such as xdr_hyper, xdr_u_longlong_t, |
---|
| 18 | and xdr_int64_t, as well as the xdr-specific typedefs |
---|
| 19 | quad_t and u_quad_t, are guarded by ___int64_t_defined. |
---|
| 20 | 4) Out-of-memory conditions are indicated by returning FALSE |
---|
| 21 | and setting errno = ENOMEM, rather than by printing error |
---|
| 22 | messages to stderr. (See #8, below). |
---|
| 23 | 5) Only xdrstdio.c requires stdio support, and it is only |
---|
| 24 | compiled if the target supports stdio (see stdio_dir in |
---|
| 25 | configure.host) |
---|
| 26 | 6) Uses a local implementation of ntohl/htonl, rather than |
---|
| 27 | one provided elsewhere. No dependency on any networking |
---|
| 28 | functions. |
---|
| 29 | 7) Floating point support refactored. Currently supports |
---|
| 30 | IEEE single and double precision, and VAX single and |
---|
| 31 | double precision. |
---|
| 32 | a) Those platforms which use float to represent double |
---|
| 33 | do not provide xdr_double(). |
---|
| 34 | 8) Error reporting can be customized using a private hook. |
---|
| 35 | This is described below. |
---|
| 36 | |
---|
| 37 | xdr is compiled and supported only for those platforms which |
---|
| 38 | set xdr_dir nonempty in configure.host. At present, the list |
---|
| 39 | of platforms which do this is: |
---|
| 40 | cygwin |
---|
| 41 | |
---|
| 42 | |
---|
| 43 | PORTING |
---|
| 44 | ====================== |
---|
| 45 | To port XDR to a new newlib target, first enable building it |
---|
| 46 | by modifying configure.host. Search for the 'case' statement |
---|
| 47 | where various *_dir= variables are set, and look for your |
---|
| 48 | target's entry (or add one if not present). Set xdr_dir: |
---|
| 49 | |
---|
| 50 | *-*-myplatform*) |
---|
| 51 | xdr_dir=xdr |
---|
| 52 | ;; |
---|
| 53 | |
---|
| 54 | If your platform does not use IEEE754 standard formats for |
---|
| 55 | floating point values (floats, doubles) you may need to add |
---|
| 56 | a new xdr_float_*.c implementation, and modify the bottom of |
---|
| 57 | xdr_float.c: |
---|
| 58 | |
---|
| 59 | ... |
---|
| 60 | #elif defined(__vax__) |
---|
| 61 | #include "xdr_float_vax.c" |
---|
| 62 | +#elif defined(__my_platform__) |
---|
| 63 | +#include "xdr_float_my_platform.c" |
---|
| 64 | #endif |
---|
| 65 | |
---|
| 66 | You may want to customize your platform's startup objects to set |
---|
| 67 | the error reporting callback for xdr (not likely, but see ERROR |
---|
| 68 | MESSAGES section). |
---|
| 69 | |
---|
| 70 | You may also want to customize the memory allocation semantics |
---|
| 71 | employed by the xdr routines. As stated in the xdr.h header: |
---|
| 72 | |
---|
| 73 | XDR_DECODE may allocate space if the pointer [to the location |
---|
| 74 | at which the decoded data is to be stored] is NULL. This |
---|
| 75 | data can be freed with the XDR_FREE operation. |
---|
| 76 | |
---|
| 77 | The default implementation defines the following macros in |
---|
| 78 | rpc/types.h, used throughout xdr/ to deal with memory |
---|
| 79 | allocation: |
---|
| 80 | |
---|
| 81 | #ifndef mem_alloc |
---|
| 82 | #define mem_alloc(bsize) calloc(1, bsize) |
---|
| 83 | #endif |
---|
| 84 | #ifndef mem_free |
---|
| 85 | #define mem_free(ptr, bsize) free(ptr) |
---|
| 86 | #endif |
---|
| 87 | |
---|
| 88 | By arranging that these symbols are #defined to some other |
---|
| 89 | memory allocation functions, different memory semantics can be |
---|
| 90 | imposed. To disallow memory allocation entirely, use the |
---|
| 91 | following: |
---|
| 92 | |
---|
| 93 | -D'mem_alloc(a)'=NULL -D'mem_free(a,b)'='do { ; } while(0)' |
---|
| 94 | |
---|
| 95 | In this case, any operations which would otherwise require |
---|
| 96 | memory to be allocated, will instead fail (return FALSE), |
---|
| 97 | and set errno=ENOMEM. |
---|
| 98 | |
---|
| 99 | |
---|
| 100 | ERROR MESSAGES |
---|
| 101 | ====================== |
---|
| 102 | This implementation of xdr provides a special hook, so that |
---|
| 103 | error messages generated by xdr may be captured by a user- |
---|
| 104 | defined facility. For certain error conditions, the internal |
---|
| 105 | printf-like function |
---|
| 106 | xdr_warnx (fmt, ...) |
---|
| 107 | is called. However, that function simply delegates to an |
---|
| 108 | internal function pointer to a callback function if set; |
---|
| 109 | otherwise, xdr_warnx does nothing. |
---|
| 110 | |
---|
| 111 | By setting this function pointer to a user-defined callback, |
---|
| 112 | the user can enable these messages to go to a syslog, stderr, |
---|
| 113 | or some other facility. The function should match the |
---|
| 114 | following typedef (see xdr_private.h): |
---|
| 115 | |
---|
| 116 | typedef void (* xdr_vprintf_t) (const char *, va_list); |
---|
| 117 | |
---|
| 118 | The desired callback can be registered by calling: |
---|
| 119 | |
---|
| 120 | xdr_vprintf_t xdr_set_vprintf (xdr_vprintf_t fnptr); |
---|
| 121 | |
---|
| 122 | The return value is the "old" function pointer, which may |
---|
| 123 | be NULL. |
---|
| 124 | |
---|
| 125 | However, neither the typedef nor the registration function |
---|
| 126 | are declared in the public headers. Clients wishing to use |
---|
| 127 | them must either declare the necessary symbols manually, |
---|
| 128 | or #include "xdr_private.h". More on this point, below. |
---|
| 129 | |
---|
| 130 | For instance: |
---|
| 131 | #include <stdarg.h> |
---|
| 132 | #include <stdio.h> |
---|
| 133 | typedef void (* xdr_vprintf_t) (const char *, va_list); |
---|
| 134 | xdr_vprintf_t xdr_set_vprintf (xdr_vprintf_t fnptr); |
---|
| 135 | |
---|
| 136 | void my_vwarnx (const char * fmt, va_list ap) |
---|
| 137 | { |
---|
| 138 | (void) fprintf (stderr, fmt, ap); |
---|
| 139 | } |
---|
| 140 | |
---|
| 141 | main() |
---|
| 142 | { |
---|
| 143 | (void) xdr_set_vprintf (&my_vwarnx); |
---|
| 144 | ... |
---|
| 145 | } |
---|
| 146 | |
---|
| 147 | will cause xdr-generated error messages to go to stderr. |
---|
| 148 | |
---|
| 149 | It is not expected that end-user applications will make use |
---|
| 150 | of this facility. Rather, it is expected that IF certain |
---|
| 151 | *platforms* desire that these error messages be recorded, |
---|
| 152 | instead of expecting client apps to print error messages as |
---|
| 153 | necessary (*), then those platforms will, in their startup |
---|
| 154 | objects or static initialization, direct these messages to |
---|
| 155 | a logging facility, strace debug facility, etc. |
---|
| 156 | |
---|
| 157 | Therefore, the platform startup code, if part of newlib, can |
---|
| 158 | #include "xdr_private.h", or simply copy the two declarations |
---|
| 159 | from that file. |
---|
| 160 | |
---|
| 161 | However, most newlib targets will probably be satisfied with |
---|
| 162 | the default (silent) behavior. Note that the original Sun RPC |
---|
| 163 | implementation of XDR, as well as the glibc implementation, |
---|
| 164 | print these error messages to stderr. Cygwin, for greater |
---|
| 165 | similarity to glibc, registers an error message handler similar |
---|
| 166 | to the example above, within its startup code. |
---|
| 167 | |
---|
| 168 | (*) Client apps should already check for FALSE return values. |
---|
| 169 | In this case when xdr function return FALSE, the client |
---|
| 170 | app would then check errno and act appropriately. |
---|
| 171 | |
---|
| 172 | |
---|
| 173 | LICENSING AND PEDIGREE |
---|
| 174 | ====================== |
---|
| 175 | For years, the Sun RPC code, and the XDR implementation, was in |
---|
| 176 | legal license limbo |
---|
| 177 | http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=181493 |
---|
| 178 | as its license terms, while open, were of debatable compatibility |
---|
| 179 | with the GPL. In February of 2009, that changed: |
---|
| 180 | http://blogs.sun.com/webmink/entry/old_code_and_old_licenses |
---|
| 181 | http://lwn.net/Articles/319648/ |
---|
| 182 | |
---|
| 183 | As documented in the libtirpc rpm.spec file from Fedora 11: |
---|
| 184 | * Tue May 19 2009 Tom "spot" Callaway <xxxx@redhat.com> 0.1.10-7 |
---|
| 185 | - Replace the Sun RPC license with the BSD license, with the |
---|
| 186 | explicit permission of Sun Microsystems |
---|
| 187 | |
---|
| 188 | So, in the XDR implementation from Fedora 11's libtirpc package, |
---|
| 189 | after the modification above by Tom Callaway, each file carries |
---|
| 190 | the 3-clause BSD license and not the so-called "SunRPC" license. |
---|
| 191 | It is from this version that the newlib implementation here was |
---|
| 192 | derived, with the modifications described in the introduction, |
---|
| 193 | above. |
---|
| 194 | |
---|