/* 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, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1994-1995, 2000-2011 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* 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>
_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"
#include "dispextern.h" /* for xstrcasecmp */
#include "coding.h" /* for Vlocale_coding_system */
+#include "careadlinkat.h"
+#include "allocator.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;
-extern Lisp_Object Vw32_generate_fake_inodes;
-extern Lisp_Object Vw32_get_true_file_attributes;
-/* Defined in process.c for its own purpose. */
-extern Lisp_Object Qlocal;
-
-extern int w32_num_mouse_buttons;
-
\f
/* Initialization states.
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;
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);
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)
{
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)
{
/* ** The wrapper functions ** */
-BOOL WINAPI
+static BOOL WINAPI
open_process_token (HANDLE ProcessHandle,
DWORD DesiredAccess,
PHANDLE TokenHandle)
);
}
-BOOL WINAPI
+static BOOL WINAPI
get_token_information (HANDLE TokenHandle,
TOKEN_INFORMATION_CLASS TokenInformationClass,
LPVOID TokenInformation,
);
}
-BOOL WINAPI
+static BOOL WINAPI
lookup_account_sid (LPCTSTR lpSystemName,
PSID Sid,
LPTSTR Name,
);
}
-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
+static PDWORD WINAPI
get_sid_sub_authority (PSID pSid, DWORD n)
{
static GetSidSubAuthority_Proc s_pfn_Get_Sid_Sub_Authority = NULL;
return (s_pfn_Get_Sid_Sub_Authority (pSid, n));
}
-PUCHAR WINAPI
+static PUCHAR WINAPI
get_sid_sub_authority_count (PSID pSid)
{
static GetSidSubAuthorityCount_Proc s_pfn_Get_Sid_Sub_Authority_Count = NULL;
return (s_pfn_Get_Sid_Sub_Authority_Count (pSid));
}
-BOOL WINAPI
+static BOOL WINAPI
get_file_security (LPCTSTR lpFileName,
SECURITY_INFORMATION RequestedInformation,
PSECURITY_DESCRIPTOR pSecurityDescriptor,
lpnLengthNeeded));
}
-BOOL WINAPI
+static BOOL WINAPI
get_security_descriptor_owner (PSECURITY_DESCRIPTOR pSecurityDescriptor,
PSID *pOwner,
LPBOOL lpbOwnerDefaulted)
lpbOwnerDefaulted));
}
-BOOL WINAPI
+static BOOL WINAPI
get_security_descriptor_group (PSECURITY_DESCRIPTOR pSecurityDescriptor,
PSID *pGroup,
LPBOOL lpbGroupDefaulted)
lpbGroupDefaulted));
}
-BOOL WINAPI
+static BOOL WINAPI
is_valid_sid (PSID sid)
{
static IsValidSid_Proc s_pfn_Is_Valid_Sid = NULL;
return (s_pfn_Is_Valid_Sid (sid));
}
-BOOL WINAPI
+static BOOL WINAPI
equal_sid (PSID sid1, PSID sid2)
{
static EqualSid_Proc s_pfn_Equal_Sid = NULL;
return (s_pfn_Equal_Sid (sid1, sid2));
}
-DWORD WINAPI
+static DWORD WINAPI
get_length_sid (PSID sid)
{
static GetLengthSid_Proc s_pfn_Get_Length_Sid = NULL;
return (s_pfn_Get_Length_Sid (sid));
}
-BOOL WINAPI
+static BOOL WINAPI
copy_sid (DWORD destlen, PSID dest, PSID src)
{
static CopySid_Proc s_pfn_Copy_Sid = NULL;
supported in Windows NT / 2k / XP
*/
-void WINAPI
+static void WINAPI
get_native_system_info (LPSYSTEM_INFO lpSystemInfo)
{
static GetNativeSystemInfo_Proc s_pfn_Get_Native_System_Info = NULL;
lpSystemInfo->dwNumberOfProcessors = -1;
}
-BOOL WINAPI
+static BOOL WINAPI
get_system_times (LPFILETIME lpIdleTime,
LPFILETIME lpKernelTime,
LPFILETIME lpUserTime)
#endif
}
-#ifndef HAVE_SOCKETS
-/* Emulate gethostname. */
-int
-gethostname (char *buffer, int size)
-{
- /* NT only allows small host names, so the buffer is
- certainly large enough. */
- return !GetComputerName (buffer, &size);
-}
-#endif /* HAVE_SOCKETS */
-
/* Emulate getloadavg. */
struct load_sample {
};
unsigned
-getuid ()
+getuid (void)
{
return dflt_passwd.pw_uid;
}
unsigned
-geteuid ()
+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
}
unsigned
-getgid ()
+getgid (void)
{
return dflt_passwd.pw_gid;
}
unsigned
-getegid ()
+getegid (void)
{
return getgid ();
}
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;
}
char *get_emacs_configuration (void);
-extern Lisp_Object Vsystem_configuration;
void
init_environment (char ** argv)
{"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
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)
- {
- 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. */
- ShGetFolderPath_fn get_folder_path;
- get_folder_path = (ShGetFolderPath_fn)
- GetProcAddress (GetModuleHandle ("shell32.dll"), "SHGetFolderPathA");
-
- if (get_folder_path != NULL)
- {
- profile_result = get_folder_path (NULL, CSIDL_APPDATA, NULL,
- 0, default_home);
+ {
+ 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. */
+ ShGetFolderPath_fn get_folder_path;
+ get_folder_path = (ShGetFolderPath_fn)
+ GetProcAddress (GetModuleHandle ("shell32.dll"), "SHGetFolderPathA");
+
+ if (get_folder_path != NULL)
+ {
+ profile_result = get_folder_path (NULL, CSIDL_APPDATA, NULL,
+ 0, default_home);
- /* If we can't get the appdata dir, revert to old behavior. */
- if (profile_result == S_OK)
- env_vars[0].def_value = default_home;
- }
- }
+ /* If we can't get the appdata dir, revert to old behavior. */
+ if (profile_result == S_OK)
+ env_vars[0].def_value = default_home;
+ }
+ }
/* Get default locale info and use it for LANG. */
if (GetLocaleInfo (LOCALE_USER_DEFAULT,
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], ':' };
info = lookup_volume_info (root_dir);
if (info == NULL || ! VOLINFO_STILL_VALID (root_dir, info))
- {
- char name[ 256 ];
- DWORD serialnum;
- DWORD maxcomp;
- DWORD flags;
- char type[ 256 ];
-
- /* Info is not cached, or is stale. */
- if (!GetVolumeInformation (root_dir,
- name, sizeof (name),
- &serialnum,
- &maxcomp,
- &flags,
- type, sizeof (type)))
- return NULL;
+ {
+ char name[ 256 ];
+ DWORD serialnum;
+ DWORD maxcomp;
+ DWORD flags;
+ char type[ 256 ];
+
+ /* Info is not cached, or is stale. */
+ if (!GetVolumeInformation (root_dir,
+ name, sizeof (name),
+ &serialnum,
+ &maxcomp,
+ &flags,
+ type, sizeof (type)))
+ return NULL;
- /* Cache the volume information for future use, overwriting existing
- entry if present. */
- if (info == NULL)
- {
- info = (volume_info_data *) xmalloc (sizeof (volume_info_data));
- add_volume_info (root_dir, info);
- }
- else
- {
- xfree (info->name);
- xfree (info->type);
- }
+ /* Cache the volume information for future use, overwriting existing
+ entry if present. */
+ if (info == NULL)
+ {
+ info = (volume_info_data *) xmalloc (sizeof (volume_info_data));
+ add_volume_info (root_dir, info);
+ }
+ else
+ {
+ xfree (info->name);
+ xfree (info->type);
+ }
- info->name = xstrdup (name);
- info->serialnum = serialnum;
- info->maxcomp = maxcomp;
- info->flags = flags;
- info->type = xstrdup (type);
- info->timestamp = GetTickCount ();
- }
+ info->name = xstrdup (name);
+ info->serialnum = serialnum;
+ info->maxcomp = maxcomp;
+ info->flags = flags;
+ info->type = xstrdup (type);
+ info->timestamp = GetTickCount ();
+ }
return info;
}
/* 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)
if (wnet_enum_handle != INVALID_HANDLE_VALUE)
{
if (!read_unc_volume (wnet_enum_handle,
- dir_find_data.cFileName,
- MAX_PATH))
+ dir_find_data.cFileName,
+ MAX_PATH))
return NULL;
}
/* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
return &dir_static;
}
-HANDLE
+static HANDLE
open_unc_volume (const char *path)
{
NETRESOURCE nr;
return INVALID_HANDLE_VALUE;
}
-char *
+static char *
read_unc_volume (HANDLE henum, char *readbuf, int size)
{
DWORD count;
count = 1;
buffer = alloca (bufsize);
- result = WNetEnumResource (wnet_enum_handle, &count, buffer, &bufsize);
+ result = WNetEnumResource (henum, &count, buffer, &bufsize);
if (result != NO_ERROR)
return NULL;
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;
} while (0)
static void
-initialize_utc_base ()
+initialize_utc_base (void)
{
/* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
SYSTEMTIME st;
return (time_t) ((tmp - utc_base) / 10000000L);
}
-
-void
+static void
convert_from_time_t (time_t time, FILETIME * pft)
{
ULARGE_INTEGER tmp;
stat (const char * path, struct stat * buf)
{
char *name, *r;
- char drive_root[4];
- UINT devtype;
WIN32_FIND_DATA wfd;
HANDLE fh;
unsigned __int64 fake_inode;
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;
return 0;
}
+\f
+/* Symlink-related functions that always fail. Used in fileio.c and in
+ sysdep.c to avoid #ifdef's. */
+int
+symlink (char const *dummy1, char const *dummy2)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+ssize_t
+readlink (const char *name, char *dummy1, size_t dummy2)
+{
+ /* `access' is much faster than `stat' on MS-Windows. */
+ if (sys_access (name, 0) == 0)
+ errno = EINVAL;
+ return -1;
+}
+
+char *
+careadlinkat (int fd, char const *filename,
+ char *buffer, size_t buffer_size,
+ struct allocator const *alloc,
+ ssize_t (*preadlinkat) (int, char const *, char *, size_t))
+{
+ errno = ENOSYS;
+ return NULL;
+}
+
+ssize_t
+careadlinkatcwd (int fd, char const *filename, char *buffer,
+ size_t buffer_size)
+{
+ (void) fd;
+ return readlink (filename, buffer, buffer_size);
+}
+
\f
/* Support for browsing other processes and their attributes. See
process.c for the Lisp bindings. */
/* Helper wrapper functions. */
-HANDLE WINAPI
+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
+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
+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
+static BOOL WINAPI
open_thread_token (HANDLE ThreadHandle,
DWORD DesiredAccess,
BOOL OpenAsSelf,
);
}
-BOOL WINAPI
+static BOOL WINAPI
impersonate_self (SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
{
static ImpersonateSelf_Proc s_pfn_Impersonate_Self = NULL;
return s_pfn_Impersonate_Self (ImpersonationLevel);
}
-BOOL WINAPI
+static BOOL WINAPI
revert_to_self (void)
{
static RevertToSelf_Proc s_pfn_Revert_To_Self = NULL;
return s_pfn_Revert_To_Self ();
}
-BOOL WINAPI
+static BOOL WINAPI
get_process_memory_info (HANDLE h_proc,
PPROCESS_MEMORY_COUNTERS mem_counters,
DWORD bufsize)
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
+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
+static BOOL WINAPI
global_memory_status_ex (MEMORY_STATUS_EX *buf)
{
static GlobalMemoryStatusEx_Proc s_pfn_Global_Memory_Status_Ex = NULL;
}
Lisp_Object
-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),
#define U64_TO_LISP_TIME(time) ltime ((time) / 1000000L, (time) % 1000000L)
static int
-process_times (h_proc, ctime, etime, stime, utime, ttime, pcpu)
- HANDLE h_proc;
- Lisp_Object *ctime, *etime, *stime, *utime, *ttime;
- 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;
ULONGLONG tem1, tem2, tem3, tem;
}
Lisp_Object
-system_process_attributes (pid)
- Lisp_Object pid;
+system_process_attributes (Lisp_Object pid)
{
struct gcpro gcpro1, gcpro2, gcpro3;
Lisp_Object attrs = Qnil;
TOKEN_PRIMARY_GROUP group_token;
unsigned euid;
unsigned egid;
- DWORD sess;
PROCESS_MEMORY_COUNTERS mem;
PROCESS_MEMORY_COUNTERS_EX mem_ex;
DWORD minrss, maxrss;
}
\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");
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);
int errnum;
char * msg;
} _wsa_errlist[] = {
- WSAEINTR , "Interrupted function call",
- WSAEBADF , "Bad file descriptor",
- WSAEACCES , "Permission denied",
- WSAEFAULT , "Bad address",
- WSAEINVAL , "Invalid argument",
- WSAEMFILE , "Too many open files",
-
- WSAEWOULDBLOCK , "Resource temporarily unavailable",
- WSAEINPROGRESS , "Operation now in progress",
- WSAEALREADY , "Operation already in progress",
- WSAENOTSOCK , "Socket operation on non-socket",
- WSAEDESTADDRREQ , "Destination address required",
- WSAEMSGSIZE , "Message too long",
- WSAEPROTOTYPE , "Protocol wrong type for socket",
- WSAENOPROTOOPT , "Bad protocol option",
- WSAEPROTONOSUPPORT , "Protocol not supported",
- WSAESOCKTNOSUPPORT , "Socket type not supported",
- WSAEOPNOTSUPP , "Operation not supported",
- WSAEPFNOSUPPORT , "Protocol family not supported",
- WSAEAFNOSUPPORT , "Address family not supported by protocol family",
- WSAEADDRINUSE , "Address already in use",
- WSAEADDRNOTAVAIL , "Cannot assign requested address",
- WSAENETDOWN , "Network is down",
- WSAENETUNREACH , "Network is unreachable",
- WSAENETRESET , "Network dropped connection on reset",
- WSAECONNABORTED , "Software caused connection abort",
- WSAECONNRESET , "Connection reset by peer",
- WSAENOBUFS , "No buffer space available",
- WSAEISCONN , "Socket is already connected",
- WSAENOTCONN , "Socket is not connected",
- WSAESHUTDOWN , "Cannot send after socket shutdown",
- WSAETOOMANYREFS , "Too many references", /* not sure */
- WSAETIMEDOUT , "Connection timed out",
- WSAECONNREFUSED , "Connection refused",
- WSAELOOP , "Network loop", /* not sure */
- WSAENAMETOOLONG , "Name is too long",
- WSAEHOSTDOWN , "Host is down",
- WSAEHOSTUNREACH , "No route to host",
- WSAENOTEMPTY , "Buffer not empty", /* not sure */
- WSAEPROCLIM , "Too many processes",
- WSAEUSERS , "Too many users", /* not sure */
- WSAEDQUOT , "Double quote in host name", /* really not sure */
- WSAESTALE , "Data is stale", /* not sure */
- WSAEREMOTE , "Remote error", /* not sure */
-
- WSASYSNOTREADY , "Network subsystem is unavailable",
- WSAVERNOTSUPPORTED , "WINSOCK.DLL version out of range",
- WSANOTINITIALISED , "Winsock not initialized successfully",
- WSAEDISCON , "Graceful shutdown in progress",
+ {WSAEINTR , "Interrupted function call"},
+ {WSAEBADF , "Bad file descriptor"},
+ {WSAEACCES , "Permission denied"},
+ {WSAEFAULT , "Bad address"},
+ {WSAEINVAL , "Invalid argument"},
+ {WSAEMFILE , "Too many open files"},
+
+ {WSAEWOULDBLOCK , "Resource temporarily unavailable"},
+ {WSAEINPROGRESS , "Operation now in progress"},
+ {WSAEALREADY , "Operation already in progress"},
+ {WSAENOTSOCK , "Socket operation on non-socket"},
+ {WSAEDESTADDRREQ , "Destination address required"},
+ {WSAEMSGSIZE , "Message too long"},
+ {WSAEPROTOTYPE , "Protocol wrong type for socket"},
+ {WSAENOPROTOOPT , "Bad protocol option"},
+ {WSAEPROTONOSUPPORT , "Protocol not supported"},
+ {WSAESOCKTNOSUPPORT , "Socket type not supported"},
+ {WSAEOPNOTSUPP , "Operation not supported"},
+ {WSAEPFNOSUPPORT , "Protocol family not supported"},
+ {WSAEAFNOSUPPORT , "Address family not supported by protocol family"},
+ {WSAEADDRINUSE , "Address already in use"},
+ {WSAEADDRNOTAVAIL , "Cannot assign requested address"},
+ {WSAENETDOWN , "Network is down"},
+ {WSAENETUNREACH , "Network is unreachable"},
+ {WSAENETRESET , "Network dropped connection on reset"},
+ {WSAECONNABORTED , "Software caused connection abort"},
+ {WSAECONNRESET , "Connection reset by peer"},
+ {WSAENOBUFS , "No buffer space available"},
+ {WSAEISCONN , "Socket is already connected"},
+ {WSAENOTCONN , "Socket is not connected"},
+ {WSAESHUTDOWN , "Cannot send after socket shutdown"},
+ {WSAETOOMANYREFS , "Too many references"}, /* not sure */
+ {WSAETIMEDOUT , "Connection timed out"},
+ {WSAECONNREFUSED , "Connection refused"},
+ {WSAELOOP , "Network loop"}, /* not sure */
+ {WSAENAMETOOLONG , "Name is too long"},
+ {WSAEHOSTDOWN , "Host is down"},
+ {WSAEHOSTUNREACH , "No route to host"},
+ {WSAENOTEMPTY , "Buffer not empty"}, /* not sure */
+ {WSAEPROCLIM , "Too many processes"},
+ {WSAEUSERS , "Too many users"}, /* not sure */
+ {WSAEDQUOT , "Double quote in host name"}, /* really not sure */
+ {WSAESTALE , "Data is stale"}, /* not sure */
+ {WSAEREMOTE , "Remote error"}, /* not sure */
+
+ {WSASYSNOTREADY , "Network subsystem is unavailable"},
+ {WSAVERNOTSUPPORTED , "WINSOCK.DLL version out of range"},
+ {WSANOTINITIALISED , "Winsock not initialized successfully"},
+ {WSAEDISCON , "Graceful shutdown in progress"},
#ifdef WSAENOMORE
- WSAENOMORE , "No more operations allowed", /* not sure */
- WSAECANCELLED , "Operation cancelled", /* not sure */
- WSAEINVALIDPROCTABLE , "Invalid procedure table from service provider",
- WSAEINVALIDPROVIDER , "Invalid service provider version number",
- WSAEPROVIDERFAILEDINIT , "Unable to initialize a service provider",
- WSASYSCALLFAILURE , "System call failure",
- WSASERVICE_NOT_FOUND , "Service not found", /* not sure */
- WSATYPE_NOT_FOUND , "Class type not found",
- WSA_E_NO_MORE , "No more resources available", /* really not sure */
- WSA_E_CANCELLED , "Operation already cancelled", /* really not sure */
- WSAEREFUSED , "Operation refused", /* not sure */
+ {WSAENOMORE , "No more operations allowed"}, /* not sure */
+ {WSAECANCELLED , "Operation cancelled"}, /* not sure */
+ {WSAEINVALIDPROCTABLE , "Invalid procedure table from service provider"},
+ {WSAEINVALIDPROVIDER , "Invalid service provider version number"},
+ {WSAEPROVIDERFAILEDINIT , "Unable to initialize a service provider"},
+ {WSASYSCALLFAILURE , "System call failure"},
+ {WSASERVICE_NOT_FOUND , "Service not found"}, /* not sure */
+ {WSATYPE_NOT_FOUND , "Class type not found"},
+ {WSA_E_NO_MORE , "No more resources available"}, /* really not sure */
+ {WSA_E_CANCELLED , "Operation already cancelled"}, /* really not sure */
+ {WSAEREFUSED , "Operation refused"}, /* not sure */
#endif
- WSAHOST_NOT_FOUND , "Host not found",
- WSATRY_AGAIN , "Authoritative host not found during name lookup",
- WSANO_RECOVERY , "Non-recoverable error during name lookup",
- WSANO_DATA , "Valid name, no data record of requested type",
+ {WSAHOST_NOT_FOUND , "Host not found"},
+ {WSATRY_AGAIN , "Authoritative host not found during name lookup"},
+ {WSANO_RECOVERY , "Non-recoverable error during name lookup"},
+ {WSANO_DATA , "Valid name, no data record of requested type"},
- -1, NULL
+ {-1, NULL}
};
char *
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)
}
/* 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)
{
return SOCKET_ERROR;
}
-
int
sys_shutdown (int s, int how)
{
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 rc;
}
-/* From ntproc.c */
-extern int w32_pipe_read_delay;
-
/* Function to do blocking read of one byte, needed to implement
select. It is only allowed on sockets and pipes. */
int
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;
{
HANDLE hnd = fd_info[fd].hnd;
OVERLAPPED *ovl = &fd_info[fd].cp->ovl_read;
- DWORD err = 0;
int rc = 0;
COMMTIMEOUTS ct;
nchars += rc;
}
}
-#ifdef HAVE_SOCKETS
else /* FILE_SOCKET */
{
if (winsock_lib == NULL) abort ();
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 ();
}
}
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;
-
/* A common indication that Emacs is not installed properly is when
it cannot find the Windows installation file. If this file does
not exist in the expected place, tell the user. */
if (!noninteractive && !inhibit_window_system)
{
- extern Lisp_Object Vwindow_system, Vload_path, Qfile_exists_p;
Lisp_Object objs[2];
Lisp_Object full_load_path;
Lisp_Object init_file;
}
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
+static BOOL WINAPI
shutdown_handler (DWORD type)
{
/* Ctrl-C and Ctrl-Break are already suppressed, so don't handle them. */
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;
/* end of w32.c */
-/* arch-tag: 90442dd3-37be-482b-b272-ac752e3049f1
- (do not change this comment) */