summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog18
-rw-r--r--winsup/cygwin/fhandler.h3
-rw-r--r--winsup/cygwin/fhandler_process.cc39
-rw-r--r--winsup/cygwin/path.cc27
-rw-r--r--winsup/cygwin/release/1.7.343
5 files changed, 78 insertions, 12 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 87d0ffe7c..f177b3a53 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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,
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 0128815e7..5fa6fe222 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -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();
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index e2de05b3c..161050b3b 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -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;
}
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index dc8b97fc3..ff6751583 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -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)
diff --git a/winsup/cygwin/release/1.7.34 b/winsup/cygwin/release/1.7.34
index f9a618c51..44a0cc435 100644
--- a/winsup/cygwin/release/1.7.34
+++ b/winsup/cygwin/release/1.7.34
@@ -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