pipewire: make pw_get_prgname() thread safe

Make sure the string isn't overwritten while another thread is reading
it.

Fixes #1402
This commit is contained in:
Jonas Holmberg 2021-07-06 19:23:36 +02:00
parent 8184d4576a
commit 298dfa7da4

View file

@ -33,6 +33,7 @@
#include <pwd.h> #include <pwd.h>
#include <errno.h> #include <errno.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <pthread.h>
#include <locale.h> #include <locale.h>
#include <libintl.h> #include <libintl.h>
@ -51,6 +52,8 @@
#define SUPPORTLIB "support/libspa-support" #define SUPPORTLIB "support/libspa-support"
static char *prgname;
static struct spa_i18n *_pipewire_i18n = NULL; static struct spa_i18n *_pipewire_i18n = NULL;
struct plugin { struct plugin {
@ -610,33 +613,48 @@ const char *pw_get_application_name(void)
return NULL; return NULL;
} }
/** Get the program name */ static void init_prgname(void)
SPA_EXPORT
const char *pw_get_prgname(void)
{ {
static char prgname[PATH_MAX]; static char name[PATH_MAX];
spa_memzero(prgname, sizeof(prgname));
spa_memzero(name, sizeof(name));
#if defined(__linux__) || defined(__FreeBSD_kernel__) #if defined(__linux__) || defined(__FreeBSD_kernel__)
{ {
if (readlink("/proc/self/exe", prgname, sizeof(prgname)-1) > 0) if (readlink("/proc/self/exe", name, sizeof(name)-1) > 0) {
return strrchr(prgname, '/') + 1; prgname = strrchr(name, '/') + 1;
return;
}
} }
#endif #endif
#if defined __FreeBSD__ #if defined __FreeBSD__
{ {
ssize_t len; ssize_t len;
spa_memzero(prgname, sizeof(prgname));
if ((len = readlink("/proc/curproc/file", prgname, sizeof(prgname)-1)) > 0) if ((len = readlink("/proc/curproc/file", name, sizeof(name)-1)) > 0) {
return strrchr(prgname, '/') + 1; prgname = strrchr(name, '/') + 1;
return;
}
} }
#endif #endif
#ifndef __FreeBSD__ #ifndef __FreeBSD__
{ {
if (prctl(PR_GET_NAME, (unsigned long) prgname, 0, 0, 0) == 0) if (prctl(PR_GET_NAME, (unsigned long) name, 0, 0, 0) == 0) {
return prgname; prgname = name;
return;
}
} }
#endif #endif
snprintf(prgname, sizeof(prgname), "pid-%d", getpid()); snprintf(name, sizeof(name), "pid-%d", getpid());
prgname = name;
}
/** Get the program name */
SPA_EXPORT
const char *pw_get_prgname(void)
{
static pthread_once_t prgname_is_initialized = PTHREAD_ONCE_INIT;
pthread_once(&prgname_is_initialized, init_prgname);
return prgname; return prgname;
} }