#include #include #include #include #include "comm.h" #include "log.h" #include "swaylock.h" #include "password-buffer.h" static int comm[2][2] = {{-1, -1}, {-1, -1}}; ssize_t read_comm_request(char **buf_ptr) { size_t size; ssize_t amt; amt = read(comm[0][0], &size, sizeof(size)); if (amt == 0) { return 0; } else if (amt < 0) { swaylock_log_errno(LOG_ERROR, "read pw request"); return -1; } swaylock_log(LOG_DEBUG, "received pw check request"); char *buf = password_buffer_create(size); if (!buf) { return -1; } size_t offs = 0; do { amt = read(comm[0][0], &buf[offs], size - offs); if (amt <= 0) { swaylock_log_errno(LOG_ERROR, "failed to read pw"); return -1; } offs += (size_t)amt; } while (offs < size); *buf_ptr = buf; return size; } bool write_comm_reply(struct comm_reply reply) { if (write(comm[1][1], &reply, sizeof(reply)) != sizeof(reply)) { swaylock_log_errno(LOG_ERROR, "failed to write pw check result"); return false; } return true; } bool spawn_comm_child(void) { if (pipe(comm[0]) != 0) { swaylock_log_errno(LOG_ERROR, "failed to create pipe"); return false; } if (pipe(comm[1]) != 0) { swaylock_log_errno(LOG_ERROR, "failed to create pipe"); return false; } pid_t child = fork(); if (child < 0) { swaylock_log_errno(LOG_ERROR, "failed to fork"); return false; } else if (child == 0) { close(comm[0][1]); close(comm[1][0]); run_pw_backend_child(); } close(comm[0][0]); close(comm[1][1]); return true; } bool write_comm_request(struct swaylock_password *pw) { bool result = false; size_t len = pw->len + 1; size_t offs = 0; if (write(comm[0][1], &len, sizeof(len)) < 0) { swaylock_log_errno(LOG_ERROR, "Failed to request pw check"); goto out; } do { ssize_t amt = write(comm[0][1], &pw->buffer[offs], len - offs); if (amt < 0) { swaylock_log_errno(LOG_ERROR, "Failed to write pw buffer"); goto out; } offs += amt; } while (offs < len); result = true; out: clear_password_buffer(pw); return result; } struct comm_reply read_comm_reply(void) { struct comm_reply result; if (read(comm[1][0], &result, sizeof(result)) != sizeof(result)) { swaylock_log_errno(LOG_ERROR, "Failed to read pw result"); result.kind = REPLY_AUTH_ERR; } return result; } int get_comm_reply_fd(void) { return comm[1][0]; }