(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.
This commit is contained in:
parent
a027a91ba2
commit
ca149beb3f
1 changed files with 119 additions and 52 deletions
171
src/w32.c
171
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[] =
|
||||
static struct env_entry
|
||||
{
|
||||
"HOME",
|
||||
"PRELOAD_WINSOCK",
|
||||
"emacs_dir",
|
||||
"EMACSLOADPATH",
|
||||
"SHELL",
|
||||
"CMDPROXY",
|
||||
"EMACSDATA",
|
||||
"EMACSPATH",
|
||||
"EMACSLOCKDIR",
|
||||
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));
|
||||
}
|
||||
else if (dwType == REG_SZ)
|
||||
if ((lpval = w32_get_resource (env_vars[i].name, &dwType)) == NULL)
|
||||
{
|
||||
char buf[500];
|
||||
lpval = env_vars[i].def_value;
|
||||
dwType = REG_EXPAND_SZ;
|
||||
dont_free = 1;
|
||||
}
|
||||
|
||||
if (lpval)
|
||||
{
|
||||
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)
|
||||
{
|
||||
DuplicateHandle (parent,
|
||||
(HANDLE) s,
|
||||
parent,
|
||||
&new_s,
|
||||
0,
|
||||
FALSE,
|
||||
DUPLICATE_SAME_ACCESS);
|
||||
pfn_closesocket (s);
|
||||
s = (SOCKET) new_s;
|
||||
pfn_SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue