#include <grp.h>
/* MinGW64 defines these in its _mingw.h. */
-#if defined(__GNUC__) && !defined(MINGW_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
typedef HRESULT (WINAPI * ShGetFolderPath_fn)
(IN HWND, IN int, IN HANDLE, IN DWORD, OUT char *);
-Lisp_Object QCloaded_from;
-
void globals_of_w32 (void);
static DWORD get_rid (PSID);
static int is_symlink (const char *);
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
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)
/* 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)
/* 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;
}
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)
{
{
char *var;
size_t name_len;
- int retval;
if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
{
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
{"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
int ln;
strcpy (filename, dir_pathname);
- ln = strlen (filename) - 1;
- if (!IS_DIRECTORY_SEP (filename[ln]))
- strcat (filename, "\\");
- strcat (filename, "*");
+ ln = strlen (filename);
+ if (!IS_DIRECTORY_SEP (filename[ln - 1]))
+ filename[ln++] = '\\';
+ strcpy (filename + ln, "*");
/* Note: No need to resolve symlinks in FILENAME, because
FindFirst opens the directory that is the target of a
{
/* Make sure root directories end in a slash. */
if (!IS_DIRECTORY_SEP (name[len-1]))
- strcat (name, "\\");
+ strcpy (name + len, "\\");
if (GetDriveType (name) < 2)
{
errno = ENOENT;
p--;
if (p > linkfn)
strncpy (tem, linkfn, p - linkfn);
- tem[p - linkfn] = '\0';
- strcat (tem, filename);
+ strcpy (tem + (p - linkfn), filename);
dir_access = faccessat (AT_FDCWD, tem, D_OK, AT_EACCESS);
}
else
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;
+}
+
\f
/* Wrappers for winsock functions to map between our file descriptors
and winsock's handles; also set h_errno for convenience.
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
sys_write (int fd, const void * buffer, unsigned int count)
{
int nchars;
+ USE_SAFE_ALLOCA;
if (fd < 0)
{
/* 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;
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;
+ }
}
}
}
}
}
+ SAFE_FREE ();
return nchars;
}
/* 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;
}
}
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
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;