#include <sys/wait.h>
#include <unistd.h>
+#include <string>
+#include <vector>
+
#include "launchpad-process-pool/launchpad_dbus.h"
#include "launchpad-process-pool/launchpad_io_channel.h"
+#include "launchpad-process-pool/launchpad_worker.h"
#include "lib/common/inc/launchpad_common.h"
#include "lib/common/inc/launchpad_proc.h"
#include "lib/common/inc/launchpad_socket.h"
#include "lib/common/inc/log_private.h"
-#define HYDRA_SIGCHLD_SOCK ".hydra-sigchld-sock"
+namespace {
+
+constexpr const char HYDRA_SIGCHLD_SOCK[] = ".hydra-sigchld-sock";
+
+pid_t __pid;
+sigset_t __mask;
+sigset_t __old_mask;
+socket_h __sigchld_socket;
+io_channel_h __sigchld_channel;
+socket_h __hydra_sigchld_socket;
+io_channel_h __hydra_sigchld_channel;
+signal_sigchld_cb __callback;
+void* __user_data;
+
+worker_h recycle_bin;
-static pid_t __pid;
-static sigset_t __mask;
-static sigset_t __old_mask;
-static socket_h __sigchld_socket;
-static io_channel_h __sigchld_channel;
-static socket_h __hydra_sigchld_socket;
-static io_channel_h __hydra_sigchld_channel;
-static signal_sigchld_cb __callback;
-static void* __user_data;
+} // namespace
static gboolean __hydra_sigchld_recovery_cb(gpointer data);
static gboolean __sigchld_recovery_cb(gpointer data);
closedir(dp);
}
-static void __sigchld_action(int pid) {
- _dbus_send_app_dead_signal(pid);
+static void __delete_unused_files(pid_t pid) {
+ std::vector<std::string> files = {
+ "clr-debug-pipe-" + std::to_string(pid) + "-",
+ "dotnet-diagnostic-" + std::to_string(pid) + "-"
+ };
+
+ DIR* dp = opendir("/tmp");
+ if (dp == nullptr) {
+ _E("opendir() is failed");
+ return;
+ }
+
+ struct dirent* dentry = nullptr;
+ while ((dentry = readdir(dp)) != nullptr) {
+ if (dentry->d_name[0] == '.')
+ continue;
+
+ if (dentry->d_name[0] != 'c' && dentry->d_name[0] != 'd')
+ continue;
+
+ for (size_t i = 0; i < files.size(); ++i) {
+ if (files[i].compare(0, files[i].length(), dentry->d_name, 0,
+ files[i].length()) == 0) {
+ std::string path = std::string("/tmp/") + dentry->d_name;
+ unlink(path.c_str());
+ _W("unlink(%s)", path.c_str());
+ }
+ }
+ }
+ closedir(dp);
+}
+
+static bool __garbage_collector(void *user_data) {
+ pid_t pid = GPOINTER_TO_INT(
+ reinterpret_cast<unsigned long>(user_data) & UINT32_MAX);
+ _W("pid(%d)", pid);
_delete_sock_path(pid, getuid());
+ __delete_unused_files(pid);
__socket_garbage_collector();
+ return false;
+}
+
+static void __sigchld_action(int pid) {
+ _dbus_send_app_dead_signal(pid);
+ _worker_add_job(recycle_bin, __garbage_collector, GINT_TO_POINTER(pid));
}
static int __check_permission(int pid) {
}
}
+ ret = _worker_create("RecycleBin+", &recycle_bin);
+ if (ret < 0) {
+ _E("_worker_create() is failed");
+ return ret;
+ }
+
return 0;
}
#endif
_D("SIGNAL_FINI");
+ if (getpid() == __pid)
+ _worker_destroy(recycle_bin);
+
_signal_set_sigchld_cb(nullptr, nullptr);
__hydra_sigchld_fini();
__sigchld_fini();