X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/16b22fef423afedf034460a0f811abf50d0c5f3e..49cdacdad393e2b9282a19a963030dfbe1a738ab:/src/w32.c diff --git a/src/w32.c b/src/w32.c index f7e1635479..94cf472a4a 100644 --- a/src/w32.c +++ b/src/w32.c @@ -31,13 +31,13 @@ along with GNU Emacs. If not, see . */ #include #include #include -#include /* for _mbspbrk */ #include #include /* must include CRT headers *before* config.h */ #include +#include /* for _mbspbrk */ #undef access #undef chdir @@ -173,7 +173,9 @@ typedef struct _REPARSE_DATA_BUFFER { #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 */ @@ -197,6 +199,12 @@ static int enable_privilege (LPCTSTR, BOOL, TOKEN_PRIVILEGES *); 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 *); + + /* Initialization states. @@ -866,23 +874,6 @@ create_symbolic_link (LPTSTR lpSymlinkFilename, return retval; } -/* 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. @@ -1528,52 +1519,6 @@ is_unc_volume (const char *filename) 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 @@ -1652,7 +1597,7 @@ init_environment (char ** argv) 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); @@ -1674,7 +1619,6 @@ init_environment (char ** argv) LPBYTE lpval; DWORD dwType; char locale_name[32]; - struct stat ignored; char default_home[MAX_PATH]; int appdata = 0; @@ -1715,7 +1659,7 @@ init_environment (char ** argv) /* 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 @@ -1784,7 +1728,8 @@ init_environment (char ** argv) /* 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, '\\'); @@ -1932,7 +1877,16 @@ get_emacs_configuration (void) 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 @@ -2754,16 +2708,20 @@ logon_network_drive (const char *path) 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); @@ -2771,7 +2729,8 @@ sys_access (const char * path, int mode) 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) @@ -2803,7 +2762,8 @@ sys_access (const char * path, int mode) } 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; @@ -2821,6 +2781,11 @@ sys_access (const char * path, int mode) 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) { @@ -3006,7 +2971,7 @@ sys_mktemp (char * template) { 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; @@ -3988,9 +3953,13 @@ utime (const char *name, struct utimbuf *times) } /* 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); @@ -4053,7 +4022,7 @@ symlink (char const *filename, char const *linkname) { /* 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 @@ -4067,10 +4036,10 @@ symlink (char const *filename, char const *linkname) 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 @@ -5885,7 +5854,7 @@ fcntl (int s, int cmd, int options) 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); @@ -6521,10 +6490,6 @@ sys_localtime (const time_t *t) -/* 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 @@ -6627,6 +6592,9 @@ void term_ntproc (int ignored) { (void)ignored; + + term_timers (); + /* shutdown the socket interface if necessary */ term_winsock (); @@ -6636,6 +6604,8 @@ term_ntproc (int ignored) 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 @@ -6691,19 +6661,19 @@ init_ntproc (int dumping) 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"); @@ -6712,7 +6682,12 @@ init_ntproc (int dumping) /* 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 */ { @@ -6769,9 +6744,6 @@ globals_of_w32 (void) 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; @@ -6822,7 +6794,7 @@ serial_open (char *port) 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); @@ -7007,7 +6979,7 @@ emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz) { 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; @@ -7023,8 +6995,7 @@ emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz) 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);