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 | |
---|