// It turns out that ncurses isn't thread-safe gint wsh_client_init(GError **err) { int ret = -1; if (initialized) return 0; if ((ret = wsh_client_init_fds(err))) return ret; #if ! GLIB_CHECK_VERSION( 2, 32, 0 ) g_thread_init(NULL); #endif g_mutex_init(&client_mtx); initialized = 1; return ret; }
int main(int argc, char** argv, char** env) { GIOChannel* in = g_io_channel_unix_new(STDIN_FILENO); GIOChannel* out = g_io_channel_unix_new(STDOUT_FILENO); GError* err = NULL; gint ret = 0; wsh_cmd_req_t* req = NULL; wsh_cmd_res_t* res = g_slice_new0(wsh_cmd_res_t); wsh_init_logger(WSH_LOGGER_SERVER); if (wsh_client_init_fds(&err)) { wsh_log_message(err->message); return EXIT_FAILURE; } do { if (errno == EINTR) errno = 0; if ((gintptr)(req = (wsh_cmd_req_t*)mmap(NULL, sizeof(*req), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0)) == -1 && errno != EINTR) { wsh_log_message(strerror(errno)); return EXIT_FAILURE; } } while (errno == EINTR); do { if (errno == EINTR) errno = 0; if (mlock((void*)req, sizeof(*req)) && errno != EINTR) { wsh_log_message(strerror(errno)); return EXIT_FAILURE; } } while (errno == EINTR); wshd_get_message(in, &req, err); if (err != NULL) { ret = err->code; goto wshd_error; } wsh_run_cmd(res, req); wshd_error: do { if (errno == EINTR) errno = 0; if (munlock((void*)req, sizeof(*req)) && errno != EINTR) { wsh_log_message(strerror(errno)); return EXIT_FAILURE; } } while (errno == EINTR); do { if (errno == EINTR) errno = 0; if (munmap((void*)req, sizeof(*req)) && errno != EINTR) { wsh_log_message(strerror(errno)); return EXIT_FAILURE; } } while (errno == EINTR); wshd_send_message(out, res, err); if (err != NULL) ret = err->code; g_slice_free(wsh_cmd_res_t, res); return ret; }