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