summaryrefslogtreecommitdiff
path: root/os/utils.c
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2012-03-05 22:16:33 +0000
committerJon TURNEY <jon.turney@dronecode.org.uk>2015-02-08 17:38:37 +0000
commit6411fcd679436cd67f065389b4f1a0de0e60a540 (patch)
tree96549bda9cbf71fc3da2c0d08dc9716a2e684b62 /os/utils.c
parent81d4386949bfcab5e98a9393df613aeb58346ade (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.c35
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
/*