* cygheap.h (class cygheap_fdenum): New class to enumerate used
fhandlers. * dtable.h (class dtable): Add cygheap_fdenum as friend class. * fhandler.h (fhandler_base::get_proc_fd_name): New virtual method to return a name for /proc/<pid>/fd. (fhandler_socket::get_proc_fd_name): Ditto. (fhandler_pipe::get_proc_fd_name): Ditto. (fhandler_virtual::opendir): Make virtual method. (fhandler_process::opendir): New method. * fhandler.cc (fhandler_base::get_proc_fd_name): New method. * fhandler_process.cc: Include ctype.h. (PROCESS_FD): Define. (process_listing): Add "fd". (fhandler_process::exists): Fix comment. Return 1 in case of "fd" directory. Handle files below "fd". (fhandler_process::fstat): Drop "self" handling. Set correct link count for directories. (fhandler_process::opendir): New method to handle "fd" directory. (fhandler_process::readdir): Add "fd" handling. (fhandler_process::open): Drop "self" handling. (fhandler_process::fill_filebuf): Ditto. Add "fd" handling. Fix "maps" output string. * fhandler_registry.cc (fhandler_registry::fstat): Set correct link count for directories. * fhandler_socket.cc (fhandler_socket::get_proc_fd_name): New method. * path.cc (symlink_info::set): Fix thinko. * pinfo.cc (_pinfo::commune_recv): Rename pathbuf to path throughout. Drop local path variable in PICOM_FIFO case. Fix debug output. Close handles as early as possible. Add PICOM_FDS and PICOM_FD handling. (_pinfo::commune_send): Add PICOM_FDS and PICOM_FD handling. (_pinfo::fd): New method. (_pinfo::fds): New method. * pinfo.h (enum picom): Add PICOM_FDS and PICOM_FD. (_pinfo::fd): Declare. (_pinfo::fds): Declare. * pipe.cc (fhandler_pipe::get_proc_fd_name): New method.
This commit is contained in:
@ -25,6 +25,7 @@ details. */
|
||||
#include <sys/param.h>
|
||||
#include <assert.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <ctype.h>
|
||||
#include <psapi.h>
|
||||
|
||||
#define _COMPILING_NEWLIB
|
||||
@ -43,10 +44,11 @@ static const int PROCESS_STAT = 11;
|
||||
static const int PROCESS_STATM = 12;
|
||||
static const int PROCESS_CMDLINE = 13;
|
||||
static const int PROCESS_MAPS = 14;
|
||||
static const int PROCESS_FD = 15;
|
||||
/* Keep symlinks always the last entries. */
|
||||
static const int PROCESS_ROOT = 15;
|
||||
static const int PROCESS_EXE = 16;
|
||||
static const int PROCESS_CWD = 17;
|
||||
static const int PROCESS_ROOT = 16;
|
||||
static const int PROCESS_EXE = 17;
|
||||
static const int PROCESS_CWD = 18;
|
||||
|
||||
/* The position of "root" defines the beginning of symlik entries. */
|
||||
#define is_symlink(nr) ((nr) >= PROCESS_ROOT)
|
||||
@ -68,6 +70,7 @@ static const char * const process_listing[] =
|
||||
"statm",
|
||||
"cmdline",
|
||||
"maps",
|
||||
"fd",
|
||||
/* Keep symlinks always the last entries. */
|
||||
"root",
|
||||
"exe",
|
||||
@ -89,7 +92,7 @@ static bool get_mem_values (DWORD dwProcessId, unsigned long *vmsize,
|
||||
unsigned long *vmshare);
|
||||
|
||||
/* Returns 0 if path doesn't exist, >0 if path is a directory,
|
||||
* <0 if path is a file.
|
||||
* -1 if path is a file, -2 if path is a symlink.
|
||||
*/
|
||||
int
|
||||
fhandler_process::exists ()
|
||||
@ -106,8 +109,14 @@ fhandler_process::exists ()
|
||||
if (pathmatch (path + 1, process_listing[i]))
|
||||
{
|
||||
fileid = i;
|
||||
return is_symlink (i) ? -2 : -1;
|
||||
return is_symlink (i) ? -2 : (i == PROCESS_FD) ? 1 : -1;
|
||||
}
|
||||
if (pathnmatch (strchr (path, '/') + 1, "fd/", 3))
|
||||
{
|
||||
fileid = PROCESS_FD;
|
||||
if (fill_filebuf ())
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -123,10 +132,7 @@ fhandler_process::fstat (struct __stat64 *buf)
|
||||
int file_type = exists ();
|
||||
(void) fhandler_base::fstat (buf);
|
||||
path += proc_len + 1;
|
||||
if (path_prefix_p ("self", path, 4))
|
||||
pid = getpid ();
|
||||
else
|
||||
pid = atoi (path);
|
||||
pid = atoi (path);
|
||||
pinfo p (pid);
|
||||
if (!p)
|
||||
{
|
||||
@ -142,8 +148,6 @@ fhandler_process::fstat (struct __stat64 *buf)
|
||||
set_errno (ENOENT);
|
||||
return -1;
|
||||
case 1:
|
||||
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||
return 0;
|
||||
case 2:
|
||||
buf->st_ctime = buf->st_mtime = p->start_time;
|
||||
buf->st_ctim.tv_nsec = buf->st_mtim.tv_nsec = 0;
|
||||
@ -151,7 +155,10 @@ fhandler_process::fstat (struct __stat64 *buf)
|
||||
buf->st_uid = p->uid;
|
||||
buf->st_gid = p->gid;
|
||||
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||
buf->st_nlink = PROCESS_LINK_COUNT;
|
||||
if (file_type == 1)
|
||||
buf->st_nlink = 2;
|
||||
else
|
||||
buf->st_nlink = 3;
|
||||
return 0;
|
||||
case -2:
|
||||
buf->st_uid = p->uid;
|
||||
@ -167,14 +174,38 @@ fhandler_process::fstat (struct __stat64 *buf)
|
||||
}
|
||||
}
|
||||
|
||||
DIR *
|
||||
fhandler_process::opendir ()
|
||||
{
|
||||
DIR *dir = fhandler_virtual::opendir ();
|
||||
if (dir && fileid == PROCESS_FD)
|
||||
fill_filebuf ();
|
||||
return dir;
|
||||
}
|
||||
|
||||
struct dirent *
|
||||
fhandler_process::readdir (DIR * dir)
|
||||
{
|
||||
if (dir->__d_position >= PROCESS_LINK_COUNT)
|
||||
if (fileid == PROCESS_FD)
|
||||
{
|
||||
if (dir->__d_position >= 2 + filesize / sizeof (int))
|
||||
return NULL;
|
||||
}
|
||||
else if (dir->__d_position >= PROCESS_LINK_COUNT)
|
||||
return NULL;
|
||||
strcpy (dir->__d_dirent->d_name, process_listing[dir->__d_position++]);
|
||||
syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,
|
||||
dir->__d_dirent->d_name);
|
||||
if (fileid == PROCESS_FD && dir->__d_position > 1)
|
||||
{
|
||||
int *p = (int *) filebuf;
|
||||
__small_sprintf (dir->__d_dirent->d_name, "%d", p[dir->__d_position++ - 2]);
|
||||
syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,
|
||||
dir->__d_dirent->d_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy (dir->__d_dirent->d_name, process_listing[dir->__d_position++]);
|
||||
syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,
|
||||
dir->__d_dirent->d_name);
|
||||
}
|
||||
return dir->__d_dirent;
|
||||
}
|
||||
|
||||
@ -191,10 +222,7 @@ fhandler_process::open (int flags, mode_t mode)
|
||||
|
||||
const char *path;
|
||||
path = get_name () + proc_len + 1;
|
||||
if (path_prefix_p ("self", path, 4))
|
||||
pid = getpid ();
|
||||
else
|
||||
pid = atoi (path);
|
||||
pid = atoi (path);
|
||||
while (*path != 0 && !isdirsep (*path))
|
||||
path++;
|
||||
|
||||
@ -272,15 +300,11 @@ out:
|
||||
bool
|
||||
fhandler_process::fill_filebuf ()
|
||||
{
|
||||
const char *path;
|
||||
path = get_name () + proc_len + 1;
|
||||
if (!pid)
|
||||
{
|
||||
const char *path;
|
||||
path = get_name () + proc_len + 1;
|
||||
if (path_prefix_p ("self", path, 4))
|
||||
pid = getpid ();
|
||||
else
|
||||
pid = atoi (path);
|
||||
}
|
||||
pid = atoi (path);
|
||||
|
||||
pinfo p (pid);
|
||||
|
||||
if (!p)
|
||||
@ -291,6 +315,36 @@ fhandler_process::fill_filebuf ()
|
||||
|
||||
switch (fileid)
|
||||
{
|
||||
case PROCESS_FD:
|
||||
{
|
||||
size_t fs;
|
||||
char *fdp = strrchr (path, '/');
|
||||
if (!fdp || *++fdp == 'f') /* The "fd" directory itself. */
|
||||
{
|
||||
if (filebuf)
|
||||
free (filebuf);
|
||||
filebuf = p->fds (fs);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filebuf)
|
||||
free (filebuf);
|
||||
int fd = atoi (fdp);
|
||||
if (fd < 0 || (fd == 0 && !isdigit (*fdp)))
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
return false;
|
||||
}
|
||||
filebuf = p->fd (fd, fs);
|
||||
if (!filebuf || !*filebuf)
|
||||
{
|
||||
filebuf = strdup ("<disconnected>");
|
||||
fs = strlen (filebuf) + 1;
|
||||
}
|
||||
}
|
||||
filesize = fs;
|
||||
break;
|
||||
}
|
||||
case PROCESS_UID:
|
||||
case PROCESS_GID:
|
||||
case PROCESS_PGID:
|
||||
@ -502,7 +556,7 @@ format_process_maps (_pinfo *p, char *destbuf, size_t maxsize)
|
||||
st.st_ino);
|
||||
while (written++ < 61)
|
||||
destbuf[len + written] = ' ';
|
||||
len += written;
|
||||
len += written - 1;
|
||||
len += __small_sprintf (destbuf + len, "%s\n", posix_modname);
|
||||
}
|
||||
out:
|
||||
|
Reference in New Issue
Block a user