#include <ctype.h>
#include <signal.h>
#include <sys/file.h>
+#include <time.h> /* must be before nt/inc/sys/time.h, for MinGW64 */
#include <sys/time.h>
#include <sys/utime.h>
#include <math.h>
-#include <time.h>
/* must include CRT headers *before* config.h */
#include <pwd.h>
#include <grp.h>
-#ifdef __GNUC__
+/* MinGW64 (_W64) defines these in its _mingw.h. */
+#if defined(__GNUC__) && !defined(_W64)
#define _ANONYMOUS_UNION
#define _ANONYMOUS_STRUCT
#endif
#ifndef _MSC_VER
#include <w32api.h>
#endif
+#if _WIN32_WINNT < 0x0500
#if !defined (__MINGW32__) || __W32API_MAJOR_VERSION < 3 || (__W32API_MAJOR_VERSION == 3 && __W32API_MINOR_VERSION < 15)
/* This either is not in psapi.h or guarded by higher value of
_WIN32_WINNT than what we use. w32api supplied with MinGW 3.15
SIZE_T PrivateUsage;
} PROCESS_MEMORY_COUNTERS_EX,*PPROCESS_MEMORY_COUNTERS_EX;
#endif
+#endif
#include <winioctl.h>
#include <aclapi.h>
#define SDDL_REVISION_1 1
#endif /* SDDL_REVISION_1 */
-#ifdef _MSC_VER
-/* MSVC doesn't provide the definition of REPARSE_DATA_BUFFER and the
- associated macros, except on ntifs.h, which cannot be included
- because it triggers conflicts with other Windows API headers. So
- we define it here by hand. */
+#if defined(_MSC_VER) || defined(_W64)
+/* MSVC and MinGW64 don't provide the definition of
+ REPARSE_DATA_BUFFER and the associated macros, except on ntifs.h,
+ which cannot be included because it triggers conflicts with other
+ Windows API headers. So we define it here by hand. */
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
#ifndef CTL_CODE
#define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m))
#endif
+/* MinGW64 defines FSCTL_GET_REPARSE_POINT on winioctl.h. */
+#ifndef FSCTL_GET_REPARSE_POINT
#define FSCTL_GET_REPARSE_POINT \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
#endif
+#endif
/* TCP connection support. */
#include <sys/socket.h>
return _chmod (path, mode);
}
-int
-sys_chown (const char *path, uid_t owner, gid_t group)
-{
- if (sys_chmod (path, S_IREAD) == -1) /* check if file exists */
- return -1;
- return 0;
-}
-
int
sys_creat (const char * path, int mode)
{
sys_open (const char * path, int oflag, int mode)
{
const char* mpath = map_w32_filename (path, NULL);
- /* Try to open file without _O_CREAT, to be able to write to hidden
- and system files. Force all file handles to be
- non-inheritable. */
- int res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode);
+ int res = -1;
+
+ /* If possible, try to open file without _O_CREAT, to be able to
+ write to existing hidden and system files. Force all file
+ handles to be non-inheritable. */
+ if ((oflag & (_O_CREAT | _O_EXCL)) != (_O_CREAT | _O_EXCL))
+ res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode);
if (res < 0)
res = _open (mpath, oflag | _O_NOINHERIT, mode);
- if (res >= 0 && res < MAXDESC)
- fd_info[res].flags = 0;
return res;
}
int
-sys_rename (const char * oldname, const char * newname)
+fchmod (int fd, mode_t mode)
+{
+ return 0;
+}
+
+int
+sys_rename_replace (const char *oldname, const char *newname, BOOL force)
{
BOOL result;
char temp[MAX_PATH];
return -1;
}
- /* Emulate Unix behavior - newname is deleted if it already exists
+ /* If FORCE, emulate Unix behavior - newname is deleted if it already exists
(at least if it is a file; don't do this for directories).
Since we mustn't do this if we are just changing the case of the
result = rename (temp, newname);
- if (result < 0)
+ if (result < 0 && force)
{
DWORD w32err = GetLastError ();
return result;
}
+int
+sys_rename (char const *old, char const *new)
+{
+ return sys_rename_replace (old, new, TRUE);
+}
+
int
sys_rmdir (const char * path)
{
{
ULONGLONG time_sec = time_100ns / 10000000;
int subsec = time_100ns % 10000000;
- return list4 (make_number (time_sec >> 16),
- make_number (time_sec & 0xffff),
- make_number (subsec / 10),
- make_number (subsec % 10 * 100000));
+ return list4i (time_sec >> 16, time_sec & 0xffff,
+ subsec / 10, subsec % 10 * 100000);
}
#define U64_TO_LISP_TIME(time) ltime (time)
int h_errno = 0;
-/* function to set h_errno for compatibility; map winsock error codes to
- normal system codes where they overlap (non-overlapping definitions
- are already in <sys/socket.h> */
+/* Function to map winsock error codes to errno codes for those errno
+ code defined in errno.h (errno values not defined by errno.h are
+ already in nt/inc/sys/socket.h). */
static void
set_errno (void)
{
+ int wsa_err;
+
+ h_errno = 0;
if (winsock_lib == NULL)
- h_errno = EINVAL;
+ wsa_err = EINVAL;
else
- h_errno = pfn_WSAGetLastError ();
+ wsa_err = pfn_WSAGetLastError ();
- switch (h_errno)
+ switch (wsa_err)
{
- case WSAEACCES: h_errno = EACCES; break;
- case WSAEBADF: h_errno = EBADF; break;
- case WSAEFAULT: h_errno = EFAULT; break;
- case WSAEINTR: h_errno = EINTR; break;
- case WSAEINVAL: h_errno = EINVAL; break;
- case WSAEMFILE: h_errno = EMFILE; break;
- case WSAENAMETOOLONG: h_errno = ENAMETOOLONG; break;
- case WSAENOTEMPTY: h_errno = ENOTEMPTY; break;
+ case WSAEACCES: errno = EACCES; break;
+ case WSAEBADF: errno = EBADF; break;
+ case WSAEFAULT: errno = EFAULT; break;
+ case WSAEINTR: errno = EINTR; break;
+ case WSAEINVAL: errno = EINVAL; break;
+ case WSAEMFILE: errno = EMFILE; break;
+ case WSAENAMETOOLONG: errno = ENAMETOOLONG; break;
+ case WSAENOTEMPTY: errno = ENOTEMPTY; break;
+ default: errno = wsa_err; break;
}
- errno = h_errno;
}
static void
check_errno (void)
{
- if (h_errno == 0 && winsock_lib != NULL)
+ h_errno = 0;
+ if (winsock_lib != NULL)
pfn_WSASetLastError (0);
}
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ errno = ENETDOWN;
return INVALID_SOCKET;
}
}
}
}
+ eassert (fd < MAXDESC);
fd_info[fd].hnd = (HANDLE) s;
/* set our own internal flags */
/* clean up */
_close (fd);
}
+ else
pfn_closesocket (s);
- h_errno = EMFILE;
+ errno = EMFILE;
return -1;
}
{
if (winsock_lib == NULL)
{
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
set_errno ();
return rc;
}
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
{
if (winsock_lib == NULL)
{
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
set_errno ();
return rc;
}
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
sys_gethostname (char * name, int namelen)
{
if (winsock_lib != NULL)
- return pfn_gethostname (name, namelen);
+ {
+ int retval;
+
+ check_errno ();
+ retval = pfn_gethostname (name, namelen);
+ if (retval == SOCKET_ERROR)
+ set_errno ();
+ return retval;
+ }
if (namelen > MAX_COMPUTERNAME_LENGTH)
return !GetComputerName (name, (DWORD *)&namelen);
- h_errno = EFAULT;
+ errno = EFAULT;
return SOCKET_ERROR;
}
sys_gethostbyname (const char * name)
{
struct hostent * host;
+ int h_err = h_errno;
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ h_errno = NO_RECOVERY;
+ errno = ENETDOWN;
return NULL;
}
check_errno ();
host = pfn_gethostbyname (name);
if (!host)
- set_errno ();
+ {
+ set_errno ();
+ h_errno = errno;
+ }
+ else
+ h_errno = h_err;
return host;
}
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ errno = ENETDOWN;
return NULL;
}
{
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ errno = ENETDOWN;
return SOCKET_ERROR;
}
set_errno ();
return rc;
}
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
{
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ errno = ENETDOWN;
return SOCKET_ERROR;
}
set_errno ();
return rc;
}
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
{
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ errno = ENETDOWN;
return SOCKET_ERROR;
}
set_errno ();
return rc;
}
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
{
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ errno = ENETDOWN;
return SOCKET_ERROR;
}
fd_info[s].flags |= FILE_LISTEN;
return rc;
}
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
{
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ errno = ENETDOWN;
return SOCKET_ERROR;
}
set_errno ();
return rc;
}
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
{
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ errno = ENETDOWN;
return -1;
}
else
fd = socket_to_fd (t);
- fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED;
- ResetEvent (fd_info[s].cp->char_avail);
+ if (fd >= 0)
+ {
+ fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED;
+ ResetEvent (fd_info[s].cp->char_avail);
+ }
return fd;
}
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return -1;
}
{
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ errno = ENETDOWN;
return SOCKET_ERROR;
}
set_errno ();
return rc;
}
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
{
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ errno = ENETDOWN;
return SOCKET_ERROR;
}
set_errno ();
return rc;
}
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
{
if (winsock_lib == NULL)
{
- h_errno = ENETDOWN;
+ errno = ENETDOWN;
return -1;
}
}
else
{
- h_errno = EINVAL;
+ errno = EINVAL;
return SOCKET_ERROR;
}
}
- h_errno = ENOTSOCK;
+ errno = ENOTSOCK;
return SOCKET_ERROR;
}
pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting);
if (waiting == 0 && nchars == 0)
{
- h_errno = errno = EWOULDBLOCK;
+ errno = EWOULDBLOCK;
return -1;
}
ssize_t
emacs_gnutls_pull (gnutls_transport_ptr_t p, void* buf, size_t sz)
{
- int n, sc, err;
+ int n, err;
SELECT_TYPE fdset;
EMACS_TIME timeout;
struct Lisp_Process *process = (struct Lisp_Process *)p;
int fd = process->infd;
- for (;;)
- {
- n = sys_read (fd, (char*)buf, sz);
+ n = sys_read (fd, (char*)buf, sz);
- if (n >= 0)
- return n;
+ if (n >= 0)
+ return n;
- err = errno;
+ err = errno;
- if (err == EWOULDBLOCK)
- {
- /* Set a small timeout. */
- timeout = make_emacs_time (1, 0);
- FD_ZERO (&fdset);
- FD_SET ((int)fd, &fdset);
-
- /* Use select with the timeout to poll the selector. */
- sc = select (fd + 1, &fdset, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
- &timeout, NULL);
-
- if (sc > 0)
- continue; /* Try again. */
-
- /* Translate the WSAEWOULDBLOCK alias EWOULDBLOCK to EAGAIN.
- Also accept select return 0 as an indicator to EAGAIN. */
- if (sc == 0 || errno == EWOULDBLOCK)
- err = EAGAIN;
- else
- err = errno; /* Other errors are just passed on. */
- }
+ /* Translate the WSAEWOULDBLOCK alias EWOULDBLOCK to EAGAIN. */
+ if (err == EWOULDBLOCK)
+ err = EAGAIN;
- emacs_gnutls_transport_set_errno (process->gnutls_state, err);
+ emacs_gnutls_transport_set_errno (process->gnutls_state, err);
- return -1;
- }
+ return -1;
}
ssize_t