diff options
Diffstat (limited to 'src/w32.c')
-rw-r--r-- | src/w32.c | 130 |
1 files changed, 93 insertions, 37 deletions
diff --git a/src/w32.c b/src/w32.c index aba0b5a81f9..f014cd73a76 100644 --- a/src/w32.c +++ b/src/w32.c @@ -73,9 +73,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <grp.h> /* MinGW64 (_W64) defines these in its _mingw.h. */ -#if defined(__GNUC__) && !defined(_W64) -#define _ANONYMOUS_UNION -#define _ANONYMOUS_STRUCT +#ifndef _ANONYMOUS_UNION +# define _ANONYMOUS_UNION +#endif +#ifndef _ANONYMOUS_STRUCT +# define _ANONYMOUS_STRUCT #endif #include <windows.h> /* Some versions of compiler define MEMORYSTATUSEX, some don't, so we @@ -307,6 +309,8 @@ static BOOL g_b_init_set_named_security_info_w; static BOOL g_b_init_set_named_security_info_a; static BOOL g_b_init_get_adapters_info; +BOOL g_b_init_compare_string_w; + /* BEGIN: Wrapper functions around OpenProcessToken and other functions in advapi32.dll that are only @@ -880,7 +884,7 @@ set_named_security_info (LPCTSTR lpObjectName, g_b_init_set_named_security_info_a = 1; hm_advapi32 = LoadLibrary ("Advapi32.dll"); s_pfn_Set_Named_Security_InfoA = - (SetNamedSecurityInfoA_Proc) GetProcAddress (hm_advapi32, + (SetNamedSecurityInfoA_Proc) GetProcAddress (hm_advapi32, "SetNamedSecurityInfoA"); } if (s_pfn_Set_Named_Security_InfoA == NULL) @@ -1707,7 +1711,7 @@ 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 max_idx = ARRAYELTS (samples); static int buf_next (int from) @@ -2290,7 +2294,7 @@ get_long_basename (char * name, char * buf, int size) /* Get long name for file, if possible (assumed to be absolute). */ BOOL -w32_get_long_filename (char * name, char * buf, int size) +w32_get_long_filename (const char * name, char * buf, int size) { char * o = buf; char * p; @@ -2341,7 +2345,7 @@ w32_get_long_filename (char * name, char * buf, int size) } unsigned int -w32_get_short_filename (char * name, char * buf, int size) +w32_get_short_filename (const char * name, char * buf, int size) { if (w32_unicode_filenames) { @@ -2415,7 +2419,6 @@ unsetenv (const char *name) { char *var; size_t name_len; - int retval; if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) { @@ -2514,7 +2517,7 @@ init_environment (char ** argv) int i; - const int imax = sizeof (tempdirs) / sizeof (tempdirs[0]); + const int imax = ARRAYELTS (tempdirs); /* Implementation note: This function explicitly works with ANSI file names, not with UTF-8 encoded file names. This is because @@ -2587,7 +2590,7 @@ init_environment (char ** argv) {"LANG", NULL}, }; -#define N_ENV_VARS sizeof (dflt_envvars)/sizeof (dflt_envvars[0]) +#define N_ENV_VARS ARRAYELTS (dflt_envvars) /* We need to copy dflt_envvars[] and work on the copy because we don't want the dumped Emacs to inherit the values of @@ -6956,6 +6959,35 @@ system_process_attributes (Lisp_Object pid) return attrs; } +int +w32_memory_info (unsigned long long *totalram, unsigned long long *freeram, + unsigned long long *totalswap, unsigned long long *freeswap) +{ + MEMORYSTATUS memst; + MEMORY_STATUS_EX memstex; + + /* Use GlobalMemoryStatusEx if available, as it can report more than + 2GB of memory. */ + if (global_memory_status_ex (&memstex)) + { + *totalram = memstex.ullTotalPhys; + *freeram = memstex.ullAvailPhys; + *totalswap = memstex.ullTotalPageFile; + *freeswap = memstex.ullAvailPageFile; + return 0; + } + else if (global_memory_status (&memst)) + { + *totalram = memst.dwTotalPhys; + *freeram = memst.dwAvailPhys; + *totalswap = memst.dwTotalPageFile; + *freeswap = memst.dwAvailPageFile; + return 0; + } + else + return -1; +} + /* Wrappers for winsock functions to map between our file descriptors and winsock's handles; also set h_errno for convenience. @@ -7860,7 +7892,7 @@ pipe2 (int * phandles, int pipe2_flags) int rc; unsigned flags; - eassert (pipe2_flags == O_CLOEXEC); + eassert (pipe2_flags == (O_BINARY | O_CLOEXEC)); /* make pipe handles non-inheritable; when we spawn a child, we replace the relevant handle with an inheritable one. Also put @@ -8233,6 +8265,7 @@ int sys_write (int fd, const void * buffer, unsigned int count) { int nchars; + USE_SAFE_ALLOCA; if (fd < 0) { @@ -8251,30 +8284,33 @@ sys_write (int fd, const void * buffer, unsigned int count) /* Perform text mode translation if required. */ if ((fd_info[fd].flags & FILE_BINARY) == 0) { - char * tmpbuf = alloca (count * 2); - unsigned char * src = (void *)buffer; - unsigned char * dst = tmpbuf; + char * tmpbuf; + const unsigned char * src = buffer; + unsigned char * dst; int nbytes = count; + SAFE_NALLOCA (tmpbuf, 2, count); + dst = tmpbuf; + while (1) { unsigned char *next; - /* copy next line or remaining bytes */ + /* Copy next line or remaining bytes. */ next = _memccpy (dst, src, '\n', nbytes); if (next) { - /* copied one line ending with '\n' */ + /* Copied one line ending with '\n'. */ int copied = next - dst; nbytes -= copied; src += copied; - /* insert '\r' before '\n' */ + /* Insert '\r' before '\n'. */ next[-1] = '\r'; next[0] = '\n'; dst = next + 1; count++; } else - /* copied remaining partial line -> now finished */ + /* Copied remaining partial line -> now finished. */ break; } buffer = tmpbuf; @@ -8288,31 +8324,44 @@ sys_write (int fd, const void * buffer, unsigned int count) HANDLE wait_hnd[2] = { interrupt_handle, ovl->hEvent }; DWORD active = 0; + /* This is async (a.k.a. "overlapped") I/O, so the return value + of FALSE from WriteFile means either an error or the output + will be completed asynchronously (ERROR_IO_PENDING). */ if (!WriteFile (hnd, buffer, count, (DWORD*) &nchars, ovl)) { if (GetLastError () != ERROR_IO_PENDING) { errno = EIO; - return -1; + nchars = -1; } - if (detect_input_pending ()) - active = MsgWaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE, - QS_ALLINPUT); else - active = WaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE); - if (active == WAIT_OBJECT_0) - { /* User pressed C-g, cancel write, then leave. Don't bother - cleaning up as we may only get stuck in buggy drivers. */ - PurgeComm (hnd, PURGE_TXABORT | PURGE_TXCLEAR); - CancelIo (hnd); - errno = EIO; - return -1; - } - if (active == WAIT_OBJECT_0 + 1 - && !GetOverlappedResult (hnd, ovl, (DWORD*) &nchars, TRUE)) { - errno = EIO; - return -1; + /* Wait for the write to complete, and watch C-g while + at that. */ + if (detect_input_pending ()) + active = MsgWaitForMultipleObjects (2, wait_hnd, FALSE, + INFINITE, QS_ALLINPUT); + else + active = WaitForMultipleObjects (2, wait_hnd, FALSE, INFINITE); + switch (active) + { + case WAIT_OBJECT_0: + /* User pressed C-g, cancel write, then leave. + Don't bother cleaning up as we may only get stuck + in buggy drivers. */ + PurgeComm (hnd, PURGE_TXABORT | PURGE_TXCLEAR); + CancelIo (hnd); + errno = EIO; /* Why not EINTR? */ + nchars = -1; + break; + case WAIT_OBJECT_0 + 1: + if (!GetOverlappedResult (hnd, ovl, (DWORD*) &nchars, TRUE)) + { + errno = EIO; + nchars = -1; + } + break; + } } } } @@ -8389,6 +8438,7 @@ sys_write (int fd, const void * buffer, unsigned int count) } } + SAFE_FREE (); return nchars; } @@ -8738,6 +8788,13 @@ w32_delayed_load (Lisp_Object library_id) /* Possibly truncated */ ? make_specified_string (name, -1, len, 1) : Qnil); + /* This prevents thread start and end notifications + from being sent to the DLL, for every thread we + start. We don't need those notifications because + threads we create never use any of these DLLs, only + the main thread uses them. This is supposed to + speed up thread creation. */ + DisableThreadLibraryCalls (dll_handle); break; } } @@ -9071,6 +9128,7 @@ globals_of_w32 (void) g_b_init_set_named_security_info_w = 0; g_b_init_set_named_security_info_a = 0; g_b_init_get_adapters_info = 0; + g_b_init_compare_string_w = 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 @@ -9290,8 +9348,6 @@ ssize_t emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz) { int n, err; - SELECT_TYPE fdset; - struct timespec timeout; struct Lisp_Process *process = (struct Lisp_Process *)p; int fd = process->infd; |