Replacing recursive opendir with a utility function
authorJanusz Majnert <j.majnert@samsung.com>
Tue, 23 Oct 2012 12:32:29 +0000 (14:32 +0200)
committerTaejeong Lee <taejeong.lee@samsung.com>
Fri, 2 Nov 2012 07:10:06 +0000 (16:10 +0900)
[Issue#] N/A
[Feature] Replacing recursive opendir with safer utility function
[Cause] Recursive opendir may reach limit of open dirs for process
[Solution] Replace with a utility function
[Verification] Uninstall widget, verify that installation directory was removed

Installer removes the widget installation directory, which can have multiple
levels of directories. Instead of recursively calling opendir, installer will
now call WrtUtilRemove function that uses safe fts_* functions to traverse the
directory tree.

Change-Id: I3ff7e02b32c76da37785f6d6b793e19bca308ae1

src/jobs/widget_uninstall/task_remove_files.cpp
src/jobs/widget_uninstall/task_remove_files.h
src/jobs/widget_uninstall/uninstaller_context.h

index a9eaebb..ea67ab0 100644 (file)
 #include <widget_uninstall/uninstaller_context.h>
 #include <dpl/wrt-dao-rw/widget_dao.h>
 #include <dpl/wrt-dao-ro/widget_config.h>
-#include <errno.h>
 #include <dpl/assert.h>
 #include <dpl/utils/wrt_utility.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <dirent.h>
 #include <ail.h>
-#include <dpl/utils/wrt_utility.h>
 #include <pkgmgr/pkgmgr_parser.h>
 
 namespace Jobs {
@@ -41,91 +35,11 @@ namespace WidgetUninstall {
 
 using namespace WrtDB;
 
-void TaskRemoveFiles::ReadDir(const std::string& path,
-        std::list<std::string>& filesList)
-{
-    LogInfo("Reading directory " << path);
-    DIR* dir = NULL;
-    struct dirent* ptr = NULL;
-    dir = opendir(path.c_str());
-    std::string delim = "";
-
-    // adding / for path to directory to build a proper path to file under directory
-    if (path[path.size() - 1] != '/') {
-        delim = "/";
-    }
-
-    if (dir) {
-        while ((ptr = readdir(dir)) != NULL) {
-            if ((!strcmp(ptr->d_name, ".")) || (!strcmp(ptr->d_name, ".."))) {
-                LogPedantic("Omiting " << ptr->d_name);
-                continue;
-            }
-            std::string childPath = path + delim + ptr->d_name;
-
-            struct stat st;
-            if (0 != lstat(childPath.c_str(), &st)) {
-                switch (errno) {
-                case EACCES:
-                    LogWarning(
-                        "EACCESS Error occured during lstat with path: " <<
-                        childPath);
-                    continue;
-                case EBADF:
-                    LogWarning(
-                        "EBADF Error occured during lstat with path: " <<
-                        childPath);
-                    continue;
-                case ENOENT:
-                    LogWarning(
-                        "ENOENT Error occured during lstat with path: " <<
-                        childPath);
-                    continue;
-                case ENOTDIR:
-                    LogWarning(
-                        "ENOTDIR Error occured during lstat with path: " <<
-                        childPath);
-                    continue;
-                default:
-                    LogWarning(
-                        "Unknown Error occured during lstat with path: " <<
-                        childPath);
-                    continue;
-                }
-            } else {
-                if (S_ISDIR(st.st_mode)) {
-                    LogPedantic(
-                        "Calling ReadDir in recursive way " << childPath);
-                    ReadDir(childPath, filesList);
-                } else if (S_ISREG(st.st_mode) ||
-                           S_ISCHR(st.st_mode) ||
-                           S_ISBLK(st.st_mode) ||
-                           S_ISFIFO(st.st_mode) ||
-                           S_ISLNK(st.st_mode) ||
-                           S_ISSOCK(st.st_mode)) {
-                    LogPedantic("Adding to list  " << childPath);
-                    filesList.push_front(childPath);
-                } else {
-                    LogWarning("Uknown file type ??");
-                }
-            }
-        }
-        closedir(dir);
-    } else if (errno == ENOTDIR) {
-        LogDebug("Adding to list " << path);
-        filesList.push_front(path);
-    } else {
-        LogWarning("Unknown error");
-    }
-}
-
 TaskRemoveFiles::TaskRemoveFiles(UninstallerContext& context) :
     DPL::TaskDecl<TaskRemoveFiles>(this),
     m_context(context)
 {
-    AddStep(&TaskRemoveFiles::StepPrepare);
-    AddStep(&TaskRemoveFiles::StepRemoveOneFile);
-    AddStep(&TaskRemoveFiles::StepRemoveDirectories);
+    AddStep(&TaskRemoveFiles::StepRemoveInstallationDirectory);
     //AddStep(&TaskRemoveFiles::StepRemoveDesktop);
     AddStep(&TaskRemoveFiles::StepRemoveManifest);
     AddStep(&TaskRemoveFiles::StepRemoveExternalLocations);
@@ -136,56 +50,19 @@ TaskRemoveFiles::~TaskRemoveFiles()
 {
 }
 
-void TaskRemoveFiles::StepPrepare()
+void TaskRemoveFiles::StepRemoveInstallationDirectory()
 {
-    LogInfo("StepPrepare started");
-
-    std::ostringstream widgetDir;
-
-    widgetDir << m_context.locations->getPackageInstallationDir() << "/";
-
-    uninstRootDir = widgetDir.str();
-    ReadDir(uninstRootDir, filesList);
+    LogInfo("StepRemoveInstallationDirectory started");
 
-    LogInfo("StepPrepare finished");
-
-    m_context.job->UpdateProgress(
-        UninstallerContext::UNINSTALL_REMOVE_PREPARE,
-        "Widget remove prepare Finished");
     m_context.removeStarted = true;
-}
-
-void TaskRemoveFiles::StepRemoveOneFile()
-{
-    if (filesList.size() > 0) {
-        LogDebug("Removing " << filesList.front());
-        if (0 != unlink(filesList.front().c_str())) {
-            LogWarning("Failed to remove file" << filesList.front());
-        }
-        filesList.pop_front();
-        SwitchToStep(&TaskRemoveFiles::StepRemoveOneFile);
-    } else {
-        m_context.removeFinished = true;
-    }
-
-    m_context.job->UpdateProgress(
-        UninstallerContext::UNINSTALL_REMOVE_ONEFILE,
-        "Widget remove onefile Finished");
-}
-
-void TaskRemoveFiles::StepRemoveDirectories()
-{
-    using namespace WrtDB;
-    LogInfo("StepRemoveDirectories started");
-
-    if (!WrtUtilRemove(uninstRootDir)) {
-        LogWarning("Failed to remove directory" << uninstRootDir);
+    std::string widgetDir =
+        m_context.locations->getPackageInstallationDir();
+    if(!WrtUtilRemove(widgetDir)){
+        LogWarning("Removing widget installation directory failed");
     }
-    LogInfo("StepRemoveDirectories finished");
-
     m_context.job->UpdateProgress(
-        UninstallerContext::UNINSTALL_REMOVE_DIRECTORIES,
-        "Widget remove directories Finished");
+        UninstallerContext::UNINSTALL_REMOVE_WIDGETDIR,
+        "Widget INstallation Directory Removal Finished");
 }
 
 void TaskRemoveFiles::StepRemoveFinished()
index 38fcdb9..6959242 100644 (file)
@@ -44,16 +44,9 @@ class TaskRemoveFiles :
     };
 
     UninstallerContext& m_context;
-    std::list<std::string> filesList;
-    std::string uninstRootDir;
-
-    static void ReadDir(const std::string& path,
-            std::list<std::string>& filesList);
 
   private:
-    void StepPrepare();
-    void StepRemoveOneFile();
-    void StepRemoveDirectories();
+    void StepRemoveInstallationDirectory();
     void StepRemoveFinished();
     void StepRemoveDesktop();
     void StepRemoveManifest();
index d6e9d52..873852f 100644 (file)
@@ -40,9 +40,7 @@ struct UninstallerContext
         UNINSTALL_START,
         UNINSTALL_SMACK_ENABLE,
         UNINSTALL_PRECHECK,
-        UNINSTALL_REMOVE_PREPARE,
-        UNINSTALL_REMOVE_ONEFILE,
-        UNINSTALL_REMOVE_DIRECTORIES,
+        UNINSTALL_REMOVE_WIDGETDIR,
         UNINSTALL_REMOVE_DESKTOP,
         UNINSTALL_REMOVE_FINISHED,
         UNINSTALL_DB_UPDATE,