diff --git a/slirp/if.c b/slirp/if.c index 9317cbfe9c..2ce9a6424f 100644 --- a/slirp/if.c +++ b/slirp/if.c @@ -79,14 +79,14 @@ writen(fd, bptr, n) int total; /* This should succeed most of the time */ - ret = write(fd, bptr, n); + ret = send(fd, bptr, n,0); if (ret == n || ret <= 0) return ret; /* Didn't write everything, go into the loop */ total = ret; while (n > total) { - ret = write(fd, bptr+total, n-total); + ret = send(fd, bptr+total, n-total,0); if (ret <= 0) return ret; total += ret; @@ -111,7 +111,7 @@ if_input(ttyp) DEBUG_CALL("if_input"); DEBUG_ARG("ttyp = %lx", (long)ttyp); - if_n = read(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE); + if_n = recv(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE,0); DEBUG_MISC((dfd, " read %d bytes\n", if_n)); diff --git a/slirp/slirp.c b/slirp/slirp.c index 99f1687400..3b840a82da 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -414,7 +414,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) /* Connected */ so->so_state &= ~SS_ISFCONNECTING; - ret = write(so->s, &ret, 0); + ret = send(so->s, &ret, 0, 0); if (ret < 0) { /* XXXXX Must fix, zero bytes is a NOP */ if (errno == EAGAIN || errno == EWOULDBLOCK || @@ -447,7 +447,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) */ #ifdef PROBE_CONN if (so->so_state & SS_ISFCONNECTING) { - ret = read(so->s, (char *)&ret, 0); + ret = recv(so->s, (char *)&ret, 0,0); if (ret < 0) { /* XXX */ @@ -460,7 +460,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) /* tcp_input will take care of it */ } else { - ret = write(so->s, &ret, 0); + ret = send(so->s, &ret, 0,0); if (ret < 0) { /* XXX */ if (errno == EAGAIN || errno == EWOULDBLOCK || @@ -496,6 +496,15 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) */ if (if_queued && link_up) if_start(); + + /* clear global file descriptor sets. + * these reside on the stack in vl.c + * so they're unusable if we're not in + * slirp_select_fill or slirp_select_poll. + */ + global_readfds = NULL; + global_writefds = NULL; + global_xfds = NULL; } #define ETH_ALEN 6 diff --git a/slirp/slirp.h b/slirp/slirp.h index b52044a65a..964d5e19b7 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -329,4 +329,8 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err); #define max(x,y) ((x) > (y) ? (x) : (y)) #endif +#ifdef _WIN32 +#define errno (WSAGetLastError()) +#endif + #endif diff --git a/slirp/socket.c b/slirp/socket.c index 7286b5e19f..fe03d448a5 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -152,7 +152,7 @@ soread(so) nn = readv(so->s, (struct iovec *)iov, n); DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); #else - nn = read(so->s, iov[0].iov_base, iov[0].iov_len); + nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0); #endif if (nn <= 0) { if (nn < 0 && (errno == EINTR || errno == EAGAIN)) @@ -176,7 +176,7 @@ soread(so) * A return of -1 wont (shouldn't) happen, since it didn't happen above */ if (n == 2 && nn == iov[0].iov_len) - nn += read(so->s, iov[1].iov_base, iov[1].iov_len); + nn += recv(so->s, iov[1].iov_base, iov[1].iov_len,0); DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); #endif @@ -333,7 +333,7 @@ sowrite(so) DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); #else - nn = write(so->s, iov[0].iov_base, iov[0].iov_len); + nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0); #endif /* This should never happen, but people tell me it does *shrug* */ if (nn < 0 && (errno == EAGAIN || errno == EINTR)) @@ -349,7 +349,7 @@ sowrite(so) #ifndef HAVE_READV if (n == 2 && nn == iov[0].iov_len) - nn += write(so->s, iov[1].iov_base, iov[1].iov_len); + nn += send(so->s, iov[1].iov_base, iov[1].iov_len,0); DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); #endif @@ -572,7 +572,11 @@ solisten(port, laddr, lport, flags) close(s); sofree(so); /* Restore the real errno */ +#ifdef _WIN32 + WSASetLastError(tmperrno); +#else errno = tmperrno; +#endif return NULL; } setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); @@ -643,7 +647,9 @@ sofcantrcvmore(so) { if ((so->so_state & SS_NOFDREF) == 0) { shutdown(so->s,0); - FD_CLR(so->s, global_writefds); + if(global_writefds) { + FD_CLR(so->s,global_writefds); + } } so->so_state &= ~(SS_ISFCONNECTING); if (so->so_state & SS_FCANTSENDMORE) @@ -657,9 +663,13 @@ sofcantsendmore(so) struct socket *so; { if ((so->so_state & SS_NOFDREF) == 0) { - shutdown(so->s,1); /* send FIN to fhost */ - FD_CLR(so->s, global_readfds); - FD_CLR(so->s, global_xfds); + shutdown(so->s,1); /* send FIN to fhost */ + if (global_readfds) { + FD_CLR(so->s,global_readfds); + } + if (global_xfds) { + FD_CLR(so->s,global_xfds); + } } so->so_state &= ~(SS_ISFCONNECTING); if (so->so_state & SS_FCANTRCVMORE) diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c index 42f02b3e65..8729d76a7f 100644 --- a/slirp/tcp_input.c +++ b/slirp/tcp_input.c @@ -681,7 +681,7 @@ findso: goto cont_input; } - if(tcp_fconnect(so) == -1 && errno != EINPROGRESS) { + if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) { u_char code=ICMP_UNREACH_NET; DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n", errno,strerror(errno))); diff --git a/slirp/udp.c b/slirp/udp.c index 2dd51a39fe..aefa0b749b 100644 --- a/slirp/udp.c +++ b/slirp/udp.c @@ -339,7 +339,11 @@ udp_attach(so) int lasterrno=errno; closesocket(so->s); so->s=-1; +#ifdef _WIN32 + WSASetLastError(lasterrno); +#else errno=lasterrno; +#endif } else { /* success, insert in queue */ so->so_expire = curtime + SO_EXPIRE;