static pseudo_msg_t * pseudo_client_request(pseudo_msg_t *msg, size_t len, const char *path) { pseudo_msg_t *response = 0; int tries = 0; int rc; if (!msg) return 0; do { do { pseudo_debug(4, "sending a message: ino %llu\n", (unsigned long long) msg->ino); if (connect_fd < 0) { pseudo_debug(2, "trying to get server\n"); if (pseudo_client_setup()) { return 0; } } rc = pseudo_msg_send(connect_fd, msg, len, path); if (rc != 0) { pseudo_debug(2, "msg_send: %d%s\n", rc, rc == -1 ? " (sigpipe)" : " (short write)"); pseudo_client_setup(); ++tries; if (tries > 3) { pseudo_debug(1, "can't get server going again.\n"); return 0; } } } while (rc != 0); pseudo_debug(5, "sent!\n"); response = pseudo_msg_receive(connect_fd); if (!response) { ++tries; if (tries > 3) { pseudo_debug(1, "can't get responses.\n"); return 0; } } } while (response == 0); if (response->type != PSEUDO_MSG_ACK) { pseudo_debug(2, "got non-ack response %d\n", response->type); return 0; } else { pseudo_debug(4, "got response type %d\n", response->type); } return response; }
static int client_ping(void) { pseudo_msg_t ping; pseudo_msg_t *ack; char tagbuf[pseudo_path_max()]; char *tag = pseudo_get_value("PSEUDO_TAG"); memset(&ping, 0, sizeof(ping)); ping.type = PSEUDO_MSG_PING; ping.op = OP_NONE; ping.pathlen = snprintf(tagbuf, sizeof(tagbuf), "%s%c%s", program_invocation_name ? program_invocation_name : "<unknown>", 0, tag ? tag : ""); free(tag); ping.client = getpid(); ping.result = 0; errno = 0; pseudo_debug(4, "sending ping\n"); if (pseudo_msg_send(connect_fd, &ping, ping.pathlen, tagbuf)) { pseudo_debug(3, "error pinging server: %s\n", strerror(errno)); return 1; } ack = pseudo_msg_receive(connect_fd); if (!ack) { pseudo_debug(2, "no ping response from server: %s\n", strerror(errno)); /* and that's not good, so... */ server_pid = 0; return 1; } if (ack->type != PSEUDO_MSG_ACK) { pseudo_debug(1, "invalid ping response from server: expected ack, got %d\n", ack->type); /* and that's not good, so... */ server_pid = 0; return 1; } pseudo_debug(5, "ping ok\n"); return 0; }
int pseudo_client_shutdown(void) { pseudo_msg_t msg; pseudo_msg_t *ack; char *pseudo_path; pseudo_path = pseudo_prefix_path(NULL); if (pseudo_prefix_dir_fd == -1) { if (pseudo_path) { pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY); /* directory is missing? */ if (pseudo_prefix_dir_fd == -1 && errno == ENOENT) { pseudo_debug(1, "prefix directory doesn't exist, trying to create\n"); mkdir_p(pseudo_path); pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY); } pseudo_prefix_dir_fd = pseudo_fd(pseudo_prefix_dir_fd, COPY_FD); free(pseudo_path); } else { pseudo_diag("No prefix available to to find server.\n"); exit(1); } if (pseudo_prefix_dir_fd == -1) { pseudo_diag("Can't open prefix path (%s) for server. (%s)\n", pseudo_prefix_path(NULL), strerror(errno)); exit(1); } } pseudo_path = pseudo_localstatedir_path(NULL); mkdir_p(pseudo_path); if (pseudo_localstate_dir_fd == -1) { if (pseudo_path) { pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY); /* directory is missing? */ if (pseudo_localstate_dir_fd == -1 && errno == ENOENT) { pseudo_debug(1, "local state dir doesn't exist, trying to create\n"); mkdir_p(pseudo_path); pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY); } pseudo_localstate_dir_fd = pseudo_fd(pseudo_localstate_dir_fd, COPY_FD); free(pseudo_path); } else { pseudo_diag("No prefix available to to find server.\n"); exit(1); } if (pseudo_localstate_dir_fd == -1) { pseudo_diag("Can't open local state path (%s) for server. (%s)\n", pseudo_localstatedir_path(NULL), strerror(errno)); exit(1); } } if (client_connect()) { pseudo_diag("Pseudo server seems to be already offline.\n"); return 0; } memset(&msg, 0, sizeof(pseudo_msg_t)); msg.type = PSEUDO_MSG_SHUTDOWN; msg.op = OP_NONE; msg.client = getpid(); pseudo_debug(2, "sending shutdown request\n"); if (pseudo_msg_send(connect_fd, &msg, 0, NULL)) { pseudo_debug(1, "error requesting shutdown: %s\n", strerror(errno)); return 1; } ack = pseudo_msg_receive(connect_fd); if (!ack) { pseudo_diag("server did not respond to shutdown query.\n"); return 1; } if (ack->type == PSEUDO_MSG_ACK) { return 0; } pseudo_diag("Server refused shutdown. Remaining client fds: %d\n", ack->fd); pseudo_diag("Client pids: %s\n", ack->path); pseudo_diag("Server will shut down after all clients exit.\n"); return 0; }