diff --git a/C/iopreds.c b/C/iopreds.c index 0b85dc33a..0ed2d9435 100644 --- a/C/iopreds.c +++ b/C/iopreds.c @@ -1085,18 +1085,25 @@ SocketGetc(int sno) register int ch; char c; int count; - /* should be able to use a buffer */ + /* should be able to use a buffer */ #if _MSC_VER || defined(__MINGW32__) count = recv(s->u.socket.fd, &c, sizeof(char), 0); #else count = read(s->u.socket.fd, &c, sizeof(char)); #endif if (count == 0) { + s->u.socket.flags = closed_socket; ch = EOF; } else if (count > 0) { ch = c; } else { - Error(SYSTEM_ERROR, TermNil, "read"); +#if HAVE_STRERROR + Error(SYSTEM_ERROR, TermNil, + "( socket_getc: %s)", strerror(errno)); +#else + Error(SYSTEM_ERROR, TermNil, + "(socket_getc)"); +#endif return(EOF); } return(post_process_read_char(ch, s, sno)); diff --git a/C/ypsocks.c b/C/ypsocks.c index 7eb76cdbc..bc7262d2b 100644 --- a/C/ypsocks.c +++ b/C/ypsocks.c @@ -450,7 +450,42 @@ p_socket(void) Int CloseSocket(int fd, socket_info status, socket_domain domain) { - if (domain == client_socket || domain == server_session_socket) { +#if _MSC_VER || defined(__MINGW32__) + /* prevent further writing + to the socket */ + if (status == server_session_socket || + status == client_socket) { + char bfr; + + if (shutdown(fd, 1) != 0) { + Error(SYSTEM_ERROR, TermNil, + "socket_close/1 (close)"); + return(FALSE); + } + /* read all pending characters + from the socket */ + while( recv( fd, &bfr, 1, 0 ) > 0 ); + /* prevent further reading + from the socket */ + if (shutdown(fd, 0) < 0) { + Error(SYSTEM_ERROR, TermNil, + "socket_close/1 (close)"); + return(FALSE); + } + + /* close the socket */ + if (closesocket(fd) != 0) { +#if HAVE_STRERROR + Error(SYSTEM_ERROR, TermNil, + "socket_close/1 (close: %s)", strerror(socket_errno)); +#else + Error(SYSTEM_ERROR, TermNil, + "socket_close/1 (close)"); +#endif + } +#else + if (status == server_session_socket || + status == client_socket) { if (shutdown(fd,2) < 0) { #if HAVE_STRERROR Error(SYSTEM_ERROR, TermNil, @@ -462,17 +497,14 @@ CloseSocket(int fd, socket_info status, socket_domain domain) return(FALSE); } } -#if _MSC_VER || defined(__MINGW32__) - if (closesocket(fd) != 0) { -#else - if (close(fd) < 0) { -#endif + if (close(fd) != 0) { #if HAVE_STRERROR Error(SYSTEM_ERROR, TermNil, - "socket_close/1 (close: %s)", strerror(socket_errno)); + "socket_close/1 (close: %s)", strerror(socket_errno)); #else Error(SYSTEM_ERROR, TermNil, - "socket_close/1 (close)"); + "socket_close/1 (close)"); +#endif #endif return(FALSE); } diff --git a/H/yapio.h b/H/yapio.h index bd15c1733..8f5662384 100644 --- a/H/yapio.h +++ b/H/yapio.h @@ -218,10 +218,11 @@ typedef struct VARSTRUCT { /****************** defines for sockets *********************************/ typedef enum{ /* in YAP, sockets may be in one of 4 possible status */ - new_socket, - server_socket, - client_socket, - server_session_socket + new_socket, + server_socket, + client_socket, + server_session_socket, + closed_socket } socket_info; typedef enum{ /* we accept two domains for the moment, IPV6 may follow */