* 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.
This commit is contained in:
Corinna Vinschen 2015-01-22 13:46:12 +00:00
parent 638dd243f2
commit 185784962a
5 changed files with 78 additions and 12 deletions

View 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,

View 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();

View 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;
}

View 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)

View 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