* cygheap.h (class cwdstuff): Make drive_length private.

Add "error" member.
	(cwdstuff::get_error): New inline method.
	(cwdstuff::get_error_desc): Declare.
	(cwdstuff::set): Change first parameter to pointer to path_conv.
	* path.cc (chdir): Drop doit.  Align call to cwdstuff::set to
	new arguments.
	(cwdstuff::init): Only call cwdstuff::set if it's not already
	initialized.  Add comment.  Drop third parameter in call to
	cwdstuff::set.
	(cwdstuff::set): Partially rewrite.  Add lots of comments to explain
	everything.  Drop "doit" since it's not used anymore.  Always create
	new handle to CWD if not in a virtual path.  Drop PEB locking when
	reading PEB values in init phase.  Check for accessibility to set
	correct error code.  Drop Vista workaround.  Never write back into PEB.
	Set Win32 CWD to \\?\PIPE\ on init.  Simplify creation of win32 path.
	Set new error member to a meaningful value.
	(cwdstuff::get_error_desc): New method to generate error message
	from cwd error code.
	* spawn.cc (spawn_guts): Call cwdstuff::get_error_desc to create
	more meaningful error message when not being able to start native
	Win32 app due to CWD restrictions.  When starting native Win32 app,
	lock cwd and use in calls to CreateProcessW/CreateProcessAsUserW.
This commit is contained in:
Corinna Vinschen
2010-08-13 11:51:54 +00:00
parent 7aba919b5e
commit 260b80740e
4 changed files with 240 additions and 163 deletions

View File

@@ -380,17 +380,12 @@ spawn_guts (const char *prog_arg, const char *const *argv,
if (res)
goto out;
if (!real_path.iscygexec ()
&& (cygheap->cwd.drive_length == 0
|| cygheap->cwd.win32.Length >= MAX_PATH * sizeof (WCHAR)))
if (!real_path.iscygexec () && cygheap->cwd.get_error ())
{
small_printf ("Error: Current working directory is a %s.\n"
small_printf ("Error: Current working directory %s.\n"
"Can't start native Windows application from here.\n\n",
cygheap->cwd.drive_length == 0
? "virtual Cygwin directory"
: "path longer than allowed for a\n"
"Win32 working directory");
set_errno (ENAMETOOLONG);
cygheap->cwd.get_error_desc ());
set_errno (cygheap->cwd.get_error ());
res = -1;
goto out;
}
@@ -551,6 +546,14 @@ spawn_guts (const char *prog_arg, const char *const *argv,
loop:
cygheap->user.deimpersonate ();
PWCHAR cwd;
cwd = NULL;
if (!real_path.iscygexec())
{
cygheap->cwd.cwd_lock.acquire ();
cwd = cygheap->cwd.win32.Buffer;
}
if (!cygheap->user.issetuid ()
|| (cygheap->user.saved_uid == cygheap->user.real_uid
&& cygheap->user.saved_gid == cygheap->user.real_gid
@@ -564,7 +567,7 @@ loop:
TRUE, /* inherit handles from parent */
c_flags,
envblock, /* environment */
NULL,
cwd,
&si,
&pi);
}
@@ -627,7 +630,7 @@ loop:
TRUE, /* inherit handles from parent */
c_flags,
envblock, /* environment */
NULL,
cwd,
&si,
&pi);
if (hwst)
@@ -642,6 +645,9 @@ loop:
}
}
if (!real_path.iscygexec())
cygheap->cwd.cwd_lock.release ();
/* Restore impersonation. In case of _P_OVERLAY this isn't
allowed since it would overwrite child data. */
if (mode != _P_OVERLAY || !rc)