/* Utility and Unix shadow routines for GNU Emacs on the Microsoft W32 API.
- Copyright (C) 1994, 1995, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1995, 2000, 2001, 2002, 2003, 2004,
+ 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Emacs.
struct stat ignored;
char default_home[MAX_PATH];
- static struct env_entry
+ static const struct env_entry
{
char * name;
char * def_value;
- } env_vars[] =
+ } dflt_envvars[] =
{
{"HOME", "C:/"},
{"PRELOAD_WINSOCK", NULL},
{"LANG", NULL},
};
+#define N_ENV_VARS sizeof(dflt_envvars)/sizeof(dflt_envvars[0])
+
+ /* We need to copy dflt_envvars[] and work on the copy because we
+ don't want the dumped Emacs to inherit the values of
+ environment variables we saw during dumping (which could be on
+ a different system). The defaults above must be left intact. */
+ struct env_entry env_vars[N_ENV_VARS];
+
+ for (i = 0; i < N_ENV_VARS; i++)
+ env_vars[i] = dflt_envvars[i];
+
/* 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. */
LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP,
locale_name, sizeof (locale_name)))
{
- for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
+ for (i = 0; i < N_ENV_VARS; i++)
{
if (strcmp (env_vars[i].name, "LANG") == 0)
{
}
}
- for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
+ for (i = 0; i < N_ENV_VARS; i++)
{
if (!getenv (env_vars[i].name))
{
if (lpval)
{
- if (dwType == REG_EXPAND_SZ)
- {
- char buf1[SET_ENV_BUF_SIZE], buf2[SET_ENV_BUF_SIZE];
+ char buf1[SET_ENV_BUF_SIZE], buf2[SET_ENV_BUF_SIZE];
- ExpandEnvironmentStrings ((LPSTR) lpval, buf1, sizeof(buf1));
- _snprintf (buf2, sizeof(buf2)-1, "%s=%s", env_vars[i].name, buf1);
- _putenv (strdup (buf2));
- }
+ if (dwType == REG_EXPAND_SZ)
+ ExpandEnvironmentStrings ((LPSTR) lpval, buf1, sizeof(buf1));
else if (dwType == REG_SZ)
+ strcpy (buf1, lpval);
+ if (dwType == REG_EXPAND_SZ || dwType == REG_SZ)
{
- char buf[SET_ENV_BUF_SIZE];
-
- _snprintf (buf, sizeof(buf)-1, "%s=%s", env_vars[i].name, lpval);
- _putenv (strdup (buf));
+ _snprintf (buf2, sizeof(buf2)-1, "%s=%s", env_vars[i].name,
+ buf1);
+ _putenv (strdup (buf2));
}
if (!dont_free)
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;
{
int rc;
- if (fd < 0 || fd >= MAXDESC)
+ if (fd < 0)
{
errno = EBADF;
return -1;
}
- if (fd_info[fd].cp)
+ if (fd < MAXDESC && fd_info[fd].cp)
{
child_process * cp = fd_info[fd].cp;
because socket handles are fully fledged kernel handles. */
rc = _close (fd);
- if (rc == 0)
+ if (rc == 0 && fd < MAXDESC)
fd_info[fd].flags = 0;
return rc;
int new_fd;
new_fd = _dup (fd);
- if (new_fd >= 0)
+ if (new_fd >= 0 && new_fd < MAXDESC)
{
/* duplicate our internal info as well */
fd_info[new_fd] = fd_info[fd];
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)
{
DWORD waiting;
char * orig_buffer = buffer;
- if (fd < 0 || fd >= MAXDESC)
+ if (fd < 0)
{
errno = EBADF;
return -1;
}
- if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
+ if (fd < MAXDESC && fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
{
child_process *cp = fd_info[fd].cp;
{
int nchars;
- if (fd < 0 || fd >= MAXDESC)
+ if (fd < 0)
{
errno = EBADF;
return -1;
}
- if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
+ if (fd < MAXDESC && fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
{
if ((fd_info[fd].flags & FILE_WRITE) == 0)
{
}
#ifdef HAVE_SOCKETS
- if (fd_info[fd].flags & FILE_SOCKET)
+ if (fd < MAXDESC && fd_info[fd].flags & FILE_SOCKET)
{
unsigned long nblock = 0;
if (winsock_lib == NULL) abort ();
objs[1] = decode_env_path (0, (getenv ("EMACSLOADPATH")));
full_load_path = Fappend (2, objs);
init_file = build_string ("term/w32-win");
- fd = openp (full_load_path, init_file, Vload_suffixes, NULL, Qnil);
+ fd = openp (full_load_path, init_file, Fget_load_suffixes (), NULL, Qnil);
if (fd < 0)
{
Lisp_Object load_path_print = Fprin1_to_string (full_load_path, Qnil);
char *init_file_name = SDATA (init_file);
char *load_path = SDATA (load_path_print);
- char *buffer = alloca (1024);
+ char *buffer = alloca (1024
+ + strlen (init_file_name)
+ + strlen (load_path));
sprintf (buffer,
"The Emacs Windows initialization file \"%s.el\" "