* Throughout, use __try/__except/__endtry blocks, rather than myfault

handler.
	* cygtls.cc (_cygtls::remove): Accommodate the fact that pathbufs
	has been moved from _local_storage to _cygtls.
	* cygtls.h (class tls_pathbuf): Add comment to hint to gendef usage
	of counters.  Change type of counters to uint32_t for clarity.
	Remove _cygtls as friend class.
	(struct _local_storage): Move pathbufs from here...
	(struct _cygtls): ...to here, allowing to access it from _sigbe.
	(class san): Only define on 32 bit.  Remove errno, _c_cnt and _w_cnt
	members.
	(san::setup): Drop parameter.  Don't initialize removed members.
	(san::leave): Don't set removed members.
	(class myfault): Only define on 32 bit.
	(myfault::faulted): Only keep implementation not taking any parameter.
	Drop argument in call to sebastian.setup.
	(__try/__leave/__except/__endtry): Implement to support real SEH.  For
	now stick to SJLJ on 32 bit.
	* dcrt0.cc (dll_crt0_0): Drop 64 bit call to
	exception::install_myfault_handler.
	* exception.h (exception_handler): Define with EXCEPTION_DISPOSITION
	as return type.
	(PDISPATCHER_CONTEXT): Define as void * on 32 bit.  Define as pointer
	to _DISPATCHER_CONTEXT on 64 bit.
	(class exception): Define separately for 32 and 64 bit.
	(exception::myfault): Add handler for myfault SEH handling on 64 bit.
	(exception::exception): Fix mangled method name to account for change
	in type of last parameter.
	(exception::install_myfault_handler): Remove.
	* exceptions.cc (exception::myfault_handle): Remove.
	(exception::myfault): New SEH handler for 64 bit.
	* gendef (_sigbe): Set tls_pathbuf counters to 0 explicitely when
	returning to the caller.
	* ntdll.h: Move a comment to a better place.
	(struct _SCOPE_TABLE): Define on 64 bit.
	* thread.cc (verifyable_object_isvalid): Remove gcc 4.7 workaround.
	* tls_pbuf.cc (tls_pbuf): Fix to accommodate new place of pathbufs.
	(tls_pathbuf::destroy): Change type of loop variables to uint32_t.
	* tls_pbuf.h (class tmp_pathbuf): Change type of buffer counters to
	uint32_t.  Accommodate new place of pathbufs.
	* tlsoffsets.h: Regenerate.
	* tlsoffsets64.h: Regenerate.
This commit is contained in:
Corinna Vinschen
2014-08-22 09:21:33 +00:00
parent 33ed7bb5bc
commit 3f3bd10104
41 changed files with 6383 additions and 5924 deletions

View File

@@ -2,7 +2,7 @@
process's environment.
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
@@ -664,19 +664,22 @@ _addenv (const char *name, const char *value, int overwrite)
extern "C" int
putenv (char *str)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (*str)
__try
{
char *eq = strchr (str, '=');
if (eq)
return _addenv (str, eq + 1, -1);
if (*str)
{
char *eq = strchr (str, '=');
if (eq)
return _addenv (str, eq + 1, -1);
/* Remove str from the environment. */
unsetenv (str);
/* Remove str from the environment. */
unsetenv (str);
}
return 0;
}
return 0;
__except (EFAULT) {}
__endtry
return -1;
}
/* Set the value of the environment variable "name" to be
@@ -684,15 +687,18 @@ putenv (char *str)
extern "C" int
setenv (const char *name, const char *value, int overwrite)
{
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (!name || !*name || strchr (name, '='))
__try
{
set_errno (EINVAL);
return -1;
if (!name || !*name || strchr (name, '='))
{
set_errno (EINVAL);
__leave;
}
return _addenv (name, value, !!overwrite);
}
return _addenv (name, value, !!overwrite);
__except (EFAULT) {}
__endtry
return -1;
}
/* Delete environment variable "name". */
@@ -701,22 +707,26 @@ unsetenv (const char *name)
{
register char **e;
int offset;
myfault efault;
if (efault.faulted (EFAULT))
return -1;
if (!name || *name == '\0' || strchr (name, '='))
__try
{
set_errno (EINVAL);
return -1;
if (!name || *name == '\0' || strchr (name, '='))
{
set_errno (EINVAL);
__leave;
}
while (my_findenv (name, &offset)) /* if set multiple times */
/* Move up the rest of the array */
for (e = cur_environ () + offset; ; e++)
if (!(*e = *(e + 1)))
break;
return 0;
}
while (my_findenv (name, &offset)) /* if set multiple times */
/* Move up the rest of the array */
for (e = cur_environ () + offset; ; e++)
if (!(*e = *(e + 1)))
break;
return 0;
__except (EFAULT) {}
__endtry
return -1;
}
/* Minimal list of Windows vars which must be converted to uppercase.
@@ -822,96 +832,101 @@ environ_init (char **envp, int envc)
bool envp_passed_in;
bool got_something_from_registry;
static char NO_COPY cygterm[] = "TERM=cygwin";
myfault efault;
tmp_pathbuf tp;
if (efault.faulted ())
api_fatal ("internal error reading the windows environment - too many environment variables?");
char *tmpbuf = tp.t_get ();
got_something_from_registry = regopt (L"default", tmpbuf);
if (myself->progname[0])
got_something_from_registry = regopt (myself->progname, tmpbuf)
|| got_something_from_registry;
if (!envp)
envp_passed_in = 0;
else
__try
{
envc++;
envc *= sizeof (char *);
char **newenv = (char **) malloc (envc);
memcpy (newenv, envp, envc);
cfree (envp);
char *tmpbuf = tp.t_get ();
got_something_from_registry = regopt (L"default", tmpbuf);
if (myself->progname[0])
got_something_from_registry = regopt (myself->progname, tmpbuf)
|| got_something_from_registry;
/* Older applications relied on the fact that cygwin malloced elements of the
environment list. */
envp = newenv;
if (ENVMALLOC)
for (char **e = newenv; *e; e++)
{
char *p = *e;
*e = strdup (p);
cfree (p);
}
envp_passed_in = 1;
goto out;
if (!envp)
envp_passed_in = 0;
else
{
envc++;
envc *= sizeof (char *);
char **newenv = (char **) malloc (envc);
memcpy (newenv, envp, envc);
cfree (envp);
/* Older applications relied on the fact that cygwin malloced elements of the
environment list. */
envp = newenv;
if (ENVMALLOC)
for (char **e = newenv; *e; e++)
{
char *p = *e;
*e = strdup (p);
cfree (p);
}
envp_passed_in = 1;
goto out;
}
/* Allocate space for environment + trailing NULL + CYGWIN env. */
lastenviron = envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *));
rawenv = GetEnvironmentStringsW ();
if (!rawenv)
{
system_printf ("GetEnvironmentStrings returned NULL, %E");
return;
}
debug_printf ("GetEnvironmentStrings returned %p", rawenv);
/* Current directory information is recorded as variables of the
form "=X:=X:\foo\bar; these must be changed into something legal
(we could just ignore them but maybe an application will
eventually want to use them). */
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
{
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
if (i >= envc)
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
envp[i] = newp;
if (*newp == '=')
*newp = '!';
char *eq = strchrnul (newp, '=');
ucenv (newp, eq); /* uppercase env vars which need it */
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
sawTERM = 1;
else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0)
parse_options (newp + 7);
if (*eq)
posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf);
debug_printf ("%p: %s", envp[i], envp[i]);
}
if (!sawTERM)
envp[i++] = strdup (cygterm);
envp[i] = NULL;
FreeEnvironmentStringsW (rawenv);
out:
findenv_func = (char * (*)(const char*, int*)) my_findenv;
__cygwin_environ = envp;
update_envptrs ();
if (envp_passed_in)
{
p = getenv ("CYGWIN");
if (p)
parse_options (p);
}
if (got_something_from_registry)
parse_options (NULL); /* possibly export registry settings to
environment */
MALLOC_CHECK;
}
/* Allocate space for environment + trailing NULL + CYGWIN env. */
lastenviron = envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *));
rawenv = GetEnvironmentStringsW ();
if (!rawenv)
__except (NO_ERROR)
{
system_printf ("GetEnvironmentStrings returned NULL, %E");
return;
api_fatal ("internal error reading the windows environment "
"- too many environment variables?");
}
debug_printf ("GetEnvironmentStrings returned %p", rawenv);
/* Current directory information is recorded as variables of the
form "=X:=X:\foo\bar; these must be changed into something legal
(we could just ignore them but maybe an application will
eventually want to use them). */
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
{
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
if (i >= envc)
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
envp[i] = newp;
if (*newp == '=')
*newp = '!';
char *eq = strchrnul (newp, '=');
ucenv (newp, eq); /* uppercase env vars which need it */
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
sawTERM = 1;
else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0)
parse_options (newp + 7);
if (*eq)
posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf);
debug_printf ("%p: %s", envp[i], envp[i]);
}
if (!sawTERM)
envp[i++] = strdup (cygterm);
envp[i] = NULL;
FreeEnvironmentStringsW (rawenv);
out:
findenv_func = (char * (*)(const char*, int*)) my_findenv;
__cygwin_environ = envp;
update_envptrs ();
if (envp_passed_in)
{
p = getenv ("CYGWIN");
if (p)
parse_options (p);
}
if (got_something_from_registry)
parse_options (NULL); /* possibly export registry settings to
environment */
MALLOC_CHECK;
__endtry
}
/* Function called by qsort to sort environment strings. */