diff options
author | Russ Allbery <rra@stanford.edu> | 2011-09-20 21:39:52 -0700 |
---|---|---|
committer | Russ Allbery <rra@stanford.edu> | 2011-09-20 21:39:52 -0700 |
commit | c82ebaa070d5c4e9e1311b336139160ddf9e12cc (patch) | |
tree | 1b67c222b72f00eda61b79dbd03e56a7589f4536 /util | |
parent | d4fb4c26b7e3a3911c7d02da7cad6135435a7977 (diff) |
Update to rra-c-util 3.9
* Add notices in each file copied from rra-c-util.
* Prefer gssapi/gssapi.h to gssapi.h.
* Include strings.h if it exists for strncasecmp on some platforms.
* getaddrinfo replacement now portable to systems with bad netdb.h.
* Avoid krb5-config if --with-gssapi-{include,lib} are given.
* Add Windows implementation of fdflag_nonblocking.
* The network_connect utility functions now take an optional timeout.
* Use typedef instead of #define for socklen_t and sig_atomic_t.
* Stop providing or using INADDR_LOOPBACK for portability reasons.
Diffstat (limited to 'util')
-rw-r--r-- | util/concat.c | 3 | ||||
-rw-r--r-- | util/concat.h | 3 | ||||
-rw-r--r-- | util/fdflag.c | 67 | ||||
-rw-r--r-- | util/fdflag.h | 16 | ||||
-rw-r--r-- | util/macros.h | 12 | ||||
-rw-r--r-- | util/messages.c | 7 | ||||
-rw-r--r-- | util/messages.h | 5 | ||||
-rw-r--r-- | util/network.c | 118 | ||||
-rw-r--r-- | util/network.h | 13 | ||||
-rw-r--r-- | util/vector.c | 11 | ||||
-rw-r--r-- | util/vector.h | 7 | ||||
-rw-r--r-- | util/xmalloc.c | 3 | ||||
-rw-r--r-- | util/xmalloc.h | 3 | ||||
-rw-r--r-- | util/xwrite.c | 3 | ||||
-rw-r--r-- | util/xwrite.h | 3 |
15 files changed, 212 insertions, 62 deletions
diff --git a/util/concat.c b/util/concat.c index 0525ddb..fb4afa8 100644 --- a/util/concat.c +++ b/util/concat.c @@ -18,6 +18,9 @@ * together and returned. This is useful for building file names where names * that aren't fully qualified are qualified with some particular directory. * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Written by Russ Allbery <rra@stanford.edu> * * The authors hereby relinquish any claim to any copyright that they may have diff --git a/util/concat.h b/util/concat.h index 9712d70..960f242 100644 --- a/util/concat.h +++ b/util/concat.h @@ -1,6 +1,9 @@ /* * Prototypes for string concatenation with dynamic memory allocation. * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Written by Russ Allbery <rra@stanford.edu> * * The authors hereby relinquish any claim to any copyright that they may have diff --git a/util/fdflag.c b/util/fdflag.c index bf3125e..1be200c 100644 --- a/util/fdflag.c +++ b/util/fdflag.c @@ -4,7 +4,10 @@ * Simple functions (wrappers around fcntl) to set or clear file descriptor * flags like close-on-exec or nonblocking I/O. * - * Copyright 2008 + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * + * Copyright 2008, 2011 * The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2004, 2005, 2006 * by Internet Systems Consortium, Inc. ("ISC") @@ -30,16 +33,21 @@ #include <config.h> #include <portable/system.h> -#include <errno.h> -#include <fcntl.h> -#ifndef O_NONBLOCK -# include <sys/ioctl.h> -# if HAVE_SYS_FILIO_H -# include <sys/filio.h> +#ifdef _WIN32 +# include <winsock2.h> +#else +# include <errno.h> +# include <fcntl.h> +# ifndef O_NONBLOCK +# include <sys/ioctl.h> +# if HAVE_SYS_FILIO_H +# include <sys/filio.h> +# endif # endif #endif #include <util/fdflag.h> +#include <util/macros.h> /* @@ -49,7 +57,17 @@ * One is supposed to retrieve the flags, add FD_CLOEXEC, and then set them, * although I've never seen a system with any flags other than close-on-exec. * Do it right anyway; it's not that expensive. -*/ + * + * Stub this out on Windows, where it's not supported (at least currently by + * this utility library). + */ +#ifdef _WIN32 +bool +fdflag_close_exec(int fd UNUSED, bool flag UNUSED) +{ + return false; +} +#else bool fdflag_close_exec(int fd, bool flag) { @@ -61,17 +79,23 @@ fdflag_close_exec(int fd, bool flag) mode = flag ? (oflag | FD_CLOEXEC) : (oflag & ~FD_CLOEXEC); return (fcntl(fd, F_SETFD, mode) == 0); } +#endif /* * Set a file descriptor to nonblocking (or clear the nonblocking flag if flag * is false), returning true on success and false on failure. * - * Always use O_NONBLOCK; O_NDELAY is not the same thing historically. The - * semantics of O_NDELAY are that if the read would block, it returns 0 - * instead. This is indistinguishable from an end of file condition. POSIX - * added O_NONBLOCK, which requires read to return -1 and set errno to EAGAIN, - * which is what we want. + * For Windows, be aware that this will only work for sockets. For UNIX, you + * can pass a non-socket in and it will do the right thing, since UNIX doesn't + * distinguish, but Windows will not allow that. Thankfully, there's rarely + * any need to set non-sockets non-blocking. + * + * For UNIX, always use O_NONBLOCK; O_NDELAY is not the same thing + * historically. The semantics of O_NDELAY are that if the read would block, + * it returns 0 instead. This is indistinguishable from an end of file + * condition. POSIX added O_NONBLOCK, which requires read to return -1 and + * set errno to EAGAIN, which is what we want. * * FNDELAY (4.3BSD) originally did the correct thing, although it has a * different incompatibility (affecting all users of a socket rather than just @@ -93,9 +117,18 @@ fdflag_close_exec(int fd, bool flag) * O_NONBLOCK). Accordingly, we currently unconditionally use O_NONBLOCK. If * this causes too many problems, an autoconf test may be required. */ -#ifdef O_NONBLOCK +#if defined(_WIN32) +bool +fdflag_nonblocking(socket_type fd, bool flag) +{ + u_long mode; + + mode = flag ? 1 : 0; + return (ioctlsocket(fd, FIONBIO, &mode) == 0); +} +#elif defined(O_NONBLOCK) bool -fdflag_nonblocking(int fd, bool flag) +fdflag_nonblocking(socket_type fd, bool flag) { int mode; @@ -106,8 +139,8 @@ fdflag_nonblocking(int fd, bool flag) return (fcntl(fd, F_SETFL, mode) == 0); } #else /* !O_NONBLOCK */ -int -nonblocking(int fd, bool flag) +bool +fdflag_nonblocking(socket_type fd, bool flag) { int state; diff --git a/util/fdflag.h b/util/fdflag.h index 6b8af60..bed45da 100644 --- a/util/fdflag.h +++ b/util/fdflag.h @@ -1,7 +1,10 @@ /* * Prototypes for setting or clearing file descriptor flags. * - * Copyright 2008, 2010 + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * + * Copyright 2008, 2010, 2011 * The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2004, 2005, 2006 * by Internet Systems Consortium, Inc. ("ISC") @@ -30,15 +33,22 @@ #include <config.h> #include <portable/macros.h> #include <portable/stdbool.h> +#include <portable/socket.h> BEGIN_DECLS /* Default to a hidden visibility for all util functions. */ #pragma GCC visibility push(hidden) -/* Set a file descriptor close-on-exec or nonblocking. */ +/* + * Set a file descriptor close-on-exec or nonblocking. fdflag_close_exec is + * not supported on Windows and will always return false. fdflag_nonblocking + * is defined to take a socket_type so that it can be supported on Windows. + * On UNIX systems, you can safely pass in a non-socket file descriptor, but + * be aware that this will fail to compile on Windows. + */ bool fdflag_close_exec(int fd, bool flag); -bool fdflag_nonblocking(int fd, bool flag); +bool fdflag_nonblocking(socket_type fd, bool flag); /* Undo default visibility change. */ #pragma GCC visibility pop diff --git a/util/macros.h b/util/macros.h index 084a5a2..54faee5 100644 --- a/util/macros.h +++ b/util/macros.h @@ -1,6 +1,9 @@ /* * Some standard helpful macros. * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Written by Russ Allbery <rra@stanford.edu> * * The authors hereby relinquish any claim to any copyright that they may have @@ -17,6 +20,15 @@ #include <portable/macros.h> +/* + * Used for iterating through arrays. ARRAY_SIZE returns the number of + * elements in the array (useful for a < upper bound in a for loop) and + * ARRAY_END returns a pointer to the element past the end (ISO C99 makes it + * legal to refer to such a pointer as long as it's never dereferenced). + */ +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) +#define ARRAY_END(array) (&(array)[ARRAY_SIZE(array)]) + /* Used for unused parameters to silence gcc warnings. */ #define UNUSED __attribute__((__unused__)) diff --git a/util/messages.c b/util/messages.c index 01038d6..52fcfb7 100644 --- a/util/messages.c +++ b/util/messages.c @@ -50,6 +50,9 @@ * generates given the format and arguments), a format, an argument list as a * va_list, and the applicable errno value (if any). * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Written by Russ Allbery <rra@stanford.edu> * Copyright 2008, 2009, 2010 * The Board of Trustees of the Leland Stanford Junior University @@ -204,8 +207,8 @@ message_log_syslog(int pri, size_t len, const char *fmt, va_list args, int err) buffer = malloc(len + 1); if (buffer == NULL) { - fprintf(stderr, "failed to malloc %u bytes at %s line %d: %s", - len + 1, __FILE__, __LINE__, strerror(errno)); + fprintf(stderr, "failed to malloc %lu bytes at %s line %d: %s", + (unsigned long) len + 1, __FILE__, __LINE__, strerror(errno)); exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1); } vsnprintf(buffer, len + 1, fmt, args); diff --git a/util/messages.h b/util/messages.h index 05dacac..0f8b5b6 100644 --- a/util/messages.h +++ b/util/messages.h @@ -1,6 +1,9 @@ /* * Prototypes for message and error reporting (possibly fatal). * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Copyright 2008, 2010 * The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2004, 2005, 2006 @@ -91,7 +94,7 @@ void message_log_syslog_crit(size_t, const char *, va_list, int) __attribute__((__nonnull__)); /* The type of a message handler. */ -typedef void (*message_handler_func)(size_t, const char *, va_list, int); +typedef void (*message_handler_func)(unsigned int, const char *, va_list, int); /* If non-NULL, called before exit and its return value passed to exit. */ extern int (*message_fatal_cleanup)(void); diff --git a/util/network.c b/util/network.c index 50d7f8d..b88f83b 100644 --- a/util/network.c +++ b/util/network.c @@ -10,6 +10,15 @@ * implementations for functions that aren't found on some pre-IPv6 systems. * No other part of the source tree should have to care about IPv4 vs. IPv6. * + * In this file, casts through void * or const void * of struct sockaddr * + * parameters are to silence gcc warnings with -Wcast-align. The specific + * address types often require stronger alignment than a struct sockaddr, and + * were originally allocated with that alignment. GCC doesn't have a good way + * of knowing that this code is correct. + * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Written by Russ Allbery <rra@stanford.edu> * Copyright 2009, 2011 * The Board of Trustees of the Leland Stanford Junior University @@ -39,7 +48,14 @@ #include <portable/socket.h> #include <errno.h> +#ifdef HAVE_SYS_SELECT_H +# include <sys/select.h> +#endif +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif +#include <util/fdflag.h> #include <util/messages.h> #include <util/network.h> #include <util/xmalloc.h> @@ -218,7 +234,7 @@ network_bind_ipv6(const char *address, unsigned short port) */ #if HAVE_INET6 void -network_bind_all(unsigned short port, int **fds, unsigned int *count) +network_bind_all(unsigned short port, socket_type **fds, unsigned int *count) { struct addrinfo hints, *addrs, *addr; unsigned int size; @@ -245,7 +261,7 @@ network_bind_all(unsigned short port, int **fds, unsigned int *count) * assuming an IPv6 and IPv4 socket, and grow it by two when necessary. */ size = 2; - *fds = xmalloc(size * sizeof(int)); + *fds = xmalloc(size * sizeof(socket_type)); for (addr = addrs; addr != NULL; addr = addr->ai_next) { network_sockaddr_sprint(name, sizeof(name), addr->ai_addr); if (addr->ai_family == AF_INET) @@ -285,6 +301,18 @@ network_bind_all(unsigned short port, socket_type **fds, unsigned int *count) /* + * Free the array of file descriptors allocated by network_bind_all. This is + * a simple wrapper around free, needed on platforms where libraries allocate + * memory from a different memory domain than programs (such as Windows). + */ +void +network_bind_all_free(socket_type *fds) +{ + free(fds); +} + + +/* * Given an array of file descriptors and the length of that array (the same * data that's returned by network_bind_all), wait for an incoming connection * on any of those sockets, accept the connection with accept(), and return @@ -327,7 +355,10 @@ network_accept_any(socket_type fds[], unsigned int count, fd = fds[i]; break; } - return accept(fd, addr, addrlen); + if (fd == INVALID_SOCKET) + return INVALID_SOCKET; + else + return accept(fd, addr, addrlen); } @@ -336,18 +367,18 @@ network_accept_any(socket_type fds[], unsigned int count, * using the provided source address. Returns true on success and false on * failure. */ -static int +static bool network_source(socket_type fd, int family, const char *source) { if (source == NULL || strcmp(source, "all") == 0) - return 1; + return true; if (family == AF_INET) { struct sockaddr_in saddr; memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; if (!inet_aton(source, &saddr.sin_addr)) - return 0; + return false; return bind(fd, (struct sockaddr *) &saddr, sizeof(saddr)) == 0; } #ifdef HAVE_INET6 @@ -357,7 +388,7 @@ network_source(socket_type fd, int family, const char *source) memset(&saddr, 0, sizeof(saddr)); saddr.sin6_family = AF_INET6; if (inet_pton(AF_INET6, source, &saddr.sin6_addr) < 1) - return 0; + return false; return bind(fd, (struct sockaddr *) &saddr, sizeof(saddr)) == 0; } #endif @@ -367,7 +398,7 @@ network_source(socket_type fd, int family, const char *source) #else socket_set_errno(EINVAL); #endif - return 0; + return false; } } @@ -381,13 +412,15 @@ network_source(socket_type fd, int family, const char *source) * errno. */ socket_type -network_connect(struct addrinfo *ai, const char *source) +network_connect(struct addrinfo *ai, const char *source, time_t timeout) { socket_type fd = INVALID_SOCKET; - int oerrno; - int success; + int oerrno, status, err; + socklen_t len; + struct timeval tv; + fd_set set; - for (success = 0; ai != NULL; ai = ai->ai_next) { + for (status = -1; status != 0 && ai != NULL; ai = ai->ai_next) { if (fd != INVALID_SOCKET) socket_close(fd); fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); @@ -395,15 +428,34 @@ network_connect(struct addrinfo *ai, const char *source) continue; if (!network_source(fd, ai->ai_family, source)) continue; - if (connect(fd, ai->ai_addr, ai->ai_addrlen) == 0) { - success = 1; - break; + if (timeout == 0) + status = connect(fd, ai->ai_addr, ai->ai_addrlen); + else { + fdflag_nonblocking(fd, true); + status = connect(fd, ai->ai_addr, ai->ai_addrlen); + if (status < 0 && socket_errno == EINPROGRESS) { + tv.tv_sec = timeout; + tv.tv_usec = 0; + FD_ZERO(&set); + FD_SET(fd, &set); + status = select(fd + 1, NULL, &set, NULL, &tv); + if (status == 0 && !FD_ISSET(fd, &set)) { + status = -1; + socket_set_errno(ETIMEDOUT); + } else if (status > 0 && FD_ISSET(fd, &set)) { + len = sizeof(err); + status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len); + if (status == 0) + status = err; + } + } + fdflag_nonblocking(fd, false); } } - if (success) + if (status == 0) return fd; else { - if (fd >= 0) { + if (fd != INVALID_SOCKET) { oerrno = socket_errno; socket_close(fd); socket_set_errno(oerrno); @@ -421,7 +473,7 @@ network_connect(struct addrinfo *ai, const char *source) */ socket_type network_connect_host(const char *host, unsigned short port, - const char *source) + const char *source, time_t timeout) { struct addrinfo hints, *ai; char portbuf[16]; @@ -434,7 +486,7 @@ network_connect_host(const char *host, unsigned short port, snprintf(portbuf, sizeof(portbuf), "%d", port); if (getaddrinfo(host, portbuf, &hints, &ai) != 0) return INVALID_SOCKET; - fd = network_connect(ai, source); + fd = network_connect(ai, source, timeout); oerrno = socket_errno; freeaddrinfo(ai); socket_set_errno(oerrno); @@ -483,7 +535,7 @@ network_sockaddr_sprint(char *dst, size_t size, const struct sockaddr *addr) if (addr->sa_family == AF_INET6) { const struct sockaddr_in6 *sin6; - sin6 = (const struct sockaddr_in6 *) addr; + sin6 = (const struct sockaddr_in6 *) (const void *) addr; if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { struct in_addr in; @@ -497,7 +549,7 @@ network_sockaddr_sprint(char *dst, size_t size, const struct sockaddr *addr) if (addr->sa_family == AF_INET) { const struct sockaddr_in *sin; - sin = (const struct sockaddr_in *) addr; + sin = (const struct sockaddr_in *) (const void *) addr; result = inet_ntop(AF_INET, &sin->sin_addr, dst, size); return (result != NULL); } else { @@ -515,20 +567,26 @@ network_sockaddr_sprint(char *dst, size_t size, const struct sockaddr *addr) bool network_sockaddr_equal(const struct sockaddr *a, const struct sockaddr *b) { - const struct sockaddr_in *a4 = (const struct sockaddr_in *) a; - const struct sockaddr_in *b4 = (const struct sockaddr_in *) b; - + const struct sockaddr_in *a4; + const struct sockaddr_in *b4; #ifdef HAVE_INET6 - const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) a; - const struct sockaddr_in6 *b6 = (const struct sockaddr_in6 *) b; + const struct sockaddr_in6 *a6; + const struct sockaddr_in6 *b6; const struct sockaddr *tmp; +#endif + + a4 = (const struct sockaddr_in *) (const void *) a; + b4 = (const struct sockaddr_in *) (const void *) b; +#ifdef HAVE_INET6 + a6 = (const struct sockaddr_in6 *) (const void *) a; + b6 = (const struct sockaddr_in6 *) (const void *) b; if (a->sa_family == AF_INET && b->sa_family == AF_INET6) { tmp = a; a = b; b = tmp; - a6 = (const struct sockaddr_in6 *) a; - b4 = (const struct sockaddr_in *) b; + a6 = (const struct sockaddr_in6 *) (const void *) a; + b4 = (const struct sockaddr_in *) (const void *) b; } if (a->sa_family == AF_INET6) { if (b->sa_family == AF_INET6) @@ -564,14 +622,14 @@ network_sockaddr_port(const struct sockaddr *sa) const struct sockaddr_in6 *sin6; if (sa->sa_family == AF_INET6) { - sin6 = (const struct sockaddr_in6 *) sa; + sin6 = (const struct sockaddr_in6 *) (const void *) sa; return htons(sin6->sin6_port); } #endif if (sa->sa_family != AF_INET) return 0; else { - sin = (const struct sockaddr_in *) sa; + sin = (const struct sockaddr_in *) (const void *) sa; return htons(sin->sin_port); } } diff --git a/util/network.h b/util/network.h index d528a1a..5c4d981 100644 --- a/util/network.h +++ b/util/network.h @@ -1,6 +1,9 @@ /* * Prototypes for network connection utility functions. * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Written by Russ Allbery <rra@stanford.edu> * Copyright 2009, 2010, 2011 * The Board of Trustees of the Leland Stanford Junior University @@ -56,11 +59,13 @@ socket_type network_bind_ipv6(const char *address, unsigned short port) * and one for IPv6, if IPv6 support is enabled). If IPv6 is not enabled, * just one socket will be created and bound to the IPv4 wildcard address. * fds will be set to an array containing the resulting file descriptors, with - * count holding the count returned. + * count holding the count returned. Use network_bind_all_free to free the + * array of file descriptors when no longer needed. */ void network_bind_all(unsigned short port, socket_type **fds, unsigned int *count) __attribute__((__nonnull__)); +void network_bind_all_free(socket_type *fds); /* * Accept an incoming connection from any file descriptor in an array. This @@ -78,9 +83,9 @@ socket_type network_accept_any(socket_type fds[], unsigned int count, * Create a socket and connect it to the remote service given by the linked * list of addrinfo structs. Returns the new file descriptor on success and * -1 on failure, with the error left in errno. Takes an optional source - * address. + * address and a timeout in seconds, which may be 0 for no timeout. */ -socket_type network_connect(struct addrinfo *, const char *source) +socket_type network_connect(struct addrinfo *, const char *source, time_t) __attribute__((__nonnull__(1))); /* @@ -88,7 +93,7 @@ socket_type network_connect(struct addrinfo *, const char *source) * fails, errno may not be set to anything useful. */ socket_type network_connect_host(const char *host, unsigned short port, - const char *source) + const char *source, time_t) __attribute__((__nonnull__(1))); /* diff --git a/util/vector.c b/util/vector.c index 5138438..285969c 100644 --- a/util/vector.c +++ b/util/vector.c @@ -20,6 +20,9 @@ * and perform the same operations, but I'm leery of doing that as I'm not * sure if it's a violation of the C type aliasing rules. * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Written by Russ Allbery <rra@stanford.edu> * * The authors hereby relinquish any claim to any copyright that they may have @@ -345,7 +348,7 @@ vector_split_multi(const char *string, const char *seps, if (vector->allocated < count) vector_resize(vector, count); - for (start = string, p = string, i = 0; *p; p++) + for (start = string, p = string, i = 0; *p != '\0'; p++) if (strchr(seps, *p) != NULL) { if (start != p) vector->strings[i++] = xstrndup(start, p - start); @@ -378,7 +381,7 @@ cvector_split_multi(char *string, const char *seps, struct cvector *vector) if (vector->allocated < count) cvector_resize(vector, count); - for (start = string, p = string, i = 0; *p; p++) + for (start = string, p = string, i = 0; *p != '\0'; p++) if (strchr(seps, *p) != NULL) { if (start != p) { *p = '\0'; @@ -438,7 +441,7 @@ vector_split_space(const char *string, struct vector *vector) if (vector->allocated < count) vector_resize(vector, count); - for (start = string, p = string, i = 0; *p; p++) + for (start = string, p = string, i = 0; *p != '\0'; p++) if (*p == ' ' || *p == '\t') { if (start != p) vector->strings[i++] = xstrndup(start, p - start); @@ -470,7 +473,7 @@ cvector_split_space(char *string, struct cvector *vector) if (vector->allocated < count) cvector_resize(vector, count); - for (start = string, p = string, i = 0; *p; p++) + for (start = string, p = string, i = 0; *p != '\0'; p++) if (*p == ' ' || *p == '\t') { if (start != p) { *p = '\0'; diff --git a/util/vector.h b/util/vector.h index ac3bf18..6a872d3 100644 --- a/util/vector.h +++ b/util/vector.h @@ -8,6 +8,9 @@ * Vectors require list of strings, not arbitrary binary data, and cannot * handle data elements containing nul characters. * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Written by Russ Allbery <rra@stanford.edu> * * The authors hereby relinquish any claim to any copyright that they may have @@ -97,7 +100,9 @@ void cvector_free(struct cvector *) * Empty strings will yield zero-length vectors. Adjacent delimiters are * treated as a single delimiter by *_split_space and *_split_multi, but *not* * by *_split, so callers of *_split should be prepared for zero-length - * strings in the vector. + * strings in the vector. *_split_space and *_split_multi ignore any leading + * or trailing delimiters, so those functions will never create zero-length + * strings (similar to the behavior of strtok). */ struct vector *vector_split(const char *string, char sep, struct vector *) __attribute__((__nonnull__(1))); diff --git a/util/xmalloc.c b/util/xmalloc.c index 0803999..839f5a0 100644 --- a/util/xmalloc.c +++ b/util/xmalloc.c @@ -55,6 +55,9 @@ * header file defines macros named xmalloc, etc. that pass the file name and * line number to these functions. * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Copyright (c) 2004, 2005, 2006 * by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, diff --git a/util/xmalloc.h b/util/xmalloc.h index 5447335..14d8831 100644 --- a/util/xmalloc.h +++ b/util/xmalloc.h @@ -1,6 +1,9 @@ /* * Prototypes for malloc routines with failure handling. * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Copyright 2010 * The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2004, 2005, 2006 diff --git a/util/xwrite.c b/util/xwrite.c index 7e27654..8d472a7 100644 --- a/util/xwrite.c +++ b/util/xwrite.c @@ -21,6 +21,9 @@ * written, on the subsequent additional write; in that case, these functions * will return -1 and the number of bytes actually written will be lost. * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Copyright 2008 * The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2004, 2005, 2006 diff --git a/util/xwrite.h b/util/xwrite.h index d79e801..2822727 100644 --- a/util/xwrite.h +++ b/util/xwrite.h @@ -1,6 +1,9 @@ /* * Prototypes for write and writev replacements to handle partial writes. * + * The canonical version of this file is maintained in the rra-c-util package, + * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. + * * Copyright 2008, 2010 * The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2004, 2005, 2006 |