From 7155b727c9baae9ef6d7829370aefc09c4ab64e2 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 28 Sep 2007 16:28:54 +0100 Subject: Introduce remove_dir_recursively() There was a function called remove_empty_dir_recursive() buried in refs.c. Expose a slightly enhanced version in dir.h: it can now optionally remove a non-empty directory. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- dir.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'dir.c') diff --git a/dir.c b/dir.c index eb6c3abd30..b18257e65f 100644 --- a/dir.c +++ b/dir.c @@ -685,3 +685,44 @@ int is_inside_dir(const char *dir) char buffer[PATH_MAX]; return get_relative_cwd(buffer, sizeof(buffer), dir) != NULL; } + +int remove_dir_recursively(struct strbuf *path, int only_empty) +{ + DIR *dir = opendir(path->buf); + struct dirent *e; + int ret = 0, original_len = path->len, len; + + if (!dir) + return -1; + if (path->buf[original_len - 1] != '/') + strbuf_addch(path, '/'); + + len = path->len; + while ((e = readdir(dir)) != NULL) { + struct stat st; + if ((e->d_name[0] == '.') && + ((e->d_name[1] == 0) || + ((e->d_name[1] == '.') && e->d_name[2] == 0))) + continue; /* "." and ".." */ + + strbuf_setlen(path, len); + strbuf_addstr(path, e->d_name); + if (lstat(path->buf, &st)) + ; /* fall thru */ + else if (S_ISDIR(st.st_mode)) { + if (!remove_dir_recursively(path, only_empty)) + continue; /* happy */ + } else if (!only_empty && !unlink(path->buf)) + continue; /* happy, too */ + + /* path too long, stat fails, or non-directory still exists */ + ret = -1; + break; + } + closedir(dir); + + strbuf_setlen(path, original_len); + if (!ret) + ret = rmdir(path->buf); + return ret; +} -- cgit v1.2.3