Raw
1 #include "../git-compat-util.h"
2
3 #include "system.h"
4 #include "basics.h"
5 #include "reftable-error.h"
6 #include "../lockfile.h"
7 #include "../trace.h"
8 #include "../tempfile.h"
9 #include "../write-or-die.h"
10
11 uint32_t reftable_rand(void)
12 {
13 return git_rand(CSPRNG_BYTES_INSECURE);
14 }
15
16 int tmpfile_from_pattern(struct reftable_tmpfile *out, const char *pattern)
17 {
18 struct tempfile *tempfile;
19
20 tempfile = mks_tempfile(pattern);
21 if (!tempfile)
22 return REFTABLE_IO_ERROR;
23
24 out->path = tempfile->filename.buf;
25 out->fd = tempfile->fd;
26 out->priv = tempfile;
27
28 return 0;
29 }
30
31 int tmpfile_close(struct reftable_tmpfile *t)
32 {
33 struct tempfile *tempfile = t->priv;
34 int ret = close_tempfile_gently(tempfile);
35 t->fd = -1;
36 if (ret < 0)
37 return REFTABLE_IO_ERROR;
38 return 0;
39 }
40
41 int tmpfile_delete(struct reftable_tmpfile *t)
42 {
43 struct tempfile *tempfile = t->priv;
44 int ret = delete_tempfile(&tempfile);
45 *t = REFTABLE_TMPFILE_INIT;
46 if (ret < 0)
47 return REFTABLE_IO_ERROR;
48 return 0;
49 }
50
51 int tmpfile_rename(struct reftable_tmpfile *t, const char *path)
52 {
53 struct tempfile *tempfile = t->priv;
54 int ret = rename_tempfile(&tempfile, path);
55 *t = REFTABLE_TMPFILE_INIT;
56 if (ret < 0)
57 return REFTABLE_IO_ERROR;
58 return 0;
59 }
60
61 int flock_acquire(struct reftable_flock *l, const char *target_path,
62 long timeout_ms)
63 {
64 struct lock_file *lockfile;
65 int err;
66
67 lockfile = reftable_malloc(sizeof(*lockfile));
68 if (!lockfile)
69 return REFTABLE_OUT_OF_MEMORY_ERROR;
70
71 err = hold_lock_file_for_update_timeout(lockfile, target_path, LOCK_NO_DEREF,
72 timeout_ms);
73 if (err < 0) {
74 reftable_free(lockfile);
75 if (errno == EEXIST)
76 return REFTABLE_LOCK_ERROR;
77 return REFTABLE_IO_ERROR;
78 }
79
80 l->fd = get_lock_file_fd(lockfile);
81 l->path = get_lock_file_path(lockfile);
82 l->priv = lockfile;
83
84 return 0;
85 }
86
87 int flock_close(struct reftable_flock *l)
88 {
89 struct lock_file *lockfile = l->priv;
90 int ret;
91
92 if (!lockfile)
93 return REFTABLE_API_ERROR;
94
95 ret = close_lock_file_gently(lockfile);
96 l->fd = -1;
97 if (ret < 0)
98 return REFTABLE_IO_ERROR;
99
100 return 0;
101 }
102
103 int flock_release(struct reftable_flock *l)
104 {
105 struct lock_file *lockfile = l->priv;
106 int ret;
107
108 if (!lockfile)
109 return 0;
110
111 ret = rollback_lock_file(lockfile);
112 reftable_free(lockfile);
113 *l = REFTABLE_FLOCK_INIT;
114 if (ret < 0)
115 return REFTABLE_IO_ERROR;
116
117 return 0;
118 }
119
120 int flock_commit(struct reftable_flock *l)
121 {
122 struct lock_file *lockfile = l->priv;
123 int ret;
124
125 if (!lockfile)
126 return REFTABLE_API_ERROR;
127
128 ret = commit_lock_file(lockfile);
129 reftable_free(lockfile);
130 *l = REFTABLE_FLOCK_INIT;
131 if (ret < 0)
132 return REFTABLE_IO_ERROR;
133
134 return 0;
135 }
136
137 int reftable_fsync(int fd)
138 {
139 return fsync_component(FSYNC_COMPONENT_REFERENCE, fd);
140 }
141
142 uint64_t reftable_time_ms(void)
143 {
144 return getnanotime() / 1000000;
145 }
146
147 int reftable_mmap(struct reftable_mmap *out, int fd, size_t len)
148 {
149 void *data = xmmap_gently(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
150 if (data == MAP_FAILED)
151 return REFTABLE_IO_ERROR;
152
153 out->data = data;
154 out->size = len;
155
156 return 0;
157 }
158
159 int reftable_munmap(struct reftable_mmap *mmap)
160 {
161 if (munmap(mmap->data, mmap->size) < 0)
162 return REFTABLE_IO_ERROR;
163 memset(mmap, 0, sizeof(*mmap));
164 return 0;
165 }