diff options
author | Guy Harris <guy@alum.mit.edu> | 2018-03-18 15:53:34 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2018-03-18 15:53:46 -0700 |
commit | f2974e1fc0e4c7499f0c4e241cc3263a1e808597 (patch) | |
tree | 88edb40e0ac78c9d42a834f9a392791152b61989 | |
parent | 55225fde23eb409d04eda00a453c0529d5afbb20 (diff) | |
download | libpcap-f2974e1fc0e4c7499f0c4e241cc3263a1e808597.tar.gz |
Make the size argument to sock_send() a size_t.
The equivalent argument to sock_recv() is a size_t; make sock_send()
more like sock_recv(), for consistency.
-rw-r--r-- | sockutils.c | 117 | ||||
-rw-r--r-- | sockutils.h | 3 |
2 files changed, 72 insertions, 48 deletions
diff --git a/sockutils.c b/sockutils.c index cefc34c6..12a4f5f1 100644 --- a/sockutils.c +++ b/sockutils.c @@ -90,6 +90,24 @@ #define SOCKET_NO_PORT_AVAILABLE "No port available" #define SOCKET_NAME_NULL_DAD "Null address (possibly DAD Phase)" +/* + * On UN*X, send() and recv() return ssize_t. + * + * On Windows, send() and recv() return an int. + * + * Wth MSVC, there *is* no ssize_t. + * + * With MinGW, there is an ssize_t type; it is either an int (32 bit) + * or a long long (64 bit). + * + * So, on Windows, if we don't have ssize_t defined, define it as an + * int, so we can use it, on all platforms, as the type of variables + * that hold the return values from send() and recv(). + */ +#if defined(_WIN32) && !defined(_SSIZE_T_DEFINED) +typedef int ssize_t; +#endif + /**************************************************** * * * Locally defined functions * @@ -605,53 +623,65 @@ int sock_initaddress(const char *host, const char *port, * "connection reset" occurred, '-2' if "connection reset" occurred. * For errors, an error message is returned in the 'errbuf' variable. */ -int sock_send(SOCKET sock, const char *buffer, int size, char *errbuf, int errbuflen) +int sock_send(SOCKET sock, const char *buffer, size_t size, + char *errbuf, int errbuflen) { - int nsent; + int remaining; + ssize_t nsent; -send: + if (size > INT_MAX) + { + if (errbuf) + { + pcap_snprintf(errbuf, errbuflen, + "Can't send more than %u bytes with sock_recv", + INT_MAX); + } + return -1; + } + remaining = (int)size; + + do { #ifdef linux - /* - * Another pain... in Linux there's this flag - * MSG_NOSIGNAL - * Requests not to send SIGPIPE on errors on stream-oriented - * sockets when the other end breaks the connection. - * The EPIPE error is still returned. - */ - nsent = send(sock, buffer, size, MSG_NOSIGNAL); + /* + * Another pain... in Linux there's this flag + * MSG_NOSIGNAL + * Requests not to send SIGPIPE on errors on stream-oriented + * sockets when the other end breaks the connection. + * The EPIPE error is still returned. + */ + nsent = send(sock, buffer, remaining, MSG_NOSIGNAL); #else - nsent = send(sock, buffer, size, 0); + nsent = send(sock, buffer, remaining, 0); #endif - if (nsent == -1) - { - /* - * If the client closed the connection out from under us, - * there's no need to log that as an error. - */ - int errcode; + if (nsent == -1) + { + /* + * If the client closed the connection out from + * under us, there's no need to log that as an + * error. + */ + int errcode; #ifdef _WIN32 - errcode = GetLastError(); + errcode = GetLastError(); - sock_fmterror("send(): ", errcode, errbuf, errbuflen); - if (errcode == WSAECONNRESET) - return -2; + sock_fmterror("send(): ", errcode, errbuf, errbuflen); + if (errcode == WSAECONNRESET) + return -2; #else - errcode = errno; - sock_fmterror("send(): ", errcode, errbuf, errbuflen); - if (errcode == ECONNRESET) - return -2; + errcode = errno; + sock_fmterror("send(): ", errcode, errbuf, errbuflen); + if (errcode == ECONNRESET) + return -2; #endif - return -1; - } + return -1; + } - if (nsent != size) - { - size -= nsent; + remaining -= nsent; buffer += nsent; - goto send; - } + } while (remaining != 0); return 0; } @@ -774,18 +804,6 @@ int sock_bufferize(const char *buffer, int size, char *tempbuf, int *offset, int * The error message is returned in the 'errbuf' variable. */ -/* - * On UN*X, recv() returns ssize_t. - * On MSVC, there *is* no ssize_t, and it returns an int. - * MinGW has ssize_t. It and returns either an int (32 bit) - * or a long long (64 bit). - * Define ssize_t as int only on MSVC and on those that don't define - * _SSIZE_T_DEFINED so we can use it as the return value from recv(). - */ -#if defined(_WIN32) && !defined(_SSIZE_T_DEFINED) -typedef int ssize_t; -#endif - int sock_recv(SOCKET sock, void *buffer, size_t size, int flags, char *errbuf, int errbuflen) { @@ -977,7 +995,12 @@ int sock_recv_dgram(SOCKET sock, void *buffer, size_t size, } #endif /* HAVE_STRUCT_MSGHDR_MSG_FLAGS */ #endif /* _WIN32 */ - return nread; + + /* + * The size we're reading fits in an int, so the return value + * will fit in an int. + */ + return (int)nread; } /* diff --git a/sockutils.h b/sockutils.h index ec7b449a..95dfb461 100644 --- a/sockutils.h +++ b/sockutils.h @@ -208,7 +208,8 @@ int sock_recv_dgram(SOCKET sock, void *buffer, size_t size, SOCKET sock_open(struct addrinfo *addrinfo, int server, int nconn, char *errbuf, int errbuflen); int sock_close(SOCKET sock, char *errbuf, int errbuflen); -int sock_send(SOCKET sock, const char *buffer, int size, char *errbuf, int errbuflen); +int sock_send(SOCKET sock, const char *buffer, size_t size, + char *errbuf, int errbuflen); int sock_bufferize(const char *buffer, int size, char *tempbuf, int *offset, int totsize, int checkonly, char *errbuf, int errbuflen); int sock_discard(SOCKET sock, int size, char *errbuf, int errbuflen); int sock_check_hostlist(char *hostlist, const char *sep, struct sockaddr_storage *from, char *errbuf, int errbuflen); |