| #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 REFTABLE_IO_ERROR; | |
| } | |
| 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; | |
| } |