diff --git a/racket/src/rktio/demo.c b/racket/src/rktio/demo.c index 20cddf230d..b25b673b15 100644 --- a/racket/src/rktio/demo.c +++ b/racket/src/rktio/demo.c @@ -169,7 +169,7 @@ static void check_hello_content(rktio_t *rktio, char *fn) { rktio_fd_t *fd; intptr_t amt; - char buffer[256], *s; + char buffer[256]; fd = rktio_open(rktio, fn, RKTIO_OPEN_READ); check_valid(fd); @@ -196,7 +196,7 @@ static void check_read_write_pair(rktio_t *rktio, rktio_fd_t *fd, rktio_fd_t *fd { rktio_ltps_t *lt; rktio_ltps_handle_t *h1, *h2; - intptr_t amt, i; + intptr_t amt; char buffer[256]; lt = try_check_ltps(rktio, fd, fd2, &h1, &h2); @@ -446,8 +446,6 @@ int main(int argc, char **argv) rktio_directory_list_t *ls; rktio_file_copy_t *cp; rktio_timestamp_t *ts1, *ts1a; - rktio_ltps_t *lt; - rktio_ltps_handle_t *h1, *h2; int verbose = 0, dont_rely_on_sigchild = 0; for (i = 1; i < argc; i++) { @@ -588,16 +586,21 @@ int main(int argc, char **argv) /* We expect `lt` to work on regular files except on Windows and epoll: */ #if !defined(RKTIO_SYSTEM_WINDOWS) && !defined(HAVE_EPOLL_SYSCALL) - fd = rktio_open(rktio, "test1", RKTIO_OPEN_READ); - check_valid(fd); - fd2 = rktio_open(rktio, "test1", RKTIO_OPEN_WRITE | RKTIO_OPEN_CAN_EXIST); - check_valid(fd2); - lt = try_check_ltps(rktio, fd, fd2, &h1, &h2); - check_valid(lt); - check_ltps_read_and_write_ready(rktio, lt, h1, h2); - check_valid(rktio_ltps_close(rktio, lt)); - check_valid(rktio_close(rktio, fd)); - check_valid(rktio_close(rktio, fd2)); + { + rktio_ltps_handle_t *h1, *h2; + rktio_ltps_t *lt; + + fd = rktio_open(rktio, "test1", RKTIO_OPEN_READ); + check_valid(fd); + fd2 = rktio_open(rktio, "test1", RKTIO_OPEN_WRITE | RKTIO_OPEN_CAN_EXIST); + check_valid(fd2); + lt = try_check_ltps(rktio, fd, fd2, &h1, &h2); + check_valid(lt); + check_ltps_read_and_write_ready(rktio, lt, h1, h2); + check_valid(rktio_ltps_close(rktio, lt)); + check_valid(rktio_close(rktio, fd)); + check_valid(rktio_close(rktio, fd2)); + } #endif /* Pipes, non-blocking operations, and more long-term poll sets */ diff --git a/racket/src/rktio/rktio.h b/racket/src/rktio/rktio.h index a18689ba26..200706e19a 100644 --- a/racket/src/rktio/rktio.h +++ b/racket/src/rktio/rktio.h @@ -42,6 +42,7 @@ intptr_t rktio_fd_system_fd(rktio_t *rktio, rktio_fd_t *rfd); int rktio_fd_is_regular_file(rktio_t *rktio, rktio_fd_t *rfd); int rktio_fd_is_socket(rktio_t *rktio, rktio_fd_t *rfd); int rktio_fd_is_udp(rktio_t *rktio, rktio_fd_t *rfd); +int rktio_fd_is_terminal(rktio_t *rktio, rktio_fd_t *rfd); int rktio_fd_modes(rktio_t *rktio, rktio_fd_t *rfd); diff --git a/racket/src/rktio/rktio_envvars.c b/racket/src/rktio/rktio_envvars.c index c772f910a8..39f9c1c9ca 100644 --- a/racket/src/rktio/rktio_envvars.c +++ b/racket/src/rktio/rktio_envvars.c @@ -95,7 +95,7 @@ int rktio_setenv(rktio_t *rktio, const char *name, const char *val) if (rc) return 1; - set_windows_error(); + get_windows_error(); return 0; #endif } @@ -341,8 +341,8 @@ void *rktio_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars) wchar_t *r, *s; for (i = 0; i < envvars->count; i++) { - len += wc_strlen(WIDE_PATH_temp(envvars->names[i])); - len += wc_strlen(WIDE_PATH_temp(envvars->vals[i])); + len += wcslen(WIDE_PATH_temp(envvars->names[i])); + len += wcslen(WIDE_PATH_temp(envvars->vals[i])); len += 2; } @@ -352,12 +352,12 @@ for (i = 0; i < envvars->count; i++) { for (i = 0; i < envvars->count; i++) { s = WIDE_PATH_temp(envvars->names[i]); - slen = wc_strlen(s); + slen = wcslen(s); memcpy(r + len, s, slen * sizeof(wchar_t)); len += slen; r[len++] = '='; s = WIDE_PATH_temp(envvars->vals[i]); - slen = wc_strlen(s); + slen = wcslen(s); memcpy(r + len, s, slen * sizeof(wchar_t)); len += slen; r[len++] = 0; diff --git a/racket/src/rktio/rktio_error.c b/racket/src/rktio/rktio_error.c index 0bfd80b48e..79c73de575 100644 --- a/racket/src/rktio/rktio_error.c +++ b/racket/src/rktio/rktio_error.c @@ -24,6 +24,12 @@ void rktio_get_windows_error(rktio_t *rktio) rktio->errid = GetLastError(); rktio->errkind = RKTIO_ERROR_KIND_WINDOWS; } + +void rktio_set_windows_error(rktio_t *rktio, int errid) +{ + rktio->errid = errid; + rktio->errkind = RKTIO_ERROR_KIND_WINDOWS; +} #endif int rktio_get_last_error(rktio_t *rktio) diff --git a/racket/src/rktio/rktio_fd.c b/racket/src/rktio/rktio_fd.c index 4d8935f43e..9622830698 100644 --- a/racket/src/rktio/rktio_fd.c +++ b/racket/src/rktio/rktio_fd.c @@ -234,6 +234,28 @@ int rktio_fd_is_udp(rktio_t *rktio, rktio_fd_t *rfd) return ((rfd->modes & RKTIO_OPEN_UDP) ? 1 : 0); } +int rktio_system_fd_is_terminal(rktio_t *rktio, intptr_t fd) +{ +#ifdef RKTIO_SYSTEM_UNIX + return isatty(fd); +#endif +#ifdef RKTIO_SYSTEM_WINDOWS + if (GetFileType((HANDLE)fd) == FILE_TYPE_CHAR) { + DWORD mode; + if (GetConsoleMode((HANDLE)fd, &mode)) + return 1; + else + return 0; + } else + return 0; +#endif +} + +int rktio_fd_is_terminal(rktio_t *rktio, rktio_fd_t *rfd) +{ + return rktio_system_fd_is_terminal(rktio, (intptr_t)rfd->fd); +} + rktio_fd_t *rktio_dup(rktio_t *rktio, rktio_fd_t *rfd) { #ifdef RKTIO_SYSTEM_UNIX @@ -249,9 +271,9 @@ rktio_fd_t *rktio_dup(rktio_t *rktio, rktio_fd_t *rfd) } else return rktio_system_fd(rktio, nfd, rfd->modes); #endif -#ifdef WINDOWS_FILE_HANDLES +#ifdef RKTIO_SYSTEM_WINDOWS if (rfd->modes & RKTIO_OPEN_SOCKET) { - return rktio_socket_dup(rktio_t *rktio, rktio_fd_t *rfd) + return rktio_socket_dup(rktio, rfd); } else { HANDLE newhandle; BOOL rc; @@ -632,7 +654,7 @@ void rktio_poll_add(rktio_t *rktio, rktio_fd_t *rfd, rktio_poll_set_t *fds, int if (rfd->oth && !rktio_poll_write_ready(rktio, rfd)) rktio_poll_set_add_handle(rktio, (intptr_t)rfd->oth->ready_sema, fds, 1); else - rktio_poll_set_nosleep(rktio, fds); + rktio_poll_set_add_nosleep(rktio, fds); } } #endif @@ -701,7 +723,7 @@ intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len) if (!rfd->th) { /* We can read directly. This must be a regular file, where reading never blocks. */ - DWORD rgot, delta; + DWORD rgot; if (!ReadFile((HANDLE)rfd->fd, buffer, len, &rgot, NULL)) { get_windows_error(); @@ -713,7 +735,7 @@ intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len) else return rgot; } else { - if (!rktio_poll_read(rfd)) + if (!rktio_poll_read_ready(rktio, rfd)) return 0; /* If we get this far, there's definitely data available. @@ -796,13 +818,11 @@ static long WINAPI WindowsFDReader(Win_FD_Input_Thread *th) static void WindowsFDICleanup(Win_FD_Input_Thread *th) { - int rc; - CloseHandle(th->checking_sema); CloseHandle(th->ready_sema); CloseHandle(th->you_clean_up_sema); - if (!rc) CloseHandle(th->fd); + CloseHandle(th->fd); free(th->buffer); free(th); @@ -908,7 +928,7 @@ intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len if (!rfd->oth) { /* The FILE_TYPE_PIPE test is currently redundant, I think, but better safe than sorry. */ - nonblocking = (rktio_windows_nt_or_later() + nonblocking = (rktio->windows_nt_or_later && (GetFileType((HANDLE)rfd->fd) == FILE_TYPE_PIPE)); } else nonblocking = 1; /* must be, or we would not have gotten here */ @@ -965,7 +985,7 @@ intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len || (!ok && (errsaved == ERROR_NOT_ENOUGH_MEMORY))) { towrite = towrite >> 1; if (!towrite) { - set_windows_error(); + get_windows_error(); return RKTIO_WRITE_ERROR; } } else @@ -1107,10 +1127,13 @@ intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len ok = 1; } ReleaseSemaphore(oth->lock_sema, 1, NULL); - } else if (out_len > 0) { - /* We've already written, which implies that no flush is - in progress. We'll need a flush check in the future. */ - rfd->oth->needflush = 1; + } else { + if (out_len > 0) { + /* We've already written, which implies that no flush is + in progress. We'll need a flush check in the future. */ + rfd->oth->needflush = 1; + } + ok = 1; } if (ok) @@ -1189,13 +1212,11 @@ static long WINAPI WindowsFDWriter(Win_FD_Output_Thread *oth) static void WindowsFDOCleanup(Win_FD_Output_Thread *oth) { - int rc; - CloseHandle(oth->lock_sema); CloseHandle(oth->work_sema); CloseHandle(oth->you_clean_up_sema); - if (!rc) CloseHandle(oth->fd); + CloseHandle(oth->fd); if (oth->buffer) free(oth->buffer); diff --git a/racket/src/rktio/rktio_file.c b/racket/src/rktio/rktio_file.c index 2661bb1ad1..f3aac19f74 100644 --- a/racket/src/rktio/rktio_file.c +++ b/racket/src/rktio/rktio_file.c @@ -158,7 +158,7 @@ static rktio_fd_t *open_write(rktio_t *rktio, char *filename, int modes) #endif #ifdef RKTIO_SYSTEM_WINDOWS HANDLE fd; - int hmode, regfile; + int hmode; BY_HANDLE_FILE_INFORMATION info; rktio_fd_t *rfd; diff --git a/racket/src/rktio/rktio_fs_change.c b/racket/src/rktio/rktio_fs_change.c index 924a7d62db..9c0938b571 100644 --- a/racket/src/rktio/rktio_fs_change.c +++ b/racket/src/rktio/rktio_fs_change.c @@ -127,7 +127,7 @@ rktio_fs_change_t *rktio_fs_change(rktio_t *rktio, char *path) | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES)); if (h == INVALID_HANDLE_VALUE) - set_windows_error(); + get_windows_error(); else { fd = (intptr_t)h; ok = 1; diff --git a/racket/src/rktio/rktio_ltps.c b/racket/src/rktio/rktio_ltps.c index e12ee259ee..a2de75f69e 100644 --- a/racket/src/rktio/rktio_ltps.c +++ b/racket/src/rktio/rktio_ltps.c @@ -44,15 +44,16 @@ typedef struct rktio_ltps_handle_pair_t { rktio_ltps_handle_t *write_handle; } rktio_ltps_handle_pair_t; +#ifdef RKTIO_SYSTEM_UNIX static rktio_ltps_handle_pair_t *ltps_hash_get(rktio_ltps_t *lt, intptr_t fd); static void ltps_hash_set(rktio_ltps_t *lt, intptr_t fd, rktio_ltps_handle_pair_t *v); static void ltps_hash_remove(rktio_ltps_t *lt, intptr_t fd); static void ltps_hash_init(rktio_ltps_t *lt); static void ltps_hash_free(rktio_ltps_t *lt); - #if !defined(HAVE_KQUEUE_SYSCALL) && !defined(HAVE_EPOLL_SYSCALL) static int ltps_is_hash_empty(rktio_ltps_t *lt); #endif +#endif /*========================================================================*/ @@ -104,8 +105,10 @@ rktio_ltps_t *rktio_open_ltps(rktio_t *rktio) lt->signaled = NULL; +#ifdef RKTIO_SYSTEM_UNIX ltps_hash_init(lt); - +#endif + return lt; } @@ -129,7 +132,9 @@ int rktio_ltps_close(rktio_t *rktio, rktio_ltps_t *lt) while ((s = rktio_ltps_get_signaled_handle(rktio, lt))) free(s); +#ifdef RKTIO_SYSTEM_UNIX ltps_hash_free(lt); +#endif #if defined(HAVE_KQUEUE_SYSCALL) || defined(HAVE_EPOLL_SYSCALL) if (lt->fd >= 0) { @@ -609,6 +614,8 @@ int rktio_ltps_poll(rktio_t *rktio, rktio_ltps_t *lt) /*========================================================================*/ +#ifdef RKTIO_SYSTEM_UNIX + typedef struct ltps_bucket_t { /* v is non-NULL => bucket is filled */ /* v is NULL and fd is -1 => was removed */ @@ -741,3 +748,5 @@ static int ltps_is_hash_empty(rktio_ltps_t *lt) return (lt->count == 0); } #endif + +#endif diff --git a/racket/src/rktio/rktio_main.c b/racket/src/rktio/rktio_main.c index 2f18039549..891fad45dc 100644 --- a/racket/src/rktio/rktio_main.c +++ b/racket/src/rktio/rktio_main.c @@ -21,7 +21,14 @@ rktio_t *rktio_init(void) return NULL; } - rktio_useless_wide(); +#ifdef RKTIO_SYSTEM_WINDOWS + if (!rktio_winsock_init(rktio)) { + rktio_destroy(rktio); + return NULL; + } +#endif + + rktio_init_wide(rktio); return rktio; } @@ -32,6 +39,9 @@ void rktio_destroy(rktio_t *rktio) rktio_free_ghbn(rktio); rktio_free_global_poll_set(rktio); rktio_stop_fs_change(rktio); +#ifdef RKTIO_SYSTEM_WINDOWS + rktio_winsock_done(rktio); +#endif free(rktio); } @@ -41,4 +51,3 @@ void rktio_free(void *p) { free(p); } - diff --git a/racket/src/rktio/rktio_network.c b/racket/src/rktio/rktio_network.c index 69fdc38f57..d124411a1f 100644 --- a/racket/src/rktio/rktio_network.c +++ b/racket/src/rktio/rktio_network.c @@ -24,6 +24,8 @@ # define RKTIO_AFNOSUPPORT EAFNOSUPPORT typedef intptr_t rktio_socket_t; +typedef unsigned int rktio_sockopt_len_t; + # define INVALID_SOCKET (-1) static void closesocket(rktio_socket_t s) { @@ -92,6 +94,7 @@ struct SOCKADDR_IN { # define RKTIO_AFNOSUPPORT WSAEAFNOSUPPORT typedef SOCKET rktio_socket_t; +typedef int rktio_sockopt_len_t; typedef struct SOCKADDR_IN rktio_unspec_address; # define REGISTER_SOCKET(s) winsock_remember(s) @@ -521,10 +524,6 @@ static rktio_addrinfo_lookup_t *start_lookup(rktio_t *rktio, rktio_addrinfo_look # ifdef RKTIO_SYSTEM_WINDOWS { - HANDLE ready_sema; - unsigned int id; - intptr_t th; - lookup->done_sema = CreateSemaphore(NULL, 0, 1, NULL); if (!lookup->done_sema) { get_windows_error(); @@ -761,16 +760,10 @@ const char *rktio_gai_strerror(int errnum) #ifdef RKTIO_SYSTEM_WINDOWS static HANDLE winsock_sema; +static int winsock_started = 0; static int wsr_size = 0; static rktio_socket_t *wsr_array; -void rktio_winsock_init() -{ - if (!winsock_sema) { - winsock_sema = CreateSemaphore(NULL, 1, 1, NULL); - } -} - static void winsock_remember(rktio_socket_t s) { int i, new_size; @@ -804,18 +797,14 @@ static void winsock_remember(rktio_socket_t s) wsr_size = new_size; } -# ifdef RKTIO_USE_PLACES ReleaseSemaphore(winsock_sema, 1, NULL); -# endif } static void winsock_forget(rktio_socket_t s) { int i; -# ifdef RKTIO_USE_PLACES WaitForSingleObject(winsock_sema, INFINITE); -# endif for (i = 0; i < wsr_size; i++) { if (wsr_array[i] == s) { @@ -824,50 +813,56 @@ static void winsock_forget(rktio_socket_t s) } } -# ifdef RKTIO_USE_PLACES ReleaseSemaphore(winsock_sema, 1, NULL); -# endif } -static int winsock_done(void) +int rktio_winsock_init(rktio_t *rktio) +{ + if (!winsock_sema) { + winsock_sema = CreateSemaphore(NULL, 1, 1, NULL); + } + + WaitForSingleObject(winsock_sema, INFINITE); + + if (!winsock_started) { + WSADATA data; + if (!WSAStartup(MAKEWORD(1, 1), &data)) { + winsock_started = 1; + } else { + get_windows_error(); + ReleaseSemaphore(winsock_sema, 1, NULL); + return 0; + } + } else + winsock_started++; + + ReleaseSemaphore(winsock_sema, 1, NULL); + + return 1; +} + +void rktio_winsock_done(rktio_t *rktio) { int i; - /* only called in the original place */ - - for (i = 0; i < wsr_size; i++) { - if (wsr_array[i]) { - closesocket(wsr_array[i]); - wsr_array[i] = (rktio_socket_t)NULL; - } - } - - return WSACleanup(); -} - -static void TCP_INIT(char *name) -{ - static int started = 0; - WaitForSingleObject(winsock_sema, INFINITE); - if (!started) { - WSADATA data; - if (!WSAStartup(MAKEWORD(1, 1), &data)) { - started = 1; -#ifdef __BORLANDC__ - atexit((void(*)())winsock_done); -#else - _onexit(winsock_done); -#endif + if (!--winsock_started) { + for (i = 0; i < wsr_size; i++) { + if (wsr_array[i]) { + closesocket(wsr_array[i]); + wsr_array[i] = (rktio_socket_t)NULL; + } } + + wsr_size = 0; + wsr_array = NULL; + + WSACleanup(); } - + ReleaseSemaphore(winsock_sema, 1, NULL); } -#else -/* Not Windows */ -# define TCP_INIT(x) /* nothing */ #endif /*========================================================================*/ @@ -1197,7 +1192,7 @@ rktio_fd_t *rktio_connect_finish(rktio_t *rktio, rktio_connect_t *conn) if (conn->inprogress) { /* Check whether connect succeeded, or get error: */ int errid; - unsigned int so_len = sizeof(errid); + rktio_sockopt_len_t so_len = sizeof(errid); rktio_socket_t s = rktio_fd_system_fd(rktio, rfd); if (getsockopt(s, SOL_SOCKET, SO_ERROR, (void *)&errid, &so_len) != 0) { errid = SOCK_ERRNO(); @@ -1435,7 +1430,7 @@ static int get_no_portno(rktio_t *rktio, rktio_socket_t socket) { char here[RKTIO_SOCK_NAME_MAX_LEN]; struct sockaddr_in *addr_in; - unsigned int l = sizeof(here); + rktio_sockopt_len_t l = sizeof(here); unsigned short no_port; if (getsockname(socket, (struct sockaddr *)here, &l)) { @@ -1561,7 +1556,7 @@ rktio_fd_t *rktio_accept(rktio_t *rktio, rktio_listener_t *listener) int ready_pos; rktio_socket_t s, ls; - unsigned int l; + rktio_sockopt_len_t l; char tcp_accept_addr[RKTIO_SOCK_NAME_MAX_LEN]; ready_pos = do_poll_accept_ready(rktio, listener, 1); @@ -1632,7 +1627,7 @@ static char **get_numeric_strings(rktio_t *rktio, void *sa, unsigned int salen) char **rktio_socket_address(rktio_t *rktio, rktio_fd_t *rfd) { char name[RKTIO_SOCK_NAME_MAX_LEN]; - unsigned int name_len; + rktio_sockopt_len_t name_len; name_len = sizeof(name); if (getsockname(rktio_fd_system_fd(rktio, rfd), (struct sockaddr *)name, &name_len)) { @@ -1646,7 +1641,7 @@ char **rktio_socket_address(rktio_t *rktio, rktio_fd_t *rfd) char **rktio_socket_peer_address(rktio_t *rktio, rktio_fd_t *rfd) { char name[RKTIO_SOCK_NAME_MAX_LEN]; - unsigned int name_len; + rktio_sockopt_len_t name_len; name_len = sizeof(name); if (getpeername(rktio_fd_system_fd(rktio, rfd), (struct sockaddr *)name, &name_len)) { @@ -1779,7 +1774,7 @@ rktio_length_and_addrinfo_t *rktio_udp_recvfrom(rktio_t *rktio, rktio_fd_t *rfd, rktio_length_and_addrinfo_t *r; int rn, errid; char src_addr[RKTIO_SOCK_NAME_MAX_LEN]; - unsigned int asize = sizeof(src_addr); + rktio_sockopt_len_t asize = sizeof(src_addr); while (1) { if (!len) { @@ -1830,7 +1825,7 @@ int rktio_udp_get_multicast_loopback(rktio_t *rktio, rktio_fd_t *rfd) { rktio_socket_t s = rktio_fd_system_fd(rktio, rfd); u_char loop; - unsigned int loop_len = sizeof(loop); + rktio_sockopt_len_t loop_len = sizeof(loop); int status; status = getsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&loop, &loop_len); @@ -1846,7 +1841,7 @@ int rktio_udp_set_multicast_loopback(rktio_t *rktio, rktio_fd_t *rfd, int on) { rktio_socket_t s = rktio_fd_system_fd(rktio, rfd); u_char loop = (on ? 1 : 0); - unsigned int loop_len = sizeof(loop); + rktio_sockopt_len_t loop_len = sizeof(loop); int status; status = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&loop, loop_len); @@ -1862,7 +1857,7 @@ int rktio_udp_get_multicast_ttl(rktio_t *rktio, rktio_fd_t *rfd) { rktio_socket_t s = rktio_fd_system_fd(rktio, rfd); u_char ttl; - unsigned int ttl_len = sizeof(ttl); + rktio_sockopt_len_t ttl_len = sizeof(ttl); int status; status = getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, &ttl_len); @@ -1878,7 +1873,7 @@ int rktio_udp_set_multicast_ttl(rktio_t *rktio, rktio_fd_t *rfd, int ttl_val) { rktio_socket_t s = rktio_fd_system_fd(rktio, rfd); u_char ttl = ttl_val; - unsigned int ttl_len = sizeof(ttl); + rktio_sockopt_len_t ttl_len = sizeof(ttl); int status; status = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, ttl_len); @@ -1894,7 +1889,7 @@ char *rktio_udp_multicast_interface(rktio_t *rktio, rktio_fd_t *rfd) { rktio_socket_t s = rktio_fd_system_fd(rktio, rfd); struct in_addr intf; - unsigned int intf_len = sizeof(intf); + rktio_sockopt_len_t intf_len = sizeof(intf); int status; status = getsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (void *)&intf, &intf_len); @@ -1913,7 +1908,7 @@ int rktio_udp_set_multicast_interface(rktio_t *rktio, rktio_fd_t *rfd, rktio_add { rktio_socket_t s = rktio_fd_system_fd(rktio, rfd); struct in_addr intf; - unsigned int intf_len = sizeof(intf); + rktio_sockopt_len_t intf_len = sizeof(intf); int status; if (!intf_addr) { @@ -1937,7 +1932,7 @@ int rktio_udp_change_multicast_group(rktio_t *rktio, rktio_fd_t *rfd, { rktio_socket_t s = rktio_fd_system_fd(rktio, rfd); struct ip_mreq mreq; - unsigned int mreq_len = sizeof(mreq); + rktio_sockopt_len_t mreq_len = sizeof(mreq); int status; int optname; diff --git a/racket/src/rktio/rktio_poll_set.c b/racket/src/rktio/rktio_poll_set.c index 289ddb198d..5ceb61c226 100644 --- a/racket/src/rktio/rktio_poll_set.c +++ b/racket/src/rktio/rktio_poll_set.c @@ -393,7 +393,7 @@ static void init_fdset_array(rktio_poll_set_t *fdarray, int count) int reset = 0; fd = rktio_get_fdset(fdarray, i); fd->added = 0; - if (RKTIO_INT_VAL(fd->alloc) > (2 * RKTIO_INT_VAL(fd->last_alloc))) { + if (fd->alloc > (2 * fd->last_alloc)) { fd->alloc = 0; if (fd->sockets) free(fd->sockets); fd->sockets = NULL; @@ -401,7 +401,7 @@ static void init_fdset_array(rktio_poll_set_t *fdarray, int count) } fd->last_alloc = 0; fd->num_handles = 0; - if (RKTIO_INT_VAL(fd->alloc_handles) > (2 * RKTIO_INT_VAL(fd->last_alloc_handles))) { + if (fd->alloc_handles > (2 * fd->last_alloc_handles)) { fd->alloc_handles = 0; if (fd->handles) free(fd->handles); if (fd->repost_sema) free(fd->repost_sema); @@ -488,7 +488,7 @@ void rktio_fdset(rktio_poll_set_t *fd, int n) int na; na = next_size(fd->alloc); naya = malloc(na * sizeof(SOCKET)); - memcpy(naya, fd->sockets, RKTIO_INT_VAL(fd->alloc) * sizeof(SOCKET)); + memcpy(naya, fd->sockets, fd->alloc * sizeof(SOCKET)); if (fd->sockets) free(fd->sockets); fd->sockets = naya; fd->alloc = na; @@ -630,7 +630,7 @@ void rktio_collapse_win_fd(rktio_poll_set_t *fds) rfd->combined_wait_array = NULL; } else { /* merge */ - if (rfd->alloc < RKTIO_INT_VAL(wfd->alloc)) { + if (rfd->alloc < wfd->alloc) { if (wfd->alloc < efd->alloc) wa = efd->wait_array; else @@ -924,8 +924,13 @@ int rktio_initialize_signal(rktio_t *rktio) } #endif -#ifdef WIN32_FD_HANDLES - break_semaphore = (void*)CreateSemaphore(NULL, 0, 1, NULL); +#ifdef RKTIO_SYSTEM_WINDOWS + rktio->break_semaphore = (void*)CreateSemaphore(NULL, 0, 1, NULL); + if (rktio->break_semaphore == INVALID_HANDLE_VALUE) { + get_windows_error(); + return 0; + } else + return 1; #endif } @@ -1111,11 +1116,15 @@ void rktio_sleep(rktio_t *rktio, float nsecs, rktio_poll_set_t *fds, rktio_ltps_ } # endif #else -# ifndef NO_SLEEP -# ifndef NO_USLEEP - usleep((unsigned)(nsecs * 1000)); -# else - sleep(nsecs); +# ifdef RKTIO_SYSTEM_WINDOWS + Sleep((DWORD)(nsecs * 1000)); +# else +# ifndef NO_SLEEP +# ifndef NO_USLEEP + usleep((unsigned)(nsecs * 1000)); +# else + sleep(nsecs); +# endif # endif # endif #endif @@ -1195,7 +1204,7 @@ void rktio_sleep(rktio_t *rktio, float nsecs, rktio_poll_set_t *fds, rktio_ltps_ HANDLE *array, just_two_array[2]; int count, rcount, *rps; - scheme_collapse_win_fd(fds); /* merges */ + rktio_collapse_win_fd(fds); /* merges */ rcount = fds->num_handles; count = fds->combined_len; @@ -1260,7 +1269,7 @@ void rktio_sleep(rktio_t *rktio, float nsecs, rktio_poll_set_t *fds, rktio_ltps_ result = MsgWaitForMultipleObjects(count, array, FALSE, msec, fds->wait_event_mask); } clean_up_wait(rktio, result, array, rps, rcount); - scheme_collapse_win_fd(fds); /* cleans up */ + rktio_collapse_win_fd(fds); /* cleans up */ return; } diff --git a/racket/src/rktio/rktio_private.h b/racket/src/rktio/rktio_private.h index a563783128..f57aff05e6 100644 --- a/racket/src/rktio/rktio_private.h +++ b/racket/src/rktio/rktio_private.h @@ -227,6 +227,8 @@ void rktio_set_racket_error(rktio_t *rktio, int errid); #ifdef RKTIO_SYSTEM_WINDOWS void rktio_get_windows_error(rktio_t *rktio); # define get_windows_error() rktio_get_windows_error(rktio) +void rktio_set_windows_error(rktio_t *rktio, int errid); +# define set_windows_error(errid) rktio_set_windows_error(rktio, errid) #endif #if defined(USE_FCNTL_O_NONBLOCK) @@ -243,10 +245,14 @@ void rktio_get_windows_error(rktio_t *rktio); void rktio_reliably_close(intptr_t s); #endif +int rktio_system_fd_is_terminal(rktio_t *rktio, intptr_t fd); + void *rktio_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars); void rktio_stop_fs_change(rktio_t *rktio); -#ifdef RKTIO_SYSTEM_UNIX -void rktio_useless_wide(); +#ifdef RKTIO_SYSTEM_WINDOWS +int rktio_winsock_init(rktio_t *rktio); +void rktio_winsock_done(rktio_t *rktio); #endif +void rktio_init_wide(rktio_t *rktio); diff --git a/racket/src/rktio/rktio_process.c b/racket/src/rktio/rktio_process.c index b02ced0dc7..f1af4d7b5c 100644 --- a/racket/src/rktio/rktio_process.c +++ b/racket/src/rktio/rktio_process.c @@ -948,7 +948,6 @@ static int do_subprocess_kill(rktio_t *rktio, rktio_process_t *sp, int as_kill) #if defined(RKTIO_SYSTEM_WINDOWS) if (as_kill || sp->is_group) { DWORD w; - int errid; if (!sp->handle) return 1; @@ -1137,9 +1136,9 @@ static intptr_t do_spawnv(rktio_t *rktio, /* If none of the stdio handles are consoles, specifically create the subprocess without a console: */ - if (!is_fd_terminal((intptr_t)startup.hStdInput) - && !is_fd_terminal((intptr_t)startup.hStdOutput) - && !is_fd_terminal((intptr_t)startup.hStdError)) + if (!rktio_system_fd_is_terminal(rktio, (intptr_t)startup.hStdInput) + && !rktio_system_fd_is_terminal(rktio, (intptr_t)startup.hStdOutput) + && !rktio_system_fd_is_terminal(rktio, (intptr_t)startup.hStdError)) cr_flag = CREATE_NO_WINDOW; else cr_flag = 0; @@ -1218,12 +1217,16 @@ static void CloseFileHandleForSubprocess(intptr_t *hs, int pos) #define RKTIO_COPY_FOR_SUBPROCESS(array, pos) CopyFileHandleForSubprocess(array, pos) #define RKTIO_CLOSE_SUBPROCESS_COPY(array, pos) CloseFileHandleForSubprocess(array, pos) +#define RKTIO_CLOSE(fd) CloseHandle((HANDLE)fd) #endif /* RKTIO_SYSTEM_WINDOWS */ #ifdef RKTIO_SYSTEM_UNIX + # define RKTIO_COPY_FOR_SUBPROCESS(array, pos) /* empty */ # define RKTIO_CLOSE_SUBPROCESS_COPY(array, pos) /* empty */ +# define RKTIO_CLOSE(fd) rktio_reliably_close(fd) + #endif /*========================================================================*/ @@ -1239,7 +1242,7 @@ rktio_process_result_t *rktio_process(rktio_t *rktio, { rktio_process_result_t *result; intptr_t to_subprocess[2], from_subprocess[2], err_subprocess[2]; - int pid, errid; + int pid; #if defined(RKTIO_SYSTEM_UNIX) # if !defined(CENTRALIZED_SIGCHILD) System_Child *sc; @@ -1324,8 +1327,10 @@ rktio_process_result_t *rktio_process(rktio_t *rktio, argv = new_argv; } + pid = 0; + spawn_status = do_spawnv(rktio, - command, (const char * const *)new_argv, + command, (const char * const *)argv, windows_exact_cmdline, to_subprocess[0], from_subprocess[1], @@ -1452,6 +1457,8 @@ rktio_process_result_t *rktio_process(rktio_t *rktio, case 0: /* child */ { + int errid; + /* Copy pipe descriptors to stdin and stdout */ do { errid = MSC_IZE(dup2)(to_subprocess[0], 0); @@ -1528,22 +1535,21 @@ rktio_process_result_t *rktio_process(rktio_t *rktio, free(env); - if (!stdin_fd) { - rktio_reliably_close(to_subprocess[0]); - } else { + if (!stdin_fd) + RKTIO_CLOSE(to_subprocess[0]); + else RKTIO_CLOSE_SUBPROCESS_COPY(to_subprocess, 0); - } - if (!stdout_fd) { - rktio_reliably_close(from_subprocess[1]); - } else { + + if (!stdout_fd) + RKTIO_CLOSE(from_subprocess[1]); + else RKTIO_CLOSE_SUBPROCESS_COPY(from_subprocess, 1); - } + if (!stderr_fd) { if (!stderr_is_stdout) - rktio_reliably_close(err_subprocess[1]); - } else { + RKTIO_CLOSE(err_subprocess[1]); + } else RKTIO_CLOSE_SUBPROCESS_COPY(err_subprocess, 1); - } /*--------------------------------------*/ /* Create new file-descriptor objects */ diff --git a/racket/src/rktio/rktio_wide.c b/racket/src/rktio/rktio_wide.c index 71e9b8b5b6..8d7a67f64b 100644 --- a/racket/src/rktio/rktio_wide.c +++ b/racket/src/rktio/rktio_wide.c @@ -4,8 +4,7 @@ /* For converting byte strings to and from "wide" strings on Windows. */ #ifdef RKTIO_SYSTEM_UNIX -/* To avoid complaints about an empty object file */ -void rktio_useless_wide() { } +void rktio_init_wide(rktio_t *rktio) { } #endif #ifdef RKTIO_SYSTEM_WINDOWS @@ -14,6 +13,17 @@ void rktio_useless_wide() { } #include #include +void rktio_init_wide(rktio_t *rktio) +{ + OSVERSIONINFO info; + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&info); + if (info.dwPlatformId == VER_PLATFORM_WIN32_NT) + rktio->windows_nt_or_later = 1; + else + rktio->windows_nt_or_later = 0; +} + /* A UTF-8 to UTF-16 conversion, but accepts an extended variant of UTF-16 that accommodates unpaired surrogates, so that all 16-byte sequences are accessible. */ @@ -300,7 +310,8 @@ wchar_t *rktio_convert_to_wchar(rktio_t *rktio, const char *s, int do_copy) rktio->wide_buffer_size = RKTIO_MAX_IDEAL_BUFFER_SIZE; ws = malloc(sizeof(wchar_t) * RKTIO_MAX_IDEAL_BUFFER_SIZE); rktio->wide_buffer = ws; - } + } else + ws = rktio->wide_buffer; (void)utf8ish_to_utf16ish((unsigned char *)s, l, (unsigned short*)ws, '\t'); @@ -316,9 +327,9 @@ char *rktio_convert_from_wchar(const wchar_t *ws, int free_given) len = utf16ish_to_utf8ish((unsigned short *)ws, l, NULL); - s = (char *)scheme_malloc_atomic(len); + s = malloc(len); - len = utf16ish_to_utf8ish((unsigned short *)ws, l, s); + len = utf16ish_to_utf8ish((unsigned short *)ws, l, (unsigned char *)s); if (free_given) free((void *)ws);