X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/ae0d461554a9351a0d897ce0e60b47fc9670431e..6c6f1994bf684f510d600bd18023fa01b4b06500:/src/w32.c diff --git a/src/w32.c b/src/w32.c index 647faf94ef..1a3d81bbff 100644 --- a/src/w32.c +++ b/src/w32.c @@ -29,10 +29,10 @@ along with GNU Emacs. If not, see . */ #include #include #include +#include /* must be before nt/inc/sys/time.h, for MinGW64 */ #include #include #include -#include /* must include CRT headers *before* config.h */ @@ -65,11 +65,13 @@ along with GNU Emacs. If not, see . */ #undef localtime #include "lisp.h" +#include "epaths.h" /* for SHELL */ #include #include -#ifdef __GNUC__ +/* MinGW64 (_W64) defines these in its _mingw.h. */ +#if defined(__GNUC__) && !defined(_W64) #define _ANONYMOUS_UNION #define _ANONYMOUS_STRUCT #endif @@ -96,6 +98,7 @@ typedef struct _MEMORY_STATUS_EX { #ifndef _MSC_VER #include #endif +#if _WIN32_WINNT < 0x0500 #if !defined (__MINGW32__) || __W32API_MAJOR_VERSION < 3 || (__W32API_MAJOR_VERSION == 3 && __W32API_MINOR_VERSION < 15) /* This either is not in psapi.h or guarded by higher value of _WIN32_WINNT than what we use. w32api supplied with MinGW 3.15 @@ -114,6 +117,7 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX { SIZE_T PrivateUsage; } PROCESS_MEMORY_COUNTERS_EX,*PPROCESS_MEMORY_COUNTERS_EX; #endif +#endif #include #include @@ -127,11 +131,11 @@ typedef struct _PROCESS_MEMORY_COUNTERS_EX { #define SDDL_REVISION_1 1 #endif /* SDDL_REVISION_1 */ -#ifdef _MSC_VER -/* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER and the - associated macros, except on ntifs.h, which cannot be included - because it triggers conflicts with other Windows API headers. So - we define it here by hand. */ +#if defined(_MSC_VER) || defined(_W64) +/* MSVC and MinGW64 don't provide the definition of + REPARSE_DATA_BUFFER and the associated macros, except on ntifs.h, + which cannot be included because it triggers conflicts with other + Windows API headers. So we define it here by hand. */ typedef struct _REPARSE_DATA_BUFFER { ULONG ReparseTag; @@ -171,9 +175,12 @@ typedef struct _REPARSE_DATA_BUFFER { #ifndef CTL_CODE #define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m)) #endif +/* MinGW64 defines FSCTL_GET_REPARSE_POINT on winioctl.h. */ +#ifndef FSCTL_GET_REPARSE_POINT #define FSCTL_GET_REPARSE_POINT \ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) #endif +#endif /* TCP connection support. */ #include @@ -227,6 +234,8 @@ extern int sys_access (const char *, int); extern void *e_malloc (size_t); extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, EMACS_TIME *, void *); +extern int sys_dup (int); + @@ -2012,7 +2021,7 @@ init_environment (char ** argv) {"PRELOAD_WINSOCK", NULL}, {"emacs_dir", "C:/emacs"}, {"EMACSLOADPATH", NULL}, - {"SHELL", "%emacs_dir%/bin/cmdproxy.exe"}, + {"SHELL", "cmdproxy.exe"}, /* perhaps it is somewhere on PATH */ {"EMACSDATA", NULL}, {"EMACSPATH", NULL}, {"INFOPATH", NULL}, @@ -2088,9 +2097,12 @@ init_environment (char ** argv) emacs_abort (); *p = 0; - if ((p = _mbsrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0) + if ((p = _mbsrchr (modname, '\\')) + /* From bin means installed Emacs, from src means uninstalled. */ + && (xstrcasecmp (p, "\\bin") == 0 || xstrcasecmp (p, "\\src") == 0)) { char buf[SET_ENV_BUF_SIZE]; + int within_build_tree = xstrcasecmp (p, "\\src") == 0; *p = 0; for (p = modname; *p; p = CharNext (p)) @@ -2098,6 +2110,15 @@ init_environment (char ** argv) _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); _putenv (strdup (buf)); + /* If we are running from the Posix-like build tree, define + SHELL to point to our own cmdproxy. The loop below will + then disregard PATH_EXEC and the default value. */ + if (within_build_tree) + { + _snprintf (buf, sizeof (buf) - 1, + "SHELL=%s/nt/cmdproxy.exe", modname); + _putenv (strdup (buf)); + } } /* Handle running emacs from the build directory: src/oo-spd/i386/ */ @@ -2133,16 +2154,60 @@ init_environment (char ** argv) if (!getenv (env_vars[i].name)) { int dont_free = 0; + char bufc[SET_ENV_BUF_SIZE]; if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL /* Also ignore empty environment variables. */ || *lpval == 0) { xfree (lpval); - lpval = env_vars[i].def_value; - dwType = REG_EXPAND_SZ; dont_free = 1; - if (!strcmp (env_vars[i].name, "HOME") && !appdata) + if (strcmp (env_vars[i].name, "SHELL") == 0) + { + /* Look for cmdproxy.exe in every directory in + PATH_EXEC. FIXME: This does not find cmdproxy + in nt/ when we run uninstalled. */ + char fname[MAX_PATH]; + const char *pstart = PATH_EXEC, *pend; + + do { + pend = _mbschr (pstart, ';'); + if (!pend) + pend = pstart + strlen (pstart); + /* Be defensive against series of ;;; characters. */ + if (pend > pstart) + { + strncpy (fname, pstart, pend - pstart); + fname[pend - pstart] = '/'; + strcpy (&fname[pend - pstart + 1], "cmdproxy.exe"); + ExpandEnvironmentStrings ((LPSTR) fname, bufc, + sizeof (bufc)); + if (check_existing (bufc)) + { + lpval = bufc; + dwType = REG_SZ; + break; + } + } + if (*pend) + pstart = pend + 1; + else + pstart = pend; + if (!*pstart) + { + /* If not found in any directory, use the + default as the last resort. */ + lpval = env_vars[i].def_value; + dwType = REG_EXPAND_SZ; + } + } while (*pstart); + } + else + { + lpval = env_vars[i].def_value; + dwType = REG_EXPAND_SZ; + } + if (strcmp (env_vars[i].name, "HOME") == 0 && !appdata) Vdelayed_warnings_list = Fcons (listn (CONSTYPE_HEAP, 2, intern ("initialization"), @@ -2388,8 +2453,8 @@ get_emacs_configuration_options (void) #include /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */ -void -gettimeofday (struct timeval *tv, struct timezone *tz) +int +gettimeofday (struct timeval *__restrict tv, struct timezone *__restrict tz) { struct _timeb tb; _ftime (&tb); @@ -2407,6 +2472,7 @@ gettimeofday (struct timeval *tv, struct timezone *tz) tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */ tz->tz_dsttime = tb.dstflag; /* type of dst correction */ } + return 0; } /* Emulate fdutimens. */ @@ -3721,12 +3787,6 @@ get_rid (PSID sid) /* Caching SID and account values for faster lokup. */ -#ifdef __GNUC__ -# define FLEXIBLE_ARRAY_MEMBER -#else -# define FLEXIBLE_ARRAY_MEMBER 1 -#endif - struct w32_id { unsigned rid; struct w32_id *next; @@ -6661,10 +6721,16 @@ sys_sendto (int s, const char * buf, int len, int flags, } /* Windows does not have an fcntl function. Provide an implementation - solely for making sockets non-blocking. */ + good enough for Emacs. */ int fcntl (int s, int cmd, int options) { + /* In the w32 Emacs port, fcntl (fd, F_DUPFD_CLOEXEC, fd1) is always + invoked in a context where fd1 is closed and all descriptors less + than fd1 are open, so sys_dup is an adequate implementation. */ + if (cmd == F_DUPFD_CLOEXEC) + return sys_dup (s); + if (winsock_lib == NULL) { errno = ENETDOWN; @@ -6806,13 +6872,14 @@ sys_dup2 (int src, int dst) return rc; } -/* Unix pipe() has only one arg */ int -sys_pipe (int * phandles) +pipe2 (int * phandles, int pipe2_flags) { int rc; unsigned flags; + eassert (pipe2_flags == O_CLOEXEC); + /* make pipe handles non-inheritable; when we spawn a child, we replace the relevant handle with an inheritable one. Also put pipes into binary mode; we will do text mode translation ourselves