/* Utility and Unix shadow routines for GNU Emacs on the Microsoft W32 API.
Copyright (C) 1994, 1995, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2007, 2008 Free Software Foundation, Inc.
+ 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <stddef.h> /* for offsetof */
#include <stdlib.h>
#include <stdio.h>
+#include <float.h> /* for DBL_EPSILON */
#include <io.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/utime.h>
#include <mbstring.h> /* for _mbspbrk */
#include <math.h>
+#include <setjmp.h>
/* must include CRT headers *before* config.h */
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
#undef access
#undef chdir
/* Some versions of compiler define MEMORYSTATUSEX, some don't, so we
use a different name to avoid compilation problems. */
typedef struct _MEMORY_STATUS_EX {
- DWORD dwLength;
- DWORD dwMemoryLoad;
- DWORDLONG ullTotalPhys;
- DWORDLONG ullAvailPhys;
- DWORDLONG ullTotalPageFile;
- DWORDLONG ullAvailPageFile;
- DWORDLONG ullTotalVirtual;
- DWORDLONG ullAvailVirtual;
- DWORDLONG ullAvailExtendedVirtual;
+ DWORD dwLength;
+ DWORD dwMemoryLoad;
+ DWORDLONG ullTotalPhys;
+ DWORDLONG ullAvailPhys;
+ DWORDLONG ullTotalPageFile;
+ DWORDLONG ullAvailPageFile;
+ DWORDLONG ullTotalVirtual;
+ DWORDLONG ullAvailVirtual;
+ DWORDLONG ullAvailExtendedVirtual;
} MEMORY_STATUS_EX,*LPMEMORY_STATUS_EX;
#include <lmcons.h>
#include <tlhelp32.h>
#include <psapi.h>
+#include <w32api.h>
+#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. */
+ _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;
+ DWORD PeakWorkingSetSize;
+ DWORD WorkingSetSize;
+ DWORD QuotaPeakPagedPoolUsage;
+ DWORD QuotaPagedPoolUsage;
+ DWORD QuotaPeakNonPagedPoolUsage;
+ DWORD QuotaNonPagedPoolUsage;
+ DWORD PagefileUsage;
+ DWORD PeakPagefileUsage;
+ DWORD PrivateUsage;
} PROCESS_MEMORY_COUNTERS_EX,*PPROCESS_MEMORY_COUNTERS_EX;
+#endif
-#ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */
+/* TCP connection support. */
#include <sys/socket.h>
#undef socket
#undef bind
#undef accept
#undef recvfrom
#undef sendto
-#endif
#include "w32.h"
#include "ndir.h"
/* For serial_configure and serial_open. */
#include "process.h"
-/* From process.c */
-extern Lisp_Object QCport, QCspeed, QCprocess;
-extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
-extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
typedef HRESULT (WINAPI * ShGetFolderPath_fn)
(IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *);
-void globals_of_w32 ();
+void globals_of_w32 (void);
static DWORD get_rid (PSID);
extern Lisp_Object Vw32_downcase_file_names;
static BOOL g_b_init_open_process_token;
static BOOL g_b_init_get_token_information;
static BOOL g_b_init_lookup_account_sid;
-static BOOL g_b_init_get_sid_identifier_authority;
static BOOL g_b_init_get_sid_sub_authority;
static BOOL g_b_init_get_sid_sub_authority_count;
static BOOL g_b_init_get_file_security;
static BOOL g_b_init_get_length_sid;
static BOOL g_b_init_equal_sid;
static BOOL g_b_init_copy_sid;
+static BOOL g_b_init_get_native_system_info;
+static BOOL g_b_init_get_system_times;
/*
BEGIN: Wrapper functions around OpenProcessToken
LPTSTR DomainName,
LPDWORD cbDomainName,
PSID_NAME_USE peUse);
-typedef PSID_IDENTIFIER_AUTHORITY (WINAPI * GetSidIdentifierAuthority_Proc) (
- PSID pSid);
typedef PDWORD (WINAPI * GetSidSubAuthority_Proc) (
PSID pSid,
DWORD n);
PSID pSid2);
typedef DWORD (WINAPI * GetLengthSid_Proc) (
PSID pSid);
-
-
+typedef void (WINAPI * GetNativeSystemInfo_Proc) (
+ LPSYSTEM_INFO lpSystemInfo);
+typedef BOOL (WINAPI * GetSystemTimes_Proc) (
+ LPFILETIME lpIdleTime,
+ LPFILETIME lpKernelTime,
+ LPFILETIME lpUserTime);
/* ** A utility function ** */
static BOOL
-is_windows_9x ()
+is_windows_9x (void)
{
- static BOOL s_b_ret=0;
+ static BOOL s_b_ret = 0;
OSVERSIONINFO os_ver;
if (g_b_init_is_windows_9x == 0)
{
g_b_init_is_windows_9x = 1;
- ZeroMemory(&os_ver, sizeof(OSVERSIONINFO));
- os_ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ ZeroMemory (&os_ver, sizeof (OSVERSIONINFO));
+ os_ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (GetVersionEx (&os_ver))
{
s_b_ret = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
Returns a list of three integers if the times are provided by the OS
(NT derivatives), otherwise it returns the result of current-time. */
Lisp_Object
-w32_get_internal_run_time ()
+w32_get_internal_run_time (void)
{
if (get_process_times_fn)
{
FILETIME create, exit, kernel, user;
- HANDLE proc = GetCurrentProcess();
+ HANDLE proc = GetCurrentProcess ();
if ((*get_process_times_fn) (proc, &create, &exit, &kernel, &user))
{
LARGE_INTEGER user_int, kernel_int, total;
/* ** The wrapper functions ** */
-BOOL WINAPI open_process_token (
- HANDLE ProcessHandle,
- DWORD DesiredAccess,
- PHANDLE TokenHandle)
+static BOOL WINAPI
+open_process_token (HANDLE ProcessHandle,
+ DWORD DesiredAccess,
+ PHANDLE TokenHandle)
{
static OpenProcessToken_Proc s_pfn_Open_Process_Token = NULL;
HMODULE hm_advapi32 = NULL;
);
}
-BOOL WINAPI get_token_information (
- HANDLE TokenHandle,
- TOKEN_INFORMATION_CLASS TokenInformationClass,
- LPVOID TokenInformation,
- DWORD TokenInformationLength,
- PDWORD ReturnLength)
+static BOOL WINAPI
+get_token_information (HANDLE TokenHandle,
+ TOKEN_INFORMATION_CLASS TokenInformationClass,
+ LPVOID TokenInformation,
+ DWORD TokenInformationLength,
+ PDWORD ReturnLength)
{
static GetTokenInformation_Proc s_pfn_Get_Token_Information = NULL;
HMODULE hm_advapi32 = NULL;
);
}
-BOOL WINAPI lookup_account_sid (
- LPCTSTR lpSystemName,
- PSID Sid,
- LPTSTR Name,
- LPDWORD cbName,
- LPTSTR DomainName,
- LPDWORD cbDomainName,
- PSID_NAME_USE peUse)
+static BOOL WINAPI
+lookup_account_sid (LPCTSTR lpSystemName,
+ PSID Sid,
+ LPTSTR Name,
+ LPDWORD cbName,
+ LPTSTR DomainName,
+ LPDWORD cbDomainName,
+ PSID_NAME_USE peUse)
{
static LookupAccountSid_Proc s_pfn_Lookup_Account_Sid = NULL;
HMODULE hm_advapi32 = NULL;
);
}
-PSID_IDENTIFIER_AUTHORITY WINAPI get_sid_identifier_authority (
- PSID pSid)
-{
- static GetSidIdentifierAuthority_Proc s_pfn_Get_Sid_Identifier_Authority = NULL;
- HMODULE hm_advapi32 = NULL;
- if (is_windows_9x () == TRUE)
- {
- return NULL;
- }
- if (g_b_init_get_sid_identifier_authority == 0)
- {
- g_b_init_get_sid_identifier_authority = 1;
- hm_advapi32 = LoadLibrary ("Advapi32.dll");
- s_pfn_Get_Sid_Identifier_Authority =
- (GetSidIdentifierAuthority_Proc) GetProcAddress (
- hm_advapi32, "GetSidIdentifierAuthority");
- }
- if (s_pfn_Get_Sid_Identifier_Authority == NULL)
- {
- return NULL;
- }
- return (s_pfn_Get_Sid_Identifier_Authority (pSid));
-}
-
-PDWORD WINAPI get_sid_sub_authority (
- PSID pSid,
- DWORD n)
+static PDWORD WINAPI
+get_sid_sub_authority (PSID pSid, DWORD n)
{
static GetSidSubAuthority_Proc s_pfn_Get_Sid_Sub_Authority = NULL;
static DWORD zero = 0U;
return (s_pfn_Get_Sid_Sub_Authority (pSid, n));
}
-PUCHAR WINAPI get_sid_sub_authority_count (
- PSID pSid)
+static PUCHAR WINAPI
+get_sid_sub_authority_count (PSID pSid)
{
static GetSidSubAuthorityCount_Proc s_pfn_Get_Sid_Sub_Authority_Count = NULL;
static UCHAR zero = 0U;
return (s_pfn_Get_Sid_Sub_Authority_Count (pSid));
}
-BOOL WINAPI get_file_security (
- LPCTSTR lpFileName,
- SECURITY_INFORMATION RequestedInformation,
- PSECURITY_DESCRIPTOR pSecurityDescriptor,
- DWORD nLength,
- LPDWORD lpnLengthNeeded)
+static BOOL WINAPI
+get_file_security (LPCTSTR lpFileName,
+ SECURITY_INFORMATION RequestedInformation,
+ PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ DWORD nLength,
+ LPDWORD lpnLengthNeeded)
{
static GetFileSecurity_Proc s_pfn_Get_File_Security = NULL;
HMODULE hm_advapi32 = NULL;
lpnLengthNeeded));
}
-BOOL WINAPI get_security_descriptor_owner (
- PSECURITY_DESCRIPTOR pSecurityDescriptor,
- PSID *pOwner,
- LPBOOL lpbOwnerDefaulted)
+static BOOL WINAPI
+get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ PSID *pOwner,
+ LPBOOL lpbOwnerDefaulted)
{
static GetSecurityDescriptorOwner_Proc s_pfn_Get_Security_Descriptor_Owner = NULL;
HMODULE hm_advapi32 = NULL;
lpbOwnerDefaulted));
}
-BOOL WINAPI get_security_descriptor_group (
- PSECURITY_DESCRIPTOR pSecurityDescriptor,
- PSID *pGroup,
- LPBOOL lpbGroupDefaulted)
+static BOOL WINAPI
+get_security_descriptor_group (PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ PSID *pGroup,
+ LPBOOL lpbGroupDefaulted)
{
static GetSecurityDescriptorGroup_Proc s_pfn_Get_Security_Descriptor_Group = NULL;
HMODULE hm_advapi32 = NULL;
lpbGroupDefaulted));
}
-BOOL WINAPI is_valid_sid (
- PSID sid)
+static BOOL WINAPI
+is_valid_sid (PSID sid)
{
static IsValidSid_Proc s_pfn_Is_Valid_Sid = NULL;
HMODULE hm_advapi32 = NULL;
return (s_pfn_Is_Valid_Sid (sid));
}
-BOOL WINAPI equal_sid (
- PSID sid1,
- PSID sid2)
+static BOOL WINAPI
+equal_sid (PSID sid1, PSID sid2)
{
static EqualSid_Proc s_pfn_Equal_Sid = NULL;
HMODULE hm_advapi32 = NULL;
return (s_pfn_Equal_Sid (sid1, sid2));
}
-DWORD WINAPI get_length_sid (
- PSID sid)
+static DWORD WINAPI
+get_length_sid (PSID sid)
{
static GetLengthSid_Proc s_pfn_Get_Length_Sid = NULL;
HMODULE hm_advapi32 = NULL;
return (s_pfn_Get_Length_Sid (sid));
}
-BOOL WINAPI copy_sid (
- DWORD destlen,
- PSID dest,
- PSID src)
+static BOOL WINAPI
+copy_sid (DWORD destlen, PSID dest, PSID src)
{
static CopySid_Proc s_pfn_Copy_Sid = NULL;
HMODULE hm_advapi32 = NULL;
supported in Windows NT / 2k / XP
*/
+static void WINAPI
+get_native_system_info (LPSYSTEM_INFO lpSystemInfo)
+{
+ static GetNativeSystemInfo_Proc s_pfn_Get_Native_System_Info = NULL;
+ if (is_windows_9x () != TRUE)
+ {
+ if (g_b_init_get_native_system_info == 0)
+ {
+ g_b_init_get_native_system_info = 1;
+ s_pfn_Get_Native_System_Info =
+ (GetNativeSystemInfo_Proc)GetProcAddress (GetModuleHandle ("kernel32.dll"),
+ "GetNativeSystemInfo");
+ }
+ if (s_pfn_Get_Native_System_Info != NULL)
+ s_pfn_Get_Native_System_Info (lpSystemInfo);
+ }
+ else
+ lpSystemInfo->dwNumberOfProcessors = -1;
+}
+
+static BOOL WINAPI
+get_system_times (LPFILETIME lpIdleTime,
+ LPFILETIME lpKernelTime,
+ LPFILETIME lpUserTime)
+{
+ static GetSystemTimes_Proc s_pfn_Get_System_times = NULL;
+ if (is_windows_9x () == TRUE)
+ {
+ return FALSE;
+ }
+ if (g_b_init_get_system_times == 0)
+ {
+ g_b_init_get_system_times = 1;
+ s_pfn_Get_System_times =
+ (GetSystemTimes_Proc)GetProcAddress (GetModuleHandle ("kernel32.dll"),
+ "GetSystemTimes");
+ }
+ if (s_pfn_Get_System_times == NULL)
+ return FALSE;
+ return (s_pfn_Get_System_times (lpIdleTime, lpKernelTime, lpUserTime));
+}
\f
/* Equivalent of strerror for W32 error codes. */
char *
#endif
}
-#ifndef HAVE_SOCKETS
-/* Emulate gethostname. */
-int
-gethostname (char *buffer, int size)
+/* Emulate getloadavg. */
+
+struct load_sample {
+ time_t sample_time;
+ ULONGLONG idle;
+ ULONGLONG kernel;
+ ULONGLONG user;
+};
+
+/* Number of processors on this machine. */
+static unsigned num_of_processors;
+
+/* We maintain 1-sec samples for the last 16 minutes in a circular buffer. */
+static struct load_sample samples[16*60];
+static int first_idx = -1, last_idx = -1;
+static int max_idx = sizeof (samples) / sizeof (samples[0]);
+
+static int
+buf_next (int from)
{
- /* NT only allows small host names, so the buffer is
- certainly large enough. */
- return !GetComputerName (buffer, &size);
+ int next_idx = from + 1;
+
+ if (next_idx >= max_idx)
+ next_idx = 0;
+
+ return next_idx;
+}
+
+static int
+buf_prev (int from)
+{
+ int prev_idx = from - 1;
+
+ if (prev_idx < 0)
+ prev_idx = max_idx - 1;
+
+ return prev_idx;
+}
+
+static void
+sample_system_load (ULONGLONG *idle, ULONGLONG *kernel, ULONGLONG *user)
+{
+ SYSTEM_INFO sysinfo;
+ FILETIME ft_idle, ft_user, ft_kernel;
+
+ /* Initialize the number of processors on this machine. */
+ if (num_of_processors <= 0)
+ {
+ get_native_system_info (&sysinfo);
+ num_of_processors = sysinfo.dwNumberOfProcessors;
+ if (num_of_processors <= 0)
+ {
+ GetSystemInfo (&sysinfo);
+ num_of_processors = sysinfo.dwNumberOfProcessors;
+ }
+ if (num_of_processors <= 0)
+ num_of_processors = 1;
+ }
+
+ /* TODO: Take into account threads that are ready to run, by
+ sampling the "\System\Processor Queue Length" performance
+ counter. The code below accounts only for threads that are
+ actually running. */
+
+ if (get_system_times (&ft_idle, &ft_kernel, &ft_user))
+ {
+ ULARGE_INTEGER uidle, ukernel, uuser;
+
+ memcpy (&uidle, &ft_idle, sizeof (ft_idle));
+ memcpy (&ukernel, &ft_kernel, sizeof (ft_kernel));
+ memcpy (&uuser, &ft_user, sizeof (ft_user));
+ *idle = uidle.QuadPart;
+ *kernel = ukernel.QuadPart;
+ *user = uuser.QuadPart;
+ }
+ else
+ {
+ *idle = 0;
+ *kernel = 0;
+ *user = 0;
+ }
+}
+
+/* Produce the load average for a given time interval, using the
+ samples in the samples[] array. WHICH can be 0, 1, or 2, meaning
+ 1-minute, 5-minute, or 15-minute average, respectively. */
+static double
+getavg (int which)
+{
+ double retval = -1.0;
+ double tdiff;
+ int idx;
+ double span = (which == 0 ? 1.0 : (which == 1 ? 5.0 : 15.0)) * 60;
+ time_t now = samples[last_idx].sample_time;
+
+ if (first_idx != last_idx)
+ {
+ for (idx = buf_prev (last_idx); ; idx = buf_prev (idx))
+ {
+ tdiff = difftime (now, samples[idx].sample_time);
+ if (tdiff >= span - 2*DBL_EPSILON*now)
+ {
+ long double sys =
+ samples[last_idx].kernel + samples[last_idx].user
+ - (samples[idx].kernel + samples[idx].user);
+ long double idl = samples[last_idx].idle - samples[idx].idle;
+
+ retval = (1.0 - idl / sys) * num_of_processors;
+ break;
+ }
+ if (idx == first_idx)
+ break;
+ }
+ }
+
+ return retval;
}
-#endif /* HAVE_SOCKETS */
-/* Emulate getloadavg. */
int
getloadavg (double loadavg[], int nelem)
{
- int i;
+ int elem;
+ ULONGLONG idle, kernel, user;
+ time_t now = time (NULL);
- /* A faithful emulation is going to have to be saved for a rainy day. */
- for (i = 0; i < nelem; i++)
+ /* Store another sample. We ignore samples that are less than 1 sec
+ apart. */
+ if (difftime (now, samples[last_idx].sample_time) >= 1.0 - 2*DBL_EPSILON*now)
{
- loadavg[i] = 0.0;
+ sample_system_load (&idle, &kernel, &user);
+ last_idx = buf_next (last_idx);
+ samples[last_idx].sample_time = now;
+ samples[last_idx].idle = idle;
+ samples[last_idx].kernel = kernel;
+ samples[last_idx].user = user;
+ /* If the buffer has more that 15 min worth of samples, discard
+ the old ones. */
+ if (first_idx == -1)
+ first_idx = last_idx;
+ while (first_idx != last_idx
+ && (difftime (now, samples[first_idx].sample_time)
+ >= 15.0*60 + 2*DBL_EPSILON*now))
+ first_idx = buf_next (first_idx);
}
- return i;
+
+ for (elem = 0; elem < nelem; elem++)
+ {
+ double avg = getavg (elem);
+
+ if (avg < 0)
+ break;
+ loadavg[elem] = avg;
+ }
+
+ return elem;
}
/* Emulate getpwuid, getpwnam and others. */
0,
};
-int
-getuid ()
+unsigned
+getuid (void)
{
return dflt_passwd.pw_uid;
}
-int
-geteuid ()
+unsigned
+geteuid (void)
{
/* I could imagine arguing for checking to see whether the user is
in the Administrators group and returning a UID of 0 for that
return getuid ();
}
-int
-getgid ()
+unsigned
+getgid (void)
{
return dflt_passwd.pw_gid;
}
-int
-getegid ()
+unsigned
+getegid (void)
{
return getgid ();
}
struct passwd *
-getpwuid (int uid)
+getpwuid (unsigned uid)
{
if (uid == dflt_passwd.pw_uid)
return &dflt_passwd;
return pw;
}
-void
-init_user_info ()
+static void
+init_user_info (void)
{
/* Find the user's real name by opening the process token and
looking up the name associated with the user-sid in that token.
}
int
-random ()
+random (void)
{
/* rand () on NT gives us 15 random bits...hack together 30 bits. */
return ((rand () << 15) | rand ());
case path name components to lower case. */
static void
-normalize_filename (fp, path_sep)
- register char *fp;
- char path_sep;
+normalize_filename (register char *fp, char path_sep)
{
char sep;
char *elem;
/* Destructively turn backslashes into slashes. */
void
-dostounix_filename (p)
- register char *p;
+dostounix_filename (register char *p)
{
normalize_filename (p, '/');
}
/* Destructively turn slashes into backslashes. */
void
-unixtodos_filename (p)
- register char *p;
+unixtodos_filename (register char *p)
{
normalize_filename (p, '\\');
}
/* Remove all CR's that are followed by a LF.
(From msdos.c...probably should figure out a way to share it,
although this code isn't going to ever change.) */
-int
-crlf_to_lf (n, buf)
- register int n;
- register unsigned char *buf;
+static int
+crlf_to_lf (register int n, register unsigned char *buf)
{
unsigned char *np = buf;
unsigned char *startp = buf;
return TRUE;
}
-int
+static int
is_unc_volume (const char *filename)
{
const char *ptr = filename;
return 0;
}
+int
+sigemptyset (sigset_t *set)
+{
+ 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
setpgrp (int pid, int gid)
{
#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
LPBYTE
-w32_get_resource (key, lpdwtype)
- char *key;
- LPDWORD lpdwtype;
+w32_get_resource (char *key, LPDWORD lpdwtype)
{
LPBYTE lpvalue;
HKEY hrootkey = NULL;
{"LANG", NULL},
};
-#define N_ENV_VARS sizeof(dflt_envvars)/sizeof(dflt_envvars[0])
+#define N_ENV_VARS sizeof (dflt_envvars)/sizeof (dflt_envvars[0])
/* We need to copy dflt_envvars[] and work on the copy because we
don't want the dumped Emacs to inherit the values of
HRESULT profile_result;
/* Dynamically load ShGetFolderPath, as it won't exist on versions
of Windows 95 and NT4 that have not been updated to include
- MSIE 5. Also we don't link with shell32.dll by default. */
- HMODULE shell32_dll;
+ MSIE 5. */
ShGetFolderPath_fn get_folder_path;
- shell32_dll = GetModuleHandle ("shell32.dll");
get_folder_path = (ShGetFolderPath_fn)
- GetProcAddress (shell32_dll, "SHGetFolderPathA");
+ GetProcAddress (GetModuleHandle ("shell32.dll"), "SHGetFolderPathA");
if (get_folder_path != NULL)
{
if (profile_result == S_OK)
env_vars[0].def_value = default_home;
}
-
- /* Unload shell32.dll, it is not needed anymore. */
- FreeLibrary (shell32_dll);
}
/* Get default locale info and use it for LANG. */
for (p = modname; *p; p++)
if (*p == '\\') *p = '/';
- _snprintf (buf, sizeof(buf)-1, "emacs_dir=%s", modname);
+ _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname);
_putenv (strdup (buf));
}
/* Handle running emacs from the build directory: src/oo-spd/i386/ */
for (p = modname; *p; p++)
if (*p == '\\') *p = '/';
- _snprintf (buf, sizeof(buf)-1, "emacs_dir=%s", modname);
+ _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname);
_putenv (strdup (buf));
}
}
char buf1[SET_ENV_BUF_SIZE], buf2[SET_ENV_BUF_SIZE];
if (dwType == REG_EXPAND_SZ)
- ExpandEnvironmentStrings ((LPSTR) lpval, buf1, sizeof(buf1));
+ ExpandEnvironmentStrings ((LPSTR) lpval, buf1, sizeof (buf1));
else if (dwType == REG_SZ)
strcpy (buf1, lpval);
if (dwType == REG_EXPAND_SZ || dwType == REG_SZ)
{
- _snprintf (buf2, sizeof(buf2)-1, "%s=%s", env_vars[i].name,
+ _snprintf (buf2, sizeof (buf2)-1, "%s=%s", env_vars[i].name,
buf1);
_putenv (strdup (buf2));
}
char *
get_emacs_configuration_options (void)
{
- static char options_buffer[256];
+ static char *options_buffer;
+ char cv[32]; /* Enough for COMPILER_VERSION. */
+ char *options[] = {
+ cv, /* To be filled later. */
+#ifdef EMACSDEBUG
+ " --no-opt",
+#endif
+ /* configure.bat already sets USER_CFLAGS and USER_LDFLAGS
+ with a starting space to save work here. */
+#ifdef USER_CFLAGS
+ " --cflags", USER_CFLAGS,
+#endif
+#ifdef USER_LDFLAGS
+ " --ldflags", USER_LDFLAGS,
+#endif
+ NULL
+ };
+ size_t size = 0;
+ int i;
/* Work out the effective configure options for this build. */
#ifdef _MSC_VER
#endif
#endif
- sprintf (options_buffer, COMPILER_VERSION);
-#ifdef EMACSDEBUG
- strcat (options_buffer, " --no-opt");
-#endif
-#ifdef USER_CFLAGS
- strcat (options_buffer, " --cflags");
- strcat (options_buffer, USER_CFLAGS);
-#endif
-#ifdef USER_LDFLAGS
- strcat (options_buffer, " --ldflags");
- strcat (options_buffer, USER_LDFLAGS);
-#endif
+ if (_snprintf (cv, sizeof (cv) - 1, COMPILER_VERSION) < 0)
+ return "Error: not enough space for compiler version";
+ cv[sizeof (cv) - 1] = '\0';
+
+ for (i = 0; options[i]; i++)
+ size += strlen (options[i]);
+
+ options_buffer = xmalloc (size + 1);
+ options_buffer[0] = '\0';
+
+ for (i = 0; options[i]; i++)
+ strcat (options_buffer, options[i]);
+
return options_buffer;
}
/* Wrapper for GetVolumeInformation, which uses caching to avoid
performance penalty (~2ms on 486 for local drives, 7.5ms for local
cdrom drive, ~5-10ms or more for remote drives on LAN). */
-volume_info_data *
+static volume_info_data *
GetCachedVolumeInformation (char * root_dir)
{
volume_info_data * info;
involve network access, and so is extremely quick). */
/* Map drive letter to UNC if remote. */
- if ( isalpha( root_dir[0] ) && !fixed[ DRIVE_INDEX( root_dir[0] ) ] )
+ if (isalpha (root_dir[0]) && !fixed[DRIVE_INDEX (root_dir[0])])
{
char remote_name[ 256 ];
char drive[3] = { root_dir[0], ':' };
/* Get information on the volume where name is held; set path pointer to
start of pathname in name (past UNC header\volume header if present). */
-int
+static int
get_volume_info (const char * name, const char ** pPath)
{
char temp[MAX_PATH];
/* Determine if volume is FAT format (ie. only supports short 8.3
names); also set path pointer to start of pathname in name. */
-int
+static int
is_fat_volume (const char * name, const char ** pPath)
{
if (get_volume_info (name, pPath))
/* Support shares on a network resource as subdirectories of a read-only
root directory. */
static HANDLE wnet_enum_handle = INVALID_HANDLE_VALUE;
-HANDLE open_unc_volume (const char *);
-char *read_unc_volume (HANDLE, char *, int);
-void close_unc_volume (HANDLE);
+static HANDLE open_unc_volume (const char *);
+static char *read_unc_volume (HANDLE, char *, int);
+static void close_unc_volume (HANDLE);
DIR *
opendir (char *filename)
return &dir_static;
}
-HANDLE
+static HANDLE
open_unc_volume (const char *path)
{
NETRESOURCE nr;
nr.lpComment = NULL;
nr.lpProvider = NULL;
- result = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
- RESOURCEUSAGE_CONNECTABLE, &nr, &henum);
+ result = WNetOpenEnum (RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
+ RESOURCEUSAGE_CONNECTABLE, &nr, &henum);
if (result == NO_ERROR)
return henum;
return INVALID_HANDLE_VALUE;
}
-char *
+static char *
read_unc_volume (HANDLE henum, char *readbuf, int size)
{
DWORD count;
return readbuf;
}
-void
+static void
close_unc_volume (HANDLE henum)
{
if (henum != INVALID_HANDLE_VALUE)
WNetCloseEnum (henum);
}
-DWORD
+static DWORD
unc_volume_file_attributes (const char *path)
{
HANDLE henum;
char share[MAX_PATH];
int i, n_slashes;
char drive[4];
+ UINT drvtype;
- sprintf (drive, "%c:\\", path[0]);
+ if (IS_DIRECTORY_SEP (path[0]) && IS_DIRECTORY_SEP (path[1]))
+ drvtype = DRIVE_REMOTE;
+ else if (path[0] == '\0' || path[1] != ':')
+ drvtype = GetDriveType (NULL);
+ else
+ {
+ drive[0] = path[0];
+ drive[1] = ':';
+ drive[2] = '\\';
+ drive[3] = '\0';
+ drvtype = GetDriveType (drive);
+ }
/* Only logon to networked drives. */
- if ((!IS_DIRECTORY_SEP (path[0]) || !IS_DIRECTORY_SEP (path[1]))
- && GetDriveType (drive) != DRIVE_REMOTE)
+ if (drvtype != DRIVE_REMOTE)
return;
n_slashes = 2;
}
FILE *
-sys_fopen(const char * path, const char * mode)
+sys_fopen (const char * path, const char * mode)
{
int fd;
int oflag;
data.wid.dwStreamId = BACKUP_LINK;
data.wid.dwStreamAttributes = 0;
- data.wid.Size.LowPart = wlen * sizeof(WCHAR);
+ data.wid.Size.LowPart = wlen * sizeof (WCHAR);
data.wid.Size.HighPart = 0;
data.wid.dwStreamNameSize = 0;
}
static FILETIME utc_base_ft;
-static long double utc_base;
+static ULONGLONG utc_base; /* In 100ns units */
static int init = 0;
-static long double
-convert_time_raw (FILETIME ft)
+#define FILETIME_TO_U64(result, ft) \
+ do { \
+ ULARGE_INTEGER uiTemp; \
+ uiTemp.LowPart = (ft).dwLowDateTime; \
+ uiTemp.HighPart = (ft).dwHighDateTime; \
+ result = uiTemp.QuadPart; \
+ } while (0)
+
+static void
+initialize_utc_base (void)
{
- return
- (long double) ft.dwHighDateTime
- * 4096.0L * 1024.0L * 1024.0L + ft.dwLowDateTime;
+ /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
+ SYSTEMTIME st;
+
+ st.wYear = 1970;
+ st.wMonth = 1;
+ st.wDay = 1;
+ st.wHour = 0;
+ st.wMinute = 0;
+ st.wSecond = 0;
+ st.wMilliseconds = 0;
+
+ SystemTimeToFileTime (&st, &utc_base_ft);
+ FILETIME_TO_U64 (utc_base, utc_base_ft);
}
static time_t
convert_time (FILETIME ft)
{
- long double ret;
+ ULONGLONG tmp;
if (!init)
{
- /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
- SYSTEMTIME st;
-
- st.wYear = 1970;
- st.wMonth = 1;
- st.wDay = 1;
- st.wHour = 0;
- st.wMinute = 0;
- st.wSecond = 0;
- st.wMilliseconds = 0;
-
- SystemTimeToFileTime (&st, &utc_base_ft);
- utc_base = (long double) utc_base_ft.dwHighDateTime
- * 4096.0L * 1024.0L * 1024.0L + utc_base_ft.dwLowDateTime;
+ initialize_utc_base ();
init = 1;
}
if (CompareFileTime (&ft, &utc_base_ft) < 0)
return 0;
- return (time_t) ((convert_time_raw (ft) - utc_base) * 1e-7L);
+ FILETIME_TO_U64 (tmp, ft);
+ return (time_t) ((tmp - utc_base) / 10000000L);
}
-
-void
+static void
convert_from_time_t (time_t time, FILETIME * pft)
{
- long double tmp;
+ ULARGE_INTEGER tmp;
if (!init)
{
- /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
- SYSTEMTIME st;
-
- st.wYear = 1970;
- st.wMonth = 1;
- st.wDay = 1;
- st.wHour = 0;
- st.wMinute = 0;
- st.wSecond = 0;
- st.wMilliseconds = 0;
-
- SystemTimeToFileTime (&st, &utc_base_ft);
- utc_base = (long double) utc_base_ft.dwHighDateTime
- * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
+ initialize_utc_base ();
init = 1;
}
/* time in 100ns units since 1-Jan-1601 */
- tmp = (long double) time * 1e7 + utc_base;
- pft->dwHighDateTime = (DWORD) (tmp / (4096.0 * 1024 * 1024));
- pft->dwLowDateTime = (DWORD) (tmp - (4096.0 * 1024 * 1024) * pft->dwHighDateTime);
+ tmp.QuadPart = (ULONGLONG) time * 10000000L + utc_base;
+ pft->dwHighDateTime = tmp.HighPart;
+ pft->dwLowDateTime = tmp.LowPart;
}
#if 0
#endif
struct w32_id {
- int rid;
+ unsigned rid;
struct w32_id *next;
char name[GNLEN+1];
unsigned char sid[FLEXIBLE_ARRAY_MEMBER];
static struct w32_id *w32_idlist;
static int
-w32_cached_id (PSID sid, int *id, char *name)
+w32_cached_id (PSID sid, unsigned *id, char *name)
{
struct w32_id *tail, *found;
}
static void
-w32_add_to_cache (PSID sid, int id, char *name)
+w32_add_to_cache (PSID sid, unsigned id, char *name)
{
DWORD sid_len;
struct w32_id *new_entry;
static int
get_name_and_id (PSECURITY_DESCRIPTOR psd, const char *fname,
- int *id, char *nm, int what)
+ unsigned *id, char *nm, int what)
{
PSID sid = NULL;
char machine[MAX_COMPUTERNAME_LENGTH+1];
char name[UNLEN+1];
DWORD name_len = sizeof (name);
char domain[1024];
- DWORD domain_len = sizeof(domain);
+ DWORD domain_len = sizeof (domain);
char *mp = NULL;
int use_dflt = 0;
int result;
}
static void
-get_file_owner_and_group (
- PSECURITY_DESCRIPTOR psd,
- const char *fname,
- struct stat *st)
+get_file_owner_and_group (PSECURITY_DESCRIPTOR psd,
+ const char *fname,
+ struct stat *st)
{
int dflt_usr = 0, dflt_grp = 0;
}
}
+/* Return non-zero if NAME is a potentially slow filesystem. */
+int
+is_slow_fs (const char *name)
+{
+ char drive_root[4];
+ UINT devtype;
+
+ if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
+ devtype = DRIVE_REMOTE; /* assume UNC name is remote */
+ else if (!(strlen (name) >= 2 && IS_DEVICE_SEP (name[1])))
+ devtype = GetDriveType (NULL); /* use root of current drive */
+ else
+ {
+ /* GetDriveType needs the root directory of the drive. */
+ strncpy (drive_root, name, 2);
+ drive_root[2] = '\\';
+ drive_root[3] = '\0';
+ devtype = GetDriveType (drive_root);
+ }
+ return !(devtype == DRIVE_FIXED || devtype == DRIVE_RAMDISK);
+}
+
/* 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 without hacks in the main Emacs code. */
}
}
- /* GetDriveType needs the root directory of NAME's drive. */
- if (!(strlen (name) >= 2 && IS_DEVICE_SEP (name[1])))
- devtype = GetDriveType (NULL); /* use root of current diectory */
- else
- {
- strncpy (drive_root, name, 3);
- drive_root[3] = '\0';
- devtype = GetDriveType (drive_root);
- }
-
if (!(NILP (Vw32_get_true_file_attributes)
- || (EQ (Vw32_get_true_file_attributes, Qlocal)
- && devtype != DRIVE_FIXED && devtype != DRIVE_RAMDISK))
+ || (EQ (Vw32_get_true_file_attributes, Qlocal) && is_slow_fs (name)))
/* No access rights required to get info. */
&& (fh = CreateFile (name, 0, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL))
buf->st_dev = volume_info.serialnum;
buf->st_rdev = volume_info.serialnum;
-
buf->st_size = wfd.nFileSizeHigh;
buf->st_size <<= 32;
buf->st_size += wfd.nFileSizeLow;
/* Helper wrapper functions. */
-HANDLE WINAPI create_toolhelp32_snapshot(
- DWORD Flags,
- DWORD Ignored)
+static HANDLE WINAPI
+create_toolhelp32_snapshot (DWORD Flags, DWORD Ignored)
{
static CreateToolhelp32Snapshot_Proc s_pfn_Create_Toolhelp32_Snapshot = NULL;
return (s_pfn_Create_Toolhelp32_Snapshot (Flags, Ignored));
}
-BOOL WINAPI process32_first(
- HANDLE hSnapshot,
- LPPROCESSENTRY32 lppe)
+static BOOL WINAPI
+process32_first (HANDLE hSnapshot, LPPROCESSENTRY32 lppe)
{
static Process32First_Proc s_pfn_Process32_First = NULL;
return (s_pfn_Process32_First (hSnapshot, lppe));
}
-BOOL WINAPI process32_next(
- HANDLE hSnapshot,
- LPPROCESSENTRY32 lppe)
+static BOOL WINAPI
+process32_next (HANDLE hSnapshot, LPPROCESSENTRY32 lppe)
{
static Process32Next_Proc s_pfn_Process32_Next = NULL;
return (s_pfn_Process32_Next (hSnapshot, lppe));
}
-BOOL WINAPI open_thread_token (
- HANDLE ThreadHandle,
- DWORD DesiredAccess,
- BOOL OpenAsSelf,
- PHANDLE TokenHandle)
+static BOOL WINAPI
+open_thread_token (HANDLE ThreadHandle,
+ DWORD DesiredAccess,
+ BOOL OpenAsSelf,
+ PHANDLE TokenHandle)
{
static OpenThreadToken_Proc s_pfn_Open_Thread_Token = NULL;
HMODULE hm_advapi32 = NULL;
);
}
-BOOL WINAPI impersonate_self (
- SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
+static BOOL WINAPI
+impersonate_self (SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
{
static ImpersonateSelf_Proc s_pfn_Impersonate_Self = NULL;
HMODULE hm_advapi32 = NULL;
return s_pfn_Impersonate_Self (ImpersonationLevel);
}
-BOOL WINAPI revert_to_self (void)
+static BOOL WINAPI
+revert_to_self (void)
{
static RevertToSelf_Proc s_pfn_Revert_To_Self = NULL;
HMODULE hm_advapi32 = NULL;
return s_pfn_Revert_To_Self ();
}
-BOOL WINAPI get_process_memory_info (
- HANDLE h_proc,
- PPROCESS_MEMORY_COUNTERS mem_counters,
- DWORD bufsize)
+static BOOL WINAPI
+get_process_memory_info (HANDLE h_proc,
+ PPROCESS_MEMORY_COUNTERS mem_counters,
+ DWORD bufsize)
{
static GetProcessMemoryInfo_Proc s_pfn_Get_Process_Memory_Info = NULL;
HMODULE hm_psapi = NULL;
return s_pfn_Get_Process_Memory_Info (h_proc, mem_counters, bufsize);
}
-BOOL WINAPI get_process_working_set_size (
- HANDLE h_proc,
- DWORD *minrss,
- DWORD *maxrss)
+static BOOL WINAPI
+get_process_working_set_size (HANDLE h_proc,
+ DWORD *minrss,
+ DWORD *maxrss)
{
static GetProcessWorkingSetSize_Proc
s_pfn_Get_Process_Working_Set_Size = NULL;
return s_pfn_Get_Process_Working_Set_Size (h_proc, minrss, maxrss);
}
-BOOL WINAPI global_memory_status (
- MEMORYSTATUS *buf)
+static BOOL WINAPI
+global_memory_status (MEMORYSTATUS *buf)
{
static GlobalMemoryStatus_Proc s_pfn_Global_Memory_Status = NULL;
return s_pfn_Global_Memory_Status (buf);
}
-BOOL WINAPI global_memory_status_ex (
- MEMORY_STATUS_EX *buf)
+static BOOL WINAPI
+global_memory_status_ex (MEMORY_STATUS_EX *buf)
{
static GlobalMemoryStatusEx_Proc s_pfn_Global_Memory_Status_Ex = NULL;
}
Lisp_Object
-w32_list_system_processes ()
+list_system_processes (void)
{
struct gcpro gcpro1;
Lisp_Object proclist = Qnil;
}
static Lisp_Object
-ltime (time_sec, time_usec)
- long time_sec, time_usec;
+ltime (long time_sec, long time_usec)
{
return list3 (make_number ((time_sec >> 16) & 0xffff),
make_number (time_sec & 0xffff),
make_number (time_usec));
}
+#define U64_TO_LISP_TIME(time) ltime ((time) / 1000000L, (time) % 1000000L)
+
static int
-process_times (h_proc, ctime, etime, stime, utime, pcpu)
- HANDLE h_proc;
- Lisp_Object *ctime, *etime, *stime, *utime;
- double *pcpu;
+process_times (HANDLE h_proc, Lisp_Object *ctime, Lisp_Object *etime,
+ Lisp_Object *stime, Lisp_Object *utime, Lisp_Object *ttime,
+ double *pcpu)
{
FILETIME ft_creation, ft_exit, ft_kernel, ft_user, ft_current;
- long ctime_sec, ctime_usec, stime_sec, stime_usec, utime_sec, utime_usec;
- long etime_sec, etime_usec;
- long double tem1, tem2, tem;
+ ULONGLONG tem1, tem2, tem3, tem;
if (!h_proc
|| !get_process_times_fn
- || !(*get_process_times_fn)(h_proc, &ft_creation, &ft_exit,
- &ft_kernel, &ft_user))
+ || !(*get_process_times_fn) (h_proc, &ft_creation, &ft_exit,
+ &ft_kernel, &ft_user))
return 0;
GetSystemTimeAsFileTime (&ft_current);
- tem1 = convert_time_raw (ft_kernel) * 0.1L;
- stime_usec = fmodl (tem1, 1000000.0L);
- stime_sec = tem1 * 0.000001L;
- *stime = ltime (stime_sec, stime_usec);
- tem2 = convert_time_raw (ft_user) * 0.1L;
- utime_usec = fmodl (tem2, 1000000.0L);
- utime_sec = tem2 * 0.000001L;
- *utime = ltime (utime_sec, utime_usec);
- tem = convert_time_raw (ft_creation);
+ FILETIME_TO_U64 (tem1, ft_kernel);
+ tem1 /= 10L;
+ *stime = U64_TO_LISP_TIME (tem1);
+
+ FILETIME_TO_U64 (tem2, ft_user);
+ tem2 /= 10L;
+ *utime = U64_TO_LISP_TIME (tem2);
+
+ tem3 = tem1 + tem2;
+ *ttime = U64_TO_LISP_TIME (tem3);
+
+ FILETIME_TO_U64 (tem, ft_creation);
/* Process no 4 (System) returns zero creation time. */
if (tem)
- tem = (tem - utc_base) * 0.1;
- ctime_usec = fmodl (tem, 1000000.0L);
- ctime_sec = tem * 0.000001L;
- *ctime = ltime (ctime_sec, ctime_usec);
+ tem = (tem - utc_base) / 10L;
+ *ctime = U64_TO_LISP_TIME (tem);
+
if (tem)
- tem = (convert_time_raw (ft_current) - utc_base) * 0.1L - tem;
- etime_usec = fmodl (tem, 1000000.0L);
- etime_sec = tem * 0.000001L;
- *etime = ltime (etime_sec, etime_usec);
+ {
+ FILETIME_TO_U64 (tem3, ft_current);
+ tem = (tem3 - utc_base) / 10L - tem;
+ }
+ *etime = U64_TO_LISP_TIME (tem);
if (tem)
{
}
Lisp_Object
-w32_system_process_attributes (pid)
- Lisp_Object pid;
+system_process_attributes (Lisp_Object pid)
{
struct gcpro gcpro1, gcpro2, gcpro3;
Lisp_Object attrs = Qnil;
DWORD blen = 0;
TOKEN_USER user_token;
TOKEN_PRIMARY_GROUP group_token;
- int euid;
- int egid;
+ unsigned euid;
+ unsigned egid;
DWORD sess;
PROCESS_MEMORY_COUNTERS mem;
PROCESS_MEMORY_COUNTERS_EX mem_ex;
MEMORYSTATUS memst;
MEMORY_STATUS_EX memstex;
double totphys = 0.0;
- Lisp_Object ctime, stime, utime, etime;
+ Lisp_Object ctime, stime, utime, etime, ttime;
double pcpu;
BOOL result = FALSE;
}
}
}
- if (buf)
- xfree (buf);
+ xfree (buf);
}
if (!result)
{
attrs = Fcons (Fcons (Qpmem, make_float (100. * rss / totphys)), attrs);
}
- if (process_times (h_proc, &ctime, &etime, &stime, &utime, &pcpu))
+ if (process_times (h_proc, &ctime, &etime, &stime, &utime, &ttime, &pcpu))
{
attrs = Fcons (Fcons (Qutime, utime), attrs);
attrs = Fcons (Fcons (Qstime, stime), attrs);
+ attrs = Fcons (Fcons (Qtime, ttime), attrs);
attrs = Fcons (Fcons (Qstart, ctime), attrs);
attrs = Fcons (Fcons (Qetime, etime), attrs);
attrs = Fcons (Fcons (Qpcpu, make_float (pcpu)), attrs);
}
\f
-#ifdef HAVE_SOCKETS
-
/* Wrappers for winsock functions to map between our file descriptors
and winsock's handles; also set h_errno for convenience.
if (winsock_lib != NULL)
return TRUE;
- pfn_SetHandleInformation = NULL;
pfn_SetHandleInformation
= (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
"SetHandleInformation");
if ((pfn_##fn = (void *) GetProcAddress (winsock_lib, #fn)) == NULL) \
goto fail;
- LOAD_PROC( WSAStartup );
- LOAD_PROC( WSASetLastError );
- LOAD_PROC( WSAGetLastError );
- LOAD_PROC( WSAEventSelect );
- LOAD_PROC( WSACreateEvent );
- LOAD_PROC( WSACloseEvent );
- LOAD_PROC( socket );
- LOAD_PROC( bind );
- LOAD_PROC( connect );
- LOAD_PROC( ioctlsocket );
- LOAD_PROC( recv );
- LOAD_PROC( send );
- LOAD_PROC( closesocket );
- LOAD_PROC( shutdown );
- LOAD_PROC( htons );
- LOAD_PROC( ntohs );
- LOAD_PROC( inet_addr );
- LOAD_PROC( gethostname );
- LOAD_PROC( gethostbyname );
- LOAD_PROC( getservbyname );
- LOAD_PROC( getpeername );
- LOAD_PROC( WSACleanup );
- LOAD_PROC( setsockopt );
- LOAD_PROC( listen );
- LOAD_PROC( getsockname );
- LOAD_PROC( accept );
- LOAD_PROC( recvfrom );
- LOAD_PROC( sendto );
+ LOAD_PROC (WSAStartup);
+ LOAD_PROC (WSASetLastError);
+ LOAD_PROC (WSAGetLastError);
+ LOAD_PROC (WSAEventSelect);
+ LOAD_PROC (WSACreateEvent);
+ LOAD_PROC (WSACloseEvent);
+ LOAD_PROC (socket);
+ LOAD_PROC (bind);
+ LOAD_PROC (connect);
+ LOAD_PROC (ioctlsocket);
+ LOAD_PROC (recv);
+ LOAD_PROC (send);
+ LOAD_PROC (closesocket);
+ LOAD_PROC (shutdown);
+ LOAD_PROC (htons);
+ LOAD_PROC (ntohs);
+ LOAD_PROC (inet_addr);
+ LOAD_PROC (gethostname);
+ LOAD_PROC (gethostbyname);
+ LOAD_PROC (getservbyname);
+ LOAD_PROC (getpeername);
+ LOAD_PROC (WSACleanup);
+ LOAD_PROC (setsockopt);
+ LOAD_PROC (listen);
+ LOAD_PROC (getsockname);
+ LOAD_PROC (accept);
+ LOAD_PROC (recvfrom);
+ LOAD_PROC (sendto);
#undef LOAD_PROC
/* specify version 1.1 of winsock */
normal system codes where they overlap (non-overlapping definitions
are already in <sys/socket.h> */
static void
-set_errno ()
+set_errno (void)
{
if (winsock_lib == NULL)
h_errno = EINVAL;
}
static void
-check_errno ()
+check_errno (void)
{
if (h_errno == 0 && winsock_lib != NULL)
pfn_WSASetLastError (0);
};
char *
-sys_strerror(int error_no)
+sys_strerror (int error_no)
{
int i;
static char unknown_msg[40];
if (_wsa_errlist[i].errnum == error_no)
return _wsa_errlist[i].msg;
- sprintf(unknown_msg, "Unidentified error: %d", error_no);
+ sprintf (unknown_msg, "Unidentified error: %d", error_no);
return unknown_msg;
}
but I believe the method of keeping the socket handle separate (and
insuring it is not inheritable) is the correct one. */
-//#define SOCK_REPLACE_HANDLE
-
-#ifdef SOCK_REPLACE_HANDLE
-#define SOCK_HANDLE(fd) ((SOCKET) _get_osfhandle (fd))
-#else
#define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
-#endif
-int socket_to_fd (SOCKET s);
+static int socket_to_fd (SOCKET s);
int
-sys_socket(int af, int type, int protocol)
+sys_socket (int af, int type, int protocol)
{
SOCKET s;
}
/* Convert a SOCKET to a file descriptor. */
-int
+static int
socket_to_fd (SOCKET s)
{
int fd;
fd = _open ("NUL:", _O_RDWR);
if (fd >= 0)
{
-#ifdef SOCK_REPLACE_HANDLE
- /* now replace handle to NUL with our socket handle */
- CloseHandle ((HANDLE) _get_osfhandle (fd));
- _free_osfhnd (fd);
- _set_osfhnd (fd, s);
- /* setmode (fd, _O_BINARY); */
-#else
/* Make a non-inheritable copy of the socket handle. Note
that it is possible that sockets aren't actually kernel
handles, which appears to be the case on Windows 9x when
}
}
fd_info[fd].hnd = (HANDLE) s;
-#endif
/* set our own internal flags */
fd_info[fd].flags = FILE_SOCKET | FILE_BINARY | FILE_READ | FILE_WRITE;
return -1;
}
-
int
sys_bind (int s, const struct sockaddr * addr, int namelen)
{
return SOCKET_ERROR;
}
-
int
sys_connect (int s, const struct sockaddr * name, int namelen)
{
}
struct hostent *
-sys_gethostbyname(const char * name)
+sys_gethostbyname (const char * name)
{
struct hostent * host;
}
struct servent *
-sys_getservbyname(const char * name, const char * proto)
+sys_getservbyname (const char * name, const char * proto)
{
struct servent * serv;
return SOCKET_ERROR;
}
-
int
sys_shutdown (int s, int how)
{
int
sys_recvfrom (int s, char * buf, int len, int flags,
- struct sockaddr * from, int * fromlen)
+ struct sockaddr * from, int * fromlen)
{
if (winsock_lib == NULL)
{
unsigned long nblock = 1;
int rc = pfn_ioctlsocket (SOCK_HANDLE (s), FIONBIO, &nblock);
if (rc == SOCKET_ERROR)
- set_errno();
+ set_errno ();
/* Keep track of the fact that we set this to non-blocking. */
fd_info[s].flags |= FILE_NDELAY;
return rc;
return SOCKET_ERROR;
}
-#endif /* HAVE_SOCKETS */
-
/* Shadow main io functions: we need to handle pipes and sockets more
intelligently, and implement non-blocking mode as well. */
}
if (i == MAXDESC)
{
-#ifdef HAVE_SOCKETS
if (fd_info[fd].flags & FILE_SOCKET)
{
-#ifndef SOCK_REPLACE_HANDLE
if (winsock_lib == NULL) abort ();
pfn_shutdown (SOCK_HANDLE (fd), 2);
rc = pfn_closesocket (SOCK_HANDLE (fd));
-#endif
+
winsock_inuse--; /* count open sockets */
}
-#endif
delete_child (cp);
}
}
return new_fd;
}
-
int
sys_dup2 (int src, int dst)
{
return STATUS_READ_ERROR;
}
}
-#ifdef HAVE_SOCKETS
else if (fd_info[fd].flags & FILE_SOCKET)
{
unsigned long nblock = 0;
pfn_ioctlsocket (SOCK_HANDLE (fd), FIONBIO, &nblock);
}
}
-#endif
if (rc == sizeof (char))
cp->status = STATUS_READ_SUCCEEDED;
nchars += rc;
}
}
-#ifdef HAVE_SOCKETS
else /* FILE_SOCKET */
{
if (winsock_lib == NULL) abort ();
int res = pfn_recv (SOCK_HANDLE (fd), buffer, count, 0);
if (res == SOCKET_ERROR)
{
- DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
- pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
+ DebPrint (("sys_read.recv failed with error %d on socket %ld\n",
+ pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
set_errno ();
return -1;
}
nchars += res;
}
}
-#endif
}
else
{
}
}
}
- else
-#ifdef HAVE_SOCKETS
- if (fd < MAXDESC && fd_info[fd].flags & FILE_SOCKET)
+ else if (fd < MAXDESC && fd_info[fd].flags & FILE_SOCKET)
{
unsigned long nblock = 0;
if (winsock_lib == NULL) abort ();
if (nchars == SOCKET_ERROR)
{
- DebPrint(("sys_write.send failed with error %d on socket %ld\n",
- pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
+ DebPrint (("sys_write.send failed with error %d on socket %ld\n",
+ pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
set_errno ();
}
}
else
-#endif
- nchars = _write (fd, buffer, count);
+ {
+ /* Some networked filesystems don't like too large writes, so
+ break them into smaller chunks. See the Comments section of
+ the MSDN documentation of WriteFile for details behind the
+ choice of the value of CHUNK below. See also the thread
+ http://thread.gmane.org/gmane.comp.version-control.git/145294
+ in the git mailing list. */
+ const unsigned char *p = buffer;
+ const unsigned chunk = 30 * 1024 * 1024;
+
+ nchars = 0;
+ while (count > 0)
+ {
+ unsigned this_chunk = count < chunk ? count : chunk;
+ int n = _write (fd, p, this_chunk);
+
+ nchars += n;
+ if (n < 0)
+ {
+ nchars = n;
+ break;
+ }
+ else if (n < this_chunk)
+ break;
+ count -= n;
+ p += n;
+ }
+ }
return nchars;
}
static void
-check_windows_init_file ()
+check_windows_init_file (void)
{
extern int noninteractive, inhibit_window_system;
}
void
-term_ntproc ()
+term_ntproc (void)
{
-#ifdef HAVE_SOCKETS
/* shutdown the socket interface if necessary */
term_winsock ();
-#endif
term_w32select ();
}
void
-init_ntproc ()
+init_ntproc (void)
{
-#ifdef HAVE_SOCKETS
/* Initialise 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
if (getenv ("PRELOAD_WINSOCK") != NULL)
init_winsock (TRUE);
-#endif
/* Initial preparation for subprocess support: replace our standard
handles with non-inheritable versions. */
shutdown_handler ensures that buffers' autosave files are
up to date when the user logs off, or the system shuts down.
*/
-BOOL WINAPI shutdown_handler(DWORD type)
+static BOOL WINAPI
+shutdown_handler (DWORD type)
{
/* Ctrl-C and Ctrl-Break are already suppressed, so don't handle them. */
if (type == CTRL_CLOSE_EVENT /* User closes console window. */
initialized is non zero (see the function main in emacs.c).
*/
void
-globals_of_w32 ()
+globals_of_w32 (void)
{
HMODULE kernel32 = GetModuleHandle ("kernel32.dll");
g_b_init_open_process_token = 0;
g_b_init_get_token_information = 0;
g_b_init_lookup_account_sid = 0;
- g_b_init_get_sid_identifier_authority = 0;
g_b_init_get_sid_sub_authority = 0;
g_b_init_get_sid_sub_authority_count = 0;
g_b_init_get_file_security = 0;
g_b_init_equal_sid = 0;
g_b_init_copy_sid = 0;
g_b_init_get_length_sid = 0;
+ g_b_init_get_native_system_info = 0;
+ g_b_init_get_system_times = 0;
+ num_of_processors = 0;
/* The following sets a handler for shutdown notifications for
console apps. This actually applies to Emacs in both console and
GUI modes, since we had to fool windows into thinking emacs is a
console application to get console mode to work. */
- SetConsoleCtrlHandler(shutdown_handler, TRUE);
+ SetConsoleCtrlHandler (shutdown_handler, TRUE);
/* "None" is the default group name on standalone workstations. */
strcpy (dflt_group_name, "None");
}
/* For make-serial-process */
-int serial_open (char *port)
+int
+serial_open (char *port)
{
HANDLE hnd;
child_process *cp;
/* For serial-process-configure */
void
-serial_configure (struct Lisp_Process *p,
- Lisp_Object contact)
+serial_configure (struct Lisp_Process *p, Lisp_Object contact)
{
Lisp_Object childp2 = Qnil;
Lisp_Object tem = Qnil;
/* end of w32.c */
-/* arch-tag: 90442dd3-37be-482b-b272-ac752e3049f1
- (do not change this comment) */