From 6b7a9c54941b5ea1299ccfb7a00e998e26a606b0 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Mon, 17 Feb 2025 20:34:17 +0800 Subject: [PATCH] git_hooks_client: Send argc/argv over the UNIX domain socket --- git_hooks_client/git_hooks_client.c | 39 ++++++++++++++++++++++++++++++++++----- diff --git a/git_hooks_client/git_hooks_client.c b/git_hooks_client/git_hooks_client.c index b1121a5cfa495f133bc2916deac7ac3ca601eec1..fa3e04ce656d20710d98b5bc95cf8d2bc5822027 100644 --- a/git_hooks_client/git_hooks_client.c +++ b/git_hooks_client/git_hooks_client.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -7,7 +8,7 @@ #include #include #include -int main(void) { +int main(int argc, char *argv[]) { const char *socket_path = getenv("LINDENII_FORGE_HOOKS_SOCKET_PATH"); if (socket_path == NULL) { dprintf(STDERR_FILENO, "environment variable LINDENII_FORGE_HOOKS_SOCKET_PATH undefined\n"); @@ -82,12 +83,41 @@ return EXIT_FAILURE; } /* + * First we report argc and argv to the UNIX domain socket. + */ + uint64_t argc64 = (uint64_t)argc; + ssize_t bytes_sent = send(sock, &argc64, sizeof(argc64), 0); + switch (bytes_sent) { + case -1: + perror("send argc"); + close(sock); + return EXIT_FAILURE; + case sizeof(argc64): + break; + default: + dprintf(STDERR_FILENO, "send returned unexpected value on internal socket\n"); + close(sock); + return EXIT_FAILURE; + } + for (int i = 0; i < argc; i++) { + unsigned long len = strlen(argv[i]) + 1; + bytes_sent = send(sock, argv[i], len, 0); + if (bytes_sent == -1) { + perror("send argv"); + close(sock); + exit(EXIT_FAILURE); + } else if ((unsigned long)bytes_sent == len) { + } else { + dprintf(STDERR_FILENO, "send returned unexpected value on internal socket\n"); + close(sock); + exit(EXIT_FAILURE); + } + } + + /* * Now we can start splicing data from stdin to the UNIX domain socket. * The format is irrelevant and depends on the hook being called. All we * do is pass it to the socket for it to handle. - * - * TODO: The argument vector may need to be passed too. We may consider - * using an ancillary message. */ ssize_t stdin_bytes_spliced; while ((stdin_bytes_spliced = splice(STDIN_FILENO, NULL, sock, NULL, stdin_pipe_size, SPLICE_F_MORE)) > 0) { @@ -101,7 +131,6 @@ /* * The first byte of the response from the UNIX domain socket is the * status code. We read it and record it as our return value. - * (Realistically we just need a boolean to indicate success or failure.) */ char status_buf[1]; ssize_t bytes_read = read(sock, status_buf, 1); -- 2.48.1