On Jul  1 16:43, Jeremy Drake via Cygwin-patches wrote:
> This will be used by posix_spawn_fileaction_add_(f)chdir.
> 
> The int cwdfd is placed such that it fits into space previously unused
> due to alignment in the cygheap_exec_info class.
> 
> This uses a file descriptor rather than a path both because it is easier
> to marshal to the child and because this should protect against races
> where the directory might be renamed or removed between addfchdir and
> the actual setting of the cwd in the child.
> 
> Signed-off-by: Jeremy Drake <cyg...@jdrake.com>
> ---
>  winsup/cygwin/dcrt0.cc                    |  19 +++-
>  winsup/cygwin/local_includes/child_info.h |   4 +-
>  winsup/cygwin/local_includes/path.h       |   6 +-
>  winsup/cygwin/local_includes/winf.h       |   2 +-
>  winsup/cygwin/spawn.cc                    | 100 ++++++++++++++++++----
>  winsup/cygwin/syscalls.cc                 |   4 +-
>  6 files changed, 113 insertions(+), 22 deletions(-)
> 
> diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
> index b0fb5c9c1e..6adc31495a 100644
> --- a/winsup/cygwin/dcrt0.cc
> +++ b/winsup/cygwin/dcrt0.cc
> @@ -46,6 +46,7 @@ extern "C" void __sinit (_reent *);
> 
>  static int NO_COPY envc;
>  static char NO_COPY **envp;
> +static int NO_COPY cwdfd = AT_FDCWD;
> 
>  bool NO_COPY jit_debug;
> 
> @@ -656,6 +657,7 @@ child_info_spawn::handle_spawn ()
>    __argv = moreinfo->argv;
>    envp = moreinfo->envp;
>    envc = moreinfo->envc;
> +  cwdfd = moreinfo->cwdfd;
>    if (!dynamically_loaded)
>      cygheap->fdtab.fixup_after_exec ();
>    if (__stdin >= 0)
> @@ -842,7 +844,22 @@ dll_crt0_1 (void *)
> 
>    ProtectHandle (hMainThread);
> 
> -  cygheap->cwd.init ();
> +  if (cwdfd >= 0)
> +    {
> +      int res = fchdir (cwdfd);
> +      if (res < 0)
> +     {
> +       /* if the error occurs after the calling process successfully
> +          returns, the child process shall exit with exit status 127. */
> +       /* why is this byteswapped? */
> +       set_api_fatal_return (0x7f00);
> +       api_fatal ("can't fchdir, %R", res);
> +     }
> +      close (cwdfd);
> +      cwdfd = AT_FDCWD;
> +    }
> +  else
> +    cygheap->cwd.init ();

Weeeeell, as discussed in the other thread, and on second thought, maybe
this is the right spot to handle all the posix_spawn stuff.

But then, it should be in it's own function.  And you don't need
moreinfo->cwdfd, because the entire set of actions requested by the
posix_spawn caller should run one at a time in that function, so
multiple chdir and fchdir actions may be required.

I would also suggest to pimp cwdstuff::init() by adding an argument
which allows to say 

Eventually, this code snippet in dll_crt0_1 should probably look like
this:

  cygheap->cwd.init ();
  if (posix_spawn_actions_present)
    posix_spawn_run_child_actions (...);
    
Regardless if posix_spawn chdir/fchdir file actions are present or not,
in the first place the cwd of the child is the parent's cwd.  The
posix_spawn chdir/fchdir file actions run afterwards.


Thanks,
Corinna

Reply via email to