diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2005-01-29 11:23:07 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2005-01-29 11:23:07 +0000 |
commit | faf07ace9256e17e846adcb514ee33d5ceccf1e7 (patch) | |
tree | 15882743895b33c69c019a08cae36d7ec7e23e68 /winsup/cygwin/fhandler_process.cc | |
parent | 2eeb0e70a3c08c88e91283028bc2f89d8f237971 (diff) | |
download | cygnal-faf07ace9256e17e846adcb514ee33d5ceccf1e7.tar.gz cygnal-faf07ace9256e17e846adcb514ee33d5ceccf1e7.tar.bz2 cygnal-faf07ace9256e17e846adcb514ee33d5ceccf1e7.zip |
* autoload.cc (GetModuleFileNameExA): Add.
(GetModuleInformation): Add.
(QueryWorkingSet): Add.
* fhandler.h (fhandler_virtual::get_filebuf): New method.
* fhandler_proc.cc (PROC_SELF): Define.
(proc_fhandlers): Change type of self to FH_PROC.
(fhandler_proc::exists): Return -3 if self.
(fhandler_proc::fstat): Handle self as symlink.
(fhandler_proc::fill_filebuf): Handle self.
* fhandler_process.cc: Include psapi.h.
(PROCESS_EXENAME): Remove.
(PROCESS_MAPS): Define.
(PROCESS_ROOT): Define.
(PROCESS_EXE): Define.
(PROCESS_CWD): Define.
(process_listing): Remove "exename", add "maps, "root", "exe" and
"cwd" elements.
(fhandler_process::exists): Return -2 for symlinks.
(fhandler_process::fstat): Handle symlinks.
(fill_filebuf): Evaluate pid if pid is 0. Use exename handling for
exe. Handle maps, root and cwd.
(format_process_maps): New function evaluating "maps".
* path.cc (symlink_info::set): New method to fill symlink_info
with data matching virtual symlinks.
(path_conv::check): Handle virtual symlinks.
* pinfo.cc (_pinfo::commune_recv): Add PICOM_CWD and PICOM_ROOT
handling.
(_pinfo::commune_send): Ditto.
(_pinfo::root): New function.
(_pinfo::cwd): New function.
* pinfo.h (enum picom): Add PICOM_CWD and PICOM_ROOT.
(_pinfo::root): Declare.
(_pinfo::cwd): Declare.
Diffstat (limited to 'winsup/cygwin/fhandler_process.cc')
-rw-r--r-- | winsup/cygwin/fhandler_process.cc | 170 |
1 files changed, 151 insertions, 19 deletions
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 3c996d067..4a14bca56 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -25,30 +25,37 @@ details. */ #include <sys/param.h> #include <assert.h> #include <sys/sysmacros.h> +#include <psapi.h> #define _COMPILING_NEWLIB #include <dirent.h> static const int PROCESS_PPID = 2; -static const int PROCESS_EXENAME = 3; -static const int PROCESS_WINPID = 4; -static const int PROCESS_WINEXENAME = 5; -static const int PROCESS_STATUS = 6; -static const int PROCESS_UID = 7; -static const int PROCESS_GID = 8; -static const int PROCESS_PGID = 9; -static const int PROCESS_SID = 10; -static const int PROCESS_CTTY = 11; -static const int PROCESS_STAT = 12; -static const int PROCESS_STATM = 13; -static const int PROCESS_CMDLINE = 14; +static const int PROCESS_WINPID = 3; +static const int PROCESS_WINEXENAME = 4; +static const int PROCESS_STATUS = 5; +static const int PROCESS_UID = 6; +static const int PROCESS_GID = 7; +static const int PROCESS_PGID = 8; +static const int PROCESS_SID = 9; +static const int PROCESS_CTTY = 10; +static const int PROCESS_STAT = 11; +static const int PROCESS_STATM = 12; +static const int PROCESS_CMDLINE = 13; +static const int PROCESS_MAPS = 14; +/* Keep symlinks always the last entries. */ +static const int PROCESS_ROOT = 15; +static const int PROCESS_EXE = 16; +static const int PROCESS_CWD = 17; + +/* The position of "root" defines the beginning of symlik entries. */ +#define is_symlink(nr) ((nr) >= PROCESS_ROOT) static const char * const process_listing[] = { ".", "..", "ppid", - "exename", "winpid", "winexename", "status", @@ -60,12 +67,18 @@ static const char * const process_listing[] = "stat", "statm", "cmdline", + "maps", + /* Keep symlinks always the last entries. */ + "root", + "exe", + "cwd", NULL }; static const int PROCESS_LINK_COUNT = (sizeof (process_listing) / sizeof (const char *)) - 1; +static _off64_t format_process_maps (_pinfo *p, char *destbuf, size_t maxsize); static _off64_t format_process_stat (_pinfo *p, char *destbuf, size_t maxsize); static _off64_t format_process_status (_pinfo *p, char *destbuf, size_t maxsize); static _off64_t format_process_statm (_pinfo *p, char *destbuf, size_t maxsize); @@ -91,7 +104,10 @@ fhandler_process::exists () for (int i = 0; process_listing[i]; i++) if (pathmatch (path + 1, process_listing[i])) - return -1; + { + fileid = i; + return is_symlink (i) ? -2 : -1; + } return 0; } @@ -137,8 +153,13 @@ fhandler_process::fstat (struct __stat64 *buf) buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; buf->st_nlink = PROCESS_LINK_COUNT; return 0; - default: + case -2: + buf->st_uid = p->uid; + buf->st_gid = p->gid; + buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; + return 0; case -1: + default: buf->st_uid = p->uid; buf->st_gid = p->gid; buf->st_mode |= S_IFREG | S_IRUSR | S_IRGRP | S_IROTH; @@ -251,6 +272,15 @@ out: bool fhandler_process::fill_filebuf () { + if (!pid) + { + const char *path; + path = get_name () + proc_len + 1; + if (path_prefix_p ("self", path, 4)) + pid = getpid (); + else + pid = atoi (path); + } pinfo p (pid); if (!p) @@ -298,12 +328,25 @@ fhandler_process::fill_filebuf () filesize = strlen (filebuf); break; } + case PROCESS_ROOT: + case PROCESS_CWD: case PROCESS_CMDLINE: { - if (filebuf) + if (filebuf) free (filebuf); - size_t fs; - filebuf = p->cmdline (fs); + size_t fs; + switch (fileid) + { + case PROCESS_ROOT: + filebuf = p->root (fs); + break; + case PROCESS_CWD: + filebuf = p->cwd (fs); + break; + case PROCESS_CMDLINE: + filebuf = p->cmdline (fs); + break; + } filesize = fs; if (!filebuf || !*filebuf) { @@ -312,7 +355,7 @@ fhandler_process::fill_filebuf () } break; } - case PROCESS_EXENAME: + case PROCESS_EXE: { filebuf = (char *) realloc (filebuf, bufalloc = CYG_MAX_PATH); if (p->process_state & PID_EXITED) @@ -365,12 +408,101 @@ fhandler_process::fill_filebuf () filesize = format_process_statm (*p, filebuf, bufalloc); break; } + case PROCESS_MAPS: + { + filebuf = (char *) realloc (filebuf, bufalloc = 2048); + filesize = format_process_maps (*p, filebuf, bufalloc); + break; + } } return true; } static _off64_t +format_process_maps (_pinfo *p, char *destbuf, size_t maxsize) +{ + if (!wincap.is_winnt ()) + return 0; + + HANDLE proc = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, + FALSE, + p->dwProcessId); + if (!proc) + return 0; + + _off64_t len = 0; + HMODULE *modules; + DWORD needed, i; + DWORD_PTR wset_size; + DWORD_PTR *workingset = NULL; + MODULEINFO info; + char modname[CYG_MAX_PATH + 1]; + char posix_modname[CYG_MAX_PATH + 1]; + + if (!EnumProcessModules (proc, NULL, 0, &needed)) + { + __seterrno (); + len = -1; + goto out; + } + modules = (HMODULE*) alloca (needed); + if (!EnumProcessModules (proc, modules, needed, &needed)) + { + __seterrno (); + len = -1; + goto out; + } + + QueryWorkingSet (proc, (void *) &wset_size, sizeof wset_size); + if (GetLastError () == ERROR_BAD_LENGTH) + { + workingset = (DWORD_PTR *) alloca (sizeof (DWORD_PTR) * ++wset_size); + if (!QueryWorkingSet (proc, (void *) workingset, + sizeof (DWORD_PTR) * wset_size)) + workingset = NULL; + } + for (i = 0; i < needed / sizeof (HMODULE); i++) + if (GetModuleInformation (proc, modules[i], &info, sizeof info) + && GetModuleFileNameEx (proc, modules[i], modname, sizeof modname)) + { + char access[5]; + strcpy (access, "r--p"); + cygwin_conv_to_full_posix_path (modname, posix_modname); + if (len + strlen (posix_modname) + 50 > maxsize - 1) + break; + if (workingset) + for (unsigned i = 1; i <= wset_size; ++i) + { + DWORD_PTR addr = workingset[i] & 0xfffff000UL; + if ((char *)addr >= info.lpBaseOfDll + && (char *)addr < (char *)info.lpBaseOfDll + info.SizeOfImage) + { + access[0] = (workingset[i] & 0x5) ? 'r' : '-'; + access[1] = (workingset[i] & 0x4) ? 'w' : '-'; + access[2] = (workingset[i] & 0x2) ? 'x' : '-'; + access[3] = (workingset[i] & 0x100) ? 's' : 'p'; + } + } + int written = __small_sprintf (destbuf + len, + "%08lx-%08lx %s %08lx 00:00 %lu ", + info.lpBaseOfDll, + (unsigned long)info.lpBaseOfDll + + info.SizeOfImage, + access, + info.EntryPoint, + info.SizeOfImage); + while (written++ < 49) + destbuf[len + written] = ' '; + len += written; + len += __small_sprintf (destbuf + len, "%s\n", posix_modname); + } +out: + CloseHandle (proc); + return len; +} + +static _off64_t format_process_stat (_pinfo *p, char *destbuf, size_t maxsize) { char cmd[CYG_MAX_PATH]; |