xwin: winprefs: use safer setenv() instead of putenv()

putenv() is deprecated due several drawbacks: the passed buffer becomes
part of the environment (not copied), thus the caller needs to allocate
a permanent buffer first - and has no way to know whether it might
become used later. And it has to fill in the new entry in the correct
form (<name>+"="+<value>)

setenv() instead is damn simple: pass env variable name and value
separately, and no need to care what's going on under the hood.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult
2026-02-11 12:13:56 +01:00
committed by Enrico Weigelt
parent 3ea028279a
commit 95b6716b6c
3 changed files with 36 additions and 8 deletions

View File

@@ -18,6 +18,13 @@ xwin_c_args = []
xwin_c_args += '-DHAVE_XWIN_CONFIG_H'
xwin_c_args += '-Wno-bad-function-cast'
# mingw lacking setenv(), so we need to do it on our own
if cc.has_function('setenv',
prefix : '#include <stdlib.h>',
args : ['-D_XOPEN_SOURCE=600'])
xwin_c_args += '-DHAVE_SETENV'
endif
srcs_windows = [
'winclipboardinit.c',
'winclipboardwrappers.c',

27
hw/xwin/os-compat.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef __XWIN_OS_COMPAT_H
#define __XWIN_OS_COMPAT_H
#include <stdlib.h>
#include <errno.h>
/* special workaround for mingw lacking setenv() */
#ifndef HAVE_SETENV
static inline int setenv(const char *name, const char *value, int overwrite)
{
size_t name_len = strlen(name);
size_t value_len = strlen(value);
size_t bufsz = name_len + value_len + 1;
char *buf = malloc(bufsz);
if (!buf) {
errno = ENOMEM;
return -1;
}
memcpy(buf, name, name_len);
memcpy(buf+name_len, value, value_len);
buf[name_len+value_len] = 0;
putenv(buf);
return 0;
}
#endif
#endif /* __XWIN_OS_COMPAT_H */

View File

@@ -44,6 +44,7 @@
#include <X11/Xwindows.h>
#include <shellapi.h>
#include "os-compat.h"
#include "winprefs.h"
#include "windisplay.h"
#include "winmultiwindowclass.h"
@@ -710,7 +711,6 @@ LoadPreferences(void)
char *home;
char fname[PATH_MAX + NAME_MAX + 2];
char szDisplay[512];
char *szEnvDisplay;
int i, j;
char param[PARAM_MAX + 1];
char *srcParam, *dstParam;
@@ -748,14 +748,8 @@ LoadPreferences(void)
("LoadPreferences: See \"man XWinrc\" to customize the XWin menu.\n");
}
/* Setup a DISPLAY environment variable, need to allocate on heap */
/* because putenv doesn't copy the argument... */
winGetDisplayName(szDisplay, 0);
szEnvDisplay = calloc(1, strlen(szDisplay) + strlen("DISPLAY=") + 1);
if (szEnvDisplay) {
snprintf(szEnvDisplay, 512, "DISPLAY=%s", szDisplay);
putenv(szEnvDisplay);
}
setenv("DISPLAY", szDisplay, 1);
/* Replace any "%display%" in menu commands with display string */
for (i = 0; i < pref.menuItems; i++) {