diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2012-03-05 22:16:33 +0000 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2015-02-08 17:38:37 +0000 |
commit | 6411fcd679436cd67f065389b4f1a0de0e60a540 (patch) | |
tree | 96549bda9cbf71fc3da2c0d08dc9716a2e684b62 /os/utils.c | |
parent | 81d4386949bfcab5e98a9393df613aeb58346ade (diff) |
Use spawnl() rather than pipe() & fork() to invoke xkbcomp
Implement System() specially on Cygwin not to use fork() and exec(), but
spawnl()
Use System() and a temp file rather than pipe() & fork() to invoke xkbcomp on
cygwin, just as done on mingw
Somewhat the counsel of despair, but sometimes Windows is being such a little
bitch that the cygwin DLL just can't emulate fork() successfully, so just using
spawnl() here is more robust and means I don't have to deal with end-users
reporting this as a problem with the xserver
Popen is not used, but must be built as it is referenced by sdksyms
v2: Update to include fix to Win32TempDir() when TMP is set but TEMP isn't
XXX: Really this should check TMPDIR first, as that's the canonical UNIX way to
set the temporary directory?
v3: Fix implicit-function-declaration of Win32TempDir() in XkbDDXCompileKeymapByNames()
Add a prototype for Win32TempDir()
v4: Improve handling of error conditions with the xkbcomp temporary file
Fix a compilation conditional so that a failure to write to the xkbcomp
temporary file is correctly reported, and reports the problematic filename.
Improve Win32TempDir() so that the directory given by the TEMP and TMP
environment variables is checked for accessibility, so that specifying a
non-existent directory doesn't cause a failure.
Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Diffstat (limited to 'os/utils.c')
-rw-r--r-- | os/utils.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/os/utils.c b/os/utils.c index 185a9d95a..c218e4960 100644 --- a/os/utils.c +++ b/os/utils.c @@ -1355,6 +1355,26 @@ OsAbort(void) * as well. As it is now, xkbcomp messages don't end up in the log file. */ +#ifdef __CYGWIN__ +#include <process.h> +int +System(const char *command) +{ + int status; + + if (!command) + return 1; + + DebugF("System: `%s'\n", command); + + /* + Use spawnl() rather than execl() to implement System() on cygwin to + avoid fork emulation overhead and brittleness + */ + status = spawnl(_P_WAIT, "/bin/sh", "sh", "-c", command, (char *) NULL); + return status; +} +#else int System(const char *command) { @@ -1397,6 +1417,7 @@ System(const char *command) return p == -1 ? -1 : status; } +#endif static struct pid { struct pid *next; @@ -1708,6 +1729,20 @@ System(const char *cmdline) return dwExitCode; } +#elif defined(__CYGWIN__) +const char* +Win32TempDir(void) +{ + const char *temp = getenv("TEMP"); + if ((temp != NULL) && (access(temp, W_OK | X_OK) == 0)) + return temp; + + temp = getenv("TMP"); + if ((temp != NULL) && (access(temp, W_OK | X_OK) == 0)) + return temp; + + return "/tmp"; +} #endif /* |