aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/init-db.c4
-rw-r--r--cache.h17
-rw-r--r--merge-recursive.c2
-rw-r--r--sha1_file.c16
4 files changed, 26 insertions, 13 deletions
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 78aa3872d..0bc14f3c8 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -515,10 +515,10 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
saved = shared_repository;
shared_repository = 0;
switch (safe_create_leading_directories_const(argv[0])) {
- case -3:
+ case SCLD_EXISTS:
errno = EEXIST;
/* fallthru */
- case -1:
+ case SCLD_FAILED:
die_errno(_("cannot mkdir %s"), argv[0]);
break;
default:
diff --git a/cache.h b/cache.h
index ce377e135..c6a41575c 100644
--- a/cache.h
+++ b/cache.h
@@ -736,8 +736,21 @@ enum sharedrepo {
};
int git_config_perm(const char *var, const char *value);
int adjust_shared_perm(const char *path);
-int safe_create_leading_directories(char *path);
-int safe_create_leading_directories_const(const char *path);
+
+/*
+ * Create the directory containing the named path, using care to be
+ * somewhat safe against races. Return one of the scld_error values
+ * to indicate success/failure.
+ */
+enum scld_error {
+ SCLD_OK = 0,
+ SCLD_FAILED = -1,
+ SCLD_PERMS = -2,
+ SCLD_EXISTS = -3
+};
+enum scld_error safe_create_leading_directories(char *path);
+enum scld_error safe_create_leading_directories_const(const char *path);
+
int mkdir_in_gitdir(const char *path);
extern void home_config_paths(char **global, char **xdg, char *file);
extern char *expand_user_path(const char *path);
diff --git a/merge-recursive.c b/merge-recursive.c
index dbb7104c0..021e1fc45 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -693,7 +693,7 @@ static int make_room_for_path(struct merge_options *o, const char *path)
/* Make sure leading directories are created */
status = safe_create_leading_directories_const(path);
if (status) {
- if (status == -3) {
+ if (status == SCLD_EXISTS) {
/* something else exists */
error(msg, path, _(": perhaps a D/F conflict?"));
return -1;
diff --git a/sha1_file.c b/sha1_file.c
index 60d6fce07..2a86912e1 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -105,12 +105,12 @@ int mkdir_in_gitdir(const char *path)
return adjust_shared_perm(path);
}
-int safe_create_leading_directories(char *path)
+enum scld_error safe_create_leading_directories(char *path)
{
char *next_component = path + offset_1st_component(path);
- int ret = 0;
+ enum scld_error ret = SCLD_OK;
- while (!ret && next_component) {
+ while (ret == SCLD_OK && next_component) {
struct stat st;
char *slash = strchr(next_component, '/');
@@ -127,26 +127,26 @@ int safe_create_leading_directories(char *path)
if (!stat(path, &st)) {
/* path exists */
if (!S_ISDIR(st.st_mode))
- ret = -3;
+ ret = SCLD_EXISTS;
} else if (mkdir(path, 0777)) {
if (errno == EEXIST &&
!stat(path, &st) && S_ISDIR(st.st_mode))
; /* somebody created it since we checked */
else
- ret = -1;
+ ret = SCLD_FAILED;
} else if (adjust_shared_perm(path)) {
- ret = -2;
+ ret = SCLD_PERMS;
}
*slash = '/';
}
return ret;
}
-int safe_create_leading_directories_const(const char *path)
+enum scld_error safe_create_leading_directories_const(const char *path)
{
/* path points to cache entries, so xstrdup before messing with it */
char *buf = xstrdup(path);
- int result = safe_create_leading_directories(buf);
+ enum scld_error result = safe_create_leading_directories(buf);
free(buf);
return result;
}