Import the gnulib 'random_r' module, which provides a nice strong random number generator that is portable across OS. bootstrap | 1 gnulib/lib/.cvsignore | 12 - gnulib/lib/Makefile.am | 13 + gnulib/lib/gettimeofday.c | 5 gnulib/lib/ioctl.c | 1 gnulib/lib/poll.c | 4 gnulib/lib/random_r.c | 420 +++++++++++++++++++++++++++++++++++++++++++ gnulib/lib/strerror.c | 128 ++++++------- gnulib/m4/gnulib-cache.m4 | 3 gnulib/m4/gnulib-comp.m4 | 5 gnulib/m4/random_r.m4 | 21 ++ gnulib/tests/Makefile.am | 9 gnulib/tests/test-random_r.c | 56 +++++ 13 files changed, 600 insertions(+), 78 deletions(-) Daniel diff --git a/bootstrap b/bootstrap --- a/bootstrap +++ b/bootstrap @@ -80,6 +80,7 @@ physmem physmem poll posix-shell +random_r recv send setsockopt diff --git a/gnulib/lib/.cvsignore b/gnulib/lib/.cvsignore --- a/gnulib/lib/.cvsignore +++ b/gnulib/lib/.cvsignore @@ -1,13 +1,13 @@ +alloca.h +arpa_inet.h +.deps +errno.h +float.h *.la +.libs *.lo -.deps -.libs Makefile Makefile.in -alloca.h -arpa_inet.h -errno.h -float.h netdb.h netinet_in.h poll.h diff --git a/gnulib/lib/Makefile.am b/gnulib/lib/Makefile.am --- a/gnulib/lib/Makefile.am +++ b/gnulib/lib/Makefile.am @@ -9,7 +9,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --tests-base=gnulib/tests --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl --no-vc-files c-ctype close connect getaddrinfo gethostname getpass gettext inet_pton ioctl mkstemp mktempd perror physmem poll posix-shell recv send setsockopt socket strerror strndup strsep sys_stat time_r useless-if-before-free vasprintf vc-list-files verify +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --tests-base=gnulib/tests --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl --no-vc-files c-ctype close connect getaddrinfo gethostname getpass gettext inet_pton ioctl mkstemp mktempd perror physmem poll posix-shell random_r recv send setsockopt socket strerror strndup strsep sys_stat time_r useless-if-before-free vasprintf vc-list-files verify AUTOMAKE_OPTIONS = 1.5 gnits @@ -26,7 +26,7 @@ DISTCLEANFILES = DISTCLEANFILES = MAINTAINERCLEANFILES = -AM_CPPFLAGS = $(WARN_CFLAGS) +AM_CPPFLAGS = noinst_LTLIBRARIES += libgnu.la @@ -454,6 +454,15 @@ EXTRA_libgnu_la_SOURCES += poll.c #MOSTLYCLEANFILES += script script-t ## end gnulib module posix-shell + +## begin gnulib module random_r + + +EXTRA_DIST += random_r.c + +EXTRA_libgnu_la_SOURCES += random_r.c + +## end gnulib module random_r ## begin gnulib module realloc-posix diff --git a/gnulib/lib/gettimeofday.c b/gnulib/lib/gettimeofday.c --- a/gnulib/lib/gettimeofday.c +++ b/gnulib/lib/gettimeofday.c @@ -47,12 +47,11 @@ static struct tm *localtime_buffer_addr On the first call, record the address of the static buffer that localtime uses for its result. */ -#undef localtime -extern struct tm *localtime (time_t const *); - struct tm * rpl_localtime (time_t const *timep) { +#undef localtime + extern struct tm *localtime (time_t const *); struct tm *tm = localtime (timep); if (localtime_buffer_addr == &tm_zero_buffer) diff --git a/gnulib/lib/ioctl.c b/gnulib/lib/ioctl.c --- a/gnulib/lib/ioctl.c +++ b/gnulib/lib/ioctl.c @@ -24,7 +24,6 @@ #define WIN32_LEAN_AND_MEAN /* Get winsock2.h. */ #include <sys/socket.h> -#include <sys/ioctl.h> /* Get set_winsock_errno, FD_TO_SOCKET etc. */ #include "w32sock.h" diff --git a/gnulib/lib/poll.c b/gnulib/lib/poll.c --- a/gnulib/lib/poll.c +++ b/gnulib/lib/poll.c @@ -404,10 +404,11 @@ poll (pfd, nfd, timeout) fd_set rfds, wfds, xfds; BOOL poll_again; MSG msg; + char sockbuf[256]; int rc = 0; nfds_t i; - if (timeout < -1) + if (nfd < 0 || timeout < -1) { errno = EINVAL; return -1; @@ -425,6 +426,7 @@ poll (pfd, nfd, timeout) /* Classify socket handles and create fd sets. */ for (i = 0; i < nfd; i++) { + size_t optlen = sizeof(sockbuf); pfd[i].revents = 0; if (pfd[i].fd < 0) continue; diff --git a/gnulib/lib/random_r.c b/gnulib/lib/random_r.c new file mode 100644 --- /dev/null +++ b/gnulib/lib/random_r.c @@ -0,0 +1,420 @@ +/* + Copyright (C) 1995, 2005, 2008 Free Software Foundation + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* + Copyright (C) 1983 Regents of the University of California. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE.*/ + +/* + * This is derived from the Berkeley source: + * @(#)random.c 5.5 (Berkeley) 7/6/88 + * It was reworked for the GNU C Library by Roland McGrath. + * Rewritten to be reentrant by Ulrich Drepper, 1995 + */ + +#include <config.h> + +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <inttypes.h> + + +/* An improved random number generation package. In addition to the standard + rand()/srand() like interface, this package also has a special state info + interface. The initstate() routine is called with a seed, an array of + bytes, and a count of how many bytes are being passed in; this array is + then initialized to contain information for random number generation with + that much state information. Good sizes for the amount of state + information are 32, 64, 128, and 256 bytes. The state can be switched by + calling the setstate() function with the same array as was initialized + with initstate(). By default, the package runs with 128 bytes of state + information and generates far better random numbers than a linear + congruential generator. If the amount of state information is less than + 32 bytes, a simple linear congruential R.N.G. is used. Internally, the + state information is treated as an array of longs; the zeroth element of + the array is the type of R.N.G. being used (small integer); the remainder + of the array is the state information for the R.N.G. Thus, 32 bytes of + state information will give 7 longs worth of state information, which will + allow a degree seven polynomial. (Note: The zeroth word of state + information also has some other information stored in it; see setstate + for details). The random number generation technique is a linear feedback + shift register approach, employing trinomials (since there are fewer terms + to sum up that way). In this approach, the least significant bit of all + the numbers in the state table will act as a linear feedback shift register, + and will have period 2^deg - 1 (where deg is the degree of the polynomial + being used, assuming that the polynomial is irreducible and primitive). + The higher order bits will have longer periods, since their values are + also influenced by pseudo-random carries out of the lower bits. The + total period of the generator is approximately deg*(2**deg - 1); thus + doubling the amount of state information has a vast influence on the + period of the generator. Note: The deg*(2**deg - 1) is an approximation + only good for large deg, when the period of the shift register is the + dominant factor. With deg equal to seven, the period is actually much + longer than the 7*(2**7 - 1) predicted by this formula. */ + + + +/* For each of the currently supported random number generators, we have a + break value on the amount of state information (you need at least this many + bytes of state info to support this random number generator), a degree for + the polynomial (actually a trinomial) that the R.N.G. is based on, and + separation between the two lower order coefficients of the trinomial. */ + +/* Linear congruential. */ +#define TYPE_0 0 +#define BREAK_0 8 +#define DEG_0 0 +#define SEP_0 0 + +/* x**7 + x**3 + 1. */ +#define TYPE_1 1 +#define BREAK_1 32 +#define DEG_1 7 +#define SEP_1 3 + +/* x**15 + x + 1. */ +#define TYPE_2 2 +#define BREAK_2 64 +#define DEG_2 15 +#define SEP_2 1 + +/* x**31 + x**3 + 1. */ +#define TYPE_3 3 +#define BREAK_3 128 +#define DEG_3 31 +#define SEP_3 3 + +/* x**63 + x + 1. */ +#define TYPE_4 4 +#define BREAK_4 256 +#define DEG_4 63 +#define SEP_4 1 + + +/* Array versions of the above information to make code run faster. + Relies on fact that TYPE_i == i. */ + +#define MAX_TYPES 5 /* Max number of types above. */ + +struct random_poly_info +{ + int seps[MAX_TYPES]; + int degrees[MAX_TYPES]; +}; + +static const struct random_poly_info random_poly_info = +{ + { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }, + { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 } +}; + +#ifndef _LIBC +# define weak_alias(local, symbol) +# define __set_errno(e) errno = (e) +# define __srandom_r srandom_r +# define __initstate_r initstate_r +# define __setstate_r setstate_r +# define __random_r random_r +#endif + + + +/* Initialize the random number generator based on the given seed. If the + type is the trivial no-state-information type, just remember the seed. + Otherwise, initializes state[] based on the given "seed" via a linear + congruential generator. Then, the pointers are set to known locations + that are exactly rand_sep places apart. Lastly, it cycles the state + information a given number of times to get rid of any initial dependencies + introduced by the L.C.R.N.G. Note that the initialization of randtbl[] + for default usage relies on values produced by this routine. */ +int +__srandom_r (unsigned int seed, struct random_data *buf) +{ + int type; + int32_t *state; + long int i; + long int word; + int32_t *dst; + int kc; + + if (buf == NULL) + goto fail; + type = buf->rand_type; + if ((unsigned int) type >= MAX_TYPES) + goto fail; + + state = buf->state; + /* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */ + if (seed == 0) + seed = 1; + state[0] = seed; + if (type == TYPE_0) + goto done; + + dst = state; + word = seed; + kc = buf->rand_deg; + for (i = 1; i < kc; ++i) + { + /* This does: + state[i] = (16807 * state[i - 1]) % 2147483647; + but avoids overflowing 31 bits. */ + long int hi = word / 127773; + long int lo = word % 127773; + word = 16807 * lo - 2836 * hi; + if (word < 0) + word += 2147483647; + *++dst = word; + } + + buf->fptr = &state[buf->rand_sep]; + buf->rptr = &state[0]; + kc *= 10; + while (--kc >= 0) + { + int32_t discard; + (void) __random_r (buf, &discard); + } + + done: + return 0; + + fail: + return -1; +} + +weak_alias (__srandom_r, srandom_r) + +/* Initialize the state information in the given array of N bytes for + future random number generation. Based on the number of bytes we + are given, and the break values for the different R.N.G.'s, we choose + the best (largest) one we can and set things up for it. srandom is + then called to initialize the state information. Note that on return + from srandom, we set state[-1] to be the type multiplexed with the current + value of the rear pointer; this is so successive calls to initstate won't + lose this information and will be able to restart with setstate. + Note: The first thing we do is save the current state, if any, just like + setstate so that it doesn't matter when initstate is called. + Returns a pointer to the old state. */ +int +__initstate_r (unsigned int seed, char *arg_state, size_t n, + struct random_data *buf) +{ + int32_t *old_state; + int32_t *state; + int type; + int degree; + int separation; + + if (buf == NULL) + goto fail; + + old_state = buf->state; + if (old_state != NULL) + { + int old_type = buf->rand_type; + if (old_type == TYPE_0) + old_state[-1] = TYPE_0; + else + old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type; + } + + if (n >= BREAK_3) + type = n < BREAK_4 ? TYPE_3 : TYPE_4; + else if (n < BREAK_1) + { + if (n < BREAK_0) + { + __set_errno (EINVAL); + goto fail; + } + type = TYPE_0; + } + else + type = n < BREAK_2 ? TYPE_1 : TYPE_2; + + degree = random_poly_info.degrees[type]; + separation = random_poly_info.seps[type]; + + buf->rand_type = type; + buf->rand_sep = separation; + buf->rand_deg = degree; + state = &((int32_t *) arg_state)[1]; /* First location. */ + /* Must set END_PTR before srandom. */ + buf->end_ptr = &state[degree]; + + buf->state = state; + + __srandom_r (seed, buf); + + state[-1] = TYPE_0; + if (type != TYPE_0) + state[-1] = (buf->rptr - state) * MAX_TYPES + type; + + return 0; + + fail: + __set_errno (EINVAL); + return -1; +} + +weak_alias (__initstate_r, initstate_r) + +/* Restore the state from the given state array. + Note: It is important that we also remember the locations of the pointers + in the current state information, and restore the locations of the pointers + from the old state information. This is done by multiplexing the pointer + location into the zeroth word of the state information. Note that due + to the order in which things are done, it is OK to call setstate with the + same state as the current state + Returns a pointer to the old state information. */ +int +__setstate_r (char *arg_state, struct random_data *buf) +{ + int32_t *new_state = 1 + (int32_t *) arg_state; + int type; + int old_type; + int32_t *old_state; + int degree; + int separation; + + if (arg_state == NULL || buf == NULL) + goto fail; + + old_type = buf->rand_type; + old_state = buf->state; + if (old_type == TYPE_0) + old_state[-1] = TYPE_0; + else + old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type; + + type = new_state[-1] % MAX_TYPES; + if (type < TYPE_0 || type > TYPE_4) + goto fail; + + buf->rand_deg = degree = random_poly_info.degrees[type]; + buf->rand_sep = separation = random_poly_info.seps[type]; + buf->rand_type = type; + + if (type != TYPE_0) + { + int rear = new_state[-1] / MAX_TYPES; + buf->rptr = &new_state[rear]; + buf->fptr = &new_state[(rear + separation) % degree]; + } + buf->state = new_state; + /* Set end_ptr too. */ + buf->end_ptr = &new_state[degree]; + + return 0; + + fail: + __set_errno (EINVAL); + return -1; +} + +weak_alias (__setstate_r, setstate_r) + +/* If we are using the trivial TYPE_0 R.N.G., just do the old linear + congruential bit. Otherwise, we do our fancy trinomial stuff, which is the + same in all the other cases due to all the global variables that have been + set up. The basic operation is to add the number at the rear pointer into + the one at the front pointer. Then both pointers are advanced to the next + location cyclically in the table. The value returned is the sum generated, + reduced to 31 bits by throwing away the "least random" low bit. + Note: The code takes advantage of the fact that both the front and + rear pointers can't wrap on the same call by not testing the rear + pointer if the front one has wrapped. Returns a 31-bit random number. */ + +int +__random_r (struct random_data *buf, int32_t *result) +{ + int32_t *state; + + if (buf == NULL || result == NULL) + goto fail; + + state = buf->state; + + if (buf->rand_type == TYPE_0) + { + int32_t val = state[0]; + val = ((state[0] * 1103515245) + 12345) & 0x7fffffff; + state[0] = val; + *result = val; + } + else + { + int32_t *fptr = buf->fptr; + int32_t *rptr = buf->rptr; + int32_t *end_ptr = buf->end_ptr; + int32_t val; + + val = *fptr += *rptr; + /* Chucking least random bit. */ + *result = (val >> 1) & 0x7fffffff; + ++fptr; + if (fptr >= end_ptr) + { + fptr = state; + ++rptr; + } + else + { + ++rptr; + if (rptr >= end_ptr) + rptr = state; + } + buf->fptr = fptr; + buf->rptr = rptr; + } + return 0; + + fail: + __set_errno (EINVAL); + return -1; +} + +weak_alias (__random_r, random_r) diff --git a/gnulib/lib/strerror.c b/gnulib/lib/strerror.c --- a/gnulib/lib/strerror.c +++ b/gnulib/lib/strerror.c @@ -45,89 +45,89 @@ rpl_strerror (int n) { # if GNULIB_defined_ETXTBSY case ETXTBSY: - return (char*)"Text file busy"; + return "Text file busy"; # endif # if GNULIB_defined_ESOCK /* native Windows platforms */ /* EWOULDBLOCK is the same as EAGAIN. */ case EINPROGRESS: - return (char*)"Operation now in progress"; + return "Operation now in progress"; case EALREADY: - return (char*)"Operation already in progress"; + return "Operation already in progress"; case ENOTSOCK: - return (char*)"Socket operation on non-socket"; + return "Socket operation on non-socket"; case EDESTADDRREQ: - return (char*)"Destination address required"; + return "Destination address required"; case EMSGSIZE: - return (char*)"Message too long"; + return "Message too long"; case EPROTOTYPE: - return (char*)"Protocol wrong type for socket"; + return "Protocol wrong type for socket"; case ENOPROTOOPT: - return (char*)"Protocol not available"; + return "Protocol not available"; case EPROTONOSUPPORT: - return (char*)"Protocol not supported"; + return "Protocol not supported"; case ESOCKTNOSUPPORT: - return (char*)"Socket type not supported"; + return "Socket type not supported"; case EOPNOTSUPP: - return (char*)"Operation not supported"; + return "Operation not supported"; case EPFNOSUPPORT: - return (char*)"Protocol family not supported"; + return "Protocol family not supported"; case EAFNOSUPPORT: - return (char*)"Address family not supported by protocol"; + return "Address family not supported by protocol"; case EADDRINUSE: - return (char*)"Address already in use"; + return "Address already in use"; case EADDRNOTAVAIL: - return (char*)"Cannot assign requested address"; + return "Cannot assign requested address"; case ENETDOWN: - return (char*)"Network is down"; + return "Network is down"; case ENETUNREACH: - return (char*)"Network is unreachable"; + return "Network is unreachable"; case ENETRESET: - return (char*)"Network dropped connection on reset"; + return "Network dropped connection on reset"; case ECONNABORTED: - return (char*)"Software caused connection abort"; + return "Software caused connection abort"; case ECONNRESET: - return (char*)"Connection reset by peer"; + return "Connection reset by peer"; case ENOBUFS: - return (char*)"No buffer space available"; + return "No buffer space available"; case EISCONN: - return (char*)"Transport endpoint is already connected"; + return "Transport endpoint is already connected"; case ENOTCONN: - return (char*)"Transport endpoint is not connected"; + return "Transport endpoint is not connected"; case ESHUTDOWN: - return (char*)"Cannot send after transport endpoint shutdown"; + return "Cannot send after transport endpoint shutdown"; case ETOOMANYREFS: - return (char*)"Too many references: cannot splice"; + return "Too many references: cannot splice"; case ETIMEDOUT: - return (char*)"Connection timed out"; + return "Connection timed out"; case ECONNREFUSED: - return (char*)"Connection refused"; + return "Connection refused"; case ELOOP: - return (char*)"Too many levels of symbolic links"; + return "Too many levels of symbolic links"; case EHOSTDOWN: - return (char*)"Host is down"; + return "Host is down"; case EHOSTUNREACH: - return (char*)"No route to host"; + return "No route to host"; case EPROCLIM: - return (char*)"Too many processes"; + return "Too many processes"; case EUSERS: - return (char*)"Too many users"; + return "Too many users"; case EDQUOT: - return (char*)"Disk quota exceeded"; + return "Disk quota exceeded"; case ESTALE: - return (char*)"Stale NFS file handle"; + return "Stale NFS file handle"; case EREMOTE: - return (char*)"Object is remote"; + return "Object is remote"; # if HAVE_WINSOCK2_H /* WSA_INVALID_HANDLE maps to EBADF */ /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */ /* WSA_INVALID_PARAMETER maps to EINVAL */ case WSA_OPERATION_ABORTED: - return (char*)"Overlapped operation aborted"; + return "Overlapped operation aborted"; case WSA_IO_INCOMPLETE: - return (char*)"Overlapped I/O event object not in signaled state"; + return "Overlapped I/O event object not in signaled state"; case WSA_IO_PENDING: - return (char*)"Overlapped operations will complete later"; + return "Overlapped operations will complete later"; /* WSAEINTR maps to EINTR */ /* WSAEBADF maps to EBADF */ /* WSAEACCES maps to EACCES */ @@ -172,86 +172,86 @@ rpl_strerror (int n) /* WSAESTALE is ESTALE */ /* WSAEREMOTE is EREMOTE */ case WSASYSNOTREADY: - return (char*)"Network subsystem is unavailable"; + return "Network subsystem is unavailable"; case WSAVERNOTSUPPORTED: - return (char*)"Winsock.dll version out of range"; + return "Winsock.dll version out of range"; case WSANOTINITIALISED: - return (char*)"Successful WSAStartup not yet performed"; + return "Successful WSAStartup not yet performed"; case WSAEDISCON: - return (char*)"Graceful shutdown in progress"; + return "Graceful shutdown in progress"; case WSAENOMORE: case WSA_E_NO_MORE: - return (char*)"No more results"; + return "No more results"; case WSAECANCELLED: case WSA_E_CANCELLED: - return (char*)"Call was canceled"; + return "Call was canceled"; case WSAEINVALIDPROCTABLE: - return (char*)"Procedure call table is invalid"; + return "Procedure call table is invalid"; case WSAEINVALIDPROVIDER: - return (char*)"Service provider is invalid"; + return "Service provider is invalid"; case WSAEPROVIDERFAILEDINIT: - return (char*)"Service provider failed to initialize"; + return "Service provider failed to initialize"; case WSASYSCALLFAILURE: - return (char*)"System call failure"; + return "System call failure"; case WSASERVICE_NOT_FOUND: - return (char*)"Service not found"; + return "Service not found"; case WSATYPE_NOT_FOUND: - return (char*)"Class type not found"; + return "Class type not found"; case WSAEREFUSED: - return (char*)"Database query was refused"; + return "Database query was refused"; case WSAHOST_NOT_FOUND: - return (char*)"Host not found"; + return "Host not found"; case WSATRY_AGAIN: - return (char*)"Nonauthoritative host not found"; + return "Nonauthoritative host not found"; case WSANO_RECOVERY: - return (char*)"Nonrecoverable error"; + return "Nonrecoverable error"; case WSANO_DATA: - return (char*)"Valid name, no data record of requested type"; + return "Valid name, no data record of requested type"; /* WSA_QOS_* omitted */ # endif # endif # if GNULIB_defined_ENOMSG case ENOMSG: - return (char*)"No message of desired type"; + return "No message of desired type"; # endif # if GNULIB_defined_EIDRM case EIDRM: - return (char*)"Identifier removed"; + return "Identifier removed"; # endif # if GNULIB_defined_ENOLINK case ENOLINK: - return (char*)"Link has been severed"; + return "Link has been severed"; # endif # if GNULIB_defined_EPROTO case EPROTO: - return (char*)"Protocol error"; + return "Protocol error"; # endif # if GNULIB_defined_EMULTIHOP case EMULTIHOP: - return (char*)"Multihop attempted"; + return "Multihop attempted"; # endif # if GNULIB_defined_EBADMSG case EBADMSG: - return (char*)"Bad message"; + return "Bad message"; # endif # if GNULIB_defined_EOVERFLOW case EOVERFLOW: - return (char*)"Value too large for defined data type"; + return "Value too large for defined data type"; # endif # if GNULIB_defined_ENOTSUP case ENOTSUP: - return (char*)"Not supported"; + return "Not supported"; # endif # if GNULIB_defined_ case ECANCELED: - return (char*)"Operation canceled"; + return "Operation canceled"; # endif } diff --git a/gnulib/m4/gnulib-cache.m4 b/gnulib/m4/gnulib-cache.m4 --- a/gnulib/m4/gnulib-cache.m4 +++ b/gnulib/m4/gnulib-cache.m4 @@ -15,7 +15,7 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --tests-base=gnulib/tests --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl --no-vc-files c-ctype close connect getaddrinfo gethostname getpass gettext inet_pton ioctl mkstemp mktempd perror physmem poll posix-shell recv send setsockopt socket strerror strndup strsep sys_stat time_r useless-if-before-free vasprintf vc-list-files verify +# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib/lib --m4-base=gnulib/m4 --doc-base=doc --tests-base=gnulib/tests --aux-dir=build-aux --with-tests --lgpl=2 --libtool --macro-prefix=gl --no-vc-files c-ctype close connect getaddrinfo gethostname getpass gettext inet_pton ioctl mkstemp mktempd perror physmem poll posix-shell random_r recv send setsockopt socket strerror strndup strsep sys_stat time_r useless-if-before-free vasprintf vc-list-files verify # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) @@ -35,6 +35,7 @@ gl_MODULES([ physmem poll posix-shell + random_r recv send setsockopt diff --git a/gnulib/m4/gnulib-comp.m4 b/gnulib/m4/gnulib-comp.m4 --- a/gnulib/m4/gnulib-comp.m4 +++ b/gnulib/m4/gnulib-comp.m4 @@ -106,6 +106,8 @@ AC_SUBST([LTALLOCA]) gl_PHYSMEM gl_FUNC_POLL gl_POSIX_SHELL + gl_FUNC_RANDOM_R + gl_STDLIB_MODULE_INDICATOR([random_r]) gl_FUNC_REALLOC_POSIX gl_STDLIB_MODULE_INDICATOR([realloc-posix]) AC_REQUIRE([gl_HEADER_SYS_SOCKET]) @@ -370,6 +372,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/printf-args.h lib/printf-parse.c lib/printf-parse.h + lib/random_r.c lib/realloc.c lib/recv.c lib/send.c @@ -461,6 +464,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/printf-posix.m4 m4/printf.m4 m4/progtest.m4 + m4/random_r.m4 m4/realloc.m4 m4/servent.m4 m4/size_max.m4 @@ -516,6 +520,7 @@ AC_DEFUN([gl_FILE_LIST], [ tests/test-perror.c tests/test-perror.sh tests/test-poll.c + tests/test-random_r.c tests/test-snprintf.c tests/test-sockets.c tests/test-stdbool.c diff --git a/gnulib/m4/random_r.m4 b/gnulib/m4/random_r.m4 new file mode 100644 --- /dev/null +++ b/gnulib/m4/random_r.m4 @@ -0,0 +1,21 @@ +# serial 1 +dnl Copyright (C) 2008 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_RANDOM_R], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_CHECK_FUNCS([random_r]) + if test $ac_cv_func_random_r = no; then + HAVE_RANDOM_R=0 + AC_LIBOBJ([random_r]) + gl_PREREQ_RANDOM_R + fi +]) + +# Prerequisites of lib/random_r.c. +AC_DEFUN([gl_PREREQ_RANDOM_R], [ + : +]) diff --git a/gnulib/tests/Makefile.am b/gnulib/tests/Makefile.am --- a/gnulib/tests/Makefile.am +++ b/gnulib/tests/Makefile.am @@ -211,6 +211,15 @@ EXTRA_DIST += test-poll.c EXTRA_DIST += test-poll.c ## end gnulib module poll-tests + +## begin gnulib module random_r-tests + +TESTS += test-random_r +check_PROGRAMS += test-random_r + +EXTRA_DIST += test-random_r.c + +## end gnulib module random_r-tests ## begin gnulib module snprintf-tests diff --git a/gnulib/tests/test-random_r.c b/gnulib/tests/test-random_r.c new file mode 100644 --- /dev/null +++ b/gnulib/tests/test-random_r.c @@ -0,0 +1,56 @@ +/* Test random_r. + Copyright (C) 2008 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> + +#define ASSERT(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ + fflush (stderr); \ + abort (); \ + } \ + } \ + while (0) + +int +main () +{ + struct random_data rand_state; + char buf[128]; + unsigned int i; + unsigned int n_big = 0; + + rand_state.state = NULL; + if (initstate_r (time (NULL), buf, sizeof buf, &rand_state)) + return 1; + for (i = 0; i < 1000; i++) + { + int32_t r; + ASSERT (random_r (&rand_state, &r) == 0); + ASSERT (0 <= r); + if (RAND_MAX / 2 < r) + ++n_big; + } + + /* Fail if none of the numbers were larger than RAND_MAX / 2. */ + return !n_big; +} -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list