Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2014-10-27 14:33:53 +0300
committerCorinna Vinschen <corinna@vinschen.de>2014-10-27 14:33:53 +0300
commitf7cb52eec7144ec100874781bc36c301b027e01d (patch)
treecc581843c0efc4cf815197230ff9bfb51c30f785 /winsup/cygwin
parent41425f2ddae53ac914dbc67cbcb25d5e1940d634 (diff)
* cygheap.cc (cygheap_fixup_in_child): Drop call to set_dll_dir.
(init_cygheap::init_installation_root): Set installation_dir_len. (setup_cygheap): Drop call to set_dll_dir. * cygheap.h (struct init_cygheap): Add installation_dir_len member. (init_cygheap::set_dll_dir): Remove. * environ.cc (win_env::add_cache): Use stpcpy for speed. (posify_maybe): Use tmp_pathbuf buffer instead of stack. (raise_envblock): New function to resize Windows environment block. (build_env): Fix indentation. Call raise_envblock function. Check if $PATH exists and is non-empty. If not, add PATH variable with Cygwin installation directory as content to Windows environment. Explain why. * uinfo.cc (cygheap_pwdgrp::_nss_init): Fill UNICODE_STRING members on the fly. Drop call to RtlInitUnicodeString. (pwdgrp::check_file): Ditto.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog18
-rw-r--r--winsup/cygwin/cygheap.cc9
-rw-r--r--winsup/cygwin/cygheap.h10
-rw-r--r--winsup/cygwin/environ.cc82
-rw-r--r--winsup/cygwin/release/1.7.335
-rw-r--r--winsup/cygwin/uinfo.cc16
6 files changed, 87 insertions, 53 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 79f32e7ca..69d37e89b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,21 @@
+2014-10-27 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygheap.cc (cygheap_fixup_in_child): Drop call to set_dll_dir.
+ (init_cygheap::init_installation_root): Set installation_dir_len.
+ (setup_cygheap): Drop call to set_dll_dir.
+ * cygheap.h (struct init_cygheap): Add installation_dir_len member.
+ (init_cygheap::set_dll_dir): Remove.
+ * environ.cc (win_env::add_cache): Use stpcpy for speed.
+ (posify_maybe): Use tmp_pathbuf buffer instead of stack.
+ (raise_envblock): New function to resize Windows environment block.
+ (build_env): Fix indentation. Call raise_envblock function. Check if
+ $PATH exists and is non-empty. If not, add PATH variable with Cygwin
+ installation directory as content to Windows environment. Explain why.
+
+ * uinfo.cc (cygheap_pwdgrp::_nss_init): Fill UNICODE_STRING members
+ on the fly. Drop call to RtlInitUnicodeString.
+ (pwdgrp::check_file): Ditto.
+
2014-10-26 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc (fhandler_socket::af_local_connect): Drop
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index 8e25a07ea..97090affc 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -83,7 +83,6 @@ cygheap_fixup_in_child (bool execed)
_csbrk ((char *) child_proc_info->cygheap_max - (char *) cygheap);
child_copy (child_proc_info->parent, false, "cygheap", cygheap, cygheap_max, NULL);
cygheap_init ();
- cygheap->set_dll_dir ();
debug_fixup_after_fork_exec ();
if (execed)
{
@@ -188,9 +187,10 @@ init_cygheap::init_installation_root ()
"Invalid DLL path");
/* Copy result into installation_dir before stripping off "bin" dir and
- revert to Win32 path. This path is used in cygheap_init to call
- SetDllDirectory. */
- wcpncpy (installation_dir, installation_root, PATH_MAX);
+ revert to Win32 path. This path is added to the Windows environment
+ in buildenv. See there for a description. */
+ installation_dir_len = wcpncpy (installation_dir, installation_root, PATH_MAX)
+ - installation_dir;
installation_dir[1] = L'\\';
/* If w < p, the Cygwin DLL resides in the root dir of a drive or network
@@ -264,7 +264,6 @@ setup_cygheap ()
cygheap_init ();
cygheap->user.init ();
cygheap->init_installation_root (); /* Requires user.init! */
- cygheap->set_dll_dir ();
cygheap->pg.init ();
}
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index 55f26ed36..ff86d5ef3 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -506,6 +506,7 @@ struct init_cygheap: public mini_cygheap
char *buckets[NBUCKETS];
WCHAR installation_root[PATH_MAX];
WCHAR installation_dir[PATH_MAX];
+ size_t installation_dir_len;
UNICODE_STRING installation_key;
WCHAR installation_key_buf[18];
cygheap_root root;
@@ -534,15 +535,6 @@ struct init_cygheap: public mini_cygheap
hook_chain hooks;
void close_ctty ();
void init_installation_root ();
- void set_dll_dir ()
- {
- /* Call SetDllDirectory on installation_dir. This removes "." from the
- DLL search path and installs our /bin dir instead.
- Amazing but true: This setting is propagated to child processes :-)
- but only starting with Windows 8 :-( */
- if (!SetDllDirectoryW (installation_dir))
- debug_printf ("SetDllDirectoryW (%W), %E", installation_dir);
- }
void __reg1 init_tls_list ();;
void __reg2 add_tls (_cygtls *);
void __reg3 remove_tls (_cygtls *, DWORD);
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index 817439b0a..9b9be4a00 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -396,18 +396,15 @@ win_env::add_cache (const char *in_posix, const char *in_native)
if (in_native)
{
native = (char *) realloc (native, namelen + 1 + strlen (in_native));
- strcpy (native, name);
- strcpy (native + namelen, in_native);
+ stpcpy (stpcpy (native, name), in_native);
}
else
{
tmp_pathbuf tp;
char *buf = tp.c_get ();
- strcpy (buf, name + namelen);
towin32 (in_posix, buf, NT_MAX_PATH);
native = (char *) realloc (native, namelen + 1 + strlen (buf));
- strcpy (native, name);
- strcpy (native + namelen, buf);
+ stpcpy (stpcpy (native, name), buf);
}
MALLOC_CHECK;
if (immediate && cygwin_finished_initializing)
@@ -480,8 +477,9 @@ posify_maybe (char **here, const char *value, char *outenv)
{
/* The conversion routine removed elements from a path list so we have
to recalculate the windows path to remove elements there, too. */
- char cleanvalue[strlen (value) + 1];
- conv->towin32 (newvalue, cleanvalue, sizeof cleanvalue);
+ tmp_pathbuf tp;
+ char *cleanvalue = tp.c_get ();
+ conv->towin32 (newvalue, cleanvalue, NT_MAX_PATH);
conv->add_cache (newvalue, cleanvalue);
}
@@ -1032,6 +1030,21 @@ spenv::retrieve (bool no_envblock, const char *const env)
return getwinenveq (name, namelen, HEAP_1_STR);
}
+static inline int
+raise_envblock (int new_tl, PWCHAR &envblock, PWCHAR &s)
+{
+ int tl = new_tl + 100;
+ PWCHAR new_envblock =
+ (PWCHAR) realloc (envblock, (2 + tl) * sizeof (WCHAR));
+ /* If realloc moves the block, move `s' with it. */
+ if (new_envblock != envblock)
+ {
+ s += new_envblock - envblock;
+ envblock = new_envblock;
+ }
+ return tl;
+}
+
#define SPENVS_SIZE (sizeof (spenvs) / sizeof (spenvs[0]))
/* Create a Windows-style environment block, i.e. a typical character buffer
@@ -1096,14 +1109,14 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
for (unsigned i = 0; i < SPENVS_SIZE; i++)
if (!saw_spenv[i] && (spenvs[i].force_into_environment || cygheap->user.issetuid ()))
{
- *dstp = spenvs[i].retrieve (false);
- if (*dstp && *dstp != env_dontadd)
- {
- *pass_dstp++ = *dstp;
- tl += strlen (*dstp) + 1;
- dstp++;
- }
- }
+ *dstp = spenvs[i].retrieve (false);
+ if (*dstp && *dstp != env_dontadd)
+ {
+ *pass_dstp++ = *dstp;
+ tl += strlen (*dstp) + 1;
+ dstp++;
+ }
+ }
envc = dstp - newenv; /* Number of entries in newenv */
assert ((size_t) envc <= (n + SPENVS_SIZE));
@@ -1126,6 +1139,7 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
PWCHAR s;
envblock = (PWCHAR) malloc ((2 + tl) * sizeof (WCHAR));
int new_tl = 0;
+ bool saw_PATH = false;
for (srcp = pass_env, s = envblock; *srcp; srcp++)
{
const char *p;
@@ -1144,7 +1158,17 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
/* See if this entry requires posix->win32 conversion. */
conv = getwinenv (*srcp, rest, &temp);
if (conv)
- p = conv->native; /* Use win32 path */
+ {
+ p = conv->native; /* Use win32 path */
+ /* Does PATH exist in the environment? */
+ if (**srcp == 'P')
+ {
+ /* And is it non-empty? */
+ if (!conv->native || !conv->native[0])
+ continue;
+ saw_PATH = true;
+ }
+ }
else
p = *srcp; /* Don't worry about it */
@@ -1153,19 +1177,9 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
/* See if we need to increase the size of the block. */
if (new_tl > tl)
- {
- tl = new_tl + 100;
- PWCHAR new_envblock =
- (PWCHAR) realloc (envblock, (2 + tl) * sizeof (WCHAR));
- /* If realloc moves the block, move `s' with it. */
- if (new_envblock != envblock)
- {
- s += new_envblock - envblock;
- envblock = new_envblock;
- }
- }
+ tl = raise_envblock (new_tl, envblock, s);
- int slen = sys_mbstowcs (s, len, p);
+ len = sys_mbstowcs (s, len, p);
/* See if environment variable is "special" in a Windows sense.
Under NT, the current directories for visited drives are stored
@@ -1174,7 +1188,17 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
if (s[0] == L'!' && (iswdrive (s + 1) || (s[1] == L':' && s[2] == L':'))
&& s[3] == L'=')
*s = L'=';
- s += slen + 1;
+ s += len + 1;
+ }
+ /* If PATH doesn't exist in the environment, add a PATH with just
+ Cygwin's bin dir to the Windows env to allow loading system DLLs
+ during execve. */
+ if (!saw_PATH)
+ {
+ new_tl += cygheap->installation_dir_len + 5;
+ if (new_tl > tl)
+ tl = raise_envblock (new_tl, envblock, s);
+ s = wcpcpy (wcpcpy (s, L"PATH="), cygheap->installation_dir) + 1;
}
*s = L'\0'; /* Two null bytes at the end */
assert ((s - envblock) <= tl); /* Detect if we somehow ran over end
diff --git a/winsup/cygwin/release/1.7.33 b/winsup/cygwin/release/1.7.33
index c64d2d3a1..c7acd071d 100644
--- a/winsup/cygwin/release/1.7.33
+++ b/winsup/cygwin/release/1.7.33
@@ -42,8 +42,9 @@ What changed:
are supposed to work. Finally implement a CLASS_OBJ emulation. Update
getfacl(1)/setfacl(1) accordingly.
-- Drop the current working directory from the default DLL search path in
- favor of Cygwin's /bin dir.
+- When exec'ing applications, check if $PATH exists and is non-empty. If not,
+ add PATH variable with Cygwin installation directory as content to Windows
+ environment to allow loading of Cygwin system DLLs.
- Improve various header files for C++- and standards-compliance.
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index 12d5069d1..75b447287 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -752,10 +752,11 @@ cygheap_pwdgrp::_nss_init ()
char *buf = tp.c_get ();
PCWSTR rel_path = L"\\etc\\nsswitch.conf";
- path.Buffer = (PWCHAR) alloca ((wcslen (cygheap->installation_root)
- + wcslen (rel_path) + 1) * sizeof (WCHAR));
+ path.Length = (wcslen (cygheap->installation_root) + wcslen (rel_path))
+ * sizeof (WCHAR);
+ path.MaximumLength = path.Length + sizeof (WCHAR);
+ path.Buffer = (PWCHAR) alloca (path.MaximumLength);
wcpcpy (wcpcpy (path.Buffer, cygheap->installation_root), rel_path);
- RtlInitUnicodeString (&path, path.Buffer);
InitializeObjectAttributes (&attr, &path, OBJ_CASE_INSENSITIVE,
NULL, NULL);
if (rl.init (&attr, buf, NT_MAX_PATH))
@@ -1045,12 +1046,11 @@ pwdgrp::check_file ()
if (!path.Buffer)
{
PCWSTR rel_path = is_group () ? L"\\etc\\group" : L"\\etc\\passwd";
- path.Buffer = (PWCHAR) cmalloc_abort (HEAP_BUF,
- (wcslen (cygheap->installation_root)
- + wcslen (rel_path) + 1)
- * sizeof (WCHAR));
+ path.Length = (wcslen (cygheap->installation_root) + wcslen (rel_path))
+ * sizeof (WCHAR);
+ path.MaximumLength = path.Length + sizeof (WCHAR);
+ path.Buffer = (PWCHAR) cmalloc_abort (HEAP_BUF, path.MaximumLength);
wcpcpy (wcpcpy (path.Buffer, cygheap->installation_root), rel_path);
- RtlInitUnicodeString (&path, path.Buffer);
InitializeObjectAttributes (&attr, &path, OBJ_CASE_INSENSITIVE,
NULL, NULL);
}