1e66f31c5Sopenharmony_ci#include <inttypes.h> 2e66f31c5Sopenharmony_ci#include <stdio.h> 3e66f31c5Sopenharmony_ci#include <stdlib.h> 4e66f31c5Sopenharmony_ci#include <string.h> 5e66f31c5Sopenharmony_ci#include <uv.h> 6e66f31c5Sopenharmony_ci 7e66f31c5Sopenharmony_ciuv_loop_t *loop; 8e66f31c5Sopenharmony_ciuv_process_t child_req; 9e66f31c5Sopenharmony_ciuv_process_options_t options; 10e66f31c5Sopenharmony_ci 11e66f31c5Sopenharmony_civoid cleanup_handles(uv_process_t *req, int64_t exit_status, int term_signal) { 12e66f31c5Sopenharmony_ci fprintf(stderr, "Process exited with status %" PRId64 ", signal %d\n", exit_status, term_signal); 13e66f31c5Sopenharmony_ci uv_close((uv_handle_t*) req->data, NULL); 14e66f31c5Sopenharmony_ci uv_close((uv_handle_t*) req, NULL); 15e66f31c5Sopenharmony_ci} 16e66f31c5Sopenharmony_ci 17e66f31c5Sopenharmony_civoid invoke_cgi_script(uv_tcp_t *client) { 18e66f31c5Sopenharmony_ci char path[500]; 19e66f31c5Sopenharmony_ci size_t size = sizeof(path); 20e66f31c5Sopenharmony_ci uv_exepath(path, &size); 21e66f31c5Sopenharmony_ci strcpy(path + (strlen(path) - strlen("cgi")), "tick"); 22e66f31c5Sopenharmony_ci 23e66f31c5Sopenharmony_ci char* args[2]; 24e66f31c5Sopenharmony_ci args[0] = path; 25e66f31c5Sopenharmony_ci args[1] = NULL; 26e66f31c5Sopenharmony_ci 27e66f31c5Sopenharmony_ci /* ... finding the executable path and setting up arguments ... */ 28e66f31c5Sopenharmony_ci 29e66f31c5Sopenharmony_ci options.stdio_count = 3; 30e66f31c5Sopenharmony_ci uv_stdio_container_t child_stdio[3]; 31e66f31c5Sopenharmony_ci child_stdio[0].flags = UV_IGNORE; 32e66f31c5Sopenharmony_ci child_stdio[1].flags = UV_INHERIT_STREAM; 33e66f31c5Sopenharmony_ci child_stdio[1].data.stream = (uv_stream_t*) client; 34e66f31c5Sopenharmony_ci child_stdio[2].flags = UV_IGNORE; 35e66f31c5Sopenharmony_ci options.stdio = child_stdio; 36e66f31c5Sopenharmony_ci 37e66f31c5Sopenharmony_ci options.exit_cb = cleanup_handles; 38e66f31c5Sopenharmony_ci options.file = args[0]; 39e66f31c5Sopenharmony_ci options.args = args; 40e66f31c5Sopenharmony_ci 41e66f31c5Sopenharmony_ci // Set this so we can close the socket after the child process exits. 42e66f31c5Sopenharmony_ci child_req.data = (void*) client; 43e66f31c5Sopenharmony_ci int r; 44e66f31c5Sopenharmony_ci if ((r = uv_spawn(loop, &child_req, &options))) { 45e66f31c5Sopenharmony_ci fprintf(stderr, "%s\n", uv_strerror(r)); 46e66f31c5Sopenharmony_ci return; 47e66f31c5Sopenharmony_ci } 48e66f31c5Sopenharmony_ci} 49e66f31c5Sopenharmony_ci 50e66f31c5Sopenharmony_civoid on_new_connection(uv_stream_t *server, int status) { 51e66f31c5Sopenharmony_ci if (status == -1) { 52e66f31c5Sopenharmony_ci // error! 53e66f31c5Sopenharmony_ci return; 54e66f31c5Sopenharmony_ci } 55e66f31c5Sopenharmony_ci 56e66f31c5Sopenharmony_ci uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t)); 57e66f31c5Sopenharmony_ci uv_tcp_init(loop, client); 58e66f31c5Sopenharmony_ci if (uv_accept(server, (uv_stream_t*) client) == 0) { 59e66f31c5Sopenharmony_ci invoke_cgi_script(client); 60e66f31c5Sopenharmony_ci } 61e66f31c5Sopenharmony_ci else { 62e66f31c5Sopenharmony_ci uv_close((uv_handle_t*) client, NULL); 63e66f31c5Sopenharmony_ci } 64e66f31c5Sopenharmony_ci} 65e66f31c5Sopenharmony_ci 66e66f31c5Sopenharmony_ciint main() { 67e66f31c5Sopenharmony_ci loop = uv_default_loop(); 68e66f31c5Sopenharmony_ci 69e66f31c5Sopenharmony_ci uv_tcp_t server; 70e66f31c5Sopenharmony_ci uv_tcp_init(loop, &server); 71e66f31c5Sopenharmony_ci 72e66f31c5Sopenharmony_ci struct sockaddr_in bind_addr; 73e66f31c5Sopenharmony_ci uv_ip4_addr("0.0.0.0", 7000, &bind_addr); 74e66f31c5Sopenharmony_ci uv_tcp_bind(&server, (const struct sockaddr *)&bind_addr, 0); 75e66f31c5Sopenharmony_ci int r = uv_listen((uv_stream_t*) &server, 128, on_new_connection); 76e66f31c5Sopenharmony_ci if (r) { 77e66f31c5Sopenharmony_ci fprintf(stderr, "Listen error %s\n", uv_err_name(r)); 78e66f31c5Sopenharmony_ci return 1; 79e66f31c5Sopenharmony_ci } 80e66f31c5Sopenharmony_ci return uv_run(loop, UV_RUN_DEFAULT); 81e66f31c5Sopenharmony_ci} 82