From b458dcd47498c11f1b2afe36044ab2429f882d2f Mon Sep 17 00:00:00 2001 From: wuyuanchao Date: Tue, 5 Dec 2023 06:15:24 +0000 Subject: [PATCH 1/9] bugfix for returncode of ChangeModeDirectory Signed-off-by: wuyuanchao --- base/src/directory_ex.cpp | 87 +++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 22 deletions(-) diff --git a/base/src/directory_ex.cpp b/base/src/directory_ex.cpp index 2ef101b..40a037f 100644 --- a/base/src/directory_ex.cpp +++ b/base/src/directory_ex.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "securec.h" #include "unistd.h" #include "utils_log.h" @@ -322,38 +323,80 @@ bool ChangeModeFile(const string& fileName, const mode_t& mode) return ChangeMode(fileName, mode); } -bool ChangeModeDirectory(const string& path, const mode_t& mode) -{ - string subPath; +bool ChangeModeDirectoryInternal(DIR *dir, const mode_t &mode) { bool ret = true; - DIR *dir = opendir(path.c_str()); - if (dir == nullptr) { + int rootFd = dirfd(dir); + if (rootFd < 0) { return false; } - while (true) { - struct dirent *ptr = readdir(dir); - if (ptr == nullptr) { - break; - } + stack dirStack; + dirStack.push(dir); - // current dir or parent dir - if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) { - continue; - } - subPath = IncludeTrailingPathDelimiter(path) + string(ptr->d_name); - if (ptr->d_type == DT_DIR) { - ret = ChangeModeDirectory(subPath, mode); - } else { - if (access(subPath.c_str(), F_OK) == 0) { - if (!ChangeMode(subPath, mode)) { - UTILS_LOGD("Failed to exec ChangeMode"); - closedir(dir); + while (!dirStack.empty()) { + DIR *currentDir = dirStack.top(); + dirStack.pop(); + + while (true) { + struct dirent *ptr = readdir(currentDir); + if (ptr == nullptr) { + break; + } + const char *name = ptr->d_name; + + // current dir or parent dir + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + continue; + } + + if (ptr->d_type == DT_DIR) { + int subFd = openat(rootFd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); + if (subFd < 0) { + UTILS_LOGD("Failed in subFd openat: %{public}s ", name); + ret = false; + continue; + } + DIR *subDir = fdopendir(subFd); + if (subDir == nullptr) { + close(subFd); + UTILS_LOGD("Failed in fdopendir: %{public}s", strerror(errno)); + ret = false; + continue; + } + dirStack.push(subDir); + if (fchmodat(rootFd, name, mode, 0) < 0) { + UTILS_LOGD("Couldn't fchmodat subDir %{public}s: %{public}s", name, strerror(errno)); + ret = false; + continue; + } + } else { + if (faccessat(rootFd, name, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { + if (fchmodat(rootFd, name, mode, 0) < 0) { + UTILS_LOGD("Couldn't fchmodat subFile %{public}s: %{public}s", name, strerror(errno)); + return false; + } + } else { + UTILS_LOGD("Access to file: %{public}s is failed", name); return false; } } } } + return ret; +} + +bool ChangeModeDirectory(const string& path, const mode_t& mode) +{ + bool ret = true; + DIR *dir = opendir(path.c_str()); + if (dir == nullptr) { + UTILS_LOGD("Failed to open root dir: %{public}s: %{public}s ", path.c_str(), strerror(errno)); + return false; + } + ret = ChangeModeDirectoryInternal(dir, mode); + if (!ret) { + UTILS_LOGD("Failed to ChangeMode some subfile under path: %{public}s", path.c_str()); + } closedir(dir); string currentPath = ExcludeTrailingPathDelimiter(path); if (access(currentPath.c_str(), F_OK) == 0) { -- Gitee From 5892ea955c1cb58c0ef54188e61a1544f76173b1 Mon Sep 17 00:00:00 2001 From: wuyuanchao Date: Tue, 5 Dec 2023 06:33:22 +0000 Subject: [PATCH 2/9] bugfix for returncode of ChangeModeDirectory Signed-off-by: wuyuanchao --- base/src/directory_ex.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/base/src/directory_ex.cpp b/base/src/directory_ex.cpp index 40a037f..8b33ab0 100644 --- a/base/src/directory_ex.cpp +++ b/base/src/directory_ex.cpp @@ -323,7 +323,8 @@ bool ChangeModeFile(const string& fileName, const mode_t& mode) return ChangeMode(fileName, mode); } -bool ChangeModeDirectoryInternal(DIR *dir, const mode_t &mode) { +bool ChangeModeDirectoryInternal(DIR *dir, const mode_t &mode) +{ bool ret = true; int rootFd = dirfd(dir); if (rootFd < 0) { @@ -363,7 +364,7 @@ bool ChangeModeDirectoryInternal(DIR *dir, const mode_t &mode) { ret = false; continue; } - dirStack.push(subDir); + dirStack.push(subDir); if (fchmodat(rootFd, name, mode, 0) < 0) { UTILS_LOGD("Couldn't fchmodat subDir %{public}s: %{public}s", name, strerror(errno)); ret = false; -- Gitee From fc1dc3f69976c39b6ec4ad7199670a526d02f4d6 Mon Sep 17 00:00:00 2001 From: wuyuanchao Date: Wed, 6 Dec 2023 06:19:09 +0000 Subject: [PATCH 3/9] =?UTF-8?q?rootFd=E8=B7=9F=E9=9A=8F=E5=AD=90=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E6=9B=B4=E6=96=B0=E8=80=8C=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wuyuanchao --- base/src/directory_ex.cpp | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/base/src/directory_ex.cpp b/base/src/directory_ex.cpp index 8b33ab0..f01e4b6 100644 --- a/base/src/directory_ex.cpp +++ b/base/src/directory_ex.cpp @@ -326,11 +326,6 @@ bool ChangeModeFile(const string& fileName, const mode_t& mode) bool ChangeModeDirectoryInternal(DIR *dir, const mode_t &mode) { bool ret = true; - int rootFd = dirfd(dir); - if (rootFd < 0) { - return false; - } - stack dirStack; dirStack.push(dir); @@ -338,6 +333,10 @@ bool ChangeModeDirectoryInternal(DIR *dir, const mode_t &mode) DIR *currentDir = dirStack.top(); dirStack.pop(); + int rootFd = dirfd(dir); + if (rootFd < 0) { + return false; + } while (true) { struct dirent *ptr = readdir(currentDir); if (ptr == nullptr) { @@ -371,15 +370,7 @@ bool ChangeModeDirectoryInternal(DIR *dir, const mode_t &mode) continue; } } else { - if (faccessat(rootFd, name, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { - if (fchmodat(rootFd, name, mode, 0) < 0) { - UTILS_LOGD("Couldn't fchmodat subFile %{public}s: %{public}s", name, strerror(errno)); - return false; - } - } else { - UTILS_LOGD("Access to file: %{public}s is failed", name); - return false; - } + continue; } } } @@ -396,16 +387,19 @@ bool ChangeModeDirectory(const string& path, const mode_t& mode) } ret = ChangeModeDirectoryInternal(dir, mode); if (!ret) { - UTILS_LOGD("Failed to ChangeMode some subfile under path: %{public}s", path.c_str()); + UTILS_LOGD("Failed to exec ChangeModeDirectoryInternal"); } - closedir(dir); - string currentPath = ExcludeTrailingPathDelimiter(path); - if (access(currentPath.c_str(), F_OK) == 0) { - if (!ChangeMode(currentPath, mode)) { - UTILS_LOGD("Failed to exec ChangeMode"); + int rootFd = dirfd(dir); + if (rootFd < 0) { + return false; + } + if (access(path.c_str(), F_OK) == 0) { + if (fchmodat(rootFd, ".", mode, 0) < 0) { + UTILS_LOGD("Failed to fchmodat current directory: %{public}s", path.c_str()); return false; } } + closedir(dir); return ret; } -- Gitee From 6f3b2e9ffc7cf414c882d79a4c257c1d0a1d7115 Mon Sep 17 00:00:00 2001 From: wuyuanchao Date: Wed, 6 Dec 2023 06:25:03 +0000 Subject: [PATCH 4/9] =?UTF-8?q?rootFd=E8=B7=9F=E9=9A=8F=E5=AD=90=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E6=9B=B4=E6=96=B0=E8=80=8C=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wuyuanchao --- base/src/directory_ex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/src/directory_ex.cpp b/base/src/directory_ex.cpp index f01e4b6..ee3a76c 100644 --- a/base/src/directory_ex.cpp +++ b/base/src/directory_ex.cpp @@ -333,7 +333,7 @@ bool ChangeModeDirectoryInternal(DIR *dir, const mode_t &mode) DIR *currentDir = dirStack.top(); dirStack.pop(); - int rootFd = dirfd(dir); + int rootFd = dirfd(currentDir); if (rootFd < 0) { return false; } -- Gitee From 8d25b20891234b046e6e12253fb0e8795ad83ebf Mon Sep 17 00:00:00 2001 From: wuyuanchao Date: Thu, 14 Dec 2023 07:17:58 +0000 Subject: [PATCH 5/9] bugfix for returncode of ForceRemoveDirectory Signed-off-by: wuyuanchao --- base/src/directory_ex.cpp | 56 ++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/base/src/directory_ex.cpp b/base/src/directory_ex.cpp index ee3a76c..60d2bc1 100644 --- a/base/src/directory_ex.cpp +++ b/base/src/directory_ex.cpp @@ -199,25 +199,32 @@ bool ForceCreateDirectory(const string& path) bool ForceRemoveDirectoryInternal(DIR *dir) { bool ret = true; - int rootFd = dirfd(dir); - if (rootFd < 0) { - UTILS_LOGD("Failed to get dirfd, fd: %{public}d: %{public}s ", rootFd, strerror(errno)); - return false; - } + std::stack dirStack; + dirStack.push(dir); - while (true) { - struct dirent *ptr = readdir(dir); - if (ptr == nullptr) { - break; - } - const char *name = ptr->d_name; + while (!dirStack.empty()) { + DIR *currentDir = dirStack.top(); + dirStack.pop(); - // current dir or parent dir - if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { - continue; + int rootFd = dirfd(currentDir); + if (rootFd < 0) { + UTILS_LOGD("Failed to get dirfd, fd: %{public}d: %{public}s ", rootFd, strerror(errno)); + return false; } + + while (true) { + struct dirent *ptr = readdir(dir); + if (ptr == nullptr) { + break; + } + const char *name = ptr->d_name; + + // current dir or parent dir + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + continue; + } - if (ptr->d_type == DT_DIR) { + if (ptr->d_type == DT_DIR) { int subFd = openat(rootFd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); if (subFd < 0) { UTILS_LOGD("Failed in subFd openat: %{public}s ", name); @@ -231,24 +238,25 @@ bool ForceRemoveDirectoryInternal(DIR *dir) ret = false; continue; } - ret = ForceRemoveDirectoryInternal(subDir); - closedir(subDir); + dirStack.push(subDir); if (unlinkat(rootFd, name, AT_REMOVEDIR) < 0) { UTILS_LOGD("Couldn't unlinkat subDir %{public}s: %{public}s", name, strerror(errno)); ret = false; continue; } - } else { - if (faccessat(rootFd, name, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { - if (unlinkat(rootFd, name, 0) < 0) { - UTILS_LOGD("Couldn't unlinkat subFile %{public}s: %{public}s", name, strerror(errno)); + } else { + if (faccessat(rootFd, name, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { + if (unlinkat(rootFd, name, 0) < 0) { + UTILS_LOGD("Couldn't unlinkat subFile %{public}s: %{public}s", name, strerror(errno)); + return false; + } + } else { + UTILS_LOGD("Access to file: %{public}s is failed", name); return false; } - } else { - UTILS_LOGD("Access to file: %{public}s is failed", name); - return false; } } + closedir(currentDir); } return ret; -- Gitee From c9ef3d9bc97a01cc3e94ba238424044944ba4e44 Mon Sep 17 00:00:00 2001 From: wuyuanchao Date: Thu, 14 Dec 2023 07:20:04 +0000 Subject: [PATCH 6/9] bugfix for returncode of ForceRemoveDirectory Signed-off-by: wuyuanchao --- base/src/directory_ex.cpp | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/base/src/directory_ex.cpp b/base/src/directory_ex.cpp index 60d2bc1..d7bb765 100644 --- a/base/src/directory_ex.cpp +++ b/base/src/directory_ex.cpp @@ -211,7 +211,7 @@ bool ForceRemoveDirectoryInternal(DIR *dir) UTILS_LOGD("Failed to get dirfd, fd: %{public}d: %{public}s ", rootFd, strerror(errno)); return false; } - + while (true) { struct dirent *ptr = readdir(dir); if (ptr == nullptr) { @@ -225,25 +225,25 @@ bool ForceRemoveDirectoryInternal(DIR *dir) } if (ptr->d_type == DT_DIR) { - int subFd = openat(rootFd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); - if (subFd < 0) { - UTILS_LOGD("Failed in subFd openat: %{public}s ", name); - ret = false; - continue; - } - DIR *subDir = fdopendir(subFd); - if (subDir == nullptr) { - close(subFd); - UTILS_LOGD("Failed in fdopendir: %{public}s", strerror(errno)); - ret = false; - continue; - } - dirStack.push(subDir); - if (unlinkat(rootFd, name, AT_REMOVEDIR) < 0) { - UTILS_LOGD("Couldn't unlinkat subDir %{public}s: %{public}s", name, strerror(errno)); - ret = false; - continue; - } + int subFd = openat(rootFd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); + if (subFd < 0) { + UTILS_LOGD("Failed in subFd openat: %{public}s ", name); + ret = false; + continue; + } + DIR *subDir = fdopendir(subFd); + if (subDir == nullptr) { + close(subFd); + UTILS_LOGD("Failed in fdopendir: %{public}s", strerror(errno)); + ret = false; + continue; + } + dirStack.push(subDir); + if (unlinkat(rootFd, name, AT_REMOVEDIR) < 0) { + UTILS_LOGD("Couldn't unlinkat subDir %{public}s: %{public}s", name, strerror(errno)); + ret = false; + continue; + } } else { if (faccessat(rootFd, name, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { if (unlinkat(rootFd, name, 0) < 0) { -- Gitee From 0f0b2a1598053ce844ae2c4a5518017fe37d7511 Mon Sep 17 00:00:00 2001 From: wuyuanchao Date: Thu, 14 Dec 2023 12:15:59 +0000 Subject: [PATCH 7/9] bugfix for returncode of ForceRemoveDirectory Signed-off-by: wuyuanchao --- base/src/directory_ex.cpp | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/base/src/directory_ex.cpp b/base/src/directory_ex.cpp index d7bb765..0209f85 100644 --- a/base/src/directory_ex.cpp +++ b/base/src/directory_ex.cpp @@ -213,7 +213,7 @@ bool ForceRemoveDirectoryInternal(DIR *dir) } while (true) { - struct dirent *ptr = readdir(dir); + struct dirent *ptr = readdir(currentDir); if (ptr == nullptr) { break; } @@ -228,21 +228,20 @@ bool ForceRemoveDirectoryInternal(DIR *dir) int subFd = openat(rootFd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); if (subFd < 0) { UTILS_LOGD("Failed in subFd openat: %{public}s ", name); - ret = false; - continue; + return false; } DIR *subDir = fdopendir(subFd); if (subDir == nullptr) { close(subFd); UTILS_LOGD("Failed in fdopendir: %{public}s", strerror(errno)); - ret = false; - continue; + return false; } dirStack.push(subDir); if (unlinkat(rootFd, name, AT_REMOVEDIR) < 0) { + close(subFd); UTILS_LOGD("Couldn't unlinkat subDir %{public}s: %{public}s", name, strerror(errno)); - ret = false; - continue; + closedir(subDir); + return false; } } else { if (faccessat(rootFd, name, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { @@ -274,14 +273,17 @@ bool ForceRemoveDirectory(const string& path) if (!ret) { UTILS_LOGD("Failed to remove some subfile under path: %{public}s", path.c_str()); } - closedir(dir); - if (faccessat(AT_FDCWD, path.c_str(), F_OK, AT_SYMLINK_NOFOLLOW) == 0) { - if (remove(path.c_str()) != 0) { - UTILS_LOGD("Failed to remove root dir: %{public}s: %{public}s ", path.c_str(), strerror(errno)); - return false; - } + int rootFd = dirfd(dir); + if (rootFd < 0) { + UTILS_LOGD("Failed to get dirfd, fd: %{public}d: %{public}s ", rootFd, strerror(errno)); + return false; } - + struct dirent *ptr = readdir(dir); + if (unlinkat(rootFd, ptr->d_name, AT_REMOVEDIR) < 0) { + UTILS_LOGD("Couldn't unlinkat subDir %{public}s: %{public}s", ptr->d_name, strerror(errno)); + return false; + } + closedir(dir); return faccessat(AT_FDCWD, path.c_str(), F_OK, AT_SYMLINK_NOFOLLOW) != 0; } @@ -331,7 +333,7 @@ bool ChangeModeFile(const string& fileName, const mode_t& mode) return ChangeMode(fileName, mode); } -bool ChangeModeDirectoryInternal(DIR *dir, const mode_t &mode) +bool ChangeModeDirectoryInternal(DIR *dir, const mode_t &mode) { bool ret = true; stack dirStack; -- Gitee From 581bcf98dd2bf84013cf7dfeed1ee69d25b1a590 Mon Sep 17 00:00:00 2001 From: wuyuanchao Date: Wed, 20 Dec 2023 03:14:29 +0000 Subject: [PATCH 8/9] bugfix for returncode of ForceRemoveDirectory Signed-off-by: wuyuanchao --- base/src/directory_ex.cpp | 267 +++++++++++++++++++++----------------- 1 file changed, 147 insertions(+), 120 deletions(-) diff --git a/base/src/directory_ex.cpp b/base/src/directory_ex.cpp index 0209f85..a495999 100644 --- a/base/src/directory_ex.cpp +++ b/base/src/directory_ex.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "securec.h" #include "unistd.h" #include "utils_log.h" @@ -199,68 +200,68 @@ bool ForceCreateDirectory(const string& path) bool ForceRemoveDirectoryInternal(DIR *dir) { bool ret = true; - std::stack dirStack; - dirStack.push(dir); + int rootFd = dirfd(dir); + if (rootFd < 0) { + UTILS_LOGD("Failed to get dirfd, fd: %{public}d: %{public}s ", rootFd, strerror(errno)); + return false; + } - while (!dirStack.empty()) { - DIR *currentDir = dirStack.top(); - dirStack.pop(); + while (true) { + struct dirent *ptr = readdir(dir); + if (ptr == nullptr) { + break; + } + const char *name = ptr->d_name; - int rootFd = dirfd(currentDir); - if (rootFd < 0) { - UTILS_LOGD("Failed to get dirfd, fd: %{public}d: %{public}s ", rootFd, strerror(errno)); - return false; + // current dir or parent dir + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + continue; } - while (true) { - struct dirent *ptr = readdir(currentDir); - if (ptr == nullptr) { - break; + if (ptr->d_type == DT_DIR) { + int subFd = openat(rootFd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); + if (subFd < 0) { + UTILS_LOGD("Failed in subFd openat: %{public}s ", name); + ret = false; + continue; } - const char *name = ptr->d_name; - - // current dir or parent dir - if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + DIR *subDir = fdopendir(subFd); + if (subDir == nullptr) { + close(subFd); + UTILS_LOGD("Failed in fdopendir: %{public}s", strerror(errno)); + ret = false; continue; } - - if (ptr->d_type == DT_DIR) { - int subFd = openat(rootFd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); - if (subFd < 0) { - UTILS_LOGD("Failed in subFd openat: %{public}s ", name); - return false; - } - DIR *subDir = fdopendir(subFd); - if (subDir == nullptr) { - close(subFd); - UTILS_LOGD("Failed in fdopendir: %{public}s", strerror(errno)); - return false; - } - dirStack.push(subDir); - if (unlinkat(rootFd, name, AT_REMOVEDIR) < 0) { - close(subFd); - UTILS_LOGD("Couldn't unlinkat subDir %{public}s: %{public}s", name, strerror(errno)); - closedir(subDir); + ret = ForceRemoveDirectoryInternal(subDir); + closedir(subDir); + if (unlinkat(rootFd, name, AT_REMOVEDIR) < 0) { + UTILS_LOGD("Couldn't unlinkat subDir %{public}s: %{public}s", name, strerror(errno)); + ret = false; + continue; + } + } else { + if (faccessat(rootFd, name, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { + if (unlinkat(rootFd, name, 0) < 0) { + UTILS_LOGD("Couldn't unlinkat subFile %{public}s: %{public}s", name, strerror(errno)); return false; } } else { - if (faccessat(rootFd, name, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { - if (unlinkat(rootFd, name, 0) < 0) { - UTILS_LOGD("Couldn't unlinkat subFile %{public}s: %{public}s", name, strerror(errno)); - return false; - } - } else { - UTILS_LOGD("Access to file: %{public}s is failed", name); - return false; - } + UTILS_LOGD("Access to file: %{public}s is failed", name); + return false; } } - closedir(currentDir); } return ret; } +struct DirectoryNdoe +{ + int directoryFd; + const char *name; + DIR *dir; +}; + bool ForceRemoveDirectory(const string& path) { bool ret = true; @@ -269,21 +270,84 @@ bool ForceRemoveDirectory(const string& path) UTILS_LOGD("Failed to open root dir: %{public}s: %{public}s ", path.c_str(), strerror(errno)); return false; } - ret = ForceRemoveDirectoryInternal(dir); + + std::queue dirQueue; + std::stack dirStack; + dirQueue.push(dir); + while (!dirQueue.empty()){ + int size = dirQueue.size(); + for (int i = 0; i < size; i++){ + DIR *currentDir = dirQueue.front(); + DirectoryNdoe node; + int currentFd = dirfd(currentDir); + dirQueue.pop(); + while (true){ + struct dirent *ptr = readdir(currentDir); + if (ptr == nullptr){ + break; + } + const char *name = ptr->d_name; + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + continue; + } + if (ptr->d_type == DT_DIR) { + node.name = name; + node.directoryFd = currentFd; + node.dir = currentDir; + dirStack.push(node); + int subFd = openat(currentFd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); + if (subFd < 0) { + UTILS_LOGD("Failed in subFd openat: %{public}s ", name); + ret = false; + break; + } + DIR *subDir = fdopendir(subFd); + if (subDir == nullptr) { + close(subFd); + UTILS_LOGD("Failed in fdopendir: %{public}s", strerror(errno)); + ret = false; + break; + } + dirQueue.push(subDir); + }else { + if (faccessat(currentFd, name, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { + if (unlinkat(currentFd, name, 0) < 0) { + UTILS_LOGD("Couldn't unlinkat subFile %{public}s: %{public}s", name, strerror(errno)); + ret = false; + break; + } + } else { + UTILS_LOGD("Access to file: %{public}s is failed", name); + ret = false; + break; + } + } + } + } + } if (!ret) { UTILS_LOGD("Failed to remove some subfile under path: %{public}s", path.c_str()); + return ret; } - int rootFd = dirfd(dir); - if (rootFd < 0) { - UTILS_LOGD("Failed to get dirfd, fd: %{public}d: %{public}s ", rootFd, strerror(errno)); - return false; - } - struct dirent *ptr = readdir(dir); - if (unlinkat(rootFd, ptr->d_name, AT_REMOVEDIR) < 0) { - UTILS_LOGD("Couldn't unlinkat subDir %{public}s: %{public}s", ptr->d_name, strerror(errno)); - return false; + + while (!dirStack.empty()) { + DirectoryNdoe node = dirStack.top(); + dirStack.pop(); + if (unlinkat(node.directoryFd, node.name, AT_REMOVEDIR) < 0) { + UTILS_LOGD("Couldn't unlinkat subDir %{public}s: %{public}s", name, strerror(errno)); + break; + } + closedir(node.dir); } + closedir(dir); + if (faccessat(AT_FDCWD, path.c_str(), F_OK, AT_SYMLINK_NOFOLLOW) == 0) { + if (remove(path.c_str()) != 0) { + UTILS_LOGD("Failed to remove root dir: %{public}s: %{public}s ", path.c_str(), strerror(errno)); + return false; + } + } + return faccessat(AT_FDCWD, path.c_str(), F_OK, AT_SYMLINK_NOFOLLOW) != 0; } @@ -333,83 +397,46 @@ bool ChangeModeFile(const string& fileName, const mode_t& mode) return ChangeMode(fileName, mode); } -bool ChangeModeDirectoryInternal(DIR *dir, const mode_t &mode) +bool ChangeModeDirectory(const string& path, const mode_t& mode) { + string subPath; bool ret = true; - stack dirStack; - dirStack.push(dir); - - while (!dirStack.empty()) { - DIR *currentDir = dirStack.top(); - dirStack.pop(); + DIR *dir = opendir(path.c_str()); + if (dir == nullptr) { + return false; + } - int rootFd = dirfd(currentDir); - if (rootFd < 0) { - return false; + while (true) { + struct dirent *ptr = readdir(dir); + if (ptr == nullptr) { + break; } - while (true) { - struct dirent *ptr = readdir(currentDir); - if (ptr == nullptr) { - break; - } - const char *name = ptr->d_name; - - // current dir or parent dir - if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { - continue; - } - if (ptr->d_type == DT_DIR) { - int subFd = openat(rootFd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); - if (subFd < 0) { - UTILS_LOGD("Failed in subFd openat: %{public}s ", name); - ret = false; - continue; - } - DIR *subDir = fdopendir(subFd); - if (subDir == nullptr) { - close(subFd); - UTILS_LOGD("Failed in fdopendir: %{public}s", strerror(errno)); - ret = false; - continue; - } - dirStack.push(subDir); - if (fchmodat(rootFd, name, mode, 0) < 0) { - UTILS_LOGD("Couldn't fchmodat subDir %{public}s: %{public}s", name, strerror(errno)); - ret = false; - continue; + // current dir or parent dir + if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) { + continue; + } + subPath = IncludeTrailingPathDelimiter(path) + string(ptr->d_name); + if (ptr->d_type == DT_DIR) { + ret = ChangeModeDirectory(subPath, mode); + } else { + if (access(subPath.c_str(), F_OK) == 0) { + if (!ChangeMode(subPath, mode)) { + UTILS_LOGD("Failed to exec ChangeMode"); + closedir(dir); + return false; } - } else { - continue; } } } - return ret; -} - -bool ChangeModeDirectory(const string& path, const mode_t& mode) -{ - bool ret = true; - DIR *dir = opendir(path.c_str()); - if (dir == nullptr) { - UTILS_LOGD("Failed to open root dir: %{public}s: %{public}s ", path.c_str(), strerror(errno)); - return false; - } - ret = ChangeModeDirectoryInternal(dir, mode); - if (!ret) { - UTILS_LOGD("Failed to exec ChangeModeDirectoryInternal"); - } - int rootFd = dirfd(dir); - if (rootFd < 0) { - return false; - } - if (access(path.c_str(), F_OK) == 0) { - if (fchmodat(rootFd, ".", mode, 0) < 0) { - UTILS_LOGD("Failed to fchmodat current directory: %{public}s", path.c_str()); + closedir(dir); + string currentPath = ExcludeTrailingPathDelimiter(path); + if (access(currentPath.c_str(), F_OK) == 0) { + if (!ChangeMode(currentPath, mode)) { + UTILS_LOGD("Failed to exec ChangeMode"); return false; } } - closedir(dir); return ret; } -- Gitee From d618f24188ae9d9651c54084d16ffd81e60af35c Mon Sep 17 00:00:00 2001 From: wuyuanchao Date: Wed, 20 Dec 2023 08:18:38 +0000 Subject: [PATCH 9/9] bugfix Signed-off-by: wuyuanchao --- base/src/directory_ex.cpp | 77 +++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/base/src/directory_ex.cpp b/base/src/directory_ex.cpp index a495999..3b713a4 100644 --- a/base/src/directory_ex.cpp +++ b/base/src/directory_ex.cpp @@ -339,10 +339,8 @@ bool ForceRemoveDirectory(const string& path) } closedir(node.dir); } - - closedir(dir); if (faccessat(AT_FDCWD, path.c_str(), F_OK, AT_SYMLINK_NOFOLLOW) == 0) { - if (remove(path.c_str()) != 0) { + if (unlinkat(AT_FDCWD, path.c_str(), 0) != 0) { UTILS_LOGD("Failed to remove root dir: %{public}s: %{public}s ", path.c_str(), strerror(errno)); return false; } @@ -405,35 +403,58 @@ bool ChangeModeDirectory(const string& path, const mode_t& mode) if (dir == nullptr) { return false; } - - while (true) { - struct dirent *ptr = readdir(dir); - if (ptr == nullptr) { - break; - } - - // current dir or parent dir - if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) { - continue; - } - subPath = IncludeTrailingPathDelimiter(path) + string(ptr->d_name); - if (ptr->d_type == DT_DIR) { - ret = ChangeModeDirectory(subPath, mode); - } else { - if (access(subPath.c_str(), F_OK) == 0) { - if (!ChangeMode(subPath, mode)) { - UTILS_LOGD("Failed to exec ChangeMode"); - closedir(dir); - return false; + std::stack dirStack1; + std::stack dirStack2; + while (!dirStack2.empty()) { + DIR *currentDir = dirStack1.top(); + dirStack1.pop(); + DirectoryNdoe node; + int currentFd = dirfd(currentDir); + while (true) { + struct dirent *ptr = readdir(currentDir); + if (ptr == nullptr) { + break; + } + const char *name = ptr->d_name; + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { + continue; + } + if (ptr->d_type == DT_DIR) { + node.name = name; + node.directoryFd = currentFd; + node.dir = currentDir; + dirStack2.push(node); + int subFd = openat(currentFd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); + if (subFd < 0) { + UTILS_LOGD("Failed in subFd openat: %{public}s ", name); + ret = false; + break; } + DIR *subDir = fdopendir(subFd); + if (subDir == nullptr) { + close(subFd); + UTILS_LOGD("Failed in fdopendir: %{public}s", strerror(errno)); + ret = false; + break; + } + dirStack1.push(subDir); } + } } - closedir(dir); - string currentPath = ExcludeTrailingPathDelimiter(path); - if (access(currentPath.c_str(), F_OK) == 0) { - if (!ChangeMode(currentPath, mode)) { - UTILS_LOGD("Failed to exec ChangeMode"); + while (!dirStack2.empty()) { + DirectoryNdoe node = dirStack2.top(); + dirStack2.pop(); + if (fchmodat(node.directoryFd, node.name, mode, 0) < 0){ + UTILS_LOGD("Failed to exec fchmodat"); + return false; + } + close(node.directoryFd); + closedir(node.dir); + } + if (access(path.c_str(), F_OK) == 0) { + if (fchmodat(AT_FDCWD, path.c_str(), mode, 0) < 0) { + UTILS_LOGD("Failed to change mode root dir: %{public}s: %{public}s ", path.c_str(), strerror(errno)); return false; } } -- Gitee