From bb1d53e341105558a1318c839c28fcebb1546c91 Mon Sep 17 00:00:00 2001 From: Gaspar Capello Date: Tue, 26 Dec 2023 16:56:23 -0300 Subject: [PATCH 1/3] Fix 'is_process_running' returns an incorrect 'true' when process 'pid' exists, but whose process does not belong to the current application. Effect on Aseprite: some recovery sessions do not appear in the Recovery menu. --- base/process.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++-- base/process.h | 3 +++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/base/process.cpp b/base/process.cpp index 887f2d475..ab610c2a4 100644 --- a/base/process.cpp +++ b/base/process.cpp @@ -1,5 +1,5 @@ // LAF Base Library -// Copyright (c) 2021 Igara Studio S.A. +// Copyright (c) 2021-2024 Igara Studio S.A. // Copyright (c) 2015-2016 David Capello // // This file is released under the terms of the MIT license. @@ -13,12 +13,19 @@ #if LAF_WINDOWS #include + #include + #include #else #include #include #include #endif +#if LAF_MACOS + #include + #include +#endif + namespace base { #if LAF_WINDOWS @@ -28,6 +35,33 @@ pid get_current_process_id() return (pid)GetCurrentProcessId(); } +bool is_process_running(pid pid, const char* pname) +{ + bool running = false; + HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); + if (handle) { + PROCESSENTRY32 pe; + pe.dwSize = sizeof(PROCESSENTRY32); + if (Process32First(handle, &pe)) { + do { + char buf[64]; + wcstombs(buf, pe.szExeFile, 64); + std::string str(buf); + for (char& c : str) { + c = tolower(c); + } + if (pe.th32ProcessID == pid && + str == pname) { + running = true; + } + } while (Process32Next(handle, &pe)); + } + CloseHandle(handle); + } + + return running; +} + bool is_process_running(pid pid) { bool running = false; @@ -44,18 +78,43 @@ bool is_process_running(pid pid) return running; } -#else // !LAF_WINDOWS +#elif LAF_MACOS pid get_current_process_id() { return (pid)getpid(); } +bool is_process_running(pid pid, const char* pname) +{ + struct proc_bsdinfo process; + proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, + &process, PROC_PIDTBSDINFO_SIZE); + return (strcmp(pname, process.pbi_name) == 0); +} + bool is_process_running(pid pid) { return (kill(pid, 0) == 0); } +#elif LAF_LINUX + +pid get_current_process_id() +{ + return (pid)getpid(); +} + +bool is_process_running(pid pid, const char* pname) +{ + return (kill(pid, 0) == 0); +} + +bool is_process_running(pid pid) +{ + return is_process_running(pid, ""); +} + #endif } // namespace base diff --git a/base/process.h b/base/process.h index 445b87cd6..3c4e4058f 100644 --- a/base/process.h +++ b/base/process.h @@ -1,4 +1,5 @@ // LAF Base Library +// Copyright (c) 2023-2024 Igara Studio S.A. // Copyright (c) 2015-2016 David Capello // // This file is released under the terms of the MIT license. @@ -16,6 +17,8 @@ namespace base { pid get_current_process_id(); + bool is_process_running(pid pid, const char* pname); + bool is_process_running(pid pid); } // namespace base From 028e445dca4c18e28a97663b432cdade03edeccb Mon Sep 17 00:00:00 2001 From: martincapello Date: Tue, 16 Jan 2024 15:59:40 -0300 Subject: [PATCH 2/3] Fix 'is_process_running' for Linux --- base/process.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/base/process.cpp b/base/process.cpp index ab610c2a4..5a79366a0 100644 --- a/base/process.cpp +++ b/base/process.cpp @@ -26,6 +26,11 @@ #include #endif +#if LAF_LINUX + #include "base/fs.h" + #include + #include +#endif namespace base { #if LAF_WINDOWS @@ -107,12 +112,22 @@ pid get_current_process_id() bool is_process_running(pid pid, const char* pname) { - return (kill(pid, 0) == 0); + char path[128]; + memset(path, 0, 128); + sprintf(path, "/proc/%d/exe", pid); + char* exepath = realpath(path, nullptr); + if (!exepath) + return false; + + auto exename = base::get_file_name(exepath); + free(exepath); + + return exename == std::string(pname); } bool is_process_running(pid pid) { - return is_process_running(pid, ""); + return (kill(pid, 0) == 0); } #endif From 689a7b9d2b7d06d6ffe62387760992ae9834cab5 Mon Sep 17 00:00:00 2001 From: Gaspar Capello Date: Tue, 23 Jan 2024 12:01:04 -0300 Subject: [PATCH 3/3] Unification of the 'is_process_running(pid pid)' function for all platforms --- base/process.cpp | 64 +++++++++++++++++------------------------------- base/process.h | 8 +++++- 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/base/process.cpp b/base/process.cpp index 5a79366a0..a0d11e338 100644 --- a/base/process.cpp +++ b/base/process.cpp @@ -13,7 +13,6 @@ #if LAF_WINDOWS #include - #include #include #else #include @@ -23,14 +22,11 @@ #if LAF_MACOS #include - #include -#endif - -#if LAF_LINUX +#elif LAF_LINUX #include "base/fs.h" - #include #include #endif + namespace base { #if LAF_WINDOWS @@ -40,9 +36,8 @@ pid get_current_process_id() return (pid)GetCurrentProcessId(); } -bool is_process_running(pid pid, const char* pname) +std::string get_process_name(pid pid) { - bool running = false; HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); if (handle) { PROCESSENTRY32 pe; @@ -55,32 +50,14 @@ bool is_process_running(pid pid, const char* pname) for (char& c : str) { c = tolower(c); } - if (pe.th32ProcessID == pid && - str == pname) { - running = true; + if (pe.th32ProcessID == pid) { + return str; } } while (Process32Next(handle, &pe)); } CloseHandle(handle); } - - return running; -} - -bool is_process_running(pid pid) -{ - bool running = false; - - HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid); - if (handle) { - DWORD exitCode = 0; - if (GetExitCodeProcess(handle, &exitCode)) { - running = (exitCode == STILL_ACTIVE); - } - CloseHandle(handle); - } - - return running; + return ""; } #elif LAF_MACOS @@ -90,17 +67,12 @@ pid get_current_process_id() return (pid)getpid(); } -bool is_process_running(pid pid, const char* pname) +std::string get_process_name(pid pid) { struct proc_bsdinfo process; proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &process, PROC_PIDTBSDINFO_SIZE); - return (strcmp(pname, process.pbi_name) == 0); -} - -bool is_process_running(pid pid) -{ - return (kill(pid, 0) == 0); + return process.pbi_name; } #elif LAF_LINUX @@ -110,26 +82,34 @@ pid get_current_process_id() return (pid)getpid(); } -bool is_process_running(pid pid, const char* pname) +std::string get_process_name(pid pid) { char path[128]; memset(path, 0, 128); sprintf(path, "/proc/%d/exe", pid); char* exepath = realpath(path, nullptr); if (!exepath) - return false; + return ""; auto exename = base::get_file_name(exepath); free(exepath); - return exename == std::string(pname); + return exename; } -bool is_process_running(pid pid) +#endif + +bool is_process_running(pid pid, std::string currentProcessName) { - return (kill(pid, 0) == 0); + std::string pidProcessName = get_process_name(pid); + if (pidProcessName == "") + return false; + return pidProcessName == currentProcessName; } -#endif +bool is_process_running(pid pid) +{ + return false; +}; } // namespace base diff --git a/base/process.h b/base/process.h index 3c4e4058f..5aa5d79b1 100644 --- a/base/process.h +++ b/base/process.h @@ -11,14 +11,20 @@ #include "base/ints.h" +#include + namespace base { typedef uint32_t pid; pid get_current_process_id(); - bool is_process_running(pid pid, const char* pname); + std::string get_process_name(pid pid); + + bool is_process_running(pid pid, std::string currentProcessName); + // Declaration to avoid errors during testing of Github actions + // TO DO: remove function after the implementation of PR aseprite/aseprite#4266 bool is_process_running(pid pid); } // namespace base