[Assorted-commits] SF.net SVN: assorted:[1493] cpp-commons/trunk/src/commons
Brought to you by:
yangzhang
From: <yan...@us...> - 2009-10-15 08:26:20
|
Revision: 1493 http://assorted.svn.sourceforge.net/assorted/?rev=1493&view=rev Author: yangzhang Date: 2009-10-15 08:26:09 +0000 (Thu, 15 Oct 2009) Log Message: ----------- added windows support; added addr2name, name2addr, checkptr Modified Paths: -------------- cpp-commons/trunk/src/commons/check.h cpp-commons/trunk/src/commons/closing.h cpp-commons/trunk/src/commons/die.h cpp-commons/trunk/src/commons/sockets.h Added Paths: ----------- cpp-commons/trunk/src/commons/win.h Modified: cpp-commons/trunk/src/commons/check.h =================================================================== --- cpp-commons/trunk/src/commons/check.h 2009-10-14 18:10:19 UTC (rev 1492) +++ cpp-commons/trunk/src/commons/check.h 2009-10-15 08:26:09 UTC (rev 1493) @@ -5,6 +5,10 @@ #include <sstream> #include <string> #include <commons/die.h> +#include <commons/utility.h> +#include <commons/win.h> +#include <commons/nullptr.h> +#include <boost/noncopyable.hpp> #include <boost/lexical_cast.hpp> // TODO: rename: @@ -28,6 +32,13 @@ namespace commons { +#ifdef WIN32 +#define wvsnprintf(buf, len, fmt, args) \ + { USE(buf); USE(len); USE(fmt); USE(args); } +// TODO get this to build! +// #define vsnprintf(buf, len, fmt, args) vsnprintf_s(buf, len, _TRUNCATE, fmt, args) +#endif + enum { buflen = 4096 }; // TODO: deal with va args @@ -44,7 +55,7 @@ virtual ~check_exception() throw() {} virtual const char *what() const throw() { return name.c_str(); } private: - const string name; + string name; }; __attribute__((format(printf, 4, 0))) inline static void @@ -85,6 +96,13 @@ } template<typename T> inline T + _checkptr(T x, const char *file, int line) + { + _check(x != nullptr, file, line); + return x; + } + + template<typename T> inline T _checknneg(T x, const char *file, int line) { if (x < 0) { @@ -177,8 +195,10 @@ * use as a guard against expected failures (such as checking return codes). * This is a macro for two reasons: (1) the file and line, and (2) the lazy * evaluation of msg. + * + * check(result, "bad result %d", result) */ -#define check(cond, msg...) _check(cond, __FILE__, __LINE__, ## msg) +#define check(cond, ...) commons::_check(cond, __FILE__, __LINE__, ## __VA_ARGS__) /** * Same as check(), but additionally returns the value that was passed in. The @@ -187,53 +207,58 @@ * return value is non-zero or not false). This is suitable for small, * copyable pieces of data, such as integers, file descriptors, pointers, etc. */ -#define checkpass(expr, msg...) _checkpass(expr, __FILE__, __LINE__, ## msg) +#define checkpass(expr, ...) commons::_checkpass(expr, __FILE__, __LINE__, ## __VA_ARGS__) /** + * Check that a pointer is not NULL. + */ +#define checkptr(expr, ...) commons::_checkptr(expr, __FILE__, __LINE__, ## __VA_ARGS__) + +/** * Same as checkpass(), but includes the strerror message in the exception. */ -#define checkerr(expr) _checkerr(expr, __FILE__, __LINE__) +#define checkerr(expr) commons::_checkerr(expr, __FILE__, __LINE__) /** * Checks that the value is non-negative. */ -#define checknneg(expr, msg...) _checknneg(expr, __FILE__, __LINE__, ## msg) +#define checknneg(expr, ...) commons::_checknneg(expr, __FILE__, __LINE__, ## __VA_ARGS__) /** * Same as checknneg, but include the strerror in the exception. */ -#define checknnegerr(expr) _checknnegerr(expr, __FILE__, __LINE__) +#define checknnegerr(expr) commons::_checknnegerr(expr, __FILE__, __LINE__) /** * Checks that the value is 0. Same as check0(), but throws an error rather * than return. Also clears the errno on error. The resulting exception * includes the strerror(). */ -#define check0x(expr, msg...) _check0(expr, __FILE__, __LINE__, ## msg) +#define check0x(expr, ...) commons::_check0(expr, __FILE__, __LINE__, ## __VA_ARGS__) /** * Checks that the values are not equal. The exception will include both * values, as formatted by ostream <<. */ -#define checkneq(l, r, msg...) _checkneq(l, r, __FILE__, __LINE__, ## msg) +#define checkneq(l, r, ...) commons::_checkneq(l, r, __FILE__, __LINE__, ## __VA_ARGS__) /** * Checks that the values are equal. The exception will include both values, * as formatted by ostream <<. */ -#define checkeq(l, r, msg...) _checkeq(l, r, __FILE__, __LINE__, ## msg) +#define checkeq(l, r, ...) commons::_checkeq(l, r, __FILE__, __LINE__, ## __VA_ARGS__) /** * Like checkeq, but if the left value is negative, then interpret that as a * sign of error, and include the errorstr in the exception message. */ -#define checkeqnneg(l, r, msg...) \ - _checkeqnneg(l, r, __FILE__, __LINE__, ## msg) +#define checkeqnneg(l, r, ...) \ + commons::_checkeqnneg(l, r, __FILE__, __LINE__, ## __VA_ARGS__) #if 0 #define checkmsg(cond, msg) \ bool b__ = cond; \ - if (!b__) _check(b__, (msg), __FILE__, __LINE__) + if (!b__) commons::_check(b__, (msg), __FILE__, __LINE__) #define checkmsgf(cond, msg...) \ do { \ @@ -241,7 +266,7 @@ if (!b__) { \ char s__[4096]; \ snprintf(s, msg); \ - _check(b__, s__, __FILE__, __LINE__); \ + commons::_check(b__, s__, __FILE__, __LINE__); \ } \ } while (0) #endif @@ -261,10 +286,10 @@ /** * Checks that the value is true or non-zero, otherwise dies (calls die()). */ -#define checkdie(expr, msg...) \ +#define checkdie(expr, ...) \ do { \ if (!expr) { \ - die(msg); \ + die(__VA_ARGS__); \ } \ } while (0) Modified: cpp-commons/trunk/src/commons/closing.h =================================================================== --- cpp-commons/trunk/src/commons/closing.h 2009-10-14 18:10:19 UTC (rev 1492) +++ cpp-commons/trunk/src/commons/closing.h 2009-10-15 08:26:09 UTC (rev 1493) @@ -4,15 +4,18 @@ #include <boost/utility.hpp> #include <commons/check.h> #include <commons/utility.h> +#include <commons/win.h> +#include <cstdio> namespace commons { using namespace boost; + using namespace std; // void checked_close(int &fd) { check0x(close(fd)); } - struct fd_closer { static void apply(int fd) { check0x(close(fd)); } }; + struct fd_closer { static void apply(fd_t fd) { check0x(close(fd)); } }; template<typename T, typename Closer> class closing @@ -29,7 +32,7 @@ bool scoped; }; - typedef closing<int, fd_closer> closingfd; + typedef closing<fd_t, fd_closer> closingfd; } Modified: cpp-commons/trunk/src/commons/die.h =================================================================== --- cpp-commons/trunk/src/commons/die.h 2009-10-14 18:10:19 UTC (rev 1492) +++ cpp-commons/trunk/src/commons/die.h 2009-10-15 08:26:09 UTC (rev 1493) @@ -1,6 +1,7 @@ #ifndef COMMONS_DIE_H #define COMMONS_DIE_H +#include <commons/win.h> #include <cerrno> #include <cstdio> #include <cstdarg> @@ -15,6 +16,8 @@ * * TODO: move into C Commons. */ +//#pragma warning(push) TODO why doesn't this work? +#pragma warning(disable: 4505) __attribute__((format(printf, 1, 2),unused)) static void die(const char *format, ...) { @@ -27,6 +30,7 @@ fprintf(stderr, ": %s\n", errstr); exit(1); } +//#pragma warning(pop) } Modified: cpp-commons/trunk/src/commons/sockets.h =================================================================== --- cpp-commons/trunk/src/commons/sockets.h 2009-10-14 18:10:19 UTC (rev 1492) +++ cpp-commons/trunk/src/commons/sockets.h 2009-10-15 08:26:09 UTC (rev 1493) @@ -1,6 +1,9 @@ #ifndef COMMONS_SOCKETS_H #define COMMONS_SOCKETS_H +#ifdef WIN32 +#include <winsock2.h> +#else #include <arpa/inet.h> #include <netdb.h> #include <netinet/in.h> @@ -9,6 +12,7 @@ #include <sys/types.h> #include <fcntl.h> #include <unistd.h> +#endif #include <commons/check.h> #include <commons/closing.h> @@ -17,6 +21,19 @@ namespace commons { +#ifdef WIN32 + typedef SOCKET socket_t; + + int inet_aton(const char *cp, struct in_addr *inp) { + uint32_t a = inet_addr(cp); + if (a == INADDR_NONE) return 0; + inp->S_un.S_addr = a; + return 1; + } +#else + typedef fd_t socket_t; +#endif + /** * Work-around for the -Wold-style-cast-unsafe FD_* macros (see select(2)). */ @@ -26,26 +43,35 @@ /** * Work-around for the -Wold-style-cast-unsafe INADDR_ANY */ +#ifndef WIN32 const in_addr_t inaddr_any = in_addr_t(0); +#else +#define inaddr_any INADDR_ANY +#endif /** * Make a TCP socket non-blocking. */ - inline int - set_non_blocking(int fd) + inline socket_t + set_non_blocking(socket_t fd) { +#ifndef WIN32 checknnegerr(fcntl(fd, F_SETFL, O_NONBLOCK | checknnegerr(fcntl(fd, F_GETFL, 0)))); +#else + unsigned long one = 1; + checknnegerr(ioctlsocket(fd, FIONBIO, &one)); +#endif return fd; } /** * Create a TCP socket. */ - inline int + inline socket_t tcp_socket(bool nb) { - int fd = checknnegerr(socket(PF_INET, SOCK_STREAM, 0)); + socket_t fd = checknnegerr(socket(PF_INET, SOCK_STREAM, 0)); // Make our socket non-blocking if desired. if (nb) set_non_blocking(fd); return fd; @@ -84,7 +110,7 @@ // First try to interpret host as a dot-notation string. if (!inet_aton(host, reinterpret_cast<in_addr*>(&a.sin_addr.s_addr))) { // Now try to resolve the hostname. - hostent *res = checkpass(gethostbyname(host)); + hostent *res = checkptr(gethostbyname(host)); memcpy(&a.sin_addr, res->h_addr_list[0], res->h_length); } } @@ -101,6 +127,16 @@ } /** + * Initialize an inet addres. + */ + inline void + sockaddr_init(sockaddr_in &a, uint32_t host, uint16_t port) + { + sockaddr_init(a, port); + a.sin_addr.s_addr = host; + } + + /** * Construct an inet address. */ template <typename T> @@ -112,18 +148,28 @@ return a; } + void close_socket(socket_t s) { +#ifdef WIN32 + closesocket(s); +#else + close(s); +#endif + } + struct socket_closer { static void apply(socket_t s) { close_socket(s); } }; + typedef closing<socket_t, socket_closer> closing_socket; + /** * Create a server socket bound to localhost, with SO_REUSEADDR enabled. * \param[in] port The port to listen on. * \param[in] nb Whether the socket should be non-blocking. * \return The server socket. */ - UNUSED static int + UNUSED static socket_t server_socket(uint16_t port, bool nb = false) { // Create the socket. - closingfd c(tcp_socket(nb)); - int fd = c.get(); + closing_socket c(tcp_socket(nb)); + socket_t fd = c.get(); // Configure the socket. int n = 1; @@ -145,17 +191,17 @@ * \param[in] nb Whether the socket should be non-blocking. * \return The listener socket. */ - UNUSED static int + UNUSED static socket_t tcp_listen(uint16_t port, bool nb = false) { - int fd = server_socket(port, nb); + socket_t fd = server_socket(port, nb); try { // SOMAXCONN is the kernel's limit on the maximum number of socket // connections. check0x(listen(fd, SOMAXCONN)); return fd; } catch (...) { - close(fd); + close_socket(fd); throw; } } @@ -163,15 +209,61 @@ /** * Connect to a TCP socket. */ - UNUSED static int - tcp_connect(const char *host, uint16_t port) + template<typename T> + UNUSED static socket_t + tcp_connect(T host, uint16_t port) { - closingfd c(tcp_socket(false)); + closing_socket c(tcp_socket(false)); sockaddr_in a = make_sockaddr(host, port); check0x(connect(c.get(), reinterpret_cast<sockaddr*>(&a), sizeof a)); return c.release(); } +#if defined(WIN32) && defined(UNICODE) +#define getnameinfo GetNameInfoW +#define getaddrinfo GetAddrInfoW +#define addrinfo ADDRINFOW +#define freeaddrinfo FreeAddrInfoW +#endif + + /** + * T is a string or wstring. + */ + template<typename T> + sockaddr_in + addr2name(const sockaddr_in sa) + { + enum { sz = 1024 }; + wchar_t buf[sz]; + check0x(getnameinfo(reinterpret_cast<const sockaddr*>(&sa), sizeof sa, + buf, sz, // output hostname + nullptr, 0, // service + 0)); // flags + return sa; + } + + /** + * Get IPv4 address for hostname. T is a string or wstring. + */ + template<typename T> + in_addr + name2addr(const T *name) + { + addrinfo *ai, hints = {0}; + in_addr addr; + hints.ai_family = AF_INET; // use AF_UNSPEC for "any" + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + check0x(getaddrinfo(name, // hostname + L"1", // service + &hints, // flags + &ai)); // output addrinfo + // just take the first one; ignore everything but in_addr + addr = reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr; + freeaddrinfo(ai); + return addr; + } + } #endif Added: cpp-commons/trunk/src/commons/win.h =================================================================== --- cpp-commons/trunk/src/commons/win.h (rev 0) +++ cpp-commons/trunk/src/commons/win.h 2009-10-15 08:26:09 UTC (rev 1493) @@ -0,0 +1,17 @@ +#ifndef COMMONS_WIN_H +#define COMMONS_WIN_H + +#ifdef WIN32 +# define NONWIN(x) +# define __attribute__(x) +typedef HANDLE fd_t; +int close(fd_t fd) { return CloseHandle(fd) ? 0 : -1; } +typedef UINT16 uint16_t; +typedef UINT32 uint32_t; +void bzero(void *s, size_t n) { memset(s, 0, n); } +#else +# define NONWIN(x) x +typedef int fd_t; +#endif + +#endif Property changes on: cpp-commons/trunk/src/commons/win.h ___________________________________________________________________ Added: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |