summaryrefslogtreecommitdiff
path: root/src/w32.c
diff options
context:
space:
mode:
authorAndrew Innes <andrewi@gnu.org>2000-07-05 16:00:13 +0000
committerAndrew Innes <andrewi@gnu.org>2000-07-05 16:00:13 +0000
commitca149beb3f107bcab371c2c4031801bcb85b7393 (patch)
tree0b49108041d1330783e8161a3d7660826b4af7b9 /src/w32.c
parenta027a91ba2daf5b3de79eb67fd77c1362580e0fe (diff)
downloademacs-ca149beb3f107bcab371c2c4031801bcb85b7393.tar.gz
(init_environment): Install code from 20.7 for providing
default values for environment variables, based on the executable's own location. (map_w32_filename): Handle filenames that are longer than MAX_PATH. (sys_socket): Install socket inheritance bug fix from 20.7.
Diffstat (limited to 'src/w32.c')
-rw-r--r--src/w32.c171
1 files changed, 119 insertions, 52 deletions
diff --git a/src/w32.c b/src/w32.c
index a7fd59366d6..243948c0a03 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -289,9 +289,9 @@ init_user_info ()
/* Ensure HOME and SHELL are defined. */
if (getenv ("HOME") == NULL)
- putenv ("HOME=c:/");
+ abort ();
if (getenv ("SHELL") == NULL)
- putenv (os_subtype == OS_WIN95 ? "SHELL=command" : "SHELL=cmd");
+ abort ();
/* Set dir and shell from environment variables. */
strcpy (the_passwd.pw_dir, getenv ("HOME"));
@@ -692,52 +692,96 @@ init_environment (char ** argv)
Qnil)),
"While setting TMPDIR: ");
- /* Check for environment variables and use registry if they don't exist */
+ /* Check for environment variables and use registry settings if they
+ don't exist. Fallback on default values where applicable. */
{
int i;
LPBYTE lpval;
DWORD dwType;
- static char * env_vars[] =
- {
- "HOME",
- "PRELOAD_WINSOCK",
- "emacs_dir",
- "EMACSLOADPATH",
- "SHELL",
- "CMDPROXY",
- "EMACSDATA",
- "EMACSPATH",
- "EMACSLOCKDIR",
+ static struct env_entry
+ {
+ char * name;
+ char * def_value;
+ } env_vars[] =
+ {
+ {"HOME", "C:/"},
+ {"PRELOAD_WINSOCK", NULL},
+ {"emacs_dir", "C:/emacs"},
+ {"EMACSLOADPATH", "%emacs_dir%/site-lisp;%emacs_dir%/lisp;%emacs_dir%/leim"},
+ {"SHELL", "%emacs_dir%/bin/cmdproxy.exe"},
+ {"EMACSDATA", "%emacs_dir%/etc"},
+ {"EMACSPATH", "%emacs_dir%/bin"},
+ {"EMACSLOCKDIR", "%emacs_dir%/lock"},
/* We no longer set INFOPATH because Info-default-directory-list
- is then ignored. We use a hook in winnt.el instead. */
- /* "INFOPATH", */
- "EMACSDOC",
- "TERM",
+ is then ignored. */
+ /* {"INFOPATH", "%emacs_dir%/info"}, */
+ {"EMACSDOC", "%emacs_dir%/etc"},
+ {"TERM", "cmd"}
};
+#define SET_ENV_BUF_SIZE (4 * MAX_PATH) /* to cover EMACSLOADPATH */
+
+ /* Treat emacs_dir specially: set it unconditionally based on our
+ location, if it appears that we are running from the bin subdir
+ of a standard installation. */
+ {
+ char *p;
+ char modname[MAX_PATH];
+
+ if (!GetModuleFileName (NULL, modname, MAX_PATH))
+ abort ();
+ if ((p = strrchr (modname, '\\')) == NULL)
+ abort ();
+ *p = 0;
+
+ if ((p = strrchr (modname, '\\')) && stricmp (p, "\\bin") == 0)
+ {
+ char buf[SET_ENV_BUF_SIZE];
+
+ *p = 0;
+ for (p = modname; *p; p++)
+ if (*p == '\\') *p = '/';
+
+ _snprintf (buf, sizeof(buf)-1, "emacs_dir=%s", modname);
+ putenv (strdup (buf));
+ }
+ }
+
for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
{
- if (!getenv (env_vars[i])
- && (lpval = w32_get_resource (env_vars[i], &dwType)) != NULL)
+ if (!getenv (env_vars[i].name))
{
- if (dwType == REG_EXPAND_SZ)
- {
- char buf1[500], buf2[500];
+ int dont_free = 0;
- ExpandEnvironmentStrings ((LPSTR) lpval, buf1, 500);
- _snprintf (buf2, 499, "%s=%s", env_vars[i], buf1);
- putenv (strdup (buf2));
+ if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL)
+ {
+ lpval = env_vars[i].def_value;
+ dwType = REG_EXPAND_SZ;
+ dont_free = 1;
}
- else if (dwType == REG_SZ)
+
+ if (lpval)
{
- char buf[500];
+ if (dwType == REG_EXPAND_SZ)
+ {
+ 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));
+ }
+ else if (dwType == REG_SZ)
+ {
+ char buf[SET_ENV_BUF_SIZE];
- _snprintf (buf, 499, "%s=%s", env_vars[i], lpval);
- putenv (strdup (buf));
- }
+ _snprintf (buf, sizeof(buf)-1, "%s=%s", env_vars[i].name, lpval);
+ putenv (strdup (buf));
+ }
- xfree (lpval);
+ if (!dont_free)
+ xfree (lpval);
+ }
}
}
}
@@ -1149,6 +1193,13 @@ map_w32_filename (const char * name, const char ** pPath)
char * path;
const char * save_name = name;
+ if (strlen (name) >= MAX_PATH)
+ {
+ /* Return a filename which will cause callers to fail. */
+ strcpy (shortname, "?");
+ return shortname;
+ }
+
if (is_fat_volume (name, &path)) /* truncate to 8.3 */
{
register int left = 8; /* maximum number of chars in part */
@@ -2548,35 +2599,51 @@ sys_socket(int af, int type, int protocol)
_set_osfhnd (fd, s);
/* setmode (fd, _O_BINARY); */
#else
- /* Make a non-inheritable copy of the socket handle. */
+ /* Make a non-inheritable copy of the socket handle. Note
+ that it is possible that sockets aren't actually kernel
+ handles, which appears to be the case on Windows 9x when
+ the MS Proxy winsock client is installed. */
{
- HANDLE parent;
- HANDLE new_s = INVALID_HANDLE_VALUE;
-
- parent = GetCurrentProcess ();
-
/* Apparently there is a bug in NT 3.51 with some service
packs, which prevents using DuplicateHandle to make a
socket handle non-inheritable (causes WSACleanup to
hang). The work-around is to use SetHandleInformation
instead if it is available and implemented. */
- if (!pfn_SetHandleInformation
- || !pfn_SetHandleInformation ((HANDLE) s,
- HANDLE_FLAG_INHERIT,
- 0))
+ if (pfn_SetHandleInformation)
+ {
+ pfn_SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0);
+ }
+ else
{
- DuplicateHandle (parent,
- (HANDLE) s,
- parent,
- &new_s,
- 0,
- FALSE,
- DUPLICATE_SAME_ACCESS);
- pfn_closesocket (s);
- s = (SOCKET) new_s;
+ HANDLE parent = GetCurrentProcess ();
+ HANDLE new_s = INVALID_HANDLE_VALUE;
+
+ if (DuplicateHandle (parent,
+ (HANDLE) s,
+ parent,
+ &new_s,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS))
+ {
+ /* It is possible that DuplicateHandle succeeds even
+ though the socket wasn't really a kernel handle,
+ because a real handle has the same value. So
+ test whether the new handle really is a socket. */
+ long nonblocking = 0;
+ if (pfn_ioctlsocket ((SOCKET) new_s, FIONBIO, &nonblocking) == 0)
+ {
+ pfn_closesocket (s);
+ s = (SOCKET) new_s;
+ }
+ else
+ {
+ CloseHandle (new_s);
+ }
+ }
}
- fd_info[fd].hnd = (HANDLE) s;
}
+ fd_info[fd].hnd = (HANDLE) s;
#endif
/* set our own internal flags */