diff options
author | Runxi Yu <me@runxiyu.org> | 2025-04-03 14:35:50 +0800 |
---|---|---|
committer | Runxi Yu <me@runxiyu.org> | 2025-04-03 14:35:50 +0800 |
commit | 43098a7f72acdde45aadbb2ed60dfa171bc03762 (patch) | |
tree | a3ccc384fe6b619953380f17abc7651e084a6f7b | |
parent | CSS: Remove Comic Sans (diff) | |
download | forge-43098a7f72acdde45aadbb2ed60dfa171bc03762.tar.gz forge-43098a7f72acdde45aadbb2ed60dfa171bc03762.tar.zst forge-43098a7f72acdde45aadbb2ed60dfa171bc03762.zip |
git2d: Use BARE to send contents too, instead of using raw write
-rw-r--r-- | git2d/bare.c | 6 | ||||
-rw-r--r-- | git2d/bare.h | 8 | ||||
-rw-r--r-- | git2d/main.c | 56 |
3 files changed, 47 insertions, 23 deletions
diff --git a/git2d/bare.c b/git2d/bare.c index 23c0352..c54ed33 100644 --- a/git2d/bare.c +++ b/git2d/bare.c @@ -318,7 +318,7 @@ bare_get_bool(struct bare_reader *ctx, bool *x) } bare_error -bare_put_fixed_data(struct bare_writer *ctx, uint8_t *src, uint64_t sz) +bare_put_fixed_data(struct bare_writer *ctx, const uint8_t *src, uint64_t sz) { return ctx->write(ctx->buffer, (void *)src, sz); } @@ -330,7 +330,7 @@ bare_get_fixed_data(struct bare_reader *ctx, uint8_t *dst, uint64_t sz) } bare_error -bare_put_data(struct bare_writer *ctx, uint8_t *src, uint64_t sz) +bare_put_data(struct bare_writer *ctx, const uint8_t *src, uint64_t sz) { bare_error err = BARE_ERROR_NONE; @@ -361,7 +361,7 @@ bare_get_data(struct bare_reader *ctx, uint8_t *dst, uint64_t sz) } bare_error -bare_put_str(struct bare_writer *ctx, char *src, uint64_t sz) +bare_put_str(struct bare_writer *ctx, const char *src, uint64_t sz) { if (!checkstr(src, sz)) { return BARE_ERROR_INVALID_UTF8; diff --git a/git2d/bare.h b/git2d/bare.h index 389017f..d494b18 100644 --- a/git2d/bare.h +++ b/git2d/bare.h @@ -17,7 +17,7 @@ typedef enum { BARE_ERROR_INVALID_UTF8, } bare_error; -typedef bare_error (*bare_write_func)(void *buffer, void *src, uint64_t sz); +typedef bare_error (*bare_write_func)(void *buffer, const void *src, uint64_t sz); typedef bare_error (*bare_read_func)(void *buffer, void *dst, uint64_t sz); struct bare_writer { @@ -60,11 +60,11 @@ bare_error bare_get_f64(struct bare_reader *ctx, double *x); bare_error bare_put_bool(struct bare_writer *ctx, bool x); bare_error bare_get_bool(struct bare_reader *ctx, bool *x); -bare_error bare_put_fixed_data(struct bare_writer *ctx, uint8_t *src, uint64_t sz); +bare_error bare_put_fixed_data(struct bare_writer *ctx, const uint8_t *src, uint64_t sz); bare_error bare_get_fixed_data(struct bare_reader *ctx, uint8_t *dst, uint64_t sz); -bare_error bare_put_data(struct bare_writer *ctx, uint8_t *src, uint64_t sz); +bare_error bare_put_data(struct bare_writer *ctx, const uint8_t *src, uint64_t sz); bare_error bare_get_data(struct bare_reader *ctx, uint8_t *dst, uint64_t sz); -bare_error bare_put_str(struct bare_writer *ctx, char *src, uint64_t sz); +bare_error bare_put_str(struct bare_writer *ctx, const char *src, uint64_t sz); bare_error bare_get_str(struct bare_reader *ctx, char *dst, uint64_t sz); #endif /* BARE_H */ diff --git a/git2d/main.c b/git2d/main.c index 0919415..91f2572 100644 --- a/git2d/main.c +++ b/git2d/main.c @@ -3,6 +3,11 @@ * SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org> */ +/* + * TODO: Pool repositories (and take care of thread safety) + * libgit2 has a nice builtin per-repo cache that we could utilize this way. + */ + #include <err.h> #include <errno.h> #include <git2.h> @@ -31,17 +36,34 @@ conn_read(void *buffer, void *dst, uint64_t sz) return (rsz == (ssize_t)sz) ? BARE_ERROR_NONE : BARE_ERROR_READ_FAILED; } +static bare_error +conn_write(void *buffer, const void *src, uint64_t sz) +{ + conn_io_t *io = buffer; + const uint8_t *data = src; + uint64_t total = 0; + + while (total < sz) { + ssize_t written = write(io->fd, data + total, sz - total); + if (written < 0) { + if (errno == EINTR) + continue; + return BARE_ERROR_WRITE_FAILED; + } + if (written == 0) + break; + total += written; + } + + return (total == sz) ? BARE_ERROR_NONE : BARE_ERROR_WRITE_FAILED; +} + void * session(void *_conn) { int conn = *(int *)_conn; free((int *)_conn); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" - int ret = 0; -#pragma GCC diagnostic pop - int err; git_repository *repo = NULL; @@ -51,24 +73,27 @@ session(void *_conn) .buffer = &io, .read = conn_read, }; + struct bare_writer writer = { + .buffer = &io, + .write = conn_write, + }; err = bare_get_data(&reader, (uint8_t *)path, sizeof(path) - 1); if (err != BARE_ERROR_NONE) { - ret = 10; goto close; } path[sizeof(path) - 1] = '\0'; err = git_repository_open_ext(&repo, path, GIT_REPOSITORY_OPEN_NO_SEARCH | GIT_REPOSITORY_OPEN_BARE | GIT_REPOSITORY_OPEN_NO_DOTGIT, NULL); if (err != 0) { - ret = 1; + bare_put_uint(&writer, 1); goto close; } git_object *obj = NULL; err = git_revparse_single(&obj, repo, "HEAD^{tree}"); if (err != 0) { - ret = 2; + bare_put_uint(&writer, 2); goto free_repo; } git_tree *tree = (git_tree *) obj; @@ -76,30 +101,32 @@ session(void *_conn) git_tree_entry *entry = NULL; err = git_tree_entry_bypath(&entry, tree, "README.md"); if (err != 0) { - ret = 3; + bare_put_uint(&writer, 3); goto free_tree; } git_otype objtype = git_tree_entry_type(entry); if (objtype != GIT_OBJECT_BLOB) { - ret = 4; + bare_put_uint(&writer, 4); goto free_tree_entry; } git_object *obj2 = NULL; err = git_tree_entry_to_object(&obj2, repo, entry); if (err != 0) { - ret = 5; + bare_put_uint(&writer, 5); goto free_tree_entry; } git_blob *blob = (git_blob *) obj2; const void *content = git_blob_rawcontent(blob); if (content == NULL) { - ret = 6; + bare_put_uint(&writer, 6); goto free_blob; } - write(conn, content, git_blob_rawsize(blob)); + + bare_put_uint(&writer, 0); + bare_put_data(&writer, content, git_blob_rawsize(blob)); free_blob: git_blob_free(blob); @@ -111,9 +138,6 @@ free_repo: git_repository_free(repo); close: - // TODO: Implement proper error handling - dprintf(conn, "%d\n", ret); - close(conn); return NULL; |