aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorB. Scott Michel <scooter.phd@gmail.com>2024-09-16 09:14:32 -0700
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2024-09-26 03:04:25 +0200
commit72f85005a2307fd0961543e3cea861ad7a4d201e (patch)
treeaaea4bf5c09fd87901712517113ff624f4cc44f4 /src
parent5e97a93bf0599037de37d45c33d4cdb902a5264e (diff)
downloadslirp-72f85005a2307fd0961543e3cea861ad7a4d201e.zip
slirp-72f85005a2307fd0961543e3cea861ad7a4d201e.tar.gz
slirp-72f85005a2307fd0961543e3cea861ad7a4d201e.tar.bz2
socket abstraction: slirp_os_socket
Use a typedef to abstract socket identifiers because Windows just has to be different (SOCKET type.) Moreover, SOCKET on Win64 is 64-bits and generates copious type slicing warnings. Other related changes: - Explicitly cast curtime's assignment to unsigned int to tamp down on type slicing warning. - Ensure that errno.h is always included. Important for Windows, which would otherwise #define errno as WSAGetLastError(); errno.h #define-s errno as a function, i.e., "*errno()". - Export slirp_inet_aton() utility function for Win32/64. - tcpx_listen() - WSASetLastError() unnecessary. - Use have_valid_socket() to check socket in error cleanup code (vs. "s >= 0").
Diffstat (limited to 'src')
-rw-r--r--src/ip6_icmp.c4
-rw-r--r--src/ip_icmp.c8
-rw-r--r--src/libslirp.h40
-rw-r--r--src/misc.c38
-rw-r--r--src/slirp.c14
-rw-r--r--src/slirp.h19
-rw-r--r--src/socket.c30
-rw-r--r--src/socket.h9
-rw-r--r--src/tcp_subr.c27
-rw-r--r--src/tftp.c13
-rw-r--r--src/udp.c18
-rw-r--r--src/udp.h10
-rw-r--r--src/udp6.c8
-rw-r--r--src/util.c106
-rw-r--r--src/util.h84
15 files changed, 266 insertions, 162 deletions
diff --git a/src/ip6_icmp.c b/src/ip6_icmp.c
index 3a5878f..2f48362 100644
--- a/src/ip6_icmp.c
+++ b/src/ip6_icmp.c
@@ -62,7 +62,7 @@ static int icmp6_send(struct socket *so, struct mbuf *m, int hlen)
#endif
so->s = slirp_socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6);
- if (so->s == -1) {
+ if (not_valid_socket(so->s)) {
if (errno == EAFNOSUPPORT
|| errno == EPROTONOSUPPORT
|| errno == EACCES) {
@@ -71,7 +71,7 @@ static int icmp6_send(struct socket *so, struct mbuf *m, int hlen)
so->s = slirp_socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
}
}
- if (so->s == -1) {
+ if (not_valid_socket(so->s)) {
return -1;
}
so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque);
diff --git a/src/ip_icmp.c b/src/ip_icmp.c
index 74524fd..b6b0fab 100644
--- a/src/ip_icmp.c
+++ b/src/ip_icmp.c
@@ -110,7 +110,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
#endif
so->s = slirp_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
- if (so->s == -1) {
+ if (not_valid_socket(so->s)) {
if (errno == EAFNOSUPPORT
|| errno == EPROTONOSUPPORT
|| errno == EACCES) {
@@ -119,7 +119,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
so->s = slirp_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
}
}
- if (so->s == -1) {
+ if (not_valid_socket(so->s)) {
return -1;
}
so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque);
@@ -127,7 +127,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
if (slirp_bind_outbound(so, AF_INET) != 0) {
// bind failed - close socket
closesocket(so->s);
- so->s = -1;
+ so->s = SLIRP_INVALID_SOCKET;
return -1;
}
@@ -222,7 +222,7 @@ void icmp_input(struct mbuf *m, int hlen)
/* We could not send this as ICMP, try to send it on UDP echo
* service (7), wishfully hoping that it is open there. */
- if (udp_attach(so, AF_INET) == -1) {
+ if (not_valid_socket(udp_attach(so, AF_INET))) {
DEBUG_MISC("icmp_input udp_attach errno = %d-%s", errno,
strerror(errno));
sofree(so);
diff --git a/src/libslirp.h b/src/libslirp.h
index d36c601..4a68cc4 100644
--- a/src/libslirp.h
+++ b/src/libslirp.h
@@ -8,9 +8,12 @@
#ifdef _WIN32
#include <winsock2.h>
+#include <windows.h>
#include <ws2tcpip.h>
#include <in6addr.h>
#include <basetsd.h>
+#include <errno.h>
+
typedef SSIZE_T slirp_ssize_t;
#ifdef LIBSLIRP_STATIC
# define SLIRP_EXPORT
@@ -33,6 +36,28 @@ typedef ssize_t slirp_ssize_t;
extern "C" {
#endif
+/* Socket abstraction:*/
+
+#if !defined(_WIN32)
+/* Traditional Unix socket. */
+typedef int slirp_os_socket;
+#define SLIRP_INVALID_SOCKET (-1)
+#define SLIRP_PRIfd "d"
+#else
+/* Windows: Win64 is a LLP64 platform, sizeof(int) < sizeof(long long) == sizeof(void *).
+ *
+ * Windows likes to pass HANDLE types around, which are pointers (aka unsigned long longs),
+ * which cannot be represented as ints. And, MS, in its infinite wisdom, decided to use
+ * a SOCKET handle instead of an int for socket library calls. */
+typedef SOCKET slirp_os_socket;
+#define SLIRP_INVALID_SOCKET INVALID_SOCKET
+#if defined(_WIN64)
+# define SLIRP_PRIfd "llx"
+#else
+# define SLIRP_PRIfd "x"
+#endif
+#endif
+
/* Opaque structure containing the slirp state */
typedef struct Slirp Slirp;
@@ -52,7 +77,7 @@ typedef slirp_ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque)
/* Timer callback */
typedef void (*SlirpTimerCb)(void *opaque);
/* Callback for libslirp to register polling callbacks */
-typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque);
+typedef int (*SlirpAddPollCb)(slirp_os_socket fd, int events, void *opaque);
/* Callback for libslirp to get polling result */
typedef int (*SlirpGetREventsCb)(int idx, void *opaque);
@@ -89,9 +114,9 @@ typedef struct SlirpCb {
/* Modify a timer to expire at @expire_time (ms) */
void (*timer_mod)(void *timer, int64_t expire_time, void *opaque);
/* Register a fd for future polling */
- void (*register_poll_fd)(int fd, void *opaque);
+ void (*register_poll_fd)(slirp_os_socket fd, void *opaque);
/* Unregister a fd */
- void (*unregister_poll_fd)(int fd, void *opaque);
+ void (*unregister_poll_fd)(slirp_os_socket fd, void *opaque);
/* Kick the io-thread, to signal that new events may be processed because some TCP buffer
* can now receive more data, i.e. slirp_socket_can_recv will return 1. */
void (*notify)(void *opaque);
@@ -337,6 +362,15 @@ int slirp_state_load(Slirp *s, int version_id, SlirpReadCb read_cb,
SLIRP_EXPORT
const char *slirp_version_string(void);
+#if defined(_WIN32)
+/* Windows utility functions: */
+
+/* inet_aton() replacement that uses inet_pton(). Eliminates the dreaded
+ * winsock2 deprecation messages. */
+SLIRP_EXPORT
+int slirp_inet_aton(const char *cp, struct in_addr *ia);
+#endif
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/src/misc.c b/src/misc.c
index 3c25835..5736816 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -77,7 +77,7 @@ int remove_guestfwd(struct gfwd_list **ex_ptr, struct in_addr addr, int port)
return -1;
}
-static int slirp_socketpair_with_oob(int sv[2])
+static int slirp_socketpair_with_oob(slirp_os_socket sv[2])
{
struct sockaddr_in addr = {
.sin_family = AF_INET,
@@ -85,18 +85,19 @@ static int slirp_socketpair_with_oob(int sv[2])
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
};
socklen_t addrlen = sizeof(addr);
- int ret, s;
+ int ret;
+ slirp_os_socket s;
- sv[1] = -1;
+ sv[1] = SLIRP_INVALID_SOCKET;
s = slirp_socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0 || bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
+ if (not_valid_socket(s) || bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
listen(s, 1) < 0 ||
getsockname(s, (struct sockaddr *)&addr, &addrlen) < 0) {
goto err;
}
sv[1] = slirp_socket(AF_INET, SOCK_STREAM, 0);
- if (sv[1] < 0) {
+ if (not_valid_socket(sv[1])) {
goto err;
}
/*
@@ -123,7 +124,7 @@ static int slirp_socketpair_with_oob(int sv[2])
err:
g_critical("slirp_socketpair(): %s", strerror(errno));
- if (s >= 0) {
+ if (have_valid_socket(s)) {
closesocket(s);
}
if (sv[1] >= 0) {
@@ -144,6 +145,10 @@ static void fork_exec_child_setup(gpointer data)
/* POSIX is obnoxious about SIGCHLD specifically across exec() */
signal(SIGCHLD, SIG_DFL);
+#else
+#ifdef GLIB_UNUSED_PARAM
+ GLIB_UNUSED_PARAM(data);
+#endif
#endif
}
@@ -209,7 +214,8 @@ int fork_exec(struct socket *so, const char *ex)
GError *err = NULL;
gint argc = 0;
gchar **argv = NULL;
- int opt, sp[2];
+ int opt;
+ slirp_os_socket sp[2];
DEBUG_CALL("fork_exec");
DEBUG_ARG("so = %p", so);
@@ -243,7 +249,7 @@ int fork_exec(struct socket *so, const char *ex)
closesocket(sp[1]);
slirp_socket_set_fast_reuse(so->s);
opt = 1;
- setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+ setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, (const void *) &opt, sizeof(int));
slirp_set_nonblock(so->s);
so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque);
return 1;
@@ -267,7 +273,7 @@ int open_unix(struct socket *so, const char *unixpath)
}
s = slirp_socket(PF_UNIX, SOCK_STREAM, 0);
- if (s < 0) {
+ if (not_valid_socket(s)) {
g_critical("open_unix(): %s", strerror(errno));
return 0;
}
@@ -284,10 +290,15 @@ int open_unix(struct socket *so, const char *unixpath)
return 1;
#else
+#ifdef GLIB_UNUSED_PARAM
+ GLIB_UNUSED_PARAM(so);
+ GLIB_UNUSED_PARAM(unixpath);
+#endif
g_assert_not_reached();
#endif
}
+SLIRP_EXPORT
char *slirp_connection_info(Slirp *slirp)
{
GString *str = g_string_new(NULL);
@@ -334,7 +345,7 @@ char *slirp_connection_info(Slirp *slirp)
dst_port = so->so_fport;
}
slirp_fmt0(buf, sizeof(buf), " TCP[%s]", state);
- g_string_append_printf(str, "%-19s %3d %15s %5d ", buf, so->s,
+ g_string_append_printf(str, "%-19s %3"SLIRP_PRIfd" %15s %5d ", buf, so->s,
src.sin_addr.s_addr ?
inet_ntop(AF_INET, &src.sin_addr, addr, sizeof(addr)) : "*",
ntohs(src.sin_port));
@@ -359,7 +370,7 @@ char *slirp_connection_info(Slirp *slirp)
dst_addr = so->so_faddr;
dst_port = so->so_fport;
}
- g_string_append_printf(str, "%-19s %3d %15s %5d ", buf, so->s,
+ g_string_append_printf(str, "%-19s %3"SLIRP_PRIfd" %15s %5d ", buf, so->s,
src.sin_addr.s_addr ?
inet_ntop(AF_INET, &src.sin_addr, addr, sizeof(addr)) : "*",
ntohs(src.sin_port));
@@ -374,7 +385,7 @@ char *slirp_connection_info(Slirp *slirp)
(so->so_expire - curtime) / 1000);
src.sin_addr = so->so_laddr;
dst_addr = so->so_faddr;
- g_string_append_printf(str, "%-19s %3d %15s - ", buf, so->s,
+ g_string_append_printf(str, "%-19s %3"SLIRP_PRIfd" %15s - ", buf, so->s,
src.sin_addr.s_addr ?
inet_ntop(AF_INET, &src.sin_addr, addr, sizeof(addr)) : "*");
g_string_append_printf(str, "%15s - %5d %5d\n",
@@ -385,6 +396,7 @@ char *slirp_connection_info(Slirp *slirp)
return g_string_free(str, FALSE);
}
+SLIRP_EXPORT
char *slirp_neighbor_info(Slirp *slirp)
{
GString *str = g_string_new(NULL);
@@ -430,7 +442,7 @@ char *slirp_neighbor_info(Slirp *slirp)
int slirp_bind_outbound(struct socket *so, unsigned short af)
{
int ret = 0;
- struct sockaddr *addr = NULL;
+ const struct sockaddr *addr = NULL;
int addr_size = 0;
if (af == AF_INET && so->slirp->outbound_addr != NULL) {
diff --git a/src/slirp.c b/src/slirp.c
index fd68f63..9f4c49e 100644
--- a/src/slirp.c
+++ b/src/slirp.c
@@ -812,7 +812,7 @@ void slirp_pollfds_fill(Slirp *slirp, uint32_t *timeout,
* NOFDREF can include still connecting to local-host,
* newly socreated() sockets etc. Don't want to select these.
*/
- if (so->so_state & SS_NOFDREF || so->s == -1) {
+ if (so->so_state & SS_NOFDREF || not_valid_socket(so->s)) {
continue;
}
@@ -931,7 +931,7 @@ void slirp_pollfds_poll(Slirp *slirp, int select_error,
struct socket *so, *so_next;
int ret;
- curtime = slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS;
+ curtime = (unsigned int) (slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS);
/*
* See if anything has timed out
@@ -965,7 +965,7 @@ void slirp_pollfds_poll(Slirp *slirp, int select_error,
revents = get_revents(so->pollfds_idx, opaque);
}
- if (so->so_state & SS_NOFDREF || so->s == -1) {
+ if (so->so_state & SS_NOFDREF || not_valid_socket(so->s)) {
continue;
}
@@ -1074,7 +1074,7 @@ void slirp_pollfds_poll(Slirp *slirp, int select_error,
revents = get_revents(so->pollfds_idx, opaque);
}
- if (so->s != -1 &&
+ if (have_valid_socket(so->s) &&
(revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) {
sorecvfrom(so);
}
@@ -1093,7 +1093,7 @@ void slirp_pollfds_poll(Slirp *slirp, int select_error,
revents = get_revents(so->pollfds_idx, opaque);
}
- if (so->s != -1 &&
+ if (have_valid_socket(so->s) &&
(revents & (SLIRP_POLL_IN | SLIRP_POLL_HUP | SLIRP_POLL_ERR))) {
if (so->so_type == IPPROTO_IPV6 || so->so_type == IPPROTO_ICMPV6)
icmp6_receive(so);
@@ -1547,14 +1547,14 @@ int slirp_remove_guestfwd(Slirp *slirp, struct in_addr guest_addr,
slirp_ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
{
- if (so->s == -1 && so->guestfwd) {
+ if (not_valid_socket(so->s) && so->guestfwd) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
so->guestfwd->write_cb(buf, len, so->guestfwd->opaque);
return len;
}
- if (so->s == -1) {
+ if (not_valid_socket(so->s)) {
/*
* This should in theory not happen but it is hard to be
* sure because some code paths will end up with so->s == -1
diff --git a/src/slirp.h b/src/slirp.h
index 2715353..e28d496 100644
--- a/src/slirp.h
+++ b/src/slirp.h
@@ -3,11 +3,19 @@
#define SLIRP_H
#ifdef _WIN32
+/* TARGET_WINVER defined on the compiler command line? */
+#if defined(TARGET_WINVER) && !defined(WINVER)
+# define WINVER TARGET_WINVER
+/* Default WINVER to Windows 7 API, same as glib. */
+#elif !defined(WINVER)
+# define WINVER 0x0601
+#endif
-/* as defined in sdkddkver.h */
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0601 /* Windows 7 */
+/* Ensure that _WIN32_WINNT matches WINVER */
+#if defined(WINVER) && !defined(_WIN32_WINNT)
+#define _WIN32_WINNT WINVER
#endif
+
/* reduces the number of implicitly included headers */
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
@@ -19,6 +27,11 @@
#include <sys/timeb.h>
#include <iphlpapi.h>
+/* Paranoia includes: */
+#include <errno.h>
+#include <stdbool.h>
+#include <io.h>
+
#else
#define O_BINARY 0
#endif
diff --git a/src/socket.c b/src/socket.c
index c426be9..09e310e 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -16,8 +16,8 @@ static void sofcantrcvmore(struct socket *so);
static void sofcantsendmore(struct socket *so);
struct socket *solookup(struct socket **last, struct socket *head,
- struct sockaddr_storage *lhost,
- struct sockaddr_storage *fhost)
+ const struct sockaddr_storage *lhost,
+ const struct sockaddr_storage *fhost)
{
struct socket *so = *last;
@@ -50,8 +50,8 @@ struct socket *socreate(Slirp *slirp, int type)
memset(so, 0, sizeof(struct socket));
so->so_type = type;
so->so_state = SS_NOFDREF;
- so->s = -1;
- so->s_aux = -1;
+ so->s = SLIRP_INVALID_SOCKET;
+ so->s_aux = SLIRP_INVALID_SOCKET;
so->slirp = slirp;
so->pollfds_idx = -1;
@@ -61,7 +61,7 @@ struct socket *socreate(Slirp *slirp, int type)
/*
* Remove references to so from the given message queue.
*/
-static void soqfree(struct socket *so, struct slirp_quehead *qh)
+static void soqfree(const struct socket *so, struct slirp_quehead *qh)
{
struct mbuf *ifq;
@@ -84,7 +84,7 @@ void sofree(struct socket *so)
{
Slirp *slirp = so->slirp;
- if (so->s_aux != -1) {
+ if (have_valid_socket(so->s_aux)) {
closesocket(so->s_aux);
}
@@ -797,7 +797,8 @@ struct socket *tcpx_listen(Slirp *slirp,
int flags)
{
struct socket *so;
- int s, opt = 1;
+ slirp_os_socket s;
+ int opt = 1;
socklen_t addrlen;
DEBUG_CALL("tcpx_listen");
@@ -863,22 +864,19 @@ struct socket *tcpx_listen(Slirp *slirp,
sockaddr_copy(&so->lhost.sa, sizeof(so->lhost), laddr, laddrlen);
s = slirp_socket(haddr->sa_family, SOCK_STREAM, 0);
- if ((s < 0) ||
+ if ((not_valid_socket(s)) ||
(haddr->sa_family == AF_INET6 && slirp_socket_set_v6only(s, (flags & SS_HOSTFWD_V6ONLY) != 0) < 0) ||
(slirp_socket_set_fast_reuse(s) < 0) ||
(bind(s, haddr, haddrlen) < 0) ||
(listen(s, 1) < 0)) {
int tmperrno = errno; /* Don't clobber the real reason we failed */
- if (s >= 0) {
+ if (have_valid_socket(s)) {
closesocket(s);
}
sofree(so);
/* Restore the real errno */
-#ifdef _WIN32
- WSASetLastError(tmperrno);
-#else
errno = tmperrno;
-#endif
+
return NULL;
}
setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
@@ -1091,7 +1089,7 @@ void sotranslate_accept(struct socket *so)
* this source port by binding to port 0 so that the OS allocates a
* port for us. If this fails, we fall back to choosing a random port
* with a random number generator. */
- int s;
+ slirp_os_socket s;
struct sockaddr_in in_addr;
struct sockaddr_in6 in6_addr;
socklen_t in_addr_len;
@@ -1112,7 +1110,7 @@ void sotranslate_accept(struct socket *so)
g_assert_not_reached();
break;
}
- if (s < 0) {
+ if (not_valid_socket(s)) {
g_error("Ephemeral slirp_socket() allocation failed");
goto unix2inet_cont;
}
@@ -1155,7 +1153,7 @@ unix2inet_cont:
g_assert_not_reached();
break;
}
- if (s < 0) {
+ if (not_valid_socket(s)) {
g_error("Ephemeral slirp_socket() allocation failed");
goto unix2inet6_cont;
}
diff --git a/src/socket.h b/src/socket.h
index 27d3b8a..c7c6834 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -39,9 +39,9 @@ union slirp_sockaddr {
struct socket {
struct socket *so_next, *so_prev; /* For a linked list of sockets */
- int s; /* The actual socket */
- int s_aux; /* An auxiliary socket for miscellaneous use. Currently used to
- * reserve OS ports in UNIX-to-inet translation. */
+ slirp_os_socket s; /* The actual socket */
+ slirp_os_socket s_aux; /* An auxiliary socket for miscellaneous use. Currently used to
+ * reserve OS ports in UNIX-to-inet translation. */
struct gfwd_list *guestfwd;
int pollfds_idx; /* GPollFD GArray index */
@@ -180,7 +180,8 @@ static inline void sockaddr_copy(struct sockaddr *dst, socklen_t dstlen, const s
/* Find the socket corresponding to lhost & fhost, trying last as a guess */
struct socket *solookup(struct socket **last, struct socket *head,
- struct sockaddr_storage *lhost, struct sockaddr_storage *fhost);
+ const struct sockaddr_storage *lhost,
+ const struct sockaddr_storage *fhost);
/* Create a new socket */
struct socket *socreate(Slirp *, int);
/* Release a socket */
diff --git a/src/tcp_subr.c b/src/tcp_subr.c
index 3cfe286..229b080 100644
--- a/src/tcp_subr.c
+++ b/src/tcp_subr.c
@@ -381,28 +381,30 @@ int tcp_fconnect(struct socket *so, unsigned short af)
DEBUG_CALL("tcp_fconnect");
DEBUG_ARG("so = %p", so);
- ret = so->s = slirp_socket(af, SOCK_STREAM, 0);
- if (ret >= 0) {
+ so->s = slirp_socket(af, SOCK_STREAM, 0);
+ ret = have_valid_socket(so->s) ? 0 : -1;
+ if (ret) {
ret = slirp_bind_outbound(so, af);
if (ret < 0) {
// bind failed - close socket
closesocket(so->s);
- so->s = -1;
+ so->s = SLIRP_INVALID_SOCKET;
return (ret);
}
}
if (ret >= 0) {
- int opt, s = so->s;
+ int opt;
+ slirp_os_socket s = so->s;
struct sockaddr_storage addr;
slirp_set_nonblock(s);
so->slirp->cb->register_poll_fd(s, so->slirp->opaque);
slirp_socket_set_fast_reuse(s);
opt = 1;
- setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
+ setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (const void *) &opt, sizeof(opt));
opt = 1;
- setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
+ setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const void *) &opt, sizeof(opt));
addr = so->fhost.ss;
DEBUG_CALL(" connect()ing");
@@ -440,7 +442,8 @@ void tcp_connect(struct socket *inso)
struct sockaddr_storage addr;
socklen_t addrlen;
struct tcpcb *tp;
- int s, opt, ret;
+ slirp_os_socket s;
+ int opt, ret;
/* AF_INET6 addresses are bigger than AF_INET, so this is big enough. */
char addrstr[INET6_ADDRSTRLEN];
char portstr[6];
@@ -480,8 +483,8 @@ void tcp_connect(struct socket *inso)
DEBUG_MISC(" guest address not available yet");
addrlen = sizeof(addr);
s = accept(inso->s, (struct sockaddr *)&addr, &addrlen);
- if (s >= 0) {
- close(s);
+ if (have_valid_socket(s)) {
+ closesocket(s);
}
return;
}
@@ -505,7 +508,7 @@ void tcp_connect(struct socket *inso)
addrlen = sizeof(addr);
s = accept(inso->s, (struct sockaddr *)&addr, &addrlen);
- if (s < 0) {
+ if (not_valid_socket(s)) {
tcp_close(sototcpcb(so)); /* This will sofree() as well */
return;
}
@@ -513,7 +516,7 @@ void tcp_connect(struct socket *inso)
so->slirp->cb->register_poll_fd(s, so->slirp->opaque);
slirp_socket_set_fast_reuse(s);
opt = 1;
- setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+ setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (const void *) &opt, sizeof(int));
slirp_socket_set_nodelay(s);
so->fhost.ss = addr;
@@ -967,7 +970,7 @@ int tcp_ctl(struct socket *so)
if (ex_ptr->ex_fport == so->so_fport &&
so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
if (ex_ptr->write_cb) {
- so->s = -1;
+ so->s = SLIRP_INVALID_SOCKET;
so->guestfwd = ex_ptr;
return 1;
}
diff --git a/src/tftp.c b/src/tftp.c
index 1b39692..bba2cf9 100644
--- a/src/tftp.c
+++ b/src/tftp.c
@@ -29,6 +29,11 @@
#include <sys/stat.h>
#include <fcntl.h>
+#if defined(_WIN32)
+#include <io.h>
+#include <share.h>
+#endif
+
static inline int tftp_session_in_use(struct tftp_session *spt)
{
return (spt->slirp != NULL);
@@ -297,13 +302,13 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas,
/* check if a session already exists and if so terminate it */
s = tftp_session_find(slirp, srcsas, &tp->hdr);
- if (s >= 0) {
+ if (have_valid_socket(s)) {
tftp_session_terminate(&slirp->tftp_sessions[s]);
}
s = tftp_session_allocate(slirp, srcsas, &tp->hdr);
- if (s < 0) {
+ if (not_valid_socket(s)) {
return;
}
@@ -437,7 +442,7 @@ static void tftp_handle_ack(Slirp *slirp, struct sockaddr_storage *srcsas,
s = tftp_session_find(slirp, srcsas, hdr);
- if (s < 0) {
+ if (not_valid_socket(s)) {
return;
}
@@ -451,7 +456,7 @@ static void tftp_handle_error(Slirp *slirp, struct sockaddr_storage *srcsas,
s = tftp_session_find(slirp, srcsas, hdr);
- if (s < 0) {
+ if (not_valid_socket(s)) {
return;
}
diff --git a/src/udp.c b/src/udp.c
index f5ca294..eaa6f41 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -178,7 +178,7 @@ void udp_input(register struct mbuf *m, int iphlen)
* create one
*/
so = socreate(slirp, IPPROTO_UDP);
- if (udp_attach(so, AF_INET) == -1) {
+ if (not_valid_socket(udp_attach(so, AF_INET))) {
DEBUG_MISC(" udp_attach errno = %d-%s", errno, strerror(errno));
sofree(so);
goto bad;
@@ -220,7 +220,7 @@ void udp_input(register struct mbuf *m, int iphlen)
icmp_send_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0, NULL);
goto bad;
}
- setsockopt(so->s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
+ setsockopt(so->s, IPPROTO_IP, IP_TTL, (const void *) &ttl, sizeof(ttl));
/*
* Now we sendto() the packet.
@@ -247,8 +247,8 @@ bad:
m_free(m);
}
-int udp_output(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr,
- struct sockaddr_in *daddr, int iptos)
+int udp_output(struct socket *so, struct mbuf *m, const struct sockaddr_in *saddr,
+ const struct sockaddr_in *daddr, int iptos)
{
Slirp *slirp = m->slirp;
char addr[INET_ADDRSTRLEN];
@@ -303,15 +303,15 @@ int udp_output(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr,
return (error);
}
-int udp_attach(struct socket *so, unsigned short af)
+slirp_os_socket udp_attach(struct socket *so, unsigned short af)
{
so->s = slirp_socket(af, SOCK_DGRAM, 0);
- if (so->s != -1) {
+ if (have_valid_socket(so->s)) {
if (slirp_bind_outbound(so, af) != 0) {
// bind failed - close socket
closesocket(so->s);
- so->s = -1;
- return -1;
+ so->s = SLIRP_INVALID_SOCKET;
+ return SLIRP_INVALID_SOCKET;
}
#ifdef __linux__
@@ -375,7 +375,7 @@ struct socket *udpx_listen(Slirp *slirp,
so = socreate(slirp, IPPROTO_UDP);
so->s = slirp_socket(haddr->sa_family, SOCK_DGRAM, 0);
- if (so->s < 0) {
+ if (not_valid_socket(so->s)) {
save_errno = errno;
sofree(so);
errno = save_errno;
diff --git a/src/udp.h b/src/udp.h
index b0514f1..6604db5 100644
--- a/src/udp.h
+++ b/src/udp.h
@@ -82,7 +82,7 @@ void udp_cleanup(Slirp *);
/* Process UDP datagram coming from the guest */
void udp_input(register struct mbuf *, int);
/* Create a host UDP socket, bound to this socket */
-int udp_attach(struct socket *, unsigned short af);
+slirp_os_socket udp_attach(struct socket *, unsigned short af);
/* Destroy socket */
void udp_detach(struct socket *);
@@ -94,13 +94,13 @@ struct socket *udpx_listen(Slirp *,
const struct sockaddr *laddr, socklen_t laddrlen,
int flags);
/* Send UDP datagram to the guest */
-int udp_output(struct socket *so, struct mbuf *m, struct sockaddr_in *saddr,
- struct sockaddr_in *daddr, int iptos);
+int udp_output(struct socket *so, struct mbuf *m, const struct sockaddr_in *saddr,
+ const struct sockaddr_in *daddr, int iptos);
/* Process UDPv6 datagram coming from the guest */
void udp6_input(register struct mbuf *);
/* Send UDPv6 datagram to the guest */
-int udp6_output(struct socket *so, struct mbuf *m, struct sockaddr_in6 *saddr,
- struct sockaddr_in6 *daddr);
+int udp6_output(struct socket *so, struct mbuf *m, const struct sockaddr_in6 *saddr,
+ const struct sockaddr_in6 *daddr);
#endif
diff --git a/src/udp6.c b/src/udp6.c
index effdf77..ea5a5ba 100644
--- a/src/udp6.c
+++ b/src/udp6.c
@@ -96,7 +96,7 @@ void udp6_input(struct mbuf *m)
if (so == NULL) {
/* If there's no socket for this packet, create one. */
so = socreate(slirp, IPPROTO_UDP);
- if (udp_attach(so, AF_INET6) == -1) {
+ if (not_valid_socket(udp_attach(so, AF_INET6))) {
DEBUG_MISC(" udp6_attach errno = %d-%s", errno, strerror(errno));
sofree(so);
goto bad;
@@ -128,7 +128,7 @@ void udp6_input(struct mbuf *m)
icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS);
goto bad;
}
- setsockopt(so->s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hop_limit, sizeof(hop_limit));
+ setsockopt(so->s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (const void *) &hop_limit, sizeof(hop_limit));
/*
* Now we sendto() the packet.
@@ -155,8 +155,8 @@ bad:
m_free(m);
}
-int udp6_output(struct socket *so, struct mbuf *m, struct sockaddr_in6 *saddr,
- struct sockaddr_in6 *daddr)
+int udp6_output(struct socket *so, struct mbuf *m, const struct sockaddr_in6 *saddr,
+ const struct sockaddr_in6 *daddr)
{
Slirp *slirp = m->slirp;
M_DUP_DEBUG(slirp, m, 0, sizeof(struct ip6) + sizeof(struct udphdr));
diff --git a/src/util.c b/src/util.c
index 8267f0c..f69a663 100644
--- a/src/util.c
+++ b/src/util.c
@@ -26,11 +26,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "util.h"
-
#include <glib.h>
#include <fcntl.h>
#include <stdint.h>
+/* Windows: If errno.h is not included, then errno is a preprocessor define
+ * for WSAGetLastError(). errno.h redefines errno as a thread safe function,
+ * i.e. "*errno()", which allows us to assign errno a value. */
+#include <errno.h>
+
+#include "util.h"
#if defined(_WIN32)
int slirp_inet_aton(const char *cp, struct in_addr *ia)
@@ -44,9 +48,10 @@ int slirp_inet_aton(const char *cp, struct in_addr *ia)
}
#endif
-void slirp_set_nonblock(int fd)
+
+void slirp_set_nonblock(slirp_os_socket fd)
{
-#ifndef _WIN32
+#if !defined(_WIN32)
int f;
f = fcntl(fd, F_GETFL);
assert(f != -1);
@@ -58,14 +63,18 @@ void slirp_set_nonblock(int fd)
#endif
}
-static void slirp_set_cloexec(int fd)
+static void slirp_set_cloexec(slirp_os_socket fd)
{
-#ifndef _WIN32
+#if !defined(_WIN32)
int f;
f = fcntl(fd, F_GETFD);
assert(f != -1);
f = fcntl(fd, F_SETFD, f | FD_CLOEXEC);
assert(f != -1);
+#else
+#ifdef GLIB_UNUSED_PARAM
+ GLIB_UNUSED_PARAM(fd);
+#endif
#endif
}
@@ -73,9 +82,9 @@ static void slirp_set_cloexec(int fd)
* Opens a socket with FD_CLOEXEC set
* On failure errno contains the reason.
*/
-int slirp_socket(int domain, int type, int protocol)
+slirp_os_socket slirp_socket(int domain, int type, int protocol)
{
- int ret;
+ slirp_os_socket ret;
#ifdef SOCK_CLOEXEC
ret = socket(domain, type | SOCK_CLOEXEC, protocol);
@@ -84,15 +93,15 @@ int slirp_socket(int domain, int type, int protocol)
}
#endif
ret = socket(domain, type, protocol);
- if (ret >= 0) {
+ if (have_valid_socket(ret)) {
slirp_set_cloexec(ret);
}
return ret;
}
-#ifdef _WIN32
-static int socket_error(void)
+#if defined(_WIN32)
+static int win32_socket_error(void)
{
switch (WSAGetLastError()) {
case 0:
@@ -169,181 +178,182 @@ static int socket_error(void)
}
#undef ioctlsocket
-int slirp_ioctlsocket_wrap(int fd, int req, void *val)
+int slirp_ioctlsocket_wrap(slirp_os_socket fd, int req, void *val)
{
int ret;
ret = ioctlsocket(fd, req, val);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef closesocket
-int slirp_closesocket_wrap(int fd)
+int slirp_closesocket_wrap(slirp_os_socket fd)
{
int ret;
ret = closesocket(fd);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef connect
-int slirp_connect_wrap(int sockfd, const struct sockaddr *addr, int addrlen)
+int slirp_connect_wrap(slirp_os_socket sockfd, const struct sockaddr *addr, int addrlen)
{
int ret;
ret = connect(sockfd, addr, addrlen);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef listen
-int slirp_listen_wrap(int sockfd, int backlog)
+int slirp_listen_wrap(slirp_os_socket sockfd, int backlog)
{
int ret;
ret = listen(sockfd, backlog);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef bind
-int slirp_bind_wrap(int sockfd, const struct sockaddr *addr, int addrlen)
+int slirp_bind_wrap(slirp_os_socket sockfd, const struct sockaddr *addr, int addrlen)
{
int ret;
ret = bind(sockfd, addr, addrlen);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef socket
-int slirp_socket_wrap(int domain, int type, int protocol)
+slirp_os_socket slirp_socket_wrap(int domain, int type, int protocol)
{
- int ret;
+ slirp_os_socket ret;
ret = socket(domain, type, protocol);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef accept
-int slirp_accept_wrap(int sockfd, struct sockaddr *addr, int *addrlen)
+slirp_os_socket slirp_accept_wrap(slirp_os_socket sockfd, struct sockaddr *addr, int *addrlen)
{
- int ret;
+ slirp_os_socket ret;
ret = accept(sockfd, addr, addrlen);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef shutdown
-int slirp_shutdown_wrap(int sockfd, int how)
+int slirp_shutdown_wrap(slirp_os_socket sockfd, int how)
{
int ret;
ret = shutdown(sockfd, how);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef getsockopt
-int slirp_getsockopt_wrap(int sockfd, int level, int optname, void *optval,
+int slirp_getsockopt_wrap(slirp_os_socket sockfd, int level, int optname, void *optval,
int *optlen)
{
int ret;
ret = getsockopt(sockfd, level, optname, optval, optlen);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef setsockopt
-int slirp_setsockopt_wrap(int sockfd, int level, int optname,
+int slirp_setsockopt_wrap(slirp_os_socket sockfd, int level, int optname,
const void *optval, int optlen)
{
int ret;
ret = setsockopt(sockfd, level, optname, optval, optlen);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef getpeername
-int slirp_getpeername_wrap(int sockfd, struct sockaddr *addr, int *addrlen)
+int slirp_getpeername_wrap(slirp_os_socket sockfd, struct sockaddr *addr, int *addrlen)
{
int ret;
ret = getpeername(sockfd, addr, addrlen);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef getsockname
-int slirp_getsockname_wrap(int sockfd, struct sockaddr *addr, int *addrlen)
+int slirp_getsockname_wrap(slirp_os_socket sockfd, struct sockaddr *addr, int *addrlen)
{
int ret;
ret = getsockname(sockfd, addr, addrlen);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef send
-slirp_ssize_t slirp_send_wrap(int sockfd, const void *buf, size_t len, int flags)
+slirp_ssize_t slirp_send_wrap(slirp_os_socket sockfd, const void *buf, size_t len, int flags)
{
int ret;
+
ret = send(sockfd, buf, len, flags);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef sendto
-slirp_ssize_t slirp_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
- const struct sockaddr *addr, int addrlen)
+slirp_ssize_t slirp_sendto_wrap(slirp_os_socket sockfd, const void *buf, size_t len, int flags,
+ const struct sockaddr *addr, int addrlen)
{
int ret;
ret = sendto(sockfd, buf, len, flags, addr, addrlen);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef recv
-slirp_ssize_t slirp_recv_wrap(int sockfd, void *buf, size_t len, int flags)
+slirp_ssize_t slirp_recv_wrap(slirp_os_socket sockfd, void *buf, size_t len, int flags)
{
int ret;
ret = recv(sockfd, buf, len, flags);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
#undef recvfrom
-slirp_ssize_t slirp_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
- struct sockaddr *addr, int *addrlen)
+slirp_ssize_t slirp_recvfrom_wrap(slirp_os_socket sockfd, void *buf, size_t len, int flags,
+ struct sockaddr *addr, int *addrlen)
{
int ret;
ret = recvfrom(sockfd, buf, len, flags, addr, addrlen);
if (ret < 0) {
- errno = socket_error();
+ errno = win32_socket_error();
}
return ret;
}
@@ -361,7 +371,7 @@ void slirp_pstrcpy(char *buf, int buf_size, const char *str)
c = *str++;
if (c == 0 || q >= buf + buf_size - 1)
break;
- *q++ = c;
+ *q++ = (char) c;
}
*q = '\0';
}
diff --git a/src/util.h b/src/util.h
index c378cee..668a73c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -43,6 +43,7 @@
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
+#include <sys/ioctl.h>
#endif
#include "libslirp.h"
@@ -100,8 +101,18 @@ struct iovec {
#define ETH_P_NCSI (0x88f8)
#define ETH_P_UNKNOWN (0xffff)
-/* FIXME: remove me when made standalone */
-#ifdef _WIN32
+
+/* Windows: BLUF -- these functions have to have wrappers because Windows, just to
+ * be Windows, has error constants that are not the same as <errno.h>. Consequently,
+ * if one of the functions returns an error, the winsock2 error from WSAGetLastError()
+ * needs to be translated.
+ *
+ * To make the problem more complex, we have to ensure to include <errno.h>, which
+ * defines errno in a thread safe way. If we do not include <errno.h>, errno gets
+ * defined as WSAGetLastError(), which makes assigning a translated value impossible.
+ * Or ends up making the errno checking much more interesting than it has to be.
+ */
+#if defined(_WIN32)
#undef accept
#undef bind
#undef closesocket
@@ -118,72 +129,73 @@ struct iovec {
#undef setsockopt
#undef shutdown
#undef socket
-#endif
-#ifdef _WIN32
#define connect slirp_connect_wrap
-int slirp_connect_wrap(int fd, const struct sockaddr *addr, int addrlen);
+int slirp_connect_wrap(slirp_os_socket fd, const struct sockaddr *addr, int addrlen);
#define listen slirp_listen_wrap
-int slirp_listen_wrap(int fd, int backlog);
+int slirp_listen_wrap(slirp_os_socket fd, int backlog);
#define bind slirp_bind_wrap
-int slirp_bind_wrap(int fd, const struct sockaddr *addr, int addrlen);
+int slirp_bind_wrap(slirp_os_socket fd, const struct sockaddr *addr, int addrlen);
#define socket slirp_socket_wrap
-int slirp_socket_wrap(int domain, int type, int protocol);
+slirp_os_socket slirp_socket_wrap(int domain, int type, int protocol);
#define accept slirp_accept_wrap
-int slirp_accept_wrap(int fd, struct sockaddr *addr, int *addrlen);
+slirp_os_socket slirp_accept_wrap(slirp_os_socket fd, struct sockaddr *addr, int *addrlen);
#define shutdown slirp_shutdown_wrap
-int slirp_shutdown_wrap(int fd, int how);
+int slirp_shutdown_wrap(slirp_os_socket fd, int how);
#define getpeername slirp_getpeername_wrap
-int slirp_getpeername_wrap(int fd, struct sockaddr *addr, int *addrlen);
+int slirp_getpeername_wrap(slirp_os_socket fd, struct sockaddr *addr, int *addrlen);
#define getsockname slirp_getsockname_wrap
-int slirp_getsockname_wrap(int fd, struct sockaddr *addr, int *addrlen);
+int slirp_getsockname_wrap(slirp_os_socket fd, struct sockaddr *addr, int *addrlen);
#define send slirp_send_wrap
-slirp_ssize_t slirp_send_wrap(int fd, const void *buf, size_t len, int flags);
+slirp_ssize_t slirp_send_wrap(slirp_os_socket fd, const void *buf, size_t len, int flags);
#define sendto slirp_sendto_wrap
-slirp_ssize_t slirp_sendto_wrap(int fd, const void *buf, size_t len, int flags,
+slirp_ssize_t slirp_sendto_wrap(slirp_os_socket fd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, int addrlen);
#define recv slirp_recv_wrap
-slirp_ssize_t slirp_recv_wrap(int fd, void *buf, size_t len, int flags);
+slirp_ssize_t slirp_recv_wrap(slirp_os_socket fd, void *buf, size_t len, int flags);
#define recvfrom slirp_recvfrom_wrap
-slirp_ssize_t slirp_recvfrom_wrap(int fd, void *buf, size_t len, int flags,
+slirp_ssize_t slirp_recvfrom_wrap(slirp_os_socket fd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, int *addrlen);
#define closesocket slirp_closesocket_wrap
-int slirp_closesocket_wrap(int fd);
+int slirp_closesocket_wrap(slirp_os_socket fd);
#define ioctlsocket slirp_ioctlsocket_wrap
-int slirp_ioctlsocket_wrap(int fd, int req, void *val);
+int slirp_ioctlsocket_wrap(slirp_os_socket fd, int req, void *val);
#define getsockopt slirp_getsockopt_wrap
-int slirp_getsockopt_wrap(int sockfd, int level, int optname, void *optval,
+int slirp_getsockopt_wrap(slirp_os_socket sockfd, int level, int optname, void *optval,
int *optlen);
#define setsockopt slirp_setsockopt_wrap
-int slirp_setsockopt_wrap(int sockfd, int level, int optname,
+int slirp_setsockopt_wrap(slirp_os_socket sockfd, int level, int optname,
const void *optval, int optlen);
#define inet_aton slirp_inet_aton
-int slirp_inet_aton(const char *cp, struct in_addr *ia);
#else
#define closesocket(s) close(s)
#define ioctlsocket(s, r, v) ioctl(s, r, v)
#endif
-int slirp_socket(int domain, int type, int protocol);
-void slirp_set_nonblock(int fd);
+slirp_os_socket slirp_socket(int domain, int type, int protocol);
+void slirp_set_nonblock(slirp_os_socket fd);
-static inline int slirp_socket_set_v6only(int fd, int v)
+static inline int slirp_socket_set_v6only(slirp_os_socket fd, int v)
{
- return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &v, sizeof(v));
+ return setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void *) &v, sizeof(v));
}
-static inline int slirp_socket_set_nodelay(int fd)
+static inline int slirp_socket_set_nodelay(slirp_os_socket fd)
{
int v = 1;
- return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
+ return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const void *) &v, sizeof(v));
}
-static inline int slirp_socket_set_fast_reuse(int fd)
+static inline int slirp_socket_set_fast_reuse(slirp_os_socket fd)
{
#ifndef _WIN32
int v = 1;
return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v));
#else
+#ifdef GLIB_UNUSED_PARAM
+ GLIB_UNUSED_PARAM(fd);
+#endif
+
/* Enabling the reuse of an endpoint that was used by a socket still in
* TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
* fast reuse is the default and SO_REUSEADDR does strange things. So we
@@ -193,6 +205,22 @@ static inline int slirp_socket_set_fast_reuse(int fd)
#endif
}
+/* Socket error check */
+static inline int have_valid_socket(slirp_os_socket s)
+{
+#if !defined(_WIN32)
+ return (s >= 0);
+#else
+ return (s != SLIRP_INVALID_SOCKET);
+#endif
+}
+
+/* And the inverse -- the code reads more smoothly vs "!have_valid_socket" */
+static inline int not_valid_socket(slirp_os_socket s)
+{
+ return !have_valid_socket(s);
+}
+
void slirp_pstrcpy(char *buf, int buf_size, const char *str);
int slirp_fmt(char *str, size_t size, const char *format, ...) G_GNUC_PRINTF(3, 4);