On Thu, 24 Jul 2025 17:55:09 +0900
Takashi Yano wrote:

> On Thu, 24 Jul 2025 17:36:07 +0900
> Takashi Yano wrote:
> > Previously, process_fd failed to correctly handle fhandlers using an
> > archetype. This was due to the missing PATH_OPEN flag in path_conv,
> > which caused build_fh_pc() to skip archetype initialization. The
> > root cause was a bug where open() did not set the PATH_OPEN flag
> > for fhandlers using an archetype.
> > 
> > This patch introduces a new method, path_conv::set_isopen(), to
> > explicitly set the PATH_OPEN flag in path_flags when opening a
> > fhandler that uses an archetype.
> > 
> > Addresses: https://cygwin.com/pipermail/cygwin/2025-May/258167.html
> > Fixes: 92ddb7429065 ("(build_pc_pc): Use fh_alloc to create. Set name from 
> > fh->dev if appropriate. Generate an archetype or point to one here.")
> > Reported-by: Christian Franke <[email protected]>
> > Reviewed-by: Corinna Vinschen <[email protected]>
> > Signed-off-by: Takashi Yano <[email protected]>
> > ---
> >  winsup/cygwin/dtable.cc             | 4 ++++
> >  winsup/cygwin/local_includes/path.h | 1 +
> >  winsup/cygwin/release/3.6.5         | 3 +++
> >  3 files changed, 8 insertions(+)
> > 
> > diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
> > index f1832a169..6a99c99f9 100644
> > --- a/winsup/cygwin/dtable.cc
> > +++ b/winsup/cygwin/dtable.cc
> > @@ -674,6 +674,8 @@ build_fh_pc (path_conv& pc)
> >                 fh->archetype->get_handle ());
> >        if (!fh->get_name ())
> >     fh->set_name (fh->archetype->dev ().name ());
> > +      if (pc.isopen ())
> > +   fh->pc.set_isopen ();
> >      }
> >    else if (cygwin_finished_initializing && !pc.isopen ())
> >      fh->set_name (pc);
> > @@ -681,6 +683,8 @@ build_fh_pc (path_conv& pc)
> >      {
> >        if (!fh->get_name ())
> >     fh->set_name (fh->dev ().native ());
> > +      if (pc.isopen ())
> > +   fh->pc.set_isopen ();
> >        fh->archetype = fh->clone ();
> >        debug_printf ("created an archetype (%p) for %s(%d/%d)", 
> > fh->archetype, fh->get_name (), fh->dev ().get_major (), fh->dev 
> > ().get_minor ());
> >        fh->archetype->archetype = NULL;
> > diff --git a/winsup/cygwin/local_includes/path.h 
> > b/winsup/cygwin/local_includes/path.h
> > index 1fd542c96..a9ce2c7e4 100644
> > --- a/winsup/cygwin/local_includes/path.h
> > +++ b/winsup/cygwin/local_includes/path.h
> > @@ -244,6 +244,7 @@ class path_conv
> >    int isopen () const {return path_flags & PATH_OPEN;}
> >    int isctty_capable () const {return path_flags & PATH_CTTY;}
> >    int follow_fd_symlink () const {return path_flags & PATH_RESOLVE_PROCFD;}
> > +  void set_isopen () {path_flags |= PATH_OPEN;}
> >    void set_cygexec (bool isset)
> >    {
> >      if (isset)
> 
> Wait. This does not fix console case.

When bash is executed from command prompt, no one calls open().
What should we do for this case?

open() is not called but open_with_arch() is called.
  init_std_file_from_handle() -> init() -> open_with_arch()

What about set PATH_OPEN flag in open_with_arch() as follows?

diff --git a/winsup/cygwin/fhandler/base.cc b/winsup/cygwin/fhandler/base.cc
index 64a5f6aea..beebd710c 100644
--- a/winsup/cygwin/fhandler/base.cc
+++ b/winsup/cygwin/fhandler/base.cc
@@ -474,6 +474,9 @@ fhandler_base::open_with_arch (int flags, mode_t mode)
       if (!open_setup (flags))
        api_fatal ("open_setup failed, %E");
     }
+  /* For pty and console, PATH_OPEN flag has not been set in open().
+     So set it here unconditionally. */
+  pc.set_isopen ();
 
   close_on_exec (flags & O_CLOEXEC);
   /* A unique ID is necessary to recognize fhandler entries which are
diff --git a/winsup/cygwin/local_includes/path.h 
b/winsup/cygwin/local_includes/path.h
index 1fd542c96..a9ce2c7e4 100644
--- a/winsup/cygwin/local_includes/path.h
+++ b/winsup/cygwin/local_includes/path.h
@@ -244,6 +244,7 @@ class path_conv
   int isopen () const {return path_flags & PATH_OPEN;}
   int isctty_capable () const {return path_flags & PATH_CTTY;}
   int follow_fd_symlink () const {return path_flags & PATH_RESOLVE_PROCFD;}
+  void set_isopen () {path_flags |= PATH_OPEN;}
   void set_cygexec (bool isset)
   {
     if (isset)

-- 
Takashi Yano <[email protected]>

Reply via email to