static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path) { int error = 0; futils__rmdir_data *data = opaque; struct stat st; if (data->depth > FUTILS_MAX_DEPTH) error = futils__error_cannot_rmdir( path->ptr, "directory nesting too deep"); else if ((error = p_lstat_posixly(path->ptr, &st)) < 0) { if (errno == ENOENT) error = 0; else if (errno == ENOTDIR) { /* asked to remove a/b/c/d/e and a/b is a normal file */ if ((data->flags & GIT_RMDIR_REMOVE_BLOCKERS) != 0) error = futils__rm_first_parent(path, data->base); else futils__error_cannot_rmdir( path->ptr, "parent is not directory"); } else error = git_path_set_error(errno, path->ptr, "rmdir"); } else if (S_ISDIR(st.st_mode)) { data->depth++; error = git_path_direach(path, 0, futils__rmdir_recurs_foreach, data); data->depth--; if (error < 0) return error; if (data->depth == 0 && (data->flags & GIT_RMDIR_SKIP_ROOT) != 0) return error; if ((error = p_rmdir(path->ptr)) < 0) { if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) != 0 && (errno == ENOTEMPTY || errno == EEXIST || errno == EBUSY)) error = 0; else error = git_path_set_error(errno, path->ptr, "rmdir"); } } else if ((data->flags & GIT_RMDIR_REMOVE_FILES) != 0) { if (p_unlink(path->ptr) < 0) error = git_path_set_error(errno, path->ptr, "remove"); } else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0) error = futils__error_cannot_rmdir(path->ptr, "still present"); return error; }
static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path) { struct stat st; futils__rmdir_data *data = opaque; if ((data->error = p_lstat_posixly(path->ptr, &st)) < 0) { if (errno == ENOENT) data->error = 0; else if (errno == ENOTDIR) { /* asked to remove a/b/c/d/e and a/b is a normal file */ if ((data->flags & GIT_RMDIR_REMOVE_BLOCKERS) != 0) data->error = futils__rm_first_parent(path, data->base); else futils__error_cannot_rmdir( path->ptr, "parent is not directory"); } else futils__error_cannot_rmdir(path->ptr, "cannot access"); } else if (S_ISDIR(st.st_mode)) { int error = git_path_direach(path, futils__rmdir_recurs_foreach, data); if (error < 0) return (error == GIT_EUSER) ? data->error : error; data->error = p_rmdir(path->ptr); if (data->error < 0) { if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) != 0 && (errno == ENOTEMPTY || errno == EEXIST || errno == EBUSY)) data->error = 0; else futils__error_cannot_rmdir(path->ptr, NULL); } } else if ((data->flags & GIT_RMDIR_REMOVE_FILES) != 0) { data->error = p_unlink(path->ptr); if (data->error < 0) futils__error_cannot_rmdir(path->ptr, "cannot be removed"); } else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0) data->error = futils__error_cannot_rmdir(path->ptr, "still present"); return data->error; }