From c5ddf79721704a3be0e8f6739d4098af0c4aa895 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 12 Jun 2017 13:07:49 -0600 Subject: [PATCH] rktio: small repairs --- racket/src/rktio/demo.c | 88 ++++++++++++++++++++++++++------ racket/src/rktio/rktio.h | 3 +- racket/src/rktio/rktio_network.c | 3 +- racket/src/rktio/rktio_process.c | 20 +++++--- 4 files changed, 90 insertions(+), 24 deletions(-) diff --git a/racket/src/rktio/demo.c b/racket/src/rktio/demo.c index 804635e139..ae2653a31a 100644 --- a/racket/src/rktio/demo.c +++ b/racket/src/rktio/demo.c @@ -380,6 +380,22 @@ rktio_addrinfo_t *lookup_loop(rktio_t *rktio, return addr; } +static void pause_for_process(rktio_t *rktio, rktio_process_t *process) +{ + int done; + + do { + rktio_poll_set_t *ps; + ps = rktio_make_poll_set(rktio); + check_valid(ps); + rktio_poll_add_process(rktio, process, ps); + rktio_sleep(rktio, 0, ps, NULL); + rktio_poll_set_close(rktio, ps); + done = rktio_poll_process_done(rktio, process); + check_valid(done != RKTIO_PROCESS_ERROR); + } while (!done); +} + static rktio_fd_t *connect_loop(rktio_t *rktio, rktio_addrinfo_t *addr, rktio_addrinfo_t *local_addr) { rktio_connect_t *conn; @@ -692,7 +708,6 @@ int main() addr = lookup_loop(rktio, "localhost", 4536, -1, 0, 0); check_valid(addr); - printf("udp\n"); check_fill_write(rktio, fd2, addr, AMOUNT_FOR_UDP); check_drain_read(rktio, fd, AMOUNT_FOR_UDP+1); @@ -707,10 +722,10 @@ int main() { rktio_status_t *status; rktio_process_result_t *result; - char *argv[2] = { "/bin/cat", NULL }; + char *argv[1] = { "/bin/cat" }; rktio_envvars_t *envvars = NULL; rktio_fd_t *err_fd = rktio_system_fd(rktio, 2, RKTIO_OPEN_WRITE); - int done; + int i; result = rktio_process(rktio, "/bin/cat", 1, argv, NULL, NULL, err_fd, @@ -718,34 +733,75 @@ int main() 0, NULL); check_valid(result); + check_valid(!result->stderr_fd); status = rktio_process_status(rktio, result->process); check_valid(status); check_valid(status->running); - check_valid(!result->stderr_fd); free(status); - check_valid(!rktio_poll_subprocess_done(rktio, result->process)); + check_valid(!rktio_poll_process_done(rktio, result->process)); check_read_write_pair(rktio, result->stdout_fd, result->stdin_fd, 0); - check_valid(rktio_poll_subprocess_done(rktio, result->process) != RKTIO_PROCESS_ERROR); + check_valid(rktio_poll_process_done(rktio, result->process) != RKTIO_PROCESS_ERROR); - do { - rktio_poll_set_t *ps; - ps = rktio_make_poll_set(rktio); - check_valid(ps); - rktio_poll_add_process(rktio, result->process, ps); - rktio_sleep(rktio, 0, ps, NULL); - rktio_poll_set_close(rktio, ps); - done = rktio_poll_subprocess_done(rktio, result->process); - check_valid(done != RKTIO_PROCESS_ERROR); - } while (!done); + pause_for_process(rktio, result->process); + + status = rktio_process_status(rktio, result->process); + check_valid(status); + check_valid(!status->running); + check_valid(!status->result); + free(status); rktio_process_forget(rktio, result->process); free(result); check_valid(rktio_close(rktio, err_fd)); + + /* Run and then break or kill "/bin/cat" */ + for (i = 0; i < 2; i++) { + result = rktio_process(rktio, "/bin/cat", 1, argv, + NULL, NULL, err_fd, + rktio_get_current_directory(rktio), envvars, + 0, + NULL); + check_valid(result); + + check_valid(!rktio_poll_process_done(rktio, result->process)); + rktio_sleep(rktio, 0.05, NULL, NULL); + check_valid(!rktio_poll_process_done(rktio, result->process)); + + switch (i) { + case 0: + check_valid(rktio_process_interrupt(rktio, result->process)); + break; + case 1: + check_valid(rktio_process_kill(rktio, result->process)); + break; + } + + pause_for_process(rktio, result->process); + + status = rktio_process_status(rktio, result->process); + check_valid(status); + check_valid(!status->running); + check_valid(status->result); + free(status); + + { + char buffer[1]; + intptr_t amt; + amt = rktio_read(rktio, result->stdout_fd, buffer, sizeof(buffer)); + check_valid(amt == RKTIO_READ_EOF); + } + + check_valid(rktio_close(rktio, result->stdin_fd)); + check_valid(rktio_close(rktio, result->stdout_fd)); + + rktio_process_forget(rktio, result->process); + free(result); + } } return 0; diff --git a/racket/src/rktio/rktio.h b/racket/src/rktio/rktio.h index 0f67a7ea62..7e533dca35 100644 --- a/racket/src/rktio/rktio.h +++ b/racket/src/rktio/rktio.h @@ -30,6 +30,7 @@ typedef struct rktio_fd_t rktio_fd_t; #define RKTIO_OPEN_SOCKET (1<<7) #define RKTIO_OPEN_UDP (1<<8) +/* A socket registered this way should be non-blocking: */ rktio_fd_t *rktio_system_fd(rktio_t *rktio, intptr_t system_fd, int modes); intptr_t rktio_fd_system_fd(rktio_t *rktio, rktio_fd_t *rfd); @@ -168,7 +169,7 @@ void rktio_process_forget(rktio_t *rktio, rktio_process_t *sp); #define RKTIO_PROCESS_ERROR (-2) #define RKTIO_PROCESS_DONE 1 -int rktio_poll_subprocess_done(rktio_t *rktio, rktio_process_t *sp); +int rktio_poll_process_done(rktio_t *rktio, rktio_process_t *sp); typedef struct rktio_status_t { int running; diff --git a/racket/src/rktio/rktio_network.c b/racket/src/rktio/rktio_network.c index d3bf969416..37dbb1e8ac 100644 --- a/racket/src/rktio/rktio_network.c +++ b/racket/src/rktio/rktio_network.c @@ -1589,6 +1589,7 @@ rktio_fd_t *rktio_accept(rktio_t *rktio, rktio_listener_t *listener) RKTIO_WHEN_SET_SOCKBUF_SIZE(setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&size, sizeof(int))); # endif + init_socket(s); REGISTER_SOCKET(s); return rktio_system_fd(rktio, s, RKTIO_OPEN_SOCKET | RKTIO_OPEN_READ | RKTIO_OPEN_WRITE); @@ -1601,9 +1602,9 @@ rktio_fd_t *rktio_accept(rktio_t *rktio, rktio_listener_t *listener) static char **get_numeric_strings(rktio_t *rktio, void *sa, unsigned int salen) { char **r; + int err; #ifdef HAVE_GETADDRINFO char host[NI_MAXHOST], serv[NI_MAXSERV]; - int err; err = getnameinfo(sa, salen, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV); diff --git a/racket/src/rktio/rktio_process.c b/racket/src/rktio/rktio_process.c index 59351ca722..2b6d299b4a 100644 --- a/racket/src/rktio/rktio_process.c +++ b/racket/src/rktio/rktio_process.c @@ -773,7 +773,7 @@ static void collect_process_time(rktio_t *rktio, DWORD w, rktio_process_t *sp) /* Process status functions */ /*========================================================================*/ -int rktio_poll_subprocess_done(rktio_t *rktio, rktio_process_t *sp) +int rktio_poll_process_done(rktio_t *rktio, rktio_process_t *sp) { #if defined(RKTIO_SYSTEM_UNIX) # if defined(CENTRALIZED_SIGCHILD) @@ -824,7 +824,7 @@ int rktio_poll_subprocess_done(rktio_t *rktio, rktio_process_t *sp) void rktio_poll_add_process(rktio_t *rktio, rktio_process_t *sp, rktio_poll_set_t *fds) { - if (rktio_poll_subprocess_done(rktio, sp)) { + if (rktio_poll_process_done(rktio, sp)) { rktio_poll_set_add_nosleep(rktio, fds); return; } @@ -1320,7 +1320,7 @@ rktio_process_result_t *rktio_process(rktio_t *rktio, if (!exact_cmdline) { /* protect spaces, etc. in the arguments: */ new_argv = malloc(sizeof(char *) * argc); - for (i = 0; i < argv; i++) { + for (i = 0; i < argc; i++) { new_argv[i] = cmdline_protect(argv[i]); } argv = new_argv; @@ -1337,7 +1337,7 @@ rktio_process_result_t *rktio_process(rktio_t *rktio, env, current_directory); if (!exact_cmdline) { - for (i = 0; i < argv; i++) { + for (i = 0; i < argc; i++) { free(argv[i]); } free(argv); @@ -1492,9 +1492,17 @@ rktio_process_result_t *rktio_process(rktio_t *rktio, /* Exec new process */ { - int err; + int err, i; + char **new_argv; - err = MSC_IZE(execve)(command, argv, (char **)env); + /* add a NULL terminator */ + new_argv = malloc(sizeof(char *) * (argc + 1)); + for (i = 0; i < argc; i++) { + new_argv[i] = argv[i]; + } + new_argv[i] = NULL; + + err = MSC_IZE(execve)(command, new_argv, (char **)env); if (err) err = errno;