146 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* pldd.c
 | 
						|
 | 
						|
   Copyright 2012 Red Hat, Inc.
 | 
						|
 | 
						|
This file is part of Cygwin.
 | 
						|
 | 
						|
This software is a copyrighted work licensed under the terms of the
 | 
						|
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 | 
						|
details. */
 | 
						|
 | 
						|
#define WIN32_LEAN_AND_MEAN
 | 
						|
#define UNICODE
 | 
						|
#include <errno.h>
 | 
						|
#include <error.h>
 | 
						|
#include <getopt.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <sys/cygwin.h>
 | 
						|
#include <cygwin/version.h>
 | 
						|
#include <windows.h>
 | 
						|
#include <psapi.h>
 | 
						|
 | 
						|
struct option longopts[] =
 | 
						|
{
 | 
						|
  {"help", no_argument, NULL, '?'},
 | 
						|
  {"version", no_argument, NULL, 'V'},
 | 
						|
  {"usage", no_argument, NULL, 0},
 | 
						|
  {0, no_argument, NULL, 0}
 | 
						|
};
 | 
						|
const char *opts = "?V";
 | 
						|
 | 
						|
__attribute__((noreturn))
 | 
						|
static void
 | 
						|
print_help (void)
 | 
						|
{
 | 
						|
  printf ("Usage: pldd [OPTION...] PID\n\n"
 | 
						|
	  "List dynamic shared objects loaded into a process.\n\n"
 | 
						|
	  "  -?, --help                 Give this help list\n"
 | 
						|
	  "      --usage                Give a short usage message\n"
 | 
						|
	  "  -V, --version              Print program version\n");
 | 
						|
  exit (EXIT_SUCCESS);
 | 
						|
}
 | 
						|
 | 
						|
__attribute__((noreturn))
 | 
						|
static void
 | 
						|
print_usage (void)
 | 
						|
{
 | 
						|
  printf ("Usage: pldd [-?V] [--help] [--usage] [--version] PID\n");
 | 
						|
  exit (EXIT_SUCCESS);
 | 
						|
}
 | 
						|
 | 
						|
__attribute__((noreturn))
 | 
						|
static void
 | 
						|
print_version ()
 | 
						|
{
 | 
						|
  printf ("pldd (cygwin) %d.%d.%d\n"
 | 
						|
	  "List dynamic shared objects loaded into process.\n"
 | 
						|
	  "Copyright (C) 2012 Red Hat, Inc.\n\n"
 | 
						|
	  "This program comes with NO WARRANTY, to the extent permitted by law.\n"
 | 
						|
	  "You may redistribute copies of this program under the terms of\n"
 | 
						|
	  "the Cygwin license. Please consult the CYGWIN_LICENSE file for details.\n",
 | 
						|
	  CYGWIN_VERSION_DLL_MAJOR / 1000,
 | 
						|
	  CYGWIN_VERSION_DLL_MAJOR % 1000,
 | 
						|
	  CYGWIN_VERSION_DLL_MINOR);
 | 
						|
  exit (EXIT_SUCCESS);
 | 
						|
}
 | 
						|
 | 
						|
__attribute__((noreturn))
 | 
						|
static void
 | 
						|
print_nargs (void)
 | 
						|
{
 | 
						|
  fprintf (stderr, "Exactly one parameter with process ID required.\n"
 | 
						|
                   "Try `pldd --help' or `pldd --usage' for more information.\n");
 | 
						|
  exit (EXIT_FAILURE);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
main (int argc, char *argv[])
 | 
						|
{
 | 
						|
  int optch, pid, winpid, i;
 | 
						|
  char *pidfile, *exefile, *exename;
 | 
						|
  FILE *fd;
 | 
						|
  HANDLE hProcess;
 | 
						|
  HMODULE hModules[1024];
 | 
						|
  DWORD cbModules;
 | 
						|
 | 
						|
  while ((optch = getopt_long (argc, argv, opts, longopts, &optind)) != -1)
 | 
						|
    switch (optch)
 | 
						|
      {
 | 
						|
      case '?':
 | 
						|
        print_help ();
 | 
						|
        break;
 | 
						|
      case 'V':
 | 
						|
        print_version ();
 | 
						|
        break;
 | 
						|
      case 0:
 | 
						|
        if (strcmp ("usage", longopts[optind].name) == 0)
 | 
						|
          print_usage ();
 | 
						|
        break;
 | 
						|
      default:
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
  argc -= optind;
 | 
						|
  argv += optind;
 | 
						|
  if (argc != 1)
 | 
						|
    print_nargs ();
 | 
						|
 | 
						|
  pid = atoi (argv[0]);
 | 
						|
 | 
						|
  if ((pid == 0))
 | 
						|
    error (1, 0, "invalid process ID '%s'", argv[0]);
 | 
						|
 | 
						|
  pidfile = (char *) malloc (32);
 | 
						|
  sprintf (pidfile, "/proc/%d/winpid", pid);
 | 
						|
  fd = fopen (pidfile, "rb");
 | 
						|
  if (!fd)
 | 
						|
    error (1, ENOENT, "cannot open /proc/%d", pid);
 | 
						|
  fscanf (fd, "%d", &winpid);
 | 
						|
 | 
						|
  exefile = (char *) malloc (32);
 | 
						|
  exename = (char *) malloc (MAX_PATH);
 | 
						|
  sprintf (exefile, "/proc/%d/exename", pid);
 | 
						|
  fd = fopen (exefile, "rb");
 | 
						|
  fscanf (fd, "%s", exename);
 | 
						|
 | 
						|
  hProcess = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, winpid);
 | 
						|
  if (!hProcess)
 | 
						|
    error (1, EPERM, "cannot attach to process %d", pid);
 | 
						|
 | 
						|
  printf ("%d:\t%s\n", pid, exename);
 | 
						|
 | 
						|
  EnumProcessModules (hProcess, hModules, sizeof (hModules), &cbModules);
 | 
						|
  /* start at 1 to skip the executable itself */
 | 
						|
  for (i = 1; i < (cbModules / sizeof (HMODULE)); i++)
 | 
						|
    {
 | 
						|
      TCHAR winname[MAX_PATH];
 | 
						|
      char posixname[MAX_PATH];
 | 
						|
      GetModuleFileNameEx (hProcess, hModules[i], winname, MAX_PATH);
 | 
						|
      cygwin_conv_path (CCP_WIN_W_TO_POSIX, winname, posixname, MAX_PATH);
 | 
						|
      printf ("%s\n", posixname);
 | 
						|
    }
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 |