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> | 2012-03-10 13:26:17 +0000 |
commit | 2457daa7959ce02c9600d545e119ec3ed7330589 (patch) | |
tree | 2a813d7e0abf8d4ae5f14d59fed3753c62e6c9e0 | |
parent | c97a74e0cef8a64ba8d3dda6147311673282d1fa (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
Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
-rw-r--r-- | os/utils.c | 22 | ||||
-rw-r--r-- | xkb/ddxList.c | 24 | ||||
-rw-r--r-- | xkb/ddxLoad.c | 25 |
3 files changed, 57 insertions, 14 deletions
diff --git a/os/utils.c b/os/utils.c index 945094c03..74b1199ca 100644 --- a/os/utils.c +++ b/os/utils.c @@ -1262,6 +1262,25 @@ 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) { @@ -1303,6 +1322,7 @@ System(const char *command) return p == -1 ? -1 : status; } +#endif static struct pid { struct pid *next; @@ -1312,6 +1332,7 @@ static struct pid { OsSigHandlerPtr old_alarm = NULL; /* XXX horrible awful hack */ +#if !defined(__CYGWIN__) pointer Popen(const char *command, const char *type) { @@ -1396,6 +1417,7 @@ Popen(const char *command, const char *type) return iop; } +#endif /* fopen that drops privileges */ pointer diff --git a/xkb/ddxList.c b/xkb/ddxList.c index db34c8df5..0164e2159 100644 --- a/xkb/ddxList.c +++ b/xkb/ddxList.c @@ -58,6 +58,16 @@ extern int Win32System(const char *cmdline); #define W32_tmplen 0 #endif +#ifdef __CYGWIN__ +extern const char* Win32TempDir(void); +#endif + +#if defined(WIN32) +#define PATHSEPARATOR "\\" +#else +#define PATHSEPARATOR "/" +#endif + /***====================================================================***/ static const char *componentDirs[_XkbListNumComponents] = { @@ -127,7 +137,7 @@ char *file,*map,*tmp,*buf=NULL; FILE *in; Status status; Bool haveDir; -#ifdef WIN32 +#if defined(WIN32) || defined(__CYGWIN__) char tmpname[PATH_MAX]; #else int rval; @@ -149,9 +159,9 @@ int rval; in= NULL; haveDir= TRUE; -#ifdef WIN32 +#if defined(WIN32) || defined(__CYGWIN__) strcpy(tmpname, Win32TempDir()); - strcat(tmpname, "\\xkb_XXXXXX"); + strcat(tmpname, PATHSEPARATOR "xkb_XXXXXX"); (void) mktemp(tmpname); #endif if (XkbBaseDirectory!=NULL) { @@ -200,7 +210,7 @@ int rval; status= Success; if (!haveDir) { -#ifndef WIN32 +#if !defined(WIN32) && !defined(__CYGWIN__) in= Popen(buf,"r"); #else if (xkbDebugFlags) @@ -214,7 +224,7 @@ int rval; if (!in) { free(buf); -#ifdef WIN32 +#if defined(WIN32) || defined(__CYGWIN__) unlink(tmpname); #endif return BadImplementation; @@ -224,7 +234,7 @@ int rval; buf = malloc(PATH_MAX * sizeof(char)); if (!buf) { fclose(in); -#ifdef WIN32 +#if defined(WIN32) || defined(__CYGWIN__) unlink(tmpname); #endif return BadAlloc; @@ -270,7 +280,7 @@ int rval; } status= _AddListComponent(list,what,flags,tmp,client); } -#ifndef WIN32 +#if !defined(WIN32) && !defined(__CYGWIN__) if (haveDir) fclose(in); else if ((rval=Pclose(in))!=0) { diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c index 196142318..0d88b7f34 100644 --- a/xkb/ddxLoad.c +++ b/xkb/ddxLoad.c @@ -144,6 +144,17 @@ Win32System(const char *cmdline) } #undef System #define System(x) Win32System(x) +#elif defined(__CYGWIN__) +const char* +Win32TempDir(void) +{ + if (getenv("TEMP") != NULL) + return getenv("TEMP"); + else if (getenv("TMP") != NULL) + return getenv("TEMP"); + else + return "/tmp"; +} #endif static void @@ -186,7 +197,7 @@ XkbDDXCompileKeymapByNames( XkbDescPtr xkb, const char *xkbbindir = emptystring; const char *xkbbindirsep = emptystring; -#ifdef WIN32 +#if defined(WIN32) || defined(__CYGWIN__) /* WIN32 has no popen. The input must be stored in a file which is used as input for xkbcomp. xkbcomp does not read from stdin. */ char tmpname[PATH_MAX]; @@ -199,9 +210,9 @@ XkbDDXCompileKeymapByNames( XkbDescPtr xkb, OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir)); -#ifdef WIN32 +#if defined(WIN32) || defined(__CYGWIN__) strcpy(tmpname, Win32TempDir()); - strcat(tmpname, "\\xkb_XXXXXX"); + strcat(tmpname, PATHSEPARATOR "xkb_XXXXXX"); (void) mktemp(tmpname); #endif @@ -240,7 +251,7 @@ XkbDDXCompileKeymapByNames( XkbDescPtr xkb, return FALSE; } -#ifndef WIN32 +#if !defined(WIN32) && !defined(__CYGWIN__) out= Popen(buf,"w"); #else out= fopen(tmpname, "w"); @@ -254,7 +265,7 @@ XkbDDXCompileKeymapByNames( XkbDescPtr xkb, } #endif XkbWriteXKBKeymapForNames(out,names,xkb,want,need); -#ifndef WIN32 +#if !defined(WIN32) && !defined(__CYGWIN__) if (Pclose(out)==0) #else if (fclose(out)==0 && System(buf) >= 0) @@ -266,14 +277,14 @@ XkbDDXCompileKeymapByNames( XkbDescPtr xkb, strlcpy(nameRtrn,keymap,nameRtrnLen); } free(buf); -#ifdef WIN32 +#if defined(WIN32) || defined(__CYGWIN__) unlink(tmpname); #endif return TRUE; } else LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap); -#ifdef WIN32 +#if defined(WIN32) || defined(__CYGWIN__) /* remove the temporary file */ unlink(tmpname); #endif |