rktio: more repairs exposed by warnings

This commit is contained in:
Matthew Flatt 2017-06-13 08:04:19 -06:00
parent 2f5797f1d5
commit 03c3655b1f
14 changed files with 215 additions and 139 deletions

View File

@ -169,7 +169,7 @@ static void check_hello_content(rktio_t *rktio, char *fn)
{ {
rktio_fd_t *fd; rktio_fd_t *fd;
intptr_t amt; intptr_t amt;
char buffer[256], *s; char buffer[256];
fd = rktio_open(rktio, fn, RKTIO_OPEN_READ); fd = rktio_open(rktio, fn, RKTIO_OPEN_READ);
check_valid(fd); 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_t *lt;
rktio_ltps_handle_t *h1, *h2; rktio_ltps_handle_t *h1, *h2;
intptr_t amt, i; intptr_t amt;
char buffer[256]; char buffer[256];
lt = try_check_ltps(rktio, fd, fd2, &h1, &h2); 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_directory_list_t *ls;
rktio_file_copy_t *cp; rktio_file_copy_t *cp;
rktio_timestamp_t *ts1, *ts1a; rktio_timestamp_t *ts1, *ts1a;
rktio_ltps_t *lt;
rktio_ltps_handle_t *h1, *h2;
int verbose = 0, dont_rely_on_sigchild = 0; int verbose = 0, dont_rely_on_sigchild = 0;
for (i = 1; i < argc; i++) { 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: */ /* We expect `lt` to work on regular files except on Windows and epoll: */
#if !defined(RKTIO_SYSTEM_WINDOWS) && !defined(HAVE_EPOLL_SYSCALL) #if !defined(RKTIO_SYSTEM_WINDOWS) && !defined(HAVE_EPOLL_SYSCALL)
fd = rktio_open(rktio, "test1", RKTIO_OPEN_READ); {
check_valid(fd); rktio_ltps_handle_t *h1, *h2;
fd2 = rktio_open(rktio, "test1", RKTIO_OPEN_WRITE | RKTIO_OPEN_CAN_EXIST); rktio_ltps_t *lt;
check_valid(fd2);
lt = try_check_ltps(rktio, fd, fd2, &h1, &h2); fd = rktio_open(rktio, "test1", RKTIO_OPEN_READ);
check_valid(lt); check_valid(fd);
check_ltps_read_and_write_ready(rktio, lt, h1, h2); fd2 = rktio_open(rktio, "test1", RKTIO_OPEN_WRITE | RKTIO_OPEN_CAN_EXIST);
check_valid(rktio_ltps_close(rktio, lt)); check_valid(fd2);
check_valid(rktio_close(rktio, fd)); lt = try_check_ltps(rktio, fd, fd2, &h1, &h2);
check_valid(rktio_close(rktio, fd2)); 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 #endif
/* Pipes, non-blocking operations, and more long-term poll sets */ /* Pipes, non-blocking operations, and more long-term poll sets */

View File

@ -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_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_socket(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_fd_is_udp(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); int rktio_fd_modes(rktio_t *rktio, rktio_fd_t *rfd);

View File

@ -95,7 +95,7 @@ int rktio_setenv(rktio_t *rktio, const char *name, const char *val)
if (rc) if (rc)
return 1; return 1;
set_windows_error(); get_windows_error();
return 0; return 0;
#endif #endif
} }
@ -341,8 +341,8 @@ void *rktio_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars)
wchar_t *r, *s; wchar_t *r, *s;
for (i = 0; i < envvars->count; i++) { for (i = 0; i < envvars->count; i++) {
len += wc_strlen(WIDE_PATH_temp(envvars->names[i])); len += wcslen(WIDE_PATH_temp(envvars->names[i]));
len += wc_strlen(WIDE_PATH_temp(envvars->vals[i])); len += wcslen(WIDE_PATH_temp(envvars->vals[i]));
len += 2; len += 2;
} }
@ -352,12 +352,12 @@ for (i = 0; i < envvars->count; i++) {
for (i = 0; i < envvars->count; i++) { for (i = 0; i < envvars->count; i++) {
s = WIDE_PATH_temp(envvars->names[i]); s = WIDE_PATH_temp(envvars->names[i]);
slen = wc_strlen(s); slen = wcslen(s);
memcpy(r + len, s, slen * sizeof(wchar_t)); memcpy(r + len, s, slen * sizeof(wchar_t));
len += slen; len += slen;
r[len++] = '='; r[len++] = '=';
s = WIDE_PATH_temp(envvars->vals[i]); s = WIDE_PATH_temp(envvars->vals[i]);
slen = wc_strlen(s); slen = wcslen(s);
memcpy(r + len, s, slen * sizeof(wchar_t)); memcpy(r + len, s, slen * sizeof(wchar_t));
len += slen; len += slen;
r[len++] = 0; r[len++] = 0;

View File

@ -24,6 +24,12 @@ void rktio_get_windows_error(rktio_t *rktio)
rktio->errid = GetLastError(); rktio->errid = GetLastError();
rktio->errkind = RKTIO_ERROR_KIND_WINDOWS; 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 #endif
int rktio_get_last_error(rktio_t *rktio) int rktio_get_last_error(rktio_t *rktio)

View File

@ -234,6 +234,28 @@ int rktio_fd_is_udp(rktio_t *rktio, rktio_fd_t *rfd)
return ((rfd->modes & RKTIO_OPEN_UDP) ? 1 : 0); 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) rktio_fd_t *rktio_dup(rktio_t *rktio, rktio_fd_t *rfd)
{ {
#ifdef RKTIO_SYSTEM_UNIX #ifdef RKTIO_SYSTEM_UNIX
@ -249,9 +271,9 @@ rktio_fd_t *rktio_dup(rktio_t *rktio, rktio_fd_t *rfd)
} else } else
return rktio_system_fd(rktio, nfd, rfd->modes); return rktio_system_fd(rktio, nfd, rfd->modes);
#endif #endif
#ifdef WINDOWS_FILE_HANDLES #ifdef RKTIO_SYSTEM_WINDOWS
if (rfd->modes & RKTIO_OPEN_SOCKET) { if (rfd->modes & RKTIO_OPEN_SOCKET) {
return rktio_socket_dup(rktio_t *rktio, rktio_fd_t *rfd) return rktio_socket_dup(rktio, rfd);
} else { } else {
HANDLE newhandle; HANDLE newhandle;
BOOL rc; 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)) if (rfd->oth && !rktio_poll_write_ready(rktio, rfd))
rktio_poll_set_add_handle(rktio, (intptr_t)rfd->oth->ready_sema, fds, 1); rktio_poll_set_add_handle(rktio, (intptr_t)rfd->oth->ready_sema, fds, 1);
else else
rktio_poll_set_nosleep(rktio, fds); rktio_poll_set_add_nosleep(rktio, fds);
} }
} }
#endif #endif
@ -701,7 +723,7 @@ intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len)
if (!rfd->th) { if (!rfd->th) {
/* We can read directly. This must be a regular file, where /* We can read directly. This must be a regular file, where
reading never blocks. */ reading never blocks. */
DWORD rgot, delta; DWORD rgot;
if (!ReadFile((HANDLE)rfd->fd, buffer, len, &rgot, NULL)) { if (!ReadFile((HANDLE)rfd->fd, buffer, len, &rgot, NULL)) {
get_windows_error(); get_windows_error();
@ -713,7 +735,7 @@ intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len)
else else
return rgot; return rgot;
} else { } else {
if (!rktio_poll_read(rfd)) if (!rktio_poll_read_ready(rktio, rfd))
return 0; return 0;
/* If we get this far, there's definitely data available. /* 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) static void WindowsFDICleanup(Win_FD_Input_Thread *th)
{ {
int rc;
CloseHandle(th->checking_sema); CloseHandle(th->checking_sema);
CloseHandle(th->ready_sema); CloseHandle(th->ready_sema);
CloseHandle(th->you_clean_up_sema); CloseHandle(th->you_clean_up_sema);
if (!rc) CloseHandle(th->fd); CloseHandle(th->fd);
free(th->buffer); free(th->buffer);
free(th); 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) { if (!rfd->oth) {
/* The FILE_TYPE_PIPE test is currently redundant, I think, /* The FILE_TYPE_PIPE test is currently redundant, I think,
but better safe than sorry. */ but better safe than sorry. */
nonblocking = (rktio_windows_nt_or_later() nonblocking = (rktio->windows_nt_or_later
&& (GetFileType((HANDLE)rfd->fd) == FILE_TYPE_PIPE)); && (GetFileType((HANDLE)rfd->fd) == FILE_TYPE_PIPE));
} else } else
nonblocking = 1; /* must be, or we would not have gotten here */ 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))) { || (!ok && (errsaved == ERROR_NOT_ENOUGH_MEMORY))) {
towrite = towrite >> 1; towrite = towrite >> 1;
if (!towrite) { if (!towrite) {
set_windows_error(); get_windows_error();
return RKTIO_WRITE_ERROR; return RKTIO_WRITE_ERROR;
} }
} else } else
@ -1107,10 +1127,13 @@ intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len
ok = 1; ok = 1;
} }
ReleaseSemaphore(oth->lock_sema, 1, NULL); ReleaseSemaphore(oth->lock_sema, 1, NULL);
} else if (out_len > 0) { } else {
/* We've already written, which implies that no flush is if (out_len > 0) {
in progress. We'll need a flush check in the future. */ /* We've already written, which implies that no flush is
rfd->oth->needflush = 1; in progress. We'll need a flush check in the future. */
rfd->oth->needflush = 1;
}
ok = 1;
} }
if (ok) if (ok)
@ -1189,13 +1212,11 @@ static long WINAPI WindowsFDWriter(Win_FD_Output_Thread *oth)
static void WindowsFDOCleanup(Win_FD_Output_Thread *oth) static void WindowsFDOCleanup(Win_FD_Output_Thread *oth)
{ {
int rc;
CloseHandle(oth->lock_sema); CloseHandle(oth->lock_sema);
CloseHandle(oth->work_sema); CloseHandle(oth->work_sema);
CloseHandle(oth->you_clean_up_sema); CloseHandle(oth->you_clean_up_sema);
if (!rc) CloseHandle(oth->fd); CloseHandle(oth->fd);
if (oth->buffer) if (oth->buffer)
free(oth->buffer); free(oth->buffer);

View File

@ -158,7 +158,7 @@ static rktio_fd_t *open_write(rktio_t *rktio, char *filename, int modes)
#endif #endif
#ifdef RKTIO_SYSTEM_WINDOWS #ifdef RKTIO_SYSTEM_WINDOWS
HANDLE fd; HANDLE fd;
int hmode, regfile; int hmode;
BY_HANDLE_FILE_INFORMATION info; BY_HANDLE_FILE_INFORMATION info;
rktio_fd_t *rfd; rktio_fd_t *rfd;

View File

@ -127,7 +127,7 @@ rktio_fs_change_t *rktio_fs_change(rktio_t *rktio, char *path)
| FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_WRITE
| FILE_NOTIFY_CHANGE_ATTRIBUTES)); | FILE_NOTIFY_CHANGE_ATTRIBUTES));
if (h == INVALID_HANDLE_VALUE) if (h == INVALID_HANDLE_VALUE)
set_windows_error(); get_windows_error();
else { else {
fd = (intptr_t)h; fd = (intptr_t)h;
ok = 1; ok = 1;

View File

@ -44,15 +44,16 @@ typedef struct rktio_ltps_handle_pair_t {
rktio_ltps_handle_t *write_handle; rktio_ltps_handle_t *write_handle;
} rktio_ltps_handle_pair_t; } 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 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_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_remove(rktio_ltps_t *lt, intptr_t fd);
static void ltps_hash_init(rktio_ltps_t *lt); static void ltps_hash_init(rktio_ltps_t *lt);
static void ltps_hash_free(rktio_ltps_t *lt); static void ltps_hash_free(rktio_ltps_t *lt);
#if !defined(HAVE_KQUEUE_SYSCALL) && !defined(HAVE_EPOLL_SYSCALL) #if !defined(HAVE_KQUEUE_SYSCALL) && !defined(HAVE_EPOLL_SYSCALL)
static int ltps_is_hash_empty(rktio_ltps_t *lt); static int ltps_is_hash_empty(rktio_ltps_t *lt);
#endif #endif
#endif
/*========================================================================*/ /*========================================================================*/
@ -104,7 +105,9 @@ rktio_ltps_t *rktio_open_ltps(rktio_t *rktio)
lt->signaled = NULL; lt->signaled = NULL;
#ifdef RKTIO_SYSTEM_UNIX
ltps_hash_init(lt); ltps_hash_init(lt);
#endif
return lt; 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))) while ((s = rktio_ltps_get_signaled_handle(rktio, lt)))
free(s); free(s);
#ifdef RKTIO_SYSTEM_UNIX
ltps_hash_free(lt); ltps_hash_free(lt);
#endif
#if defined(HAVE_KQUEUE_SYSCALL) || defined(HAVE_EPOLL_SYSCALL) #if defined(HAVE_KQUEUE_SYSCALL) || defined(HAVE_EPOLL_SYSCALL)
if (lt->fd >= 0) { 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 { typedef struct ltps_bucket_t {
/* v is non-NULL => bucket is filled */ /* v is non-NULL => bucket is filled */
/* v is NULL and fd is -1 => was removed */ /* 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); return (lt->count == 0);
} }
#endif #endif
#endif

View File

@ -21,7 +21,14 @@ rktio_t *rktio_init(void)
return NULL; 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; return rktio;
} }
@ -32,6 +39,9 @@ void rktio_destroy(rktio_t *rktio)
rktio_free_ghbn(rktio); rktio_free_ghbn(rktio);
rktio_free_global_poll_set(rktio); rktio_free_global_poll_set(rktio);
rktio_stop_fs_change(rktio); rktio_stop_fs_change(rktio);
#ifdef RKTIO_SYSTEM_WINDOWS
rktio_winsock_done(rktio);
#endif
free(rktio); free(rktio);
} }
@ -41,4 +51,3 @@ void rktio_free(void *p)
{ {
free(p); free(p);
} }

View File

@ -24,6 +24,8 @@
# define RKTIO_AFNOSUPPORT EAFNOSUPPORT # define RKTIO_AFNOSUPPORT EAFNOSUPPORT
typedef intptr_t rktio_socket_t; typedef intptr_t rktio_socket_t;
typedef unsigned int rktio_sockopt_len_t;
# define INVALID_SOCKET (-1) # define INVALID_SOCKET (-1)
static void closesocket(rktio_socket_t s) { static void closesocket(rktio_socket_t s) {
@ -92,6 +94,7 @@ struct SOCKADDR_IN {
# define RKTIO_AFNOSUPPORT WSAEAFNOSUPPORT # define RKTIO_AFNOSUPPORT WSAEAFNOSUPPORT
typedef SOCKET rktio_socket_t; typedef SOCKET rktio_socket_t;
typedef int rktio_sockopt_len_t;
typedef struct SOCKADDR_IN rktio_unspec_address; typedef struct SOCKADDR_IN rktio_unspec_address;
# define REGISTER_SOCKET(s) winsock_remember(s) # 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 # ifdef RKTIO_SYSTEM_WINDOWS
{ {
HANDLE ready_sema;
unsigned int id;
intptr_t th;
lookup->done_sema = CreateSemaphore(NULL, 0, 1, NULL); lookup->done_sema = CreateSemaphore(NULL, 0, 1, NULL);
if (!lookup->done_sema) { if (!lookup->done_sema) {
get_windows_error(); get_windows_error();
@ -761,16 +760,10 @@ const char *rktio_gai_strerror(int errnum)
#ifdef RKTIO_SYSTEM_WINDOWS #ifdef RKTIO_SYSTEM_WINDOWS
static HANDLE winsock_sema; static HANDLE winsock_sema;
static int winsock_started = 0;
static int wsr_size = 0; static int wsr_size = 0;
static rktio_socket_t *wsr_array; 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) static void winsock_remember(rktio_socket_t s)
{ {
int i, new_size; int i, new_size;
@ -804,18 +797,14 @@ static void winsock_remember(rktio_socket_t s)
wsr_size = new_size; wsr_size = new_size;
} }
# ifdef RKTIO_USE_PLACES
ReleaseSemaphore(winsock_sema, 1, NULL); ReleaseSemaphore(winsock_sema, 1, NULL);
# endif
} }
static void winsock_forget(rktio_socket_t s) static void winsock_forget(rktio_socket_t s)
{ {
int i; int i;
# ifdef RKTIO_USE_PLACES
WaitForSingleObject(winsock_sema, INFINITE); WaitForSingleObject(winsock_sema, INFINITE);
# endif
for (i = 0; i < wsr_size; i++) { for (i = 0; i < wsr_size; i++) {
if (wsr_array[i] == s) { 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); ReleaseSemaphore(winsock_sema, 1, NULL);
# endif
} }
static int winsock_done(void) int rktio_winsock_init(rktio_t *rktio)
{ {
int i; if (!winsock_sema) {
winsock_sema = CreateSemaphore(NULL, 1, 1, NULL);
/* 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); WaitForSingleObject(winsock_sema, INFINITE);
if (!started) { if (!winsock_started) {
WSADATA data; WSADATA data;
if (!WSAStartup(MAKEWORD(1, 1), &data)) { if (!WSAStartup(MAKEWORD(1, 1), &data)) {
started = 1; winsock_started = 1;
#ifdef __BORLANDC__ } else {
atexit((void(*)())winsock_done); get_windows_error();
#else ReleaseSemaphore(winsock_sema, 1, NULL);
_onexit(winsock_done); return 0;
#endif
} }
} else
winsock_started++;
ReleaseSemaphore(winsock_sema, 1, NULL);
return 1;
}
void rktio_winsock_done(rktio_t *rktio)
{
int i;
WaitForSingleObject(winsock_sema, INFINITE);
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); ReleaseSemaphore(winsock_sema, 1, NULL);
} }
#else
/* Not Windows */
# define TCP_INIT(x) /* nothing */
#endif #endif
/*========================================================================*/ /*========================================================================*/
@ -1197,7 +1192,7 @@ rktio_fd_t *rktio_connect_finish(rktio_t *rktio, rktio_connect_t *conn)
if (conn->inprogress) { if (conn->inprogress) {
/* Check whether connect succeeded, or get error: */ /* Check whether connect succeeded, or get error: */
int errid; 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); rktio_socket_t s = rktio_fd_system_fd(rktio, rfd);
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (void *)&errid, &so_len) != 0) { if (getsockopt(s, SOL_SOCKET, SO_ERROR, (void *)&errid, &so_len) != 0) {
errid = SOCK_ERRNO(); 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]; char here[RKTIO_SOCK_NAME_MAX_LEN];
struct sockaddr_in *addr_in; struct sockaddr_in *addr_in;
unsigned int l = sizeof(here); rktio_sockopt_len_t l = sizeof(here);
unsigned short no_port; unsigned short no_port;
if (getsockname(socket, (struct sockaddr *)here, &l)) { if (getsockname(socket, (struct sockaddr *)here, &l)) {
@ -1561,7 +1556,7 @@ rktio_fd_t *rktio_accept(rktio_t *rktio, rktio_listener_t *listener)
int int
ready_pos; ready_pos;
rktio_socket_t s, ls; rktio_socket_t s, ls;
unsigned int l; rktio_sockopt_len_t l;
char tcp_accept_addr[RKTIO_SOCK_NAME_MAX_LEN]; char tcp_accept_addr[RKTIO_SOCK_NAME_MAX_LEN];
ready_pos = do_poll_accept_ready(rktio, listener, 1); 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 **rktio_socket_address(rktio_t *rktio, rktio_fd_t *rfd)
{ {
char name[RKTIO_SOCK_NAME_MAX_LEN]; char name[RKTIO_SOCK_NAME_MAX_LEN];
unsigned int name_len; rktio_sockopt_len_t name_len;
name_len = sizeof(name); name_len = sizeof(name);
if (getsockname(rktio_fd_system_fd(rktio, rfd), (struct sockaddr *)name, &name_len)) { 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 **rktio_socket_peer_address(rktio_t *rktio, rktio_fd_t *rfd)
{ {
char name[RKTIO_SOCK_NAME_MAX_LEN]; char name[RKTIO_SOCK_NAME_MAX_LEN];
unsigned int name_len; rktio_sockopt_len_t name_len;
name_len = sizeof(name); name_len = sizeof(name);
if (getpeername(rktio_fd_system_fd(rktio, rfd), (struct sockaddr *)name, &name_len)) { 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; rktio_length_and_addrinfo_t *r;
int rn, errid; int rn, errid;
char src_addr[RKTIO_SOCK_NAME_MAX_LEN]; char src_addr[RKTIO_SOCK_NAME_MAX_LEN];
unsigned int asize = sizeof(src_addr); rktio_sockopt_len_t asize = sizeof(src_addr);
while (1) { while (1) {
if (!len) { 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); rktio_socket_t s = rktio_fd_system_fd(rktio, rfd);
u_char loop; u_char loop;
unsigned int loop_len = sizeof(loop); rktio_sockopt_len_t loop_len = sizeof(loop);
int status; int status;
status = getsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&loop, &loop_len); 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); rktio_socket_t s = rktio_fd_system_fd(rktio, rfd);
u_char loop = (on ? 1 : 0); u_char loop = (on ? 1 : 0);
unsigned int loop_len = sizeof(loop); rktio_sockopt_len_t loop_len = sizeof(loop);
int status; int status;
status = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&loop, loop_len); 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); rktio_socket_t s = rktio_fd_system_fd(rktio, rfd);
u_char ttl; u_char ttl;
unsigned int ttl_len = sizeof(ttl); rktio_sockopt_len_t ttl_len = sizeof(ttl);
int status; int status;
status = getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, &ttl_len); 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); rktio_socket_t s = rktio_fd_system_fd(rktio, rfd);
u_char ttl = ttl_val; u_char ttl = ttl_val;
unsigned int ttl_len = sizeof(ttl); rktio_sockopt_len_t ttl_len = sizeof(ttl);
int status; int status;
status = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, ttl_len); 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); rktio_socket_t s = rktio_fd_system_fd(rktio, rfd);
struct in_addr intf; struct in_addr intf;
unsigned int intf_len = sizeof(intf); rktio_sockopt_len_t intf_len = sizeof(intf);
int status; int status;
status = getsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (void *)&intf, &intf_len); 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); rktio_socket_t s = rktio_fd_system_fd(rktio, rfd);
struct in_addr intf; struct in_addr intf;
unsigned int intf_len = sizeof(intf); rktio_sockopt_len_t intf_len = sizeof(intf);
int status; int status;
if (!intf_addr) { 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); rktio_socket_t s = rktio_fd_system_fd(rktio, rfd);
struct ip_mreq mreq; struct ip_mreq mreq;
unsigned int mreq_len = sizeof(mreq); rktio_sockopt_len_t mreq_len = sizeof(mreq);
int status; int status;
int optname; int optname;

View File

@ -393,7 +393,7 @@ static void init_fdset_array(rktio_poll_set_t *fdarray, int count)
int reset = 0; int reset = 0;
fd = rktio_get_fdset(fdarray, i); fd = rktio_get_fdset(fdarray, i);
fd->added = 0; 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; fd->alloc = 0;
if (fd->sockets) free(fd->sockets); if (fd->sockets) free(fd->sockets);
fd->sockets = NULL; fd->sockets = NULL;
@ -401,7 +401,7 @@ static void init_fdset_array(rktio_poll_set_t *fdarray, int count)
} }
fd->last_alloc = 0; fd->last_alloc = 0;
fd->num_handles = 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; fd->alloc_handles = 0;
if (fd->handles) free(fd->handles); if (fd->handles) free(fd->handles);
if (fd->repost_sema) free(fd->repost_sema); if (fd->repost_sema) free(fd->repost_sema);
@ -488,7 +488,7 @@ void rktio_fdset(rktio_poll_set_t *fd, int n)
int na; int na;
na = next_size(fd->alloc); na = next_size(fd->alloc);
naya = malloc(na * sizeof(SOCKET)); 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); if (fd->sockets) free(fd->sockets);
fd->sockets = naya; fd->sockets = naya;
fd->alloc = na; fd->alloc = na;
@ -630,7 +630,7 @@ void rktio_collapse_win_fd(rktio_poll_set_t *fds)
rfd->combined_wait_array = NULL; rfd->combined_wait_array = NULL;
} else { } else {
/* merge */ /* merge */
if (rfd->alloc < RKTIO_INT_VAL(wfd->alloc)) { if (rfd->alloc < wfd->alloc) {
if (wfd->alloc < efd->alloc) if (wfd->alloc < efd->alloc)
wa = efd->wait_array; wa = efd->wait_array;
else else
@ -924,8 +924,13 @@ int rktio_initialize_signal(rktio_t *rktio)
} }
#endif #endif
#ifdef WIN32_FD_HANDLES #ifdef RKTIO_SYSTEM_WINDOWS
break_semaphore = (void*)CreateSemaphore(NULL, 0, 1, NULL); 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 #endif
} }
@ -1111,11 +1116,15 @@ void rktio_sleep(rktio_t *rktio, float nsecs, rktio_poll_set_t *fds, rktio_ltps_
} }
# endif # endif
#else #else
# ifndef NO_SLEEP # ifdef RKTIO_SYSTEM_WINDOWS
# ifndef NO_USLEEP Sleep((DWORD)(nsecs * 1000));
usleep((unsigned)(nsecs * 1000)); # else
# else # ifndef NO_SLEEP
sleep(nsecs); # ifndef NO_USLEEP
usleep((unsigned)(nsecs * 1000));
# else
sleep(nsecs);
# endif
# endif # endif
# 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]; HANDLE *array, just_two_array[2];
int count, rcount, *rps; int count, rcount, *rps;
scheme_collapse_win_fd(fds); /* merges */ rktio_collapse_win_fd(fds); /* merges */
rcount = fds->num_handles; rcount = fds->num_handles;
count = fds->combined_len; 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); result = MsgWaitForMultipleObjects(count, array, FALSE, msec, fds->wait_event_mask);
} }
clean_up_wait(rktio, result, array, rps, rcount); clean_up_wait(rktio, result, array, rps, rcount);
scheme_collapse_win_fd(fds); /* cleans up */ rktio_collapse_win_fd(fds); /* cleans up */
return; return;
} }

View File

@ -227,6 +227,8 @@ void rktio_set_racket_error(rktio_t *rktio, int errid);
#ifdef RKTIO_SYSTEM_WINDOWS #ifdef RKTIO_SYSTEM_WINDOWS
void rktio_get_windows_error(rktio_t *rktio); void rktio_get_windows_error(rktio_t *rktio);
# define get_windows_error() rktio_get_windows_error(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 #endif
#if defined(USE_FCNTL_O_NONBLOCK) #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); void rktio_reliably_close(intptr_t s);
#endif #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_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars);
void rktio_stop_fs_change(rktio_t *rktio); void rktio_stop_fs_change(rktio_t *rktio);
#ifdef RKTIO_SYSTEM_UNIX #ifdef RKTIO_SYSTEM_WINDOWS
void rktio_useless_wide(); int rktio_winsock_init(rktio_t *rktio);
void rktio_winsock_done(rktio_t *rktio);
#endif #endif
void rktio_init_wide(rktio_t *rktio);

View File

@ -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 defined(RKTIO_SYSTEM_WINDOWS)
if (as_kill || sp->is_group) { if (as_kill || sp->is_group) {
DWORD w; DWORD w;
int errid;
if (!sp->handle) if (!sp->handle)
return 1; return 1;
@ -1137,9 +1136,9 @@ static intptr_t do_spawnv(rktio_t *rktio,
/* If none of the stdio handles are consoles, specifically /* If none of the stdio handles are consoles, specifically
create the subprocess without a console: */ create the subprocess without a console: */
if (!is_fd_terminal((intptr_t)startup.hStdInput) if (!rktio_system_fd_is_terminal(rktio, (intptr_t)startup.hStdInput)
&& !is_fd_terminal((intptr_t)startup.hStdOutput) && !rktio_system_fd_is_terminal(rktio, (intptr_t)startup.hStdOutput)
&& !is_fd_terminal((intptr_t)startup.hStdError)) && !rktio_system_fd_is_terminal(rktio, (intptr_t)startup.hStdError))
cr_flag = CREATE_NO_WINDOW; cr_flag = CREATE_NO_WINDOW;
else else
cr_flag = 0; 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_COPY_FOR_SUBPROCESS(array, pos) CopyFileHandleForSubprocess(array, pos)
#define RKTIO_CLOSE_SUBPROCESS_COPY(array, pos) CloseFileHandleForSubprocess(array, pos) #define RKTIO_CLOSE_SUBPROCESS_COPY(array, pos) CloseFileHandleForSubprocess(array, pos)
#define RKTIO_CLOSE(fd) CloseHandle((HANDLE)fd)
#endif /* RKTIO_SYSTEM_WINDOWS */ #endif /* RKTIO_SYSTEM_WINDOWS */
#ifdef RKTIO_SYSTEM_UNIX #ifdef RKTIO_SYSTEM_UNIX
# define RKTIO_COPY_FOR_SUBPROCESS(array, pos) /* empty */ # define RKTIO_COPY_FOR_SUBPROCESS(array, pos) /* empty */
# define RKTIO_CLOSE_SUBPROCESS_COPY(array, pos) /* empty */ # define RKTIO_CLOSE_SUBPROCESS_COPY(array, pos) /* empty */
# define RKTIO_CLOSE(fd) rktio_reliably_close(fd)
#endif #endif
/*========================================================================*/ /*========================================================================*/
@ -1239,7 +1242,7 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
{ {
rktio_process_result_t *result; rktio_process_result_t *result;
intptr_t to_subprocess[2], from_subprocess[2], err_subprocess[2]; intptr_t to_subprocess[2], from_subprocess[2], err_subprocess[2];
int pid, errid; int pid;
#if defined(RKTIO_SYSTEM_UNIX) #if defined(RKTIO_SYSTEM_UNIX)
# if !defined(CENTRALIZED_SIGCHILD) # if !defined(CENTRALIZED_SIGCHILD)
System_Child *sc; System_Child *sc;
@ -1324,8 +1327,10 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
argv = new_argv; argv = new_argv;
} }
pid = 0;
spawn_status = do_spawnv(rktio, spawn_status = do_spawnv(rktio,
command, (const char * const *)new_argv, command, (const char * const *)argv,
windows_exact_cmdline, windows_exact_cmdline,
to_subprocess[0], to_subprocess[0],
from_subprocess[1], from_subprocess[1],
@ -1452,6 +1457,8 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
case 0: /* child */ case 0: /* child */
{ {
int errid;
/* Copy pipe descriptors to stdin and stdout */ /* Copy pipe descriptors to stdin and stdout */
do { do {
errid = MSC_IZE(dup2)(to_subprocess[0], 0); errid = MSC_IZE(dup2)(to_subprocess[0], 0);
@ -1528,22 +1535,21 @@ rktio_process_result_t *rktio_process(rktio_t *rktio,
free(env); free(env);
if (!stdin_fd) { if (!stdin_fd)
rktio_reliably_close(to_subprocess[0]); RKTIO_CLOSE(to_subprocess[0]);
} else { else
RKTIO_CLOSE_SUBPROCESS_COPY(to_subprocess, 0); RKTIO_CLOSE_SUBPROCESS_COPY(to_subprocess, 0);
}
if (!stdout_fd) { if (!stdout_fd)
rktio_reliably_close(from_subprocess[1]); RKTIO_CLOSE(from_subprocess[1]);
} else { else
RKTIO_CLOSE_SUBPROCESS_COPY(from_subprocess, 1); RKTIO_CLOSE_SUBPROCESS_COPY(from_subprocess, 1);
}
if (!stderr_fd) { if (!stderr_fd) {
if (!stderr_is_stdout) if (!stderr_is_stdout)
rktio_reliably_close(err_subprocess[1]); RKTIO_CLOSE(err_subprocess[1]);
} else { } else
RKTIO_CLOSE_SUBPROCESS_COPY(err_subprocess, 1); RKTIO_CLOSE_SUBPROCESS_COPY(err_subprocess, 1);
}
/*--------------------------------------*/ /*--------------------------------------*/
/* Create new file-descriptor objects */ /* Create new file-descriptor objects */

View File

@ -4,8 +4,7 @@
/* For converting byte strings to and from "wide" strings on Windows. */ /* For converting byte strings to and from "wide" strings on Windows. */
#ifdef RKTIO_SYSTEM_UNIX #ifdef RKTIO_SYSTEM_UNIX
/* To avoid complaints about an empty object file */ void rktio_init_wide(rktio_t *rktio) { }
void rktio_useless_wide() { }
#endif #endif
#ifdef RKTIO_SYSTEM_WINDOWS #ifdef RKTIO_SYSTEM_WINDOWS
@ -14,6 +13,17 @@ void rktio_useless_wide() { }
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
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 /* A UTF-8 to UTF-16 conversion, but accepts an extended variant of
UTF-16 that accommodates unpaired surrogates, so that all 16-byte UTF-16 that accommodates unpaired surrogates, so that all 16-byte
sequences are accessible. */ 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; rktio->wide_buffer_size = RKTIO_MAX_IDEAL_BUFFER_SIZE;
ws = malloc(sizeof(wchar_t) * RKTIO_MAX_IDEAL_BUFFER_SIZE); ws = malloc(sizeof(wchar_t) * RKTIO_MAX_IDEAL_BUFFER_SIZE);
rktio->wide_buffer = ws; rktio->wide_buffer = ws;
} } else
ws = rktio->wide_buffer;
(void)utf8ish_to_utf16ish((unsigned char *)s, l, (unsigned short*)ws, '\t'); (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); 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) if (free_given)
free((void *)ws); free((void *)ws);