_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. */
#undef sendto
#include "w32.h"
-#include "ndir.h"
+#include <dirent.h>
#include "w32common.h"
#include "w32heap.h"
#include "w32select.h"
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) (
/* Get the current working directory. */
char *
-getwd (char *dir)
+getcwd (char *dir, int dirsize)
{
+ if (!dirsize)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+ if (dirsize <= strlen (startup_dir))
+ {
+ errno = ERANGE;
+ return NULL;
+ }
#if 0
if (GetCurrentDirectory (MAXPATHLEN, dir) > 0)
return dir;
return 1;
}
+/* Emulate the Posix unsetenv. */
+int
+unsetenv (const char *name)
+{
+ char *var;
+ size_t name_len;
+ int retval;
+
+ if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ name_len = strlen (name);
+ /* MS docs says an environment variable cannot be longer than 32K. */
+ if (name_len > 32767)
+ {
+ errno = ENOMEM;
+ return 0;
+ }
+ /* It is safe to use 'alloca' with 32K size, since the stack is at
+ least 2MB, and we set it to 8MB in the link command line. */
+ var = alloca (name_len + 2);
+ var[name_len++] = '=';
+ var[name_len] = '\0';
+ return _putenv (var);
+}
+
+/* MS _putenv doesn't support removing a variable when the argument
+ does not include the '=' character, so we fix that here. */
+int
+sys_putenv (char *str)
+{
+ const char *const name_end = strchr (str, '=');
+
+ if (name_end == NULL)
+ {
+ /* Remove the variable from the environment. */
+ return unsetenv (str);
+ }
+
+ return _putenv (str);
+}
+
#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
LPBYTE
memcpy (*envp, "COMSPEC=", 8);
}
- /* Remember the initial working directory for getwd. */
+ /* Remember the initial working directory for getcwd. */
/* FIXME: Do we need to resolve possible symlinks in startup_dir?
Does it matter anywhere in Emacs? */
if (!GetCurrentDirectory (MAXPATHLEN, startup_dir))
and readdir. We can't use the procedures supplied in sysdep.c,
so we provide them here. */
-struct direct dir_static; /* simulated directory contents */
+struct dirent dir_static; /* simulated directory contents */
static HANDLE dir_find_handle = INVALID_HANDLE_VALUE;
static int dir_is_fat;
static char dir_pathname[MAXPATHLEN+1];
xfree ((char *) dirp);
}
-struct direct *
+struct dirent *
readdir (DIR *dirp)
{
int downcase = !NILP (Vw32_downcase_file_names);
downcase = 1; /* 8+3 aliases are returned in all caps */
}
dir_static.d_namlen = strlen (dir_static.d_name);
- dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
+ dir_static.d_reclen = sizeof (struct dirent) - MAXNAMLEN + 3 +
dir_static.d_namlen - dir_static.d_namlen % 4;
/* If the file name in cFileName[] includes `?' characters, it means
return !(devtype == DRIVE_FIXED || devtype == DRIVE_RAMDISK);
}
+/* If this is non-zero, the caller wants accurate information about
+ file's owner and group, which could be expensive to get. */
+int w32_stat_get_owner_group;
+
/* MSVC stat function can't cope with UNC names and has other bugs, so
replace it with our own. This also allows us to calculate consistent
inode values and owner/group without hacks in the main Emacs code. */
/* We produce the fallback owner and group data, based on the
current user that runs Emacs, in the following cases:
+ . caller didn't request owner and group info
. this is Windows 9X
. getting security by handle failed, and we need to produce
information for the target of a symlink (this is better
If getting security by handle fails, and we don't need to
resolve symlinks, we try getting security by name. */
- if (is_windows_9x () != TRUE)
- psd = get_file_security_desc_by_handle (fh);
- if (psd)
- {
- get_file_owner_and_group (psd, name, buf);
- LocalFree (psd);
- }
- else if (is_windows_9x () == TRUE)
+ if (!w32_stat_get_owner_group || is_windows_9x () == TRUE)
get_file_owner_and_group (NULL, name, buf);
- else if (!(is_a_symlink && follow_symlinks))
+ else
{
- psd = get_file_security_desc_by_name (name);
- get_file_owner_and_group (psd, name, buf);
- xfree (psd);
+ psd = get_file_security_desc_by_handle (fh);
+ if (psd)
+ {
+ get_file_owner_and_group (psd, name, buf);
+ LocalFree (psd);
+ }
+ else if (!(is_a_symlink && follow_symlinks))
+ {
+ psd = get_file_security_desc_by_name (name);
+ get_file_owner_and_group (psd, name, buf);
+ xfree (psd);
+ }
+ else
+ get_file_owner_and_group (NULL, name, buf);
}
- else
- get_file_owner_and_group (NULL, name, buf);
CloseHandle (fh);
}
else
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)),
check_errno ();
if (fd_info[s].flags & FILE_SOCKET)
{
- if (cmd == F_SETFL && options == O_NDELAY)
+ if (cmd == F_SETFL && options == O_NONBLOCK)
{
unsigned long nblock = 1;
int rc = pfn_ioctlsocket (SOCK_HANDLE (s), FIONBIO, &nblock);
}
/* Function to do blocking read of one byte, needed to implement
- select. It is only allowed on sockets and pipes. */
+ select. It is only allowed on communication ports, sockets, or
+ pipes. */
int
_sys_read_ahead (int fd)
{
/* "None" is the default group name on standalone workstations. */
strcpy (dflt_group_name, "None");
+
+ /* Reset, in case it has some value inherited from dump time. */
+ w32_stat_get_owner_group = 0;
}
/* For make-serial-process */