summaryrefslogtreecommitdiff
path: root/src/fileops.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fileops.c')
-rw-r--r--src/fileops.c79
1 files changed, 35 insertions, 44 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 5763b370b..a60689f3f 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -403,7 +403,6 @@ typedef struct {
const char *base;
size_t baselen;
uint32_t flags;
- int error;
int depth;
} futils__rmdir_data;
@@ -447,8 +446,8 @@ static int futils__rm_first_parent(git_buf *path, const char *ceiling)
static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
{
+ int error = 0;
futils__rmdir_data *data = opaque;
- int error = data->error;
struct stat st;
if (data->depth > FUTILS_MAX_DEPTH)
@@ -474,13 +473,14 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
data->depth++;
error = git_path_direach(path, 0, futils__rmdir_recurs_foreach, data);
- if (error < 0)
- return (error == GIT_EUSER) ? data->error : error;
data->depth--;
+ if (error < 0)
+ return error;
+
if (data->depth == 0 && (data->flags & GIT_RMDIR_SKIP_ROOT) != 0)
- return data->error;
+ return error;
if ((error = p_rmdir(path->ptr)) < 0) {
if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) != 0 &&
@@ -499,28 +499,23 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0)
error = futils__error_cannot_rmdir(path->ptr, "still present");
- data->error = error;
return error;
}
static int futils__rmdir_empty_parent(void *opaque, git_buf *path)
{
futils__rmdir_data *data = opaque;
- int error;
+ int error = 0;
if (git_buf_len(path) <= data->baselen)
- return GIT_ITEROVER;
-
- error = p_rmdir(git_buf_cstr(path));
+ error = GIT_ITEROVER;
- if (error) {
+ else if (p_rmdir(git_buf_cstr(path)) < 0) {
int en = errno;
if (en == ENOENT || en == ENOTDIR) {
- giterr_clear();
- error = 0;
+ /* do nothing */
} else if (en == ENOTEMPTY || en == EEXIST || en == EBUSY) {
- giterr_clear();
error = GIT_ITEROVER;
} else {
error = git_path_set_error(errno, git_buf_cstr(path), "rmdir");
@@ -535,12 +530,13 @@ int git_futils_rmdir_r(
{
int error;
git_buf fullpath = GIT_BUF_INIT;
- futils__rmdir_data data = { 0 };
+ futils__rmdir_data data;
/* build path and find "root" where we should start calling mkdir */
if (git_path_join_unrooted(&fullpath, path, base, NULL) < 0)
return -1;
+ memset(&data, 0, sizeof(data));
data.base = base ? base : "";
data.baselen = base ? strlen(base) : 0;
data.flags = flags;
@@ -548,12 +544,13 @@ int git_futils_rmdir_r(
error = futils__rmdir_recurs_foreach(&data, &fullpath);
/* remove now-empty parents if requested */
- if (!error && (flags & GIT_RMDIR_EMPTY_PARENTS) != 0) {
+ if (!error && (flags & GIT_RMDIR_EMPTY_PARENTS) != 0)
error = git_path_walk_up(
&fullpath, base, futils__rmdir_empty_parent, &data);
- if (error == GIT_ITEROVER)
- error = 0;
+ if (error == GIT_ITEROVER) {
+ giterr_clear();
+ error = 0;
}
git_buf_free(&fullpath);
@@ -618,6 +615,8 @@ static git_futils_dirs_guess_cb git_futils__dir_guess[GIT_FUTILS_DIR__MAX] = {
git_futils_guess_template_dirs,
};
+static int git_futils__dirs_shutdown_set = 0;
+
void git_futils_dirs_global_shutdown(void)
{
int i;
@@ -634,8 +633,6 @@ int git_futils_dirs_global_init(void)
for (i = 0; !error && i < GIT_FUTILS_DIR__MAX; i++)
error = git_futils_dirs_get(&path, i);
- git__on_shutdown(git_futils_dirs_global_shutdown);
-
return error;
}
@@ -655,9 +652,16 @@ int git_futils_dirs_get(const git_buf **out, git_futils_dir_t which)
GITERR_CHECK_ERROR(git_futils_check_selector(which));
- if (!git_buf_len(&git_futils__dirs[which]))
+ if (!git_buf_len(&git_futils__dirs[which])) {
+ /* prepare shutdown if we're going to need it */
+ if (!git_futils__dirs_shutdown_set) {
+ git__on_shutdown(git_futils_dirs_global_shutdown);
+ git_futils__dirs_shutdown_set = 1;
+ }
+
GITERR_CHECK_ERROR(
git_futils__dir_guess[which](&git_futils__dirs[which]));
+ }
*out = &git_futils__dirs[which];
return 0;
@@ -858,7 +862,6 @@ typedef struct {
uint32_t flags;
uint32_t mkdir_flags;
mode_t dirmode;
- int error;
} cp_r_info;
#define GIT_CPDIR__MKDIR_DONE_FOR_TO_ROOT (1u << 10)
@@ -896,23 +899,21 @@ static int _cp_r_callback(void *ref, git_buf *from)
from->ptr[git_path_basename_offset(from)] == '.')
return 0;
- if (git_buf_joinpath(
- &info->to, info->to_root, from->ptr + info->from_prefix) < 0) {
- error = -1;
- goto exit;
- }
+ if ((error = git_buf_joinpath(
+ &info->to, info->to_root, from->ptr + info->from_prefix)) < 0)
+ return error;
if (!(error = git_path_lstat(info->to.ptr, &to_st)))
exists = true;
else if (error != GIT_ENOTFOUND)
- goto exit;
+ return error;
else {
giterr_clear();
error = 0;
}
if ((error = git_path_lstat(from->ptr, &from_st)) < 0)
- goto exit;
+ return error;
if (S_ISDIR(from_st.st_mode)) {
mode_t oldmode = info->dirmode;
@@ -926,17 +927,13 @@ static int _cp_r_callback(void *ref, git_buf *from)
error = _cp_r_mkdir(info, from);
/* recurse onto target directory */
- if (!error && (!exists || S_ISDIR(to_st.st_mode))) {
+ if (!error && (!exists || S_ISDIR(to_st.st_mode)))
error = git_path_direach(from, 0, _cp_r_callback, info);
- if (error == GIT_EUSER)
- error = info->error;
- }
-
if (oldmode != 0)
info->dirmode = oldmode;
- goto exit;
+ return error;
}
if (exists) {
@@ -946,8 +943,7 @@ static int _cp_r_callback(void *ref, git_buf *from)
if (p_unlink(info->to.ptr) < 0) {
giterr_set(GITERR_OS, "Cannot overwrite existing file '%s'",
info->to.ptr);
- error = -1;
- goto exit;
+ return GIT_EEXISTS;
}
}
@@ -960,7 +956,7 @@ static int _cp_r_callback(void *ref, git_buf *from)
/* Make container directory on demand if needed */
if ((info->flags & GIT_CPDIR_CREATE_EMPTY_DIRS) == 0 &&
(error = _cp_r_mkdir(info, from)) < 0)
- goto exit;
+ return error;
/* make symlink or regular file */
if (S_ISLNK(from_st.st_mode))
@@ -974,8 +970,6 @@ static int _cp_r_callback(void *ref, git_buf *from)
error = git_futils_cp(from->ptr, info->to.ptr, usemode);
}
-exit:
- info->error = error;
return error;
}
@@ -992,11 +986,11 @@ int git_futils_cp_r(
if (git_buf_joinpath(&path, from, "") < 0) /* ensure trailing slash */
return -1;
+ memset(&info, 0, sizeof(info));
info.to_root = to;
info.flags = flags;
info.dirmode = dirmode;
info.from_prefix = path.size;
- info.error = 0;
git_buf_init(&info.to, 0);
/* precalculate mkdir flags */
@@ -1018,9 +1012,6 @@ int git_futils_cp_r(
git_buf_free(&path);
git_buf_free(&info.to);
- if (error == GIT_EUSER)
- error = info.error;
-
return error;
}