reftable: support preset file mode for writing

Create files with mode 0666, so umask works as intended. Provides an override, which is useful to support shared repos (test t1301-shared-repo.sh). Signed-off-by: Han-Wen Nienhuys <hanwen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Han-Wen Nienhuys committed Dec 23, 2021 at 19:29 UTC cd1799dea097cee064db1d09966fee88078476e9
3 files changed +56 -10
reftable/reftable-writer.h
+3
@@ -35,6 +35,9 @@ struct reftable_write_options {
35 */
36 uint32_t hash_id;
37
38 + /* Default mode for creating files. If unset, use 0666 (+umask) */
39 + unsigned int default_permissions;
40 +
41 /* boolean: do not check ref names for validity or dir/file conflicts.
42 */
43 unsigned skip_name_check : 1;
reftable/stack.c
+24 -6
@@ -469,7 +469,7 @@ static int reftable_stack_init_addition(struct reftable_addition *add,
469 strbuf_addstr(&add->lock_file_name, ".lock");
470
471 add->lock_file_fd = open(add->lock_file_name.buf,
472 - O_EXCL | O_CREAT | O_WRONLY, 0644);
472 + O_EXCL | O_CREAT | O_WRONLY, 0666);
473 if (add->lock_file_fd < 0) {
474 if (errno == EEXIST) {
475 err = REFTABLE_LOCK_ERROR;
@@ -478,6 +478,13 @@ static int reftable_stack_init_addition(struct reftable_addition *add,
478 }
479 goto done;
480 }
481 + if (st->config.default_permissions) {
482 + if (chmod(add->lock_file_name.buf, st->config.default_permissions) < 0) {
483 + err = REFTABLE_IO_ERROR;
484 + goto done;
485 + }
486 + }
487 +
488 err = stack_uptodate(st);
489 if (err < 0)
490 goto done;
@@ -644,7 +651,12 @@ int reftable_addition_add(struct reftable_addition *add,
651 err = REFTABLE_IO_ERROR;
652 goto done;
653 }
647 -
654 + if (add->stack->config.default_permissions) {
655 + if (chmod(temp_tab_file_name.buf, add->stack->config.default_permissions)) {
656 + err = REFTABLE_IO_ERROR;
657 + goto done;
658 + }
659 + }
660 wr = reftable_new_writer(reftable_fd_write, &tab_fd,
661 &add->stack->config);
662 err = write_table(wr, arg);
@@ -900,7 +912,7 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last,
912 strbuf_addstr(&lock_file_name, ".lock");
913
914 lock_file_fd =
903 - open(lock_file_name.buf, O_EXCL | O_CREAT | O_WRONLY, 0644);
915 + open(lock_file_name.buf, O_EXCL | O_CREAT | O_WRONLY, 0666);
916 if (lock_file_fd < 0) {
917 if (errno == EEXIST) {
918 err = 1;
@@ -931,8 +943,8 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last,
943 strbuf_addstr(&subtab_lock, ".lock");
944
945 sublock_file_fd = open(subtab_lock.buf,
934 - O_EXCL | O_CREAT | O_WRONLY, 0644);
935 - if (sublock_file_fd > 0) {
946 + O_EXCL | O_CREAT | O_WRONLY, 0666);
947 + if (sublock_file_fd >= 0) {
948 close(sublock_file_fd);
949 } else if (sublock_file_fd < 0) {
950 if (errno == EEXIST) {
@@ -967,7 +979,7 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last,
979 goto done;
980
981 lock_file_fd =
970 - open(lock_file_name.buf, O_EXCL | O_CREAT | O_WRONLY, 0644);
982 + open(lock_file_name.buf, O_EXCL | O_CREAT | O_WRONLY, 0666);
983 if (lock_file_fd < 0) {
984 if (errno == EEXIST) {
985 err = 1;
@@ -977,6 +989,12 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last,
989 goto done;
990 }
991 have_lock = 1;
992 + if (st->config.default_permissions) {
993 + if (chmod(lock_file_name.buf, st->config.default_permissions) < 0) {
994 + err = REFTABLE_IO_ERROR;
995 + goto done;
996 + }
997 + }
998
999 format_name(&new_table_name, st->readers[first]->min_update_index,
1000 st->readers[last]->max_update_index);
reftable/stack_test.c
+29 -4
@@ -17,6 +17,7 @@ https://developers.google.com/open-source/licenses/bsd
17 #include "record.h"
18 #include "test_framework.h"
19 #include "reftable-tests.h"
20 +#include "reader.h"
21
22 #include <sys/types.h>
23 #include <dirent.h>
@@ -138,8 +139,11 @@ static int write_test_log(struct reftable_writer *wr, void *arg)
139 static void test_reftable_stack_add_one(void)
140 {
141 char *dir = get_tmp_dir(__LINE__);
141 -
142 - struct reftable_write_options cfg = { 0 };
142 + struct strbuf scratch = STRBUF_INIT;
143 + int mask = umask(002);
144 + struct reftable_write_options cfg = {
145 + .default_permissions = 0660,
146 + };
147 struct reftable_stack *st = NULL;
148 int err;
149 struct reftable_ref_record ref = {
@@ -149,8 +153,7 @@ static void test_reftable_stack_add_one(void)
153 .value.symref = "master",
154 };
155 struct reftable_ref_record dest = { NULL };
152 -
153 -
156 + struct stat stat_result = { 0 };
157 err = reftable_new_stack(&st, dir, cfg);
158 EXPECT_ERR(err);
159
@@ -160,6 +163,7 @@ static void test_reftable_stack_add_one(void)
163 err = reftable_stack_read_ref(st, ref.refname, &dest);
164 EXPECT_ERR(err);
165 EXPECT(0 == strcmp("master", dest.value.symref));
166 + EXPECT(st->readers_len > 0);
167
168 printf("testing print functionality:\n");
169 err = reftable_stack_print_directory(dir, GIT_SHA1_FORMAT_ID);
@@ -168,9 +172,30 @@ static void test_reftable_stack_add_one(void)
172 err = reftable_stack_print_directory(dir, GIT_SHA256_FORMAT_ID);
173 EXPECT(err == REFTABLE_FORMAT_ERROR);
174
175 +#ifndef GIT_WINDOWS_NATIVE
176 + strbuf_addstr(&scratch, dir);
177 + strbuf_addstr(&scratch, "/tables.list");
178 + err = stat(scratch.buf, &stat_result);
179 + EXPECT(!err);
180 + EXPECT((stat_result.st_mode & 0777) == cfg.default_permissions);
181 +
182 + strbuf_reset(&scratch);
183 + strbuf_addstr(&scratch, dir);
184 + strbuf_addstr(&scratch, "/");
185 + /* do not try at home; not an external API for reftable. */
186 + strbuf_addstr(&scratch, st->readers[0]->name);
187 + err = stat(scratch.buf, &stat_result);
188 + EXPECT(!err);
189 + EXPECT((stat_result.st_mode & 0777) == cfg.default_permissions);
190 +#else
191 + (void) stat_result;
192 +#endif
193 +
194 reftable_ref_record_release(&dest);
195 reftable_stack_destroy(st);
196 + strbuf_release(&scratch);
197 clear_dir(dir);
198 + umask(mask);
199 }
200
201 static void test_reftable_stack_uptodate(void)