The reftable library includes "git-compat-util.h" in order to get a POSIX-like programming environment that papers over various differences between platforms. The header also brings with it a couple of helpers specific to the Git codebase though, and over time we have started to use these helpers in the reftable library, as well. This makes it very hard to use the reftable library as a standalone library without the rest of the Git codebase, so other libraries like e.g. libgit2 cannot easily use it. But now that we have removed all calls to Git-specific functionality and have split out "compat/posix.h" as a separate header we can address this. Stop including "git-compat-util.h" and instead include "compat/posix.h" to finalize the decoupling of the reftable library from the rest of the Git codebase. The only bits which remain specific to Git are "system.h" and "system.c", which projects will have to provide. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
134 lines
2.5 KiB
C
134 lines
2.5 KiB
C
#include "../git-compat-util.h"
|
|
|
|
#include "system.h"
|
|
#include "basics.h"
|
|
#include "reftable-error.h"
|
|
#include "../lockfile.h"
|
|
#include "../tempfile.h"
|
|
|
|
uint32_t reftable_rand(void)
|
|
{
|
|
return git_rand(CSPRNG_BYTES_INSECURE);
|
|
}
|
|
|
|
int tmpfile_from_pattern(struct reftable_tmpfile *out, const char *pattern)
|
|
{
|
|
struct tempfile *tempfile;
|
|
|
|
tempfile = mks_tempfile(pattern);
|
|
if (!tempfile)
|
|
return REFTABLE_IO_ERROR;
|
|
|
|
out->path = tempfile->filename.buf;
|
|
out->fd = tempfile->fd;
|
|
out->priv = tempfile;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int tmpfile_close(struct reftable_tmpfile *t)
|
|
{
|
|
struct tempfile *tempfile = t->priv;
|
|
int ret = close_tempfile_gently(tempfile);
|
|
t->fd = -1;
|
|
if (ret < 0)
|
|
return REFTABLE_IO_ERROR;
|
|
return 0;
|
|
}
|
|
|
|
int tmpfile_delete(struct reftable_tmpfile *t)
|
|
{
|
|
struct tempfile *tempfile = t->priv;
|
|
int ret = delete_tempfile(&tempfile);
|
|
*t = REFTABLE_TMPFILE_INIT;
|
|
if (ret < 0)
|
|
return REFTABLE_IO_ERROR;
|
|
return 0;
|
|
}
|
|
|
|
int tmpfile_rename(struct reftable_tmpfile *t, const char *path)
|
|
{
|
|
struct tempfile *tempfile = t->priv;
|
|
int ret = rename_tempfile(&tempfile, path);
|
|
*t = REFTABLE_TMPFILE_INIT;
|
|
if (ret < 0)
|
|
return REFTABLE_IO_ERROR;
|
|
return 0;
|
|
}
|
|
|
|
int flock_acquire(struct reftable_flock *l, const char *target_path,
|
|
long timeout_ms)
|
|
{
|
|
struct lock_file *lockfile;
|
|
int err;
|
|
|
|
lockfile = reftable_malloc(sizeof(*lockfile));
|
|
if (!lockfile)
|
|
return REFTABLE_OUT_OF_MEMORY_ERROR;
|
|
|
|
err = hold_lock_file_for_update_timeout(lockfile, target_path, LOCK_NO_DEREF,
|
|
timeout_ms);
|
|
if (err < 0) {
|
|
reftable_free(lockfile);
|
|
if (errno == EEXIST)
|
|
return REFTABLE_LOCK_ERROR;
|
|
return -1;
|
|
}
|
|
|
|
l->fd = get_lock_file_fd(lockfile);
|
|
l->path = get_lock_file_path(lockfile);
|
|
l->priv = lockfile;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int flock_close(struct reftable_flock *l)
|
|
{
|
|
struct lock_file *lockfile = l->priv;
|
|
int ret;
|
|
|
|
if (!lockfile)
|
|
return REFTABLE_API_ERROR;
|
|
|
|
ret = close_lock_file_gently(lockfile);
|
|
l->fd = -1;
|
|
if (ret < 0)
|
|
return REFTABLE_IO_ERROR;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int flock_release(struct reftable_flock *l)
|
|
{
|
|
struct lock_file *lockfile = l->priv;
|
|
int ret;
|
|
|
|
if (!lockfile)
|
|
return 0;
|
|
|
|
ret = rollback_lock_file(lockfile);
|
|
reftable_free(lockfile);
|
|
*l = REFTABLE_FLOCK_INIT;
|
|
if (ret < 0)
|
|
return REFTABLE_IO_ERROR;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int flock_commit(struct reftable_flock *l)
|
|
{
|
|
struct lock_file *lockfile = l->priv;
|
|
int ret;
|
|
|
|
if (!lockfile)
|
|
return REFTABLE_API_ERROR;
|
|
|
|
ret = commit_lock_file(lockfile);
|
|
reftable_free(lockfile);
|
|
*l = REFTABLE_FLOCK_INIT;
|
|
if (ret < 0)
|
|
return REFTABLE_IO_ERROR;
|
|
|
|
return 0;
|
|
}
|