]> sourceware.org Git - newlib-cygwin.git/commitdiff
* fhandler.h (class fhandler_process): Add fd_type member.
authorCorinna Vinschen <corinna@vinschen.de>
Thu, 22 Jan 2015 13:46:12 +0000 (13:46 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Thu, 22 Jan 2015 13:46:12 +0000 (13:46 +0000)
* fhandler_process.cc (process_tab): Fix indentation.
(fhandler_process::exists): Rely on format_process_fd returning file
type in fd_type.
(struct process_fd_t): Add fd_type member.
(fhandler_process::fill_filebuf): Allow format_process_fd to set
this->fd_type member.
(format_process_fd): Fix path evaluation to allow recognizing trailing
path components.  Fix check for file descriptor path component.  Return
virt_symlink in fd_type if no trailing path compenents exist, return
virt_fsdir otherwise and copy full resulting path into destbuf.
* path.cc (path_conv::check): If /proc/$PID/fd symlink has trailing
path components, reparse resulting path as if it's the incoming path.
Add comment to wail over the outdated and hackish check method, and to
explain what we do here.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_process.cc
winsup/cygwin/path.cc
winsup/cygwin/release/1.7.34

index 87d0ffe7c74b23ee44142b3b6074c2be558ff231..f177b3a534768153cfa0addf5b3e5a1550b82d26 100644 (file)
@@ -1,3 +1,21 @@
+2015-01-22  Corinna Vinschen  <corinna@vinschen.de>
+
+       * fhandler.h (class fhandler_process): Add fd_type member.
+       * fhandler_process.cc (process_tab): Fix indentation.
+       (fhandler_process::exists): Rely on format_process_fd returning file
+       type in fd_type.
+       (struct process_fd_t): Add fd_type member.
+       (fhandler_process::fill_filebuf): Allow format_process_fd to set
+       this->fd_type member.
+       (format_process_fd): Fix path evaluation to allow recognizing trailing
+       path components.  Fix check for file descriptor path component.  Return
+       virt_symlink in fd_type if no trailing path compenents exist, return
+       virt_fsdir otherwise and copy full resulting path into destbuf.
+       * path.cc (path_conv::check): If /proc/$PID/fd symlink has trailing
+       path components, reparse resulting path as if it's the incoming path.
+       Add comment to wail over the outdated and hackish check method, and to
+       explain what we do here.
+
 2015-01-21  Corinna Vinschen  <corinna@vinschen.de>
 
        * uinfo.cc (pwdgrp::fetch_account_from_windows): Allow fetching gid,
index 0128815e7f4eb23f46f696ef5a1af76b29cd46db..5fa6fe222a4d33406db0d3de9e592ae309262bfd 100644 (file)
@@ -1,7 +1,7 @@
 /* fhandler.h
 
    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-   2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
+   2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015  Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -2064,6 +2064,7 @@ class pinfo;
 class fhandler_process: public fhandler_proc
 {
   pid_t pid;
+  virtual_ftype_t fd_type;
  public:
   fhandler_process ();
   virtual_ftype_t exists();
index e2de05b3c013ff34aca1fffc48392834e9e9bd17..161050b3bd10c748572e05a2ec7ed116fa2dccad 100644 (file)
@@ -1,7 +1,7 @@
 /* fhandler_process.cc: fhandler for /proc/<pid> virtual filesystem
 
    Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
-   2013, 2014 Red Hat, Inc.
+   2013, 2014, 2015 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -77,7 +77,7 @@ static const virt_tab_t process_tab[] =
   { _VN ("uid"),        FH_PROCESS,   virt_file,      format_process_uid },
   { _VN ("winexename"), FH_PROCESS,   virt_file,      format_process_winexename },
   { _VN ("winpid"),     FH_PROCESS,   virt_file,      format_process_winpid },
-  { NULL, 0,           FH_NADA,       virt_none,      NULL }
+  { NULL, 0,           FH_NADA,      virt_none,      NULL }
 };
 
 static const int PROCESS_LINK_COUNT =
@@ -111,11 +111,11 @@ fhandler_process::exists ()
          fileid = entry - process_tab;
          return entry->type;
        }
-      if (entry->type == virt_directory)
+      if (entry->type == virt_directory)       /* fd subdir only */
        {
          fileid = entry - process_tab;
          if (fill_filebuf ())
-           return virt_symlink;
+           return fd_type;
          /* Check for nameless device entries. */
          path = strrchr (path, '/');
          if (path && *++path)
@@ -325,6 +325,7 @@ out:
 struct process_fd_t {
   const char *path;
   _pinfo *p;
+  virtual_ftype_t *fd_type;
 };
 
 bool
@@ -350,7 +351,7 @@ fhandler_process::fill_filebuf ()
     {
       if (process_tab[fileid].fhandler == FH_PROCESSFD)
        {
-         process_fd_t fd = { path, p };
+         process_fd_t fd = { path, p , &fd_type };
          filesize = process_tab[fileid].format_func (&fd, filebuf);
        }
       else
@@ -366,20 +367,27 @@ format_process_fd (void *data, char *&destbuf)
   _pinfo *p = ((process_fd_t *) data)->p;
   const char *path = ((process_fd_t *) data)->path;
   size_t fs = 0;
-  char *fdp = strrchr (path, '/');
-
-  if (!fdp || *++fdp == 'f') /* The "fd" directory itself. */
+  /* path looks like "$PID/fd", "$PID/fd/", "$PID/fd/[0-9]*".  In the latter
+     case a trailing slash and more followup chars are allowed, provided the
+     descriptor symlink points to a directory. */
+  char *fdp = strchr (path, '/') + 3;
+  /* The "fd" directory itself? */
+  if (fdp[0] =='\0' || (fdp[0] == '/' && fdp[1] == '\0'))
     {
       if (destbuf)
        cfree (destbuf);
       destbuf = p->fds (fs);
+      *((process_fd_t *) data)->fd_type = virt_symlink;
     }
   else
     {
+      char *e;
+      int fd;
+
       if (destbuf)
        cfree (destbuf);
-      int fd = atoi (fdp);
-      if (fd < 0 || (fd == 0 && !isdigit (*fdp)))
+      fd = strtol (++fdp, &e, 10);
+      if (fd < 0 || e == fdp || (*e != '/' && *e != '\0'))
        {
          set_errno (ENOENT);
          return 0;
@@ -390,6 +398,17 @@ format_process_fd (void *data, char *&destbuf)
          set_errno (ENOENT);
          return 0;
        }
+      if (*e == '\0')
+       *((process_fd_t *) data)->fd_type = virt_symlink;
+      else /* trailing path */
+       {
+         char *newbuf = (char *) cmalloc_abort (HEAP_STR, strlen (destbuf)
+                                                          + strlen (e) + 1);
+         stpcpy (stpcpy (newbuf, destbuf), e);
+         cfree (destbuf);
+         destbuf = newbuf;
+         *((process_fd_t *) data)->fd_type = virt_fsdir;
+       }
     }
   return fs;
 }
index dc8b97fc3eae208a6ac355f5343ae6e467852494..ff67515837154421ca677b970a6a97a5ed304bf1 100644 (file)
@@ -1,7 +1,7 @@
 /* path.cc: path support.
 
      Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-     2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
+     2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Red Hat, Inc.
 
   This file is part of Cygwin.
 
@@ -747,6 +747,8 @@ path_conv::check (const char *src, unsigned opt,
                  full_path = THIS_path;
                }
 
+    retry_fs_via_processfd:
+
              /* Convert to native path spec sans symbolic link info. */
              error = mount_table->conv_to_win32_path (path_copy, full_path,
                                                       dev, &sym.pflags);
@@ -796,6 +798,29 @@ path_conv::check (const char *src, unsigned opt,
                          fh->fill_filebuf ();
                          symlen = sym.set (fh->get_filebuf ());
                        }
+                     else if (file_type == virt_fsdir && dev == FH_PROCESS)
+                       {
+                         /* FIXME: This is YA bad hack to workaround that
+                            we're checking for isvirtual_dev at this point.
+                            This should only happen if the file is actually
+                            a virtual file, and NOT already if the preceeding
+                            path components constitute a virtual file.
+
+                            Anyway, what we do here is this:  If the descriptor
+                            symlink points to a dir, and if there are trailing
+                            path components, it's actually pointing somewhere
+                            else.  The format_process_fd function returns the
+                            full path, resolved symlink plus trailing path
+                            components, in its filebuf.  This is a POSIX path
+                            we know nothing about, so we have to convert it to
+                            native again, calling conv_to_win32_path.  Since
+                            basically nothing happened yet, just copy it over
+                            into full_path and jump back to the
+                            conv_to_win32_path call.  What a mess. */
+                         stpcpy (path_copy, fh->get_filebuf ());
+                         delete fh;
+                         goto retry_fs_via_processfd;
+                       }
                      delete fh;
                    }
                  switch (file_type)
index f9a618c51844ac6955cb0d112e9abf5494fe374f..44a0cc435901d803cc0d523d23b7f5c916dbb9e0 100644 (file)
@@ -82,3 +82,6 @@ Bug Fixes
   Addresses: https://cygwin.com/ml/cygwin/2015-01/msg00259.html
              https://cygwin.com/ml/cygwin/2015-01/msg00269.html
   
+- Fix handling of /proc/$PID/fd/... paths with trailing path components
+  beyond the symlink path itself.
+  Addresses: https://cygwin.com/ml/cygwin/2015-01/msg00293.html
This page took 0.040972 seconds and 5 git commands to generate.