{"thread":{"id":"17885","subject":"[PATCH] Make sure objects/pack exists before creating a new pack","startedAt":"2009-02-19T04:48:07Z","lastAt":"2009-02-19T04:48:07Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"105386","messageId":"7vr61vnibc.fsf@gitster.siamese.dyndns.org","threadId":"17885","inReplyTo":null,"subject":"[PATCH] Make sure objects/pack exists before creating a new pack","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-19T04:48:07Z","receivedAt":"2009-02-19T04:48:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"In a repository created with git older than f49fb35 (git-init-db: create\n\"pack\" subdirectory under objects, 2005-06-27), objects/pack/ directory is\nnot created upon initialization.  It was Ok because subdirectories are\ncreated as needed inside directories init-db creates.\n\n8b4eb6b (Do not perform cross-directory renames when creating packs,\n2008-09-22) moved the location temporary pack files are created from\nobjects/ directory to objects/pack/ directory; this move broke many\noperations in such a repository, because it was not careful enough to make\nsure leading directories exist.\n\nIntroduce odb_mkstemp() which is a specialized version of mkstemp() to\nrefactor the code and teach it to create a leading directories properly\nto fix this buglet.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n * I don't know why, but I somehow found doing this patch highly amusing.\n\n builtin-pack-objects.c |    5 ++---\n fast-import.c          |   10 ++++------\n git-compat-util.h      |    1 +\n index-pack.c           |    5 ++---\n pack-write.c           |    4 +---\n wrapper.c              |   17 +++++++++++++++++\n 6 files changed, 27 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin-pack-objects.c b/builtin-pack-objects.c\nindex cb51916..bcefa52 100644\n--- a/builtin-pack-objects.c\n+++ b/builtin-pack-objects.c\n@@ -488,9 +488,8 @@ static void write_pack_file(void)\n \t\t} else {\n \t\t\tchar tmpname[PATH_MAX];\n \t\t\tint fd;\n-\t\t\tsnprintf(tmpname, sizeof(tmpname),\n-\t\t\t\t \"%s/pack/tmp_pack_XXXXXX\", get_object_directory());\n-\t\t\tfd = xmkstemp(tmpname);\n+\t\t\tfd = odb_mkstemp(tmpname, sizeof(tmpname),\n+\t\t\t\t\t \"pack/tmp_pack_XXXXXX\");\n \t\t\tpack_tmp_name = xstrdup(tmpname);\n \t\t\tf = sha1fd(fd, pack_tmp_name);\n \t\t}\ndiff --git a/fast-import.c b/fast-import.c\nindex 3ef3413..99e4df4 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -817,9 +817,8 @@ static void start_packfile(void)\n \tstruct pack_header hdr;\n \tint pack_fd;\n \n-\tsnprintf(tmpfile, sizeof(tmpfile),\n-\t\t\"%s/pack/tmp_pack_XXXXXX\", get_object_directory());\n-\tpack_fd = xmkstemp(tmpfile);\n+\tpack_fd = odb_mkstemp(tmpfile, sizeof(tmpfile),\n+\t\t\t      \"pack/tmp_pack_XXXXXX\");\n \tp = xcalloc(1, sizeof(*p) + strlen(tmpfile) + 2);\n \tstrcpy(p->pack_name, tmpfile);\n \tp->pack_fd = pack_fd;\n@@ -879,9 +878,8 @@ static char *create_index(void)\n \t\tc = next;\n \t}\n \n-\tsnprintf(tmpfile, sizeof(tmpfile),\n-\t\t\"%s/pack/tmp_idx_XXXXXX\", get_object_directory());\n-\tidx_fd = xmkstemp(tmpfile);\n+\tidx_fd = odb_mkstemp(tmpfile, sizeof(tmpfile),\n+\t\t\t     \"pack/tmp_idx_XXXXXX\");\n \tf = sha1fd(idx_fd, tmpfile);\n \tsha1write(f, array, 256 * sizeof(int));\n \tgit_SHA1_Init(&ctx);\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 079cbe9..c1744b9 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -303,6 +303,7 @@ extern ssize_t xwrite(int fd, const void *buf, size_t len);\n extern int xdup(int fd);\n extern FILE *xfdopen(int fd, const char *mode);\n extern int xmkstemp(char *template);\n+extern int odb_mkstemp(char *template, size_t limit, const char *pattern);\n \n static inline size_t xsize_t(off_t len)\n {\ndiff --git a/index-pack.c b/index-pack.c\nindex f7a3807..0350c29 100644\n--- a/index-pack.c\n+++ b/index-pack.c\n@@ -172,9 +172,8 @@ static char *open_pack_file(char *pack_name)\n \t\tinput_fd = 0;\n \t\tif (!pack_name) {\n \t\t\tstatic char tmpfile[PATH_MAX];\n-\t\t\tsnprintf(tmpfile, sizeof(tmpfile),\n-\t\t\t\t \"%s/pack/tmp_pack_XXXXXX\", get_object_directory());\n-\t\t\toutput_fd = xmkstemp(tmpfile);\n+\t\t\toutput_fd = odb_mkstemp(tmpfile, sizeof(tmpfile),\n+\t\t\t\t\t\t\"pack/tmp_pack_XXXXXX\");\n \t\t\tpack_name = xstrdup(tmpfile);\n \t\t} else\n \t\t\toutput_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);\ndiff --git a/pack-write.c b/pack-write.c\nindex b426006..3ab55b9 100644\n--- a/pack-write.c\n+++ b/pack-write.c\n@@ -44,9 +44,7 @@ char *write_idx_file(char *index_name, struct pack_idx_entry **objects,\n \n \tif (!index_name) {\n \t\tstatic char tmpfile[PATH_MAX];\n-\t\tsnprintf(tmpfile, sizeof(tmpfile),\n-\t\t\t \"%s/pack/tmp_idx_XXXXXX\", get_object_directory());\n-\t\tfd = xmkstemp(tmpfile);\n+\t\tfd = odb_mkstemp(tmpfile, sizeof(tmpfile), \"pack/tmp_idx_XXXXXX\");\n \t\tindex_name = xstrdup(tmpfile);\n \t} else {\n \t\tunlink(index_name);\ndiff --git a/wrapper.c b/wrapper.c\nindex c85ca52..371cee1 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -197,6 +197,23 @@ int xmkstemp(char *template)\n \treturn fd;\n }\n \n+int odb_mkstemp(char *template, size_t limit, const char *pattern)\n+{\n+\tint fd;\n+\n+\tsnprintf(template, limit, \"%s/%s\",\n+\t\t get_object_directory(), pattern);\n+\tfd = mkstemp(template);\n+\tif (0 <= fd)\n+\t\treturn fd;\n+\n+\t/* slow path */\n+\tsafe_create_leading_directories(template);\n+\tsnprintf(template, limit, \"%s/%s\",\n+\t\t get_object_directory(), pattern);\n+\treturn xmkstemp(template);\n+}\n+\n /*\n  * zlib wrappers to make sure we don't silently miss errors\n  * at init time.\n"}]}