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.
+
+ This is called from alloc.c:valid_pointer_p. */
+int
+w32_valid_pointer_p (void *p, int size)
+{
+ SIZE_T done;
+ HANDLE h = OpenProcess (PROCESS_VM_READ, FALSE, GetCurrentProcessId ());
+
+ if (h)
+ {
+ unsigned char *buf = alloca (size);
+ int retval = ReadProcessMemory (h, p, buf, size, &done);
+
+ CloseHandle (h);
+ return retval;
+ }
+ else
+ return -1;
+}
+
static char startup_dir[MAXPATHLEN];
/* Get the current working directory. */
SystemTimeToFileTime (&st, &utc_base_ft);
utc_base = (long double) utc_base_ft.dwHighDateTime
- * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
+ * 4096.0L * 1024.0L * 1024.0L + utc_base_ft.dwLowDateTime;
init = 1;
}
if (CompareFileTime (&ft, &utc_base_ft) < 0)
return 0;
- ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime;
+ ret = (long double) ft.dwHighDateTime
+ * 4096.0L * 1024.0L * 1024.0L + ft.dwLowDateTime;
ret -= utc_base;
- return (time_t) (ret * 1e-7);
+ return (time_t) (ret * 1e-7L);
}
void
int (PASCAL *pfn_WSAStartup) (WORD wVersionRequired, LPWSADATA lpWSAData);
void (PASCAL *pfn_WSASetLastError) (int iError);
int (PASCAL *pfn_WSAGetLastError) (void);
+int (PASCAL *pfn_WSAEventSelect) (SOCKET s, HANDLE hEventObject, long lNetworkEvents);
+HANDLE (PASCAL *pfn_WSACreateEvent) (void);
+int (PASCAL *pfn_WSACloseEvent) (HANDLE hEvent);
int (PASCAL *pfn_socket) (int af, int type, int protocol);
int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen);
int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int namelen);
= (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
"SetHandleInformation");
- winsock_lib = LoadLibrary ("wsock32.dll");
+ winsock_lib = LoadLibrary ("Ws2_32.dll");
if (winsock_lib != NULL)
{
LOAD_PROC( WSAStartup );
LOAD_PROC( WSASetLastError );
LOAD_PROC( WSAGetLastError );
+ LOAD_PROC( WSAEventSelect );
+ LOAD_PROC( WSACreateEvent );
+ LOAD_PROC( WSACloseEvent );
LOAD_PROC( socket );
LOAD_PROC( bind );
LOAD_PROC( connect );
int rc = pfn_listen (SOCK_HANDLE (s), backlog);
if (rc == SOCKET_ERROR)
set_errno ();
+ else
+ fd_info[s].flags |= FILE_LISTEN;
return rc;
}
h_errno = ENOTSOCK;
}
check_errno ();
- if (fd_info[s].flags & FILE_SOCKET)
+ if (fd_info[s].flags & FILE_LISTEN)
{
SOCKET t = pfn_accept (SOCK_HANDLE (s), addr, addrlen);
- if (t != INVALID_SOCKET)
- return socket_to_fd (t);
+ int fd = -1;
+ if (t == INVALID_SOCKET)
+ set_errno ();
+ else
+ fd = socket_to_fd (t);
- set_errno ();
- return -1;
+ fd_info[s].cp->status = STATUS_READ_ACKNOWLEDGED;
+ ResetEvent (fd_info[s].cp->char_avail);
+ return fd;
}
h_errno = ENOTSOCK;
return -1;
return cp->status;
}
+int _sys_wait_accept (int fd)
+{
+ HANDLE hEv;
+ child_process * cp;
+ int rc;
+
+ if (fd < 0 || fd >= MAXDESC)
+ return STATUS_READ_ERROR;
+
+ cp = fd_info[fd].cp;
+
+ if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
+ return STATUS_READ_ERROR;
+
+ cp->status = STATUS_READ_FAILED;
+
+ hEv = pfn_WSACreateEvent ();
+ rc = pfn_WSAEventSelect (SOCK_HANDLE (fd), hEv, FD_ACCEPT);
+ if (rc != SOCKET_ERROR)
+ {
+ rc = WaitForSingleObject (hEv, INFINITE);
+ pfn_WSAEventSelect (SOCK_HANDLE (fd), NULL, 0);
+ pfn_WSACloseEvent (hEv);
+ if (rc == WAIT_OBJECT_0)
+ cp->status = STATUS_READ_SUCCEEDED;
+ }
+
+ return cp->status;
+}
+
int
sys_read (int fd, char * buffer, unsigned int count)
{
check_windows_init_file ();
}
+/*
+ shutdown_handler ensures that buffers' autosave files are
+ up to date when the user logs off, or the system shuts down.
+*/
+BOOL WINAPI shutdown_handler(DWORD type)
+{
+ /* Ctrl-C and Ctrl-Break are already suppressed, so don't handle them. */
+ if (type == CTRL_CLOSE_EVENT /* User closes console window. */
+ || type == CTRL_LOGOFF_EVENT /* User logs off. */
+ || type == CTRL_SHUTDOWN_EVENT) /* User shutsdown. */
+ {
+ /* Shut down cleanly, making sure autosave files are up to date. */
+ shut_down_emacs (0, 0, Qnil);
+ }
+
+ /* Allow other handlers to handle this signal. */
+ return FALSE;
+}
+
/*
globals_of_w32 is used to initialize those global variables that
must always be initialized on startup even when the global variable
g_b_init_get_token_information = 0;
g_b_init_lookup_account_sid = 0;
g_b_init_get_sid_identifier_authority = 0;
+ /* The following sets a handler for shutdown notifications for
+ console apps. This actually applies to Emacs in both console and
+ GUI modes, since we had to fool windows into thinking emacs is a
+ console application to get console mode to work. */
+ SetConsoleCtrlHandler(shutdown_handler, TRUE);
}
/* end of nt.c */