From ca830519e17e0b3fae6697839bc5e7347a1299a5 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Mon, 17 Feb 2025 06:56:18 +0800 Subject: [PATCH] git_hooks_client: Restructure for clarity --- git_hooks_client/git_hooks_client.c | 51 ++++++++++++++++++++++++++++----------------------- diff --git a/git_hooks_client/git_hooks_client.c b/git_hooks_client/git_hooks_client.c index 0d736a9ae736518afac27bc8f7089ef3cea7f8fe..01af1966ba90241f42f76a26f71b0f7732f2df67 100644 --- a/git_hooks_client/git_hooks_client.c +++ b/git_hooks_client/git_hooks_client.c @@ -8,21 +8,45 @@ #include #include int main(void) { - int sock; - struct sockaddr_un addr; const char *socket_path = getenv("LINDENII_FORGE_HOOKS_SOCKET_PATH"); - if (socket_path == NULL) { dprintf(STDERR_FILENO, "fatal: environment variable LINDENII_FORGE_HOOKS_SOCKET_PATH undefined\n"); return EXIT_FAILURE; } + /* + * All hooks in git (see builtin/receive-pack.c) use a pipe by setting + * .in = -1 on the child_process struct, which enables us to use + * splice(2) to move the data to the UNIX domain socket. Just to be + * safe, we check that stdin is a pipe; and additionally we fetch the + * buffer size of the pipe to use as the maximum size for the splice. + * + * We connect to the UNIX domain socket after ensuring that standard + * input matches our expectations. + */ + + struct stat stdin_stat; + if (fstat(STDIN_FILENO, &stdin_stat) == -1) { + perror("fstat"); + return EXIT_FAILURE; + } + if (!S_ISFIFO(stdin_stat.st_mode)) { + dprintf(STDERR_FILENO, "fatal: stdin must be a pipe\n"); + return EXIT_FAILURE; + } + int pipe_size = fcntl(STDIN_FILENO, F_GETPIPE_SZ); + if (pipe_size == -1) { + perror("fcntl"); + return EXIT_FAILURE; + } + + int sock; + struct sockaddr_un addr; sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock == -1) { perror("socket"); return EXIT_FAILURE; } - memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); @@ -33,25 +57,6 @@ close(sock); return EXIT_FAILURE; } - struct stat stdin_stat; - if (fstat(STDIN_FILENO, &stdin_stat) == -1) { - perror("fstat"); - close(sock); - return EXIT_FAILURE; - } - - if (!S_ISFIFO(stdin_stat.st_mode)) { - dprintf(STDERR_FILENO, "fatal: stdin must be a pipe\n"); - close(sock); - return EXIT_FAILURE; - } - - int pipe_size = fcntl(STDIN_FILENO, F_GETPIPE_SZ); - if (pipe_size == -1) { - perror("fcntl"); - close(sock); - return EXIT_FAILURE; - } ssize_t bytes_spliced; while ((bytes_spliced = splice(STDIN_FILENO, NULL, sock, NULL, pipe_size, SPLICE_F_MORE)) > 0) { -- 2.48.1