From f6bd702b46cd56c6b11767110e26c7105f30f71f Mon Sep 17 00:00:00 2001 From: Nikita Kogut Date: Sat, 29 Mar 2025 01:46:58 +0200 Subject: [PATCH] Add functions to get current process pid and name --- include/SDL3/SDL_process.h | 31 ++++++++++++++++ src/SDL.c | 3 ++ src/dynapi/SDL_dynapi.sym | 2 ++ src/dynapi/SDL_dynapi_overrides.h | 2 ++ src/dynapi/SDL_dynapi_procs.h | 2 ++ src/process/SDL_process.c | 29 +++++++++++++++ src/process/SDL_process_c.h | 28 +++++++++++++++ src/process/SDL_sysprocess.h | 2 ++ src/process/dummy/SDL_dummyprocess.c | 10 ++++++ src/process/posix/SDL_posixprocess.c | 18 ++++++++++ src/process/windows/SDL_windowsprocess.c | 45 ++++++++++++++++++++++++ 11 files changed, 172 insertions(+) create mode 100644 src/process/SDL_process_c.h diff --git a/include/SDL3/SDL_process.h b/include/SDL3/SDL_process.h index 0e19bfff1dc9a..adcc11665c894 100644 --- a/include/SDL3/SDL_process.h +++ b/include/SDL3/SDL_process.h @@ -425,6 +425,37 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WaitProcess(SDL_Process *process, bool bloc */ extern SDL_DECLSPEC void SDLCALL SDL_DestroyProcess(SDL_Process *process); +/** + * Get the current process ID. + * + * It eventually maps to the platform-specific function to get the current process ID (getpid() on Unix and GetCurrentProcessId() on Windows). + * There is no direct usage for it in SDL right now, but you may use this value for debugging or other purposes. + * + * \returns PID of the current process + * + * \threadsafety This function is not thread safe. + * + * \since This function is available since SDL 3.2.0. + * + * \sa SDL_GetCurrentProcessName + */ +extern SDL_DECLSPEC int SDLCALL SDL_GetCurrentProcessId(void); + +/** + * Get the current process name. + * + * Returned string is cached by SDL and should not be freed by the caller. + * + * \returns Name of the current process + * + * \threadsafety This function is not thread safe. + * + * \since This function is available since SDL 3.2.0. + * + * \sa SDL_GetCurrentProcessId + */ +extern SDL_DECLSPEC const char *SDLCALL SDL_GetCurrentProcessName(void); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus } diff --git a/src/SDL.c b/src/SDL.c index 502f6617a4f26..4c4be8299e3a1 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -60,6 +60,7 @@ #ifdef SDL_PLATFORM_ANDROID #include "core/android/SDL_android.h" #endif +#include "process/SDL_process_c.h" #define SDL_INIT_EVERYTHING ~0U @@ -279,6 +280,7 @@ void SDL_InitMainThread(void) SDL_InitEnvironment(); SDL_InitTicks(); SDL_InitFilesystem(); + SDL_InitProcessManagement(); if (!done_info) { const char *value; @@ -301,6 +303,7 @@ static void SDL_QuitMainThread(void) SDL_QuitTicks(); SDL_QuitEnvironment(); SDL_QuitTLSData(); + SDL_QuitProcessManagement(); } bool SDL_InitSubSystem(SDL_InitFlags flags) diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index 6ec8127dfa490..5510a3d11b2d6 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -1248,6 +1248,8 @@ SDL3_0.0.0 { SDL_GetWindowProgressValue; SDL_SetRenderTextureAddressMode; SDL_GetRenderTextureAddressMode; + SDL_GetCurrentProcessId; + SDL_GetCurrentProcessName; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index c00526490019d..2c75df7b154f6 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -1273,3 +1273,5 @@ #define SDL_GetWindowProgressValue SDL_GetWindowProgressValue_REAL #define SDL_SetRenderTextureAddressMode SDL_SetRenderTextureAddressMode_REAL #define SDL_GetRenderTextureAddressMode SDL_GetRenderTextureAddressMode_REAL +#define SDL_GetCurrentProcessId SDL_GetCurrentProcessId_REAL +#define SDL_GetCurrentProcessName SDL_GetCurrentProcessName_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 31f56143e35c1..d7bfd429e9f7b 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -1281,3 +1281,5 @@ SDL_DYNAPI_PROC(SDL_ProgressState,SDL_GetWindowProgressState,(SDL_Window *a),(a) SDL_DYNAPI_PROC(float,SDL_GetWindowProgressValue,(SDL_Window *a),(a),return) SDL_DYNAPI_PROC(bool,SDL_SetRenderTextureAddressMode,(SDL_Renderer *a,SDL_TextureAddressMode b,SDL_TextureAddressMode c),(a,b,c),return) SDL_DYNAPI_PROC(bool,SDL_GetRenderTextureAddressMode,(SDL_Renderer *a,SDL_TextureAddressMode *b,SDL_TextureAddressMode *c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_GetCurrentProcessId,(void),(),return) +SDL_DYNAPI_PROC(const char*,SDL_GetCurrentProcessName,(void),(),return) diff --git a/src/process/SDL_process.c b/src/process/SDL_process.c index 3ccf5d582b185..eefb9cbcc0f47 100644 --- a/src/process/SDL_process.c +++ b/src/process/SDL_process.c @@ -194,3 +194,32 @@ void SDL_DestroyProcess(SDL_Process *process) SDL_DestroyProperties(process->props); SDL_free(process); } + +int SDL_GetCurrentProcessId(void) +{ + return SDL_SYS_GetCurrentProcessId(); +} + +static char *CachedCurrentProcessName = NULL; + +const char *SDL_GetCurrentProcessName(void) +{ + if (!CachedCurrentProcessName) { + CachedCurrentProcessName = SDL_SYS_GetCurrentProcessName(); + } + + return CachedCurrentProcessName; +} + +void SDL_InitProcessManagement(void) +{ +} + +void SDL_QuitProcessManagement(void) +{ + if (CachedCurrentProcessName) { + SDL_free(CachedCurrentProcessName); + } + + CachedCurrentProcessName = NULL; +} diff --git a/src/process/SDL_process_c.h b/src/process/SDL_process_c.h new file mode 100644 index 0000000000000..d75c5c4f32aaa --- /dev/null +++ b/src/process/SDL_process_c.h @@ -0,0 +1,28 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_process_c_h_ +#define SDL_process_c_h_ + +extern void SDL_InitProcessManagement(void); +extern void SDL_QuitProcessManagement(void); + +#endif diff --git a/src/process/SDL_sysprocess.h b/src/process/SDL_sysprocess.h index 839ef9db13f50..65776eabe09f2 100644 --- a/src/process/SDL_sysprocess.h +++ b/src/process/SDL_sysprocess.h @@ -35,3 +35,5 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID bool SDL_SYS_KillProcess(SDL_Process *process, bool force); bool SDL_SYS_WaitProcess(SDL_Process *process, bool block, int *exitcode); void SDL_SYS_DestroyProcess(SDL_Process *process); +int SDL_SYS_GetCurrentProcessId(void); +char *SDL_SYS_GetCurrentProcessName(void); diff --git a/src/process/dummy/SDL_dummyprocess.c b/src/process/dummy/SDL_dummyprocess.c index ba69e4a04a168..a6bae84a4dab4 100644 --- a/src/process/dummy/SDL_dummyprocess.c +++ b/src/process/dummy/SDL_dummyprocess.c @@ -45,4 +45,14 @@ void SDL_SYS_DestroyProcess(SDL_Process *process) return; } +int SDL_GetCurrentProcessId(void) +{ + return -1; +} + +char *SDL_SYS_GetCurrentProcessName(void) +{ + return NULL; +} + #endif // SDL_PROCESS_DUMMY diff --git a/src/process/posix/SDL_posixprocess.c b/src/process/posix/SDL_posixprocess.c index 2e05b01324ecc..d06ce8d1e23dd 100644 --- a/src/process/posix/SDL_posixprocess.c +++ b/src/process/posix/SDL_posixprocess.c @@ -511,4 +511,22 @@ void SDL_SYS_DestroyProcess(SDL_Process *process) SDL_free(process->internal); } +int SDL_SYS_GetCurrentProcessId(void) +{ + return getpid(); +} + +char *SDL_SYS_GetCurrentProcessName(void) +{ +#if defined(SDL_PLATFORM_MACOS) || defined(SDL_PLATFORM_FREEBSD) + char *processPath = SDL_strdup(getprogname()); +#elif defined(SDL_PLATFORM_LINUX) + char *processPath = SDL_strdup(program_invocation_name); +#else + char *processPath = NULL; +#endif + + return processPath; +} + #endif // SDL_PROCESS_POSIX diff --git a/src/process/windows/SDL_windowsprocess.c b/src/process/windows/SDL_windowsprocess.c index 95f45c08f14b6..8709e5c04825b 100644 --- a/src/process/windows/SDL_windowsprocess.c +++ b/src/process/windows/SDL_windowsprocess.c @@ -564,4 +564,49 @@ void SDL_SYS_DestroyProcess(SDL_Process *process) SDL_free(data); } +int SDL_SYS_GetCurrentProcessId(void) +{ + return GetCurrentProcessId(); +} + +char *SDL_SYS_GetCurrentProcessName(void) +{ + DWORD buflen = 128; + WCHAR *path = NULL; + char *result = NULL; + DWORD len = 0; + + // Copy paste from SDL_GetBasePath() - should this be a shared function? + while (true) { + void *ptr = SDL_realloc(path, buflen * sizeof(WCHAR)); + if (!ptr) { + SDL_free(path); + return NULL; + } + + path = (WCHAR *)ptr; + + len = GetModuleFileNameW(NULL, path, buflen); + // if it truncated, then len >= buflen - 1 + // if there was enough room (or failure), len < buflen - 1 + if (len < buflen - 1) { + break; + } + + // buffer too small? Try again. + buflen *= 2; + } + + if (len == 0) { + SDL_free(path); + WIN_SetError("Couldn't locate our .exe"); + return NULL; + } + + result = WIN_StringToUTF8W(path); + SDL_free(path); + + return result; +} + #endif // SDL_PROCESS_WINDOWS