#include <sys/file.h>
#include <sys/time.h>
#include <sys/utime.h>
-#include <mbstring.h> /* for _mbspbrk */
#include <math.h>
#include <time.h>
/* must include CRT headers *before* config.h */
#include <config.h>
+#include <mbstring.h> /* for _mbspbrk */
#undef access
#undef chdir
_WIN32_WINNT than what we use. w32api supplied with MinGW 3.15
defines it in psapi.h */
typedef struct _PROCESS_MEMORY_COUNTERS_EX {
- DWORD cb;
- DWORD PageFaultCount;
- DWORD PeakWorkingSetSize;
- DWORD WorkingSetSize;
- DWORD QuotaPeakPagedPoolUsage;
- DWORD QuotaPagedPoolUsage;
- DWORD QuotaPeakNonPagedPoolUsage;
- DWORD QuotaNonPagedPoolUsage;
- DWORD PagefileUsage;
- DWORD PeakPagefileUsage;
- DWORD PrivateUsage;
+ DWORD cb;
+ DWORD PageFaultCount;
+ SIZE_T PeakWorkingSetSize;
+ SIZE_T WorkingSetSize;
+ SIZE_T QuotaPeakPagedPoolUsage;
+ SIZE_T QuotaPagedPoolUsage;
+ SIZE_T QuotaPeakNonPagedPoolUsage;
+ SIZE_T QuotaNonPagedPoolUsage;
+ SIZE_T PagefileUsage;
+ SIZE_T PeakPagefileUsage;
+ SIZE_T PrivateUsage;
} PROCESS_MEMORY_COUNTERS_EX,*PPROCESS_MEMORY_COUNTERS_EX;
#endif
#include <aclapi.h>
#ifdef _MSC_VER
-/* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER, except
- on ntifs.h, which cannot be included because it triggers conflicts
- with other Windows API headers. So we define it here by hand. */
+/* 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. */
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
} DUMMYUNIONNAME;
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+#ifndef FILE_DEVICE_FILE_SYSTEM
+#define FILE_DEVICE_FILE_SYSTEM 9
+#endif
+#ifndef METHOD_BUFFERED
+#define METHOD_BUFFERED 0
+#endif
+#ifndef FILE_ANY_ACCESS
+#define FILE_ANY_ACCESS 0x00000000
+#endif
+#ifndef CTL_CODE
+#define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m))
+#endif
+#define FSCTL_GET_REPARSE_POINT \
+ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
#endif
/* TCP connection support. */
#include "w32.h"
#include "ndir.h"
+#include "w32common.h"
#include "w32heap.h"
+#include "w32select.h"
#include "systime.h"
#include "dispextern.h" /* for xstrcasecmp */
#include "coding.h" /* for Vlocale_coding_system */
static int restore_privilege (TOKEN_PRIVILEGES *);
static BOOL WINAPI revert_to_self (void);
+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 *);
+
+
\f
/* Initialization states.
DWORD cb);
typedef BOOL (WINAPI * GetProcessWorkingSetSize_Proc) (
HANDLE hProcess,
- DWORD * lpMinimumWorkingSetSize,
- DWORD * lpMaximumWorkingSetSize);
+ PSIZE_T lpMinimumWorkingSetSize,
+ PSIZE_T lpMaximumWorkingSetSize);
typedef BOOL (WINAPI * GlobalMemoryStatus_Proc) (
LPMEMORYSTATUS lpBuffer);
typedef BOOL (WINAPI * GlobalMemoryStatusEx_Proc) (
return retval;
}
\f
-/* Equivalent of strerror for W32 error codes. */
-char *
-w32_strerror (int error_no)
-{
- static char buf[500];
-
- if (error_no == 0)
- error_no = GetLastError ();
-
- buf[0] = '\0';
- if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL,
- error_no,
- 0, /* choose most suitable language */
- buf, sizeof (buf), NULL))
- sprintf (buf, "w32 error %u", error_no);
- return buf;
-}
/* Return 1 if P is a valid pointer to an object of size SIZE. Return
0 if P is NOT a valid pointer. Return -1 if we cannot validate P.
return 1;
}
-/* Routines that are no-ops on NT but are defined to get Emacs to compile. */
-int
-sigemptyset (sigset_t *set)
-{
- *set = 0;
- return 0;
-}
-
-int
-sigaddset (sigset_t *set, int signo)
-{
- return 0;
-}
-
-int
-sigfillset (sigset_t *set)
-{
- return 0;
-}
-
-int
-sigprocmask (int how, const sigset_t *set, sigset_t *oset)
-{
- return 0;
-}
-
-int
-pthread_sigmask (int how, const sigset_t *set, sigset_t *oset)
-{
- if (sigprocmask (how, set, oset) == -1)
- return EINVAL;
- return 0;
-}
-
-int
-setpgrp (int pid, int gid)
-{
- return 0;
-}
-
-int
-alarm (int seconds)
-{
- return 0;
-}
-
#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
LPBYTE
LPBYTE lpval;
DWORD dwType;
char locale_name[32];
- struct stat ignored;
char default_home[MAX_PATH];
int appdata = 0;
/* For backwards compatibility, check if a .emacs file exists in C:/
If not, then we can try to default to the appdata directory under the
user's profile, which is more likely to be writable. */
- if (stat ("C:/.emacs", &ignored) < 0)
+ if (!check_existing ("C:/.emacs"))
{
HRESULT profile_result;
/* Dynamically load ShGetFolderPath, as it won't exist on versions
/* FIXME: should use substring of get_emacs_configuration ().
But I don't think the Windows build supports alpha, mips etc
anymore, so have taken the easy option for now. */
- else if (p && xstrcasecmp (p, "\\i386") == 0)
+ else if (p && (xstrcasecmp (p, "\\i386") == 0
+ || xstrcasecmp (p, "\\AMD64") == 0))
{
*p = 0;
p = strrchr (modname, '\\');
case PROCESSOR_INTEL_386:
case PROCESSOR_INTEL_486:
case PROCESSOR_INTEL_PENTIUM:
+#ifdef _WIN64
+ arch = "amd64";
+#else
arch = "i386";
+#endif
+ break;
+#endif
+#ifdef PROCESSOR_AMD_X8664
+ case PROCESSOR_AMD_X8664:
+ arch = "amd64";
break;
#endif
#define GID 2
static int
-get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname,
- unsigned *id, char *nm, int what)
+get_name_and_id (PSECURITY_DESCRIPTOR psd, unsigned *id, char *nm, int what)
{
PSID sid = NULL;
char machine[MAX_COMPUTERNAME_LENGTH+1];
DWORD name_len = sizeof (name);
char domain[1024];
DWORD domain_len = sizeof (domain);
- char *mp = NULL;
int use_dflt = 0;
int result;
use_dflt = 1;
else if (!w32_cached_id (sid, id, nm))
{
- /* If FNAME is a UNC, we need to lookup account on the
- specified machine. */
- if (IS_DIRECTORY_SEP (fname[0]) && IS_DIRECTORY_SEP (fname[1])
- && fname[2] != '\0')
- {
- const char *s;
- char *p;
-
- for (s = fname + 2, p = machine;
- *s && !IS_DIRECTORY_SEP (*s); s++, p++)
- *p = *s;
- *p = '\0';
- mp = machine;
- }
-
- if (!lookup_account_sid (mp, sid, name, &name_len,
+ if (!lookup_account_sid (NULL, sid, name, &name_len,
domain, &domain_len, &ignore)
|| name_len > UNLEN+1)
use_dflt = 1;
}
static void
-get_file_owner_and_group (PSECURITY_DESCRIPTOR psd,
- const char *fname,
- struct stat *st)
+get_file_owner_and_group (PSECURITY_DESCRIPTOR psd, struct stat *st)
{
int dflt_usr = 0, dflt_grp = 0;
}
else
{
- if (get_name_and_id (psd, fname, &st->st_uid, st->st_uname, UID))
+ if (get_name_and_id (psd, &st->st_uid, st->st_uname, UID))
dflt_usr = 1;
- if (get_name_and_id (psd, fname, &st->st_gid, st->st_gname, GID))
+ if (get_name_and_id (psd, &st->st_gid, st->st_gname, GID))
dflt_grp = 1;
}
/* Consider files to belong to current user/group, if we cannot get
psd = get_file_security_desc_by_handle (fh);
if (psd)
{
- get_file_owner_and_group (psd, name, buf);
+ get_file_owner_and_group (psd, buf);
LocalFree (psd);
}
else if (is_windows_9x () == TRUE)
- get_file_owner_and_group (NULL, name, buf);
+ get_file_owner_and_group (NULL, buf);
else if (!(is_a_symlink && follow_symlinks))
{
psd = get_file_security_desc_by_name (name);
- get_file_owner_and_group (psd, name, buf);
+ get_file_owner_and_group (psd, buf);
xfree (psd);
}
else
- get_file_owner_and_group (NULL, name, buf);
+ get_file_owner_and_group (NULL, buf);
CloseHandle (fh);
}
else
else
buf->st_mode = S_IFREG;
- get_file_owner_and_group (NULL, name, buf);
+ get_file_owner_and_group (NULL, buf);
}
#if 0
}
/* Need write access to set times. */
- fh = CreateFile (name, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
- 0, OPEN_EXISTING, 0, NULL);
- if (fh)
+ fh = CreateFile (name, FILE_WRITE_ATTRIBUTES,
+ /* If NAME specifies a directory, FILE_SHARE_DELETE
+ allows other processes to delete files inside it,
+ while we have the directory open. */
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (fh != INVALID_HANDLE_VALUE)
{
convert_from_time_t (times->actime, &atime);
convert_from_time_t (times->modtime, &mtime);
static BOOL WINAPI
get_process_working_set_size (HANDLE h_proc,
- DWORD *minrss,
- DWORD *maxrss)
+ PSIZE_T minrss,
+ PSIZE_T maxrss)
{
static GetProcessWorkingSetSize_Proc
s_pfn_Get_Process_Working_Set_Size = NULL;
unsigned egid;
PROCESS_MEMORY_COUNTERS mem;
PROCESS_MEMORY_COUNTERS_EX mem_ex;
- DWORD minrss, maxrss;
+ SIZE_T minrss, maxrss;
MEMORYSTATUS memst;
MEMORY_STATUS_EX memstex;
double totphys = 0.0;
&& get_process_memory_info (h_proc, (PROCESS_MEMORY_COUNTERS *)&mem_ex,
sizeof (mem_ex)))
{
- DWORD rss = mem_ex.WorkingSetSize / 1024;
+ SIZE_T rss = mem_ex.WorkingSetSize / 1024;
attrs = Fcons (Fcons (Qmajflt,
make_fixnum_or_float (mem_ex.PageFaultCount)),
else if (h_proc
&& get_process_memory_info (h_proc, &mem, sizeof (mem)))
{
- DWORD rss = mem_ex.WorkingSetSize / 1024;
+ SIZE_T rss = mem_ex.WorkingSetSize / 1024;
attrs = Fcons (Fcons (Qmajflt,
make_fixnum_or_float (mem.PageFaultCount)),
\f
-/* Delayed loading of libraries. */
-
-Lisp_Object Vlibrary_cache;
-
-/* The argument LIBRARIES is an alist that associates a symbol
- LIBRARY_ID, identifying an external DLL library known to Emacs, to
- a list of filenames under which the library is usually found. In
- most cases, the argument passed as LIBRARIES is the variable
- `dynamic-library-alist', which is initialized to a list of common
- library names. If the function loads the library successfully, it
- returns the handle of the DLL, and records the filename in the
- property :loaded-from of LIBRARY_ID; it returns NULL if the library
- could not be found, or when it was already loaded (because the
- handle is not recorded anywhere, and so is lost after use). It
- would be trivial to save the handle too in :loaded-from, but
- currently there's no use case for it. */
+/* Try loading LIBRARY_ID from the file(s) specified in
+ Vdynamic_library_alist. If the library is loaded successfully,
+ return the handle of the DLL, and record the filename in the
+ property :loaded-from of LIBRARY_ID. If the library could not be
+ found, or when it was already loaded (because the handle is not
+ recorded anywhere, and so is lost after use), return NULL.
+
+ We could also save the handle in :loaded-from, but currently
+ there's no use case for it. */
HMODULE
-w32_delayed_load (Lisp_Object libraries, Lisp_Object library_id)
+w32_delayed_load (Lisp_Object library_id)
{
HMODULE library_dll = NULL;
CHECK_SYMBOL (library_id);
- if (CONSP (libraries) && NILP (Fassq (library_id, Vlibrary_cache)))
+ if (CONSP (Vdynamic_library_alist)
+ && NILP (Fassq (library_id, Vlibrary_cache)))
{
Lisp_Object found = Qnil;
- Lisp_Object dlls = Fassq (library_id, libraries);
+ Lisp_Object dlls = Fassq (library_id, Vdynamic_library_alist);
if (CONSP (dlls))
for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls))
}
void
-term_ntproc (void)
+term_ntproc (int ignored)
{
+ (void)ignored;
+
+ term_timers ();
+
/* shutdown the socket interface if necessary */
term_winsock ();
}
void
-init_ntproc (void)
+init_ntproc (int dumping)
{
+ sigset_t initial_mask = 0;
+
/* Initialize the socket interface now if available and requested by
the user by defining PRELOAD_WINSOCK; otherwise loading will be
delayed until open-network-stream is called (w32-has-winsock can
fclose (stderr);
if (stdin_save != INVALID_HANDLE_VALUE)
- _open_osfhandle ((long) stdin_save, O_TEXT);
+ _open_osfhandle ((intptr_t) stdin_save, O_TEXT);
else
_open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY);
_fdopen (0, "r");
if (stdout_save != INVALID_HANDLE_VALUE)
- _open_osfhandle ((long) stdout_save, O_TEXT);
+ _open_osfhandle ((intptr_t) stdout_save, O_TEXT);
else
_open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
_fdopen (1, "w");
if (stderr_save != INVALID_HANDLE_VALUE)
- _open_osfhandle ((long) stderr_save, O_TEXT);
+ _open_osfhandle ((intptr_t) stderr_save, O_TEXT);
else
_open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
_fdopen (2, "w");
/* unfortunately, atexit depends on implementation of malloc */
/* atexit (term_ntproc); */
- signal (SIGABRT, term_ntproc);
+ if (!dumping)
+ {
+ /* Make sure we start with all signals unblocked. */
+ sigprocmask (SIG_SETMASK, &initial_mask, NULL);
+ signal (SIGABRT, term_ntproc);
+ }
+ init_timers ();
/* determine which drives are fixed, for GetCachedVolumeInformation */
{
DEFSYM (QCloaded_from, ":loaded-from");
- Vlibrary_cache = Qnil;
- staticpro (&Vlibrary_cache);
-
g_b_init_is_windows_9x = 0;
g_b_init_open_process_token = 0;
g_b_init_get_token_information = 0;
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (hnd == INVALID_HANDLE_VALUE)
error ("Could not open %s", port);
- fd = (int) _open_osfhandle ((int) hnd, 0);
+ fd = (int) _open_osfhandle ((intptr_t) hnd, 0);
if (fd == -1)
error ("Could not open %s", port);
{
int n, sc, err;
SELECT_TYPE fdset;
- struct timeval timeout;
+ EMACS_TIME timeout;
struct Lisp_Process *process = (struct Lisp_Process *)p;
int fd = process->infd;
if (err == EWOULDBLOCK)
{
/* Set a small timeout. */
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
+ timeout = make_emacs_time (1, 0);
FD_ZERO (&fdset);
FD_SET ((int)fd, &fdset);