Skip to content

Commit 8981dca

Browse files
ttaylorrgitster
authored andcommitted
server-info.c: remove temporary info files on exit
The update_info_file() function within server-info.c is responsible for moving the info/refs and info/packs files around when updating server info. These updates are staged into a temporary file and then moved into place atomically to avoid race conditions when reading those files. However, the temporary file used to stage these changes is managed outside of the tempfile.h API, and thus survives process death. Manage these files instead with the tempfile.h API so that they are automatically cleaned up upon abnormal process death. Unfortunately, and unlike in the previous step, there isn't a straightforward way to inject a failure into the update-server-info step that causes us to die() rather than take the cleanup path in label 'out', hence the lack of a test here. Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c195ecd commit 8981dca

File tree

1 file changed

+10
-16
lines changed

1 file changed

+10
-16
lines changed

server-info.c

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "object-store-ll.h"
1414
#include "server-info.h"
1515
#include "strbuf.h"
16+
#include "tempfile.h"
1617

1718
struct update_info_ctx {
1819
FILE *cur_fp;
@@ -75,9 +76,8 @@ static int update_info_file(char *path,
7576
int force)
7677
{
7778
char *tmp = mkpathdup("%s_XXXXXX", path);
79+
struct tempfile *f = NULL;
7880
int ret = -1;
79-
int fd = -1;
80-
FILE *to_close;
8181
struct update_info_ctx uic = {
8282
.cur_fp = NULL,
8383
.old_fp = NULL,
@@ -86,13 +86,12 @@ static int update_info_file(char *path,
8686
};
8787

8888
safe_create_leading_directories(path);
89-
fd = git_mkstemp_mode(tmp, 0666);
90-
if (fd < 0)
89+
f = mks_tempfile_m(tmp, 0666);
90+
if (!f)
9191
goto out;
92-
to_close = uic.cur_fp = fdopen(fd, "w");
92+
uic.cur_fp = fdopen_tempfile(f, "w");
9393
if (!uic.cur_fp)
9494
goto out;
95-
fd = -1;
9695

9796
/* no problem on ENOENT and old_fp == NULL, it's stale, now */
9897
if (!force)
@@ -121,27 +120,22 @@ static int update_info_file(char *path,
121120
}
122121

123122
uic.cur_fp = NULL;
124-
if (fclose(to_close))
125-
goto out;
126123

127124
if (uic_is_stale(&uic)) {
128-
if (adjust_shared_perm(tmp) < 0)
125+
if (adjust_shared_perm(get_tempfile_path(f)) < 0)
129126
goto out;
130-
if (rename(tmp, path) < 0)
127+
if (rename_tempfile(&f, path) < 0)
131128
goto out;
132129
} else {
133-
unlink(tmp);
130+
delete_tempfile(&f);
134131
}
135132
ret = 0;
136133

137134
out:
138135
if (ret) {
139136
error_errno("unable to update %s", path);
140-
if (uic.cur_fp)
141-
fclose(uic.cur_fp);
142-
else if (fd >= 0)
143-
close(fd);
144-
unlink(tmp);
137+
if (f)
138+
delete_tempfile(&f);
145139
}
146140
free(tmp);
147141
if (uic.old_fp)

0 commit comments

Comments
 (0)