#include <sys/file.h>
#include <sys/time.h>
#include <sys/utime.h>
-#include <mbstring.h> /* for _mbspbrk */
#include <math.h>
#include <time.h>
/* must include CRT headers *before* config.h */
#include <config.h>
+#include <mbstring.h> /* for _mbspbrk */
#undef access
#undef chdir
#include "w32.h"
#include "ndir.h"
+#include "w32common.h"
#include "w32heap.h"
+#include "w32select.h"
#include "systime.h"
#include "dispextern.h" /* for xstrcasecmp */
#include "coding.h" /* for Vlocale_coding_system */
static int restore_privilege (TOKEN_PRIVILEGES *);
static BOOL WINAPI revert_to_self (void);
+extern int sys_access (const char *, int);
+extern void *e_malloc (size_t);
+extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
+ EMACS_TIME *, void *);
+
+
\f
/* Initialization states.
return retval;
}
\f
-/* Equivalent of strerror for W32 error codes. */
-char *
-w32_strerror (int error_no)
-{
- static char buf[500];
-
- if (error_no == 0)
- error_no = GetLastError ();
-
- buf[0] = '\0';
- if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL,
- error_no,
- 0, /* choose most suitable language */
- buf, sizeof (buf), NULL))
- sprintf (buf, "w32 error %u", error_no);
- return buf;
-}
/* Return 1 if P is a valid pointer to an object of size SIZE. Return
0 if P is NOT a valid pointer. Return -1 if we cannot validate P.
return 1;
}
-/* Routines that are no-ops on NT but are defined to get Emacs to compile. */
-int
-sigemptyset (sigset_t *set)
-{
- *set = 0;
- 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
-pthread_sigmask (int how, const sigset_t *set, sigset_t *oset)
-{
- if (sigprocmask (how, set, oset) == -1)
- return EINVAL;
- return 0;
-}
-
-int
-setpgrp (int pid, int gid)
-{
- return 0;
-}
-
-int
-alarm (int seconds)
-{
- return 0;
-}
-
#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
LPBYTE
see if it succeeds. But I think that's too much to ask. */
/* MSVCRT's _access crashes with D_OK. */
- if (tmp && sys_access (tmp, D_OK) == 0)
+ if (tmp && faccessat (AT_FDCWD, tmp, D_OK, AT_EACCESS) == 0)
{
char * var = alloca (strlen (tmp) + 8);
sprintf (var, "TMPDIR=%s", tmp);
LPBYTE lpval;
DWORD dwType;
char locale_name[32];
- struct stat ignored;
char default_home[MAX_PATH];
int appdata = 0;
/* For backwards compatibility, check if a .emacs file exists in C:/
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)
+ if (!check_existing ("C:/.emacs"))
{
HRESULT profile_result;
/* Dynamically load ShGetFolderPath, as it won't exist on versions
/* FIXME: should use substring of get_emacs_configuration ().
But I don't think the Windows build supports alpha, mips etc
anymore, so have taken the easy option for now. */
- else if (p && xstrcasecmp (p, "\\i386") == 0)
+ else if (p && (xstrcasecmp (p, "\\i386") == 0
+ || xstrcasecmp (p, "\\AMD64") == 0))
{
*p = 0;
p = strrchr (modname, '\\');
case PROCESSOR_INTEL_386:
case PROCESSOR_INTEL_486:
case PROCESSOR_INTEL_PENTIUM:
+#ifdef _WIN64
+ arch = "amd64";
+#else
arch = "i386";
+#endif
+ break;
+#endif
+#ifdef PROCESSOR_AMD_X8664
+ case PROCESSOR_AMD_X8664:
+ arch = "amd64";
break;
#endif
WNetAddConnection2 (&resource, NULL, NULL, CONNECT_INTERACTIVE);
}
-/* Shadow some MSVC runtime functions to map requests for long filenames
- to reasonable short names if necessary. This was originally added to
- permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
- long file names. */
-
+/* Emulate faccessat(2). */
int
-sys_access (const char * path, int mode)
+faccessat (int dirfd, const char * path, int mode, int flags)
{
DWORD attributes;
+ if (dirfd != AT_FDCWD
+ && !(IS_DIRECTORY_SEP (path[0])
+ || IS_DEVICE_SEP (path[1])))
+ {
+ errno = EBADF;
+ return -1;
+ }
+
/* MSVCRT implementation of 'access' doesn't recognize D_OK, and its
newer versions blow up when passed D_OK. */
path = map_w32_filename (path, NULL);
to get the attributes of its target file. Note: any symlinks in
PATH elements other than the last one are transparently resolved
by GetFileAttributes below. */
- if ((volume_info.flags & FILE_SUPPORTS_REPARSE_POINTS) != 0)
+ if ((volume_info.flags & FILE_SUPPORTS_REPARSE_POINTS) != 0
+ && (flags & AT_SYMLINK_NOFOLLOW) == 0)
path = chase_symlinks (path);
if ((attributes = GetFileAttributes (path)) == -1)
}
return -1;
}
- if ((mode & X_OK) != 0 && !is_exec (path))
+ if ((mode & X_OK) != 0
+ && !(is_exec (path) || (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0))
{
errno = EACCES;
return -1;
return 0;
}
+/* Shadow some MSVC runtime functions to map requests for long filenames
+ to reasonable short names if necessary. This was originally added to
+ permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
+ long file names. */
+
int
sys_chdir (const char * path)
{
{
int save_errno = errno;
p[0] = first_char[i];
- if (sys_access (template, 0) < 0)
+ if (faccessat (AT_FDCWD, template, F_OK, AT_EACCESS) < 0)
{
errno = save_errno;
return template;
}
/* Need write access to set times. */
- fh = CreateFile (name, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
- 0, OPEN_EXISTING, 0, NULL);
- if (fh)
+ fh = CreateFile (name, FILE_WRITE_ATTRIBUTES,
+ /* If NAME specifies a directory, FILE_SHARE_DELETE
+ allows other processes to delete files inside it,
+ while we have the directory open. */
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (fh != INVALID_HANDLE_VALUE)
{
convert_from_time_t (times->actime, &atime);
convert_from_time_t (times->modtime, &mtime);
{
/* Non-absolute FILENAME is understood as being relative to
LINKNAME's directory. We need to prepend that directory to
- FILENAME to get correct results from sys_access below, since
+ FILENAME to get correct results from faccessat below, since
otherwise it will interpret FILENAME relative to the
directory where the Emacs process runs. Note that
make-symbolic-link always makes sure LINKNAME is a fully
strncpy (tem, linkfn, p - linkfn);
tem[p - linkfn] = '\0';
strcat (tem, filename);
- dir_access = sys_access (tem, D_OK);
+ dir_access = faccessat (AT_FDCWD, tem, D_OK, AT_EACCESS);
}
else
- dir_access = sys_access (filename, D_OK);
+ dir_access = faccessat (AT_FDCWD, filename, D_OK, AT_EACCESS);
/* Since Windows distinguishes between symlinks to directories and
to files, we provide a kludgy feature: if FILENAME doesn't
check_errno ();
if (fd_info[s].flags & FILE_SOCKET)
{
- if (cmd == F_SETFL && options == O_NDELAY)
+ if (cmd == F_SETFL && options == O_NONBLOCK)
{
unsigned long nblock = 1;
int rc = pfn_ioctlsocket (SOCK_HANDLE (s), FIONBIO, &nblock);
\f
-/* Delayed loading of libraries. */
-
-Lisp_Object Vlibrary_cache;
-
/* Try loading LIBRARY_ID from the file(s) specified in
Vdynamic_library_alist. If the library is loaded successfully,
return the handle of the DLL, and record the filename in the
term_ntproc (int ignored)
{
(void)ignored;
+
+ term_timers ();
+
/* shutdown the socket interface if necessary */
term_winsock ();
void
init_ntproc (int dumping)
{
+ sigset_t initial_mask = 0;
+
/* Initialize 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
fclose (stderr);
if (stdin_save != INVALID_HANDLE_VALUE)
- _open_osfhandle ((long) stdin_save, O_TEXT);
+ _open_osfhandle ((intptr_t) stdin_save, O_TEXT);
else
_open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY);
_fdopen (0, "r");
if (stdout_save != INVALID_HANDLE_VALUE)
- _open_osfhandle ((long) stdout_save, O_TEXT);
+ _open_osfhandle ((intptr_t) stdout_save, O_TEXT);
else
_open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
_fdopen (1, "w");
if (stderr_save != INVALID_HANDLE_VALUE)
- _open_osfhandle ((long) stderr_save, O_TEXT);
+ _open_osfhandle ((intptr_t) stderr_save, O_TEXT);
else
_open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
_fdopen (2, "w");
/* unfortunately, atexit depends on implementation of malloc */
/* atexit (term_ntproc); */
if (!dumping)
- signal (SIGABRT, term_ntproc);
+ {
+ /* Make sure we start with all signals unblocked. */
+ sigprocmask (SIG_SETMASK, &initial_mask, NULL);
+ signal (SIGABRT, term_ntproc);
+ }
+ init_timers ();
/* determine which drives are fixed, for GetCachedVolumeInformation */
{
DEFSYM (QCloaded_from, ":loaded-from");
- Vlibrary_cache = Qnil;
- staticpro (&Vlibrary_cache);
-
g_b_init_is_windows_9x = 0;
g_b_init_open_process_token = 0;
g_b_init_get_token_information = 0;
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (hnd == INVALID_HANDLE_VALUE)
error ("Could not open %s", port);
- fd = (int) _open_osfhandle ((int) hnd, 0);
+ fd = (int) _open_osfhandle ((intptr_t) hnd, 0);
if (fd == -1)
error ("Could not open %s", port);
{
int n, sc, err;
SELECT_TYPE fdset;
- struct timeval timeout;
+ EMACS_TIME timeout;
struct Lisp_Process *process = (struct Lisp_Process *)p;
int fd = process->infd;
if (err == EWOULDBLOCK)
{
/* Set a small timeout. */
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
+ timeout = make_emacs_time (1, 0);
FD_ZERO (&fdset);
FD_SET ((int)fd, &fdset);