📄 fhandler_process.cc
字号:
/* fhandler_process.cc: fhandler for /proc/<pid> virtual filesystem Copyright 2002 Red Hat, Inc.This file is part of Cygwin.This software is a copyrighted work licensed under the terms of theCygwin license. Please consult the file "CYGWIN_LICENSE" fordetails. */#include "winsup.h"#include <errno.h>#include <unistd.h>#include <stdlib.h>#include <sys/cygwin.h>#include <ntdef.h>#include "cygerrno.h"#include "security.h"#include "fhandler.h"#include "pinfo.h"#include "path.h"#include "shared_info.h"#include "dtable.h"#include "cygheap.h"#include "ntdll.h"#include <sys/param.h>#include <assert.h>#include <sys/sysmacros.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 char * const process_listing[] ={ ".", "..", "ppid", "exename", "winpid", "winexename", "status", "uid", "gid", "pgid", "sid", "ctty", "stat", "statm", "cmdline", NULL};static const int PROCESS_LINK_COUNT = (sizeof (process_listing) / sizeof (const char *)) - 1;static off_t format_process_stat (_pinfo *p, char *destbuf, size_t maxsize);static off_t format_process_status (_pinfo *p, char *destbuf, size_t maxsize);static off_t format_process_statm (_pinfo *p, char *destbuf, size_t maxsize);static int get_process_state (DWORD dwProcessId);static bool get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, unsigned long *vmtext, unsigned long *vmdata, unsigned long *vmlib, unsigned long *vmshare);/* Returns 0 if path doesn't exist, >0 if path is a directory, * <0 if path is a file. */intfhandler_process::exists (){ const char *path = get_name (); debug_printf ("exists (%s)", path); path += proc_len + 1; while (*path != 0 && !SLASH_P (*path)) path++; if (*path == 0) return 2; for (int i = 0; process_listing[i]; i++) if (pathmatch (path + 1, process_listing[i])) return -1; return 0;}fhandler_process::fhandler_process (): fhandler_proc (FH_PROCESS){}intfhandler_process::fstat (struct __stat64 *buf, path_conv *pc){ const char *path = get_name (); int file_type = exists (); (void) fhandler_base::fstat (buf, pc); path += proc_len + 1; pid = atoi (path); pinfo p (pid); if (!p) { set_errno (ENOENT); return -1; } buf->st_mode &= ~_IFMT & NO_W; switch (file_type) { case 0: 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; time_as_timestruc_t (&buf->st_atim); 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; return 0; default: case -1: buf->st_uid = p->uid; buf->st_gid = p->gid; buf->st_mode |= S_IFREG | S_IRUSR | S_IRGRP | S_IROTH; return 0; }}struct dirent *fhandler_process::readdir (DIR * dir){ if (dir->__d_position >= PROCESS_LINK_COUNT) { set_errno (ENMFILE); 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); return dir->__d_dirent;}intfhandler_process::open (path_conv *pc, int flags, mode_t mode){ int process_file_no = -1; int res = fhandler_virtual::open (pc, flags, mode); if (!res) goto out; set_nohandle (true); const char *path; path = get_name () + proc_len + 1; pid = atoi (path); while (*path != 0 && !SLASH_P (*path)) path++; if (*path == 0) { if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { set_errno (EEXIST); res = 0; goto out; } else if (flags & O_WRONLY) { set_errno (EISDIR); res = 0; goto out; } else { flags |= O_DIROPEN; goto success; } } process_file_no = -1; for (int i = 0; process_listing[i]; i++) { if (path_prefix_p (process_listing[i], path + 1, strlen (process_listing[i]))) process_file_no = i; } if (process_file_no == -1) { if (flags & O_CREAT) { set_errno (EROFS); res = 0; goto out; } else { set_errno (ENOENT); res = 0; goto out; } } if (flags & O_WRONLY) { set_errno (EROFS); res = 0; goto out; } fileid = process_file_no; if (!fill_filebuf ()) { res = 0; goto out; } if (flags & O_APPEND) position = filesize; else position = 0;success: res = 1; set_flags ((flags & ~O_TEXT) | O_BINARY); set_open_status ();out: syscall_printf ("%d = fhandler_proc::open (%p, %d)", res, flags, mode); return res;}boolfhandler_process::fill_filebuf (){ pinfo p (pid); if (!p) { set_errno (ENOENT); return false; } switch (fileid) { case PROCESS_UID: case PROCESS_GID: case PROCESS_PGID: case PROCESS_SID: case PROCESS_CTTY: case PROCESS_PPID: { filebuf = (char *) realloc (filebuf, bufalloc = 40); int num; switch (fileid) { case PROCESS_PPID: num = p->ppid; break; case PROCESS_UID: num = p->uid; break; case PROCESS_PGID: num = p->pgid; break; case PROCESS_SID: num = p->sid; break; case PROCESS_GID: num = p->gid; break; case PROCESS_CTTY: num = p->ctty; break; default: // what's this here for? num = 0; break; } __small_sprintf (filebuf, "%d\n", num); filesize = strlen (filebuf); break; } case PROCESS_CMDLINE: { if (filebuf) free (filebuf); filebuf = p->cmdline (filesize); if (!filebuf || !*filebuf) filebuf = strdup ("<defunct>"); break; } case PROCESS_EXENAME: { filebuf = (char *) realloc (filebuf, bufalloc = MAX_PATH); if (p->process_state & (PID_ZOMBIE | PID_EXITED)) strcpy (filebuf, "<defunct>"); else { mount_table->conv_to_posix_path (p->progname, filebuf, 1); int len = strlen (filebuf); if (len > 4) { char *s = filebuf + len - 4; if (strcasecmp (s, ".exe") == 0) *s = 0; } } filesize = strlen (filebuf); break; } case PROCESS_WINPID: { filebuf = (char *) realloc (filebuf, bufalloc = 40); __small_sprintf (filebuf, "%d\n", p->dwProcessId); filesize = strlen (filebuf); break; } case PROCESS_WINEXENAME: { int len = strlen (p->progname); filebuf = (char *) realloc (filebuf, bufalloc = (len + 2)); strcpy (filebuf, p->progname); filebuf[len] = '\n'; filesize = len + 1; break; } case PROCESS_STATUS: { filebuf = (char *) realloc (filebuf, bufalloc = 2048); filesize = format_process_status (*p, filebuf, bufalloc); break; } case PROCESS_STAT: { filebuf = (char *) realloc (filebuf, bufalloc = 2048); filesize = format_process_stat (*p, filebuf, bufalloc); break; } case PROCESS_STATM: { filebuf = (char *) realloc (filebuf, bufalloc = 2048); filesize = format_process_statm (*p, filebuf, bufalloc); break; } } return true;}staticoff_tformat_process_stat (_pinfo *p, char *destbuf, size_t maxsize){ char cmd[MAX_PATH]; int state = 'R'; unsigned long fault_count = 0UL, utime = 0UL, stime = 0UL, start_time = 0UL, vmsize = 0UL, vmrss = 0UL, vmmaxrss = 0UL; int priority = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -