static void ply_boot_server_on_new_connection (ply_boot_server_t *server) { ply_boot_connection_t *connection; int fd; assert (server != NULL); fd = accept (server->socket_fd, NULL, NULL); if (fd < 0) return; connection = ply_boot_connection_new (server, fd); connection->watch = ply_event_loop_watch_fd (server->loop, fd, PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, (ply_event_handler_t) ply_boot_connection_on_request, (ply_event_handler_t) ply_boot_connection_on_hangup, connection); ply_list_append_data (server->connections, connection); }
static bool ply_boot_client_send_request (ply_boot_client_t *client, ply_boot_client_request_t *request) { char *request_string; size_t request_size; assert (client != NULL); assert (request != NULL); request_string = ply_boot_client_get_request_string (client, request, &request_size); if (!ply_write (client->socket_fd, request_string, request_size)) { free (request_string); ply_boot_client_cancel_request (client, request); return false; } free (request_string); if (client->daemon_has_reply_watch == NULL) { assert (ply_list_get_length (client->requests_waiting_for_replies) == 0); client->daemon_has_reply_watch = ply_event_loop_watch_fd (client->loop, client->socket_fd, PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, (ply_event_handler_t) ply_boot_client_process_incoming_replies, NULL, client); } return true; }
static bool open_input_source (ply_renderer_backend_t *backend, ply_renderer_input_source_t *input_source) { int terminal_fd; assert (backend != NULL); assert (has_input_source (backend, input_source)); terminal_fd = ply_terminal_get_fd (backend->terminal); input_source->backend = backend; input_source->terminal_input_watch = ply_event_loop_watch_fd (backend->loop, terminal_fd, PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, (ply_event_handler_t) on_key_event, (ply_event_handler_t) on_input_source_disconnected, input_source); return true; }
static ply_terminal_open_result_t ply_terminal_open_device (ply_terminal_t *terminal) { assert (terminal != NULL); assert (terminal->name != NULL); assert (terminal->fd < 0); assert (terminal->fd_watch == NULL); terminal->fd = open (terminal->name, O_RDWR | O_NOCTTY | O_NONBLOCK); if (terminal->fd < 0) { ply_trace ("Unable to open terminal device '%s': %m", terminal->name); /* The kernel will apparently return EIO spurriously when opening a tty that's * in the process of closing down. There's more information here: * * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245 * * Work around it here. */ if (errno == EIO) return PLY_TERMINAL_OPEN_RESULT_INCOMPLETE; terminal->number_of_reopen_tries = 0; return PLY_TERMINAL_OPEN_RESULT_FAILURE; } ply_set_fd_as_blocking (terminal->fd); terminal->fd_watch = ply_event_loop_watch_fd (terminal->loop, terminal->fd, PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, (ply_event_handler_t) on_tty_input, (ply_event_handler_t) on_tty_disconnected, terminal); ply_terminal_check_for_vt (terminal); if (!ply_terminal_set_unbuffered_input (terminal)) ply_trace ("terminal '%s' will be line buffered", terminal->name); terminal->number_of_reopen_tries = 0; return PLY_TERMINAL_OPEN_RESULT_SUCCESS; }
static void ply_boot_client_queue_request (ply_boot_client_t *client, const char *request_command, const char *request_argument, ply_boot_client_response_handler_t handler, ply_boot_client_response_handler_t failed_handler, void *user_data) { assert (client != NULL); assert (client->loop != NULL); assert (request_command != NULL); assert (request_argument == NULL || strlen (request_argument) <= UCHAR_MAX); assert (handler != NULL); if (client->daemon_can_take_request_watch == NULL && client->socket_fd >= 0) { assert (ply_list_get_length (client->requests_to_send) == 0); client->daemon_can_take_request_watch = ply_event_loop_watch_fd (client->loop, client->socket_fd, PLY_EVENT_LOOP_FD_STATUS_CAN_TAKE_DATA, (ply_event_handler_t) ply_boot_client_process_pending_requests, NULL, client); } if (!client->is_connected) { if (failed_handler != NULL) { failed_handler (user_data, client); } } else { ply_boot_client_request_t *request; request = ply_boot_client_request_new (client, request_command, request_argument, handler, failed_handler, user_data); ply_list_append_data (client->requests_to_send, request); } }
void ply_boot_server_attach_to_event_loop (ply_boot_server_t *server, ply_event_loop_t *loop) { assert (server != NULL); assert (loop != NULL); assert (server->loop == NULL); assert (server->socket_fd >= 0); server->loop = loop; ply_event_loop_watch_fd (loop, server->socket_fd, PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, (ply_event_handler_t) ply_boot_server_on_new_connection, (ply_event_handler_t) ply_boot_server_on_hangup, server); ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t) ply_boot_server_detach_from_event_loop, server); }
void ply_boot_client_attach_to_event_loop (ply_boot_client_t *client, ply_event_loop_t *loop) { assert (client != NULL); assert (loop != NULL); assert (client->loop == NULL); client->loop = loop; if (client->socket_fd >= 0) { ply_event_loop_watch_fd (client->loop, client->socket_fd, PLY_EVENT_LOOP_FD_STATUS_NONE, NULL, (ply_event_handler_t) ply_boot_client_on_hangup, client); } ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t) ply_boot_client_detach_from_event_loop, client); }