summaryrefslogtreecommitdiff
path: root/src/managers/KeybindManager.cpp
diff options
context:
space:
mode:
authorCcydtN <kennyip100@gmail.com>2022-06-16 01:06:51 +0800
committerCcydtN <kennyip100@gmail.com>2022-06-17 01:14:10 +0800
commit5fa61e5a54a2c1e908a9f460bf1fb9e84e9e98c2 (patch)
treec59258bd2b71258b64058ed55df1f2f2e3cbd33d /src/managers/KeybindManager.cpp
parent36ea12b315c86e3a1448fe3e695bc5e8bca385a7 (diff)
Fix generating zombie process
Diffstat (limited to 'src/managers/KeybindManager.cpp')
-rw-r--r--src/managers/KeybindManager.cpp41
1 files changed, 39 insertions, 2 deletions
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index be87e24a..c60d22a0 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -141,11 +141,48 @@ void CKeybindManager::spawn(std::string args) {
args = "WAYLAND_DISPLAY=" + std::string(g_pCompositor->m_szWLDisplaySocket) + " " + args;
Debug::log(LOG, "Executing %s", args.c_str());
- if (fork() == 0) {
- execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
+ int socket[2];
+ if (pipe(socket) != 0) {
+ Debug::log(LOG, "Unable to create pipe for fork");
+ }
+
+ pid_t child ,grandchild;
+ child = fork();
+ if (child<0){
+ close(socket[0]);
+ close(socket[1]);
+ Debug::log(LOG, "Fail to create the first fork");
+ return;
+ }
+ if (child == 0){
+ // run in child
+ grandchild = fork();
+ if (grandchild==0){
+ // run in grandchild
+ close(socket[0]);
+ close(socket[1]);
+ execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
+ // exit grandchild
+ _exit(0);
+ }
+ close(socket[0]);
+ (void) write(socket[1], &grandchild, sizeof(grandchild));
+ close(socket[1]);
+ // exit child
_exit(0);
}
+ // run in parent
+ close(socket[1]);
+ (void) read(socket[0], &grandchild,sizeof(grandchild));
+ close(socket[0]);
+ // clear child and leave child to init
+ waitpid(child, NULL, 0);
+ if (child<0){
+ Debug::log(LOG, "Fail to create the second fork");
+ return;
+ }
+ Debug::log(LOG, "Process Created with pid %d",grandchild);
}
void CKeybindManager::killActive(std::string args) {