aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--git2d/bare.c6
-rw-r--r--git2d/bare.h8
-rw-r--r--git2d/main.c56
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;