]> sourceware.org Git - newlib-cygwin.git/commitdiff
* autoload.cc (GetModuleFileNameExA): Add.
authorCorinna Vinschen <corinna@vinschen.de>
Sat, 29 Jan 2005 11:23:07 +0000 (11:23 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Sat, 29 Jan 2005 11:23:07 +0000 (11:23 +0000)
(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.

winsup/cygwin/ChangeLog
winsup/cygwin/autoload.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_proc.cc
winsup/cygwin/fhandler_process.cc
winsup/cygwin/path.cc
winsup/cygwin/pinfo.cc
winsup/cygwin/pinfo.h

index 1b53aa42e7cfac13cb842285d94d427a7d95dd25..40ef4d14a0991d0b394ceb3551ed3e4b737016e6 100644 (file)
@@ -1,3 +1,39 @@
+2005-01-29  Corinna Vinschen  <corinna@vinschen.de>
+
+       * 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.
+
 2005-01-29  Christopher Faylor  <cgf@timesys.com>
 
        * cygthread.cc (new): Add a little more debugging.
index 5c2832a232217bdc741518ef891c7310ee23b987..125b77eb5f0910249af0c71418bce600ed9e05fd 100644 (file)
@@ -392,7 +392,10 @@ LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
 LoadDLLfuncEx (RtlIsDosDeviceName_U, 4, ntdll, 1)
 
 LoadDLLfuncEx (EnumProcessModules, 16, psapi, 1)
+LoadDLLfuncEx (GetModuleFileNameExA, 16, psapi, 1)
+LoadDLLfuncEx (GetModuleInformation, 16, psapi, 1)
 LoadDLLfuncEx (GetProcessMemoryInfo, 12, psapi, 1)
+LoadDLLfuncEx (QueryWorkingSet, 12, psapi, 1)
 
 LoadDLLfuncEx (LsaDeregisterLogonProcess, 4, secur32, 1)
 LoadDLLfuncEx (LsaFreeReturnBuffer, 4, secur32, 1)
index 34b40b83da45fa28ed26f7dc154229ac86c63fdb..f1041c68c6c89a82435ccf0be330b922b71fd433 100644 (file)
@@ -1121,6 +1121,7 @@ class fhandler_virtual : public fhandler_base
   int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
   int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
   virtual bool fill_filebuf ();
+  char *get_filebuf () { return filebuf; }
   void fixup_after_exec ();
 };
 
index 8e94092dfb3a347dfb4478927befffb64fc8ad15..f47a2fd2499b60b8738df9f6ac9c6559eff958a7 100644 (file)
@@ -41,6 +41,7 @@ static const int PROC_VERSION  = 6;     // /proc/version
 static const int PROC_UPTIME   = 7;     // /proc/uptime
 static const int PROC_CPUINFO  = 8;     // /proc/cpuinfo
 static const int PROC_PARTITIONS = 9;   // /proc/partitions
+static const int PROC_SELF     = 10;    // /proc/self
 
 /* names of objects in /proc */
 static const char *proc_listing[] = {
@@ -74,7 +75,7 @@ static const DWORD proc_fhandlers[PROC_LINK_COUNT] = {
   FH_PROC,
   FH_PROC,
   FH_PROC,
-  FH_PROCESS,
+  FH_PROC,
 };
 
 /* name of the /proc filesystem */
@@ -143,7 +144,10 @@ fhandler_proc::exists ()
     return 2;
   for (int i = 0; proc_listing[i]; i++)
     if (pathmatch (path + 1, proc_listing[i]))
-      return (proc_fhandlers[i] == FH_PROC) ? -1 : 1;
+      {
+       fileid = i;
+       return (proc_fhandlers[i] == FH_PROC) ? (i == PROC_SELF ? -3 : -1) : 1;
+      }
   return 0;
 }
 
@@ -177,6 +181,8 @@ fhandler_proc::fstat (struct __stat64 *buf)
          {
            if (proc_fhandlers[i] != FH_PROC)
              buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+           else if (i == PROC_SELF)
+             buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
            else
              {
                buf->st_mode &= NO_X;
@@ -379,6 +385,11 @@ fhandler_proc::fill_filebuf ()
        filesize = format_proc_partitions (filebuf, bufalloc);
        break;
       }
+    case PROC_SELF:
+      {
+        filebuf = (char *) realloc (filebuf, bufalloc = 32);
+       filesize = __small_sprintf (filebuf, "%d", getpid ());
+      }
     }
     return true;
 }
index 3c996d0676a945dd0370c334fc53a0c9d12b8e24..4a14bca56a1fddf5c398d5909c5d9adcc97f3713 100644 (file)
@@ -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,11 +408,100 @@ 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)
 {
index a9d6292d7b422b1bbe4164b93a52af39cef39796..0d2637537b06f1a957cbcb859124896e02956bcc 100644 (file)
@@ -95,6 +95,7 @@ struct symlink_info
   _minor_t minor;
   _mode_t mode;
   int check (char *path, const suffix_info *suffixes, unsigned opt);
+  int set (char *path, int type);
   bool parse_device (const char *);
   bool case_check (char *path);
 };
@@ -616,6 +617,11 @@ path_conv::check (const char *src, unsigned opt,
              /* FIXME: Calling build_fhandler here is not the right way to handle this. */
              fhandler_virtual *fh = (fhandler_virtual *) build_fh_dev (dev, path_copy);
              int file_type = fh->exists ();
+             if (file_type == -2 || file_type == -3)
+               {
+                 fh->fill_filebuf ();
+                 symlen = sym.set (fh->get_filebuf (), file_type);
+               }
              delete fh;
              switch (file_type)
                {
@@ -626,9 +632,12 @@ path_conv::check (const char *src, unsigned opt,
                  case -1:
                    fileattr = 0;
                    break;
+                 case -2:      /* /proc/<pid>/symlinks */
+                 case -3:      /* /proc/self */
+                   goto is_virtual_symlink;
                  default:
                    fileattr = INVALID_FILE_ATTRIBUTES;
-                   break;
+                   goto virtual_component_retry;
                }
              goto out;
            }
@@ -657,6 +666,8 @@ path_conv::check (const char *src, unsigned opt,
 
          symlen = sym.check (full_path, suff, opt | fs.has_ea ());
 
+is_virtual_symlink:
+
          if (sym.minor || sym.major)
            {
              dev.parse (sym.major, sym.minor);
@@ -740,6 +751,8 @@ path_conv::check (const char *src, unsigned opt,
              /* No existing file found. */
            }
 
+virtual_component_retry:
+
          /* Find the new "tail" of the path, e.g. in '/for/bar/baz',
             /baz is the tail. */
          if (tail != path_end)
@@ -3117,6 +3130,34 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
   return res;
 }
 
+/* "path" is the path in a virtual symlink.  Set a symlink_info struct from
+   that and proceed with further path checking afterwards. */
+int
+symlink_info::set (char *path, int type)
+{
+  extern suffix_info stat_suffixes[];
+
+  strcpy (contents, path);
+  pflags = PATH_SYMLINK;
+  if (type == -3) /* /proc/self */
+    {
+      fileattr = FILE_ATTRIBUTE_DIRECTORY;
+      error = 0;
+    }
+  else
+    {
+      /* That's save since a virtual symlink doesn't point to itself. */
+      path_conv pc (contents, PC_SYM_NOFOLLOW | PC_FULL, stat_suffixes);
+      fileattr = pc;
+      error = pc.error;
+    }
+  is_symlink = true;
+  ext_tacked_on = case_clash = false;
+  ext_here = NULL;
+  extn = major = minor = mode = 0;
+  return strlen (path);
+}
+
 /* Check the correct case of the last path component (given in DOS style).
    Adjust the case in this->path if pcheck_case == PCHECK_ADJUST or return
    false if pcheck_case == PCHECK_STRICT.
index 83764651d41ab92502afa2baa56c7f8a8173d13b..fa440aa39c84d046e05a8c58a4140c87b4e76eb6 100644 (file)
@@ -380,6 +380,7 @@ extern char **__argv;
 void
 _pinfo::commune_recv ()
 {
+  char pathbuf[CYG_MAX_PATH];
   DWORD nr;
   DWORD code;
   HANDLE hp;
@@ -457,6 +458,32 @@ _pinfo::commune_recv ()
          }
        break;
       }
+    case PICOM_CWD:
+      {
+       unsigned int n = strlen (cygheap->cwd.get (pathbuf, 1, 1, CYG_MAX_PATH)) + 1;
+        CloseHandle (__fromthem); __fromthem = NULL;
+       CloseHandle (hp);
+       if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
+         sigproc_printf ("WriteFile sizeof argv failed, %E");
+       else if (!WriteFile (__tothem, pathbuf, n, &nr, NULL))
+         sigproc_printf ("WriteFile sizeof argv failed, %E");
+       break;
+      }
+    case PICOM_ROOT:
+      {
+       unsigned int n;
+       if (cygheap->root.exists ())
+         n = strlen (strcpy (pathbuf, cygheap->root.posix_path ())) + 1;
+       else
+         n = strlen (strcpy (pathbuf, "/")) + 1;
+        CloseHandle (__fromthem); __fromthem = NULL;
+       CloseHandle (hp);
+       if (!WriteFile (__tothem, &n, sizeof n, &nr, NULL))
+         sigproc_printf ("WriteFile sizeof argv failed, %E");
+       else if (!WriteFile (__tothem, pathbuf, n, &nr, NULL))
+         sigproc_printf ("WriteFile sizeof argv failed, %E");
+       break;
+      }
     case PICOM_FIFO:
       {
        char path[CYG_MAX_PATH + 1];
@@ -588,6 +615,8 @@ _pinfo::commune_send (DWORD code, ...)
   switch (code)
     {
     case PICOM_CMDLINE:
+    case PICOM_CWD:
+    case PICOM_ROOT:
       if (!ReadFile (fromthem, &n, sizeof n, &nr, NULL) || nr != sizeof n)
        {
          __seterrno ();
@@ -654,6 +683,50 @@ out:
   return res;
 }
 
+char *
+_pinfo::root (size_t& n)
+{
+  char *s;
+  if (!this || !pid)
+    return NULL;
+  if (pid != myself->pid)
+    {
+      commune_result cr = commune_send (PICOM_ROOT);
+      s = cr.s;
+      n = cr.n;
+    }
+  else
+    {
+      if (cygheap->root.exists ())
+       s = strdup (cygheap->root.posix_path ());
+      else
+       s = strdup ("/");
+      n = strlen (s) + 1;
+    }
+  return s;
+}
+
+char *
+_pinfo::cwd (size_t& n)
+{
+  char *s;
+  if (!this || !pid)
+    return NULL;
+  if (pid != myself->pid)
+    {
+      commune_result cr = commune_send (PICOM_CWD);
+      s = cr.s;
+      n = cr.n;
+    }
+  else
+    {
+      s = (char *) malloc (CYG_MAX_PATH);
+      cygheap->cwd.get (s, 1, 1, CYG_MAX_PATH);
+      n = strlen (s) + 1;
+    }
+  return s;
+}
+
 char *
 _pinfo::cmdline (size_t& n)
 {
index 3203a6975b134cfd5312cd0526bd58479e12016a..88442ca226081bda7a9ce55608330313cb0b660b 100644 (file)
@@ -23,7 +23,9 @@ struct commune_result
 enum picom
 {
   PICOM_CMDLINE = 1,
-  PICOM_FIFO = 2
+  PICOM_FIFO = 2,
+  PICOM_CWD = 3,
+  PICOM_ROOT = 4
 };
 
 #define EXITCODE_SET 0x80000000
@@ -106,6 +108,8 @@ public:
   void commune_recv ();
   commune_result commune_send (DWORD, ...);
   bool alive ();
+  char *root (size_t &);
+  char *cwd (size_t &);
   char *cmdline (size_t &);
   void set_ctty (class tty_min *, int, class fhandler_tty_slave *);
   bool dup_proc_pipe (HANDLE) __attribute__ ((regparm(2)));
This page took 0.049564 seconds and 5 git commands to generate.