Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com Message-ID: <20011003125358.52168.qmail@web11501.mail.yahoo.com> Date: Wed, 3 Oct 2001 05:53:58 -0700 (PDT) From: Robert Legros Subject: 1.3.3-2: ps.exe bug for processes with a zero ppid To: cygwin AT cygwin DOT com MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="0-1075666131-1002113638=:50756" --0-1075666131-1002113638=:50756 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hello, There is a follow up to the bug "1.3.3-2: Process creation is possible with ppid = 0 and pgid = 0" . 'ps.exe' does not behave correctly with such processes. This is due to the fact that in the code, there is a criteria to see if a process is a Cygwin one or a Windows one. And that criteria is precisely (p-ppid != 0) !. I have written a patch for 'ps.exe'. It is more a hack than a real bug correction, but it works. In fact the real bug correction must be done somewhere in the process creation routines inside 'cygwin1.dll'. This patch is to be found in attachment. For those who should like to install this correction, here is how to do it. In attachment is the corrected version of 'ps.cc'. Do compile it using the following command : gcc -O2 -s ps.cc -o ps.exe And then install it : cp -p ps.exe /bin Best Regards, ===== Robert Legros south Brussels, Belgium robert_legros AT yahoo DOT com __________________________________________________ Do You Yahoo!? Listen to your Yahoo! Mail messages from any phone. http://phone.yahoo.com --0-1075666131-1002113638=:50756 Content-Type: text/plain; name="ps.cc-patch" Content-Description: ps.cc-patch Content-Disposition: inline; filename="ps.cc-patch" diff -upr cygwin-1.3.3-2/winsup/utils/ps.cc cygwin-1.3.3-2.new/winsup/utils/ps.cc --- cygwin-1.3.3-2/winsup/utils/ps.cc Tue May 8 05:55:40 2001 +++ cygwin-1.3.3-2.new/winsup/utils/ps.cc Wed Oct 3 14:11:24 2001 @@ -271,7 +271,7 @@ main (int argc, char *argv[]) char pname[MAX_PATH]; if (p->process_state & (PID_ZOMBIE | PID_EXITED)) strcpy (pname, ""); - else if (p->ppid) + else if (p->ctty != -1) /* THIS IS HACK ! REALLY ! */ { char *s; pname[0] = '\0'; --0-1075666131-1002113638=:50756 Content-Type: text/plain; name=ChangeLog Content-Description: ChangeLog Content-Disposition: inline; filename=ChangeLog 2001-10-03 Robert Legros * ps.cc (main): Change criteria to recognize a Cygwin process from (p->ppid) to (p->ctty != -1). This is a hack since the real bug (ppid is allowed to be zero) is inside 'cygwin1.dll'. --0-1075666131-1002113638=:50756 Content-Type: text/plain; name="ps.cc" Content-Description: ps.cc Content-Disposition: inline; filename="ps.cc" /* ps.cc Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions. 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. */ #include #include #include #include #include #include #include #include #include #include typedef BOOL (WINAPI *ENUMPROCESSMODULES)( HANDLE hProcess, // handle to the process HMODULE * lphModule, // array to receive the module handles DWORD cb, // size of the array LPDWORD lpcbNeeded // receives the number of bytes returned ); typedef DWORD (WINAPI *GETMODULEFILENAME)( HANDLE hProcess, HMODULE hModule, LPTSTR lpstrFileName, DWORD nSize ); typedef HANDLE (WINAPI *CREATESNAPSHOT)( DWORD dwFlags, DWORD th32ProcessID ); // Win95 functions typedef BOOL (WINAPI *PROCESSWALK)( HANDLE hSnapshot, LPPROCESSENTRY32 lppe ); ENUMPROCESSMODULES myEnumProcessModules; GETMODULEFILENAME myGetModuleFileNameEx; CREATESNAPSHOT myCreateToolhelp32Snapshot; PROCESSWALK myProcess32First; PROCESSWALK myProcess32Next; static BOOL WINAPI dummyprocessmodules ( HANDLE hProcess, // handle to the process HMODULE * lphModule, // array to receive the module handles DWORD cb, // size of the array LPDWORD lpcbNeeded // receives the number of bytes returned ) { lphModule[0] = (HMODULE) *lpcbNeeded; *lpcbNeeded = 1; return 1; } static DWORD WINAPI GetModuleFileNameEx95 ( HANDLE hProcess, HMODULE hModule, LPTSTR lpstrFileName, DWORD n ) { HANDLE h; DWORD pid = (DWORD) hModule; h = myCreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); if (!h) return 0; PROCESSENTRY32 proc; proc.dwSize = sizeof (proc); if (myProcess32First(h, &proc)) do if (proc.th32ProcessID == pid) { CloseHandle (h); strcpy (lpstrFileName, proc.szExeFile); return 1; } while (myProcess32Next (h, &proc)); CloseHandle (h); return 0; } int init_win () { OSVERSIONINFO os_version_info; memset (&os_version_info, 0, sizeof os_version_info); os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&os_version_info); HMODULE h; if (os_version_info.dwPlatformId == VER_PLATFORM_WIN32_NT) { h = LoadLibrary ("psapi.dll"); if (!h) return 0; myEnumProcessModules = (ENUMPROCESSMODULES) GetProcAddress (h, "EnumProcessModules"); myGetModuleFileNameEx = (GETMODULEFILENAME) GetProcAddress (h, "GetModuleFileNameExA"); if (!myEnumProcessModules || !myGetModuleFileNameEx) return 0; return 1; } h = GetModuleHandle("KERNEL32.DLL"); myCreateToolhelp32Snapshot = (CREATESNAPSHOT)GetProcAddress (h, "CreateToolhelp32Snapshot"); myProcess32First = (PROCESSWALK)GetProcAddress (h, "Process32First"); myProcess32Next = (PROCESSWALK)GetProcAddress (h, "Process32Next"); if (!myCreateToolhelp32Snapshot || !myProcess32First || !myProcess32Next) return 0; myEnumProcessModules = dummyprocessmodules; myGetModuleFileNameEx = GetModuleFileNameEx95; return 1; } static char * start_time (external_pinfo *child) { time_t st = child->start_time; time_t t = time (NULL); static char stime[40] = {'\0'}; char now[40]; strncpy (stime, ctime (&st) + 4, 15); strcpy (now, ctime (&t) + 4); if ((t - st) < (24 * 3600)) return (stime + 7); stime[6] = '\0'; return stime; } #define FACTOR (0x19db1ded53ea710LL) #define NSPERSEC 10000000LL /* Convert a Win32 time to "UNIX" format. */ long __stdcall to_time_t (FILETIME *ptr) { /* A file time is the number of 100ns since jan 1 1601 stuffed into two long words. A time_t is the number of seconds since jan 1 1970. */ long rem; long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned)ptr->dwLowDateTime); x -= FACTOR; /* number of 100ns between 1601 and 1970 */ rem = x % ((long long)NSPERSEC); rem += (NSPERSEC / 2); x /= (long long) NSPERSEC; /* number of 100ns in a second */ x += (long long) (rem / NSPERSEC); return x; } static const char * ttynam (int ntty) { static char buf[5]; if (ntty < 0) return " ?"; if (ntty == TTY_CONSOLE) return " con"; sprintf (buf, "%4d", ntty); return buf; } int main (int argc, char *argv[]) { external_pinfo *p; int aflag, lflag, fflag, sflag, uid; cygwin_getinfo_types query = CW_GETPINFO; const char *dtitle = " PID TTY STIME COMMAND\n"; const char *dfmt = "%7d%4s%10s %s\n"; const char *ftitle = " UID PID PPID TTY STIME COMMAND\n"; const char *ffmt = "%8.8s%8d%8d%4s%10s %s\n"; const char *ltitle = " PID PPID PGID WINPID TTY UID STIME COMMAND\n"; const char *lfmt = "%c %7d %7d %7d %10u %4s %4d %8s %s\n"; char ch; aflag = lflag = fflag = sflag = 0; uid = getuid (); lflag = 1; while ((ch = getopt (argc, argv, "aelfsu:W")) != -1) switch (ch) { case 'a': case 'e': aflag = 1; break; case 'f': fflag = 1; break; case 'l': lflag = 1; break; case 's': sflag = 1; break; case 'u': uid = atoi (optarg); if (uid == 0) { struct passwd *pw; if ((pw = getpwnam (optarg))) uid = pw->pw_uid; else { fprintf (stderr, "user %s unknown\n", optarg); exit (1); } } break; case 'W': query = CW_GETPINFO_FULL; aflag = 1; break; default: fprintf (stderr, "Usage %s [-aefl] [-u uid]\n", argv[0]); fprintf (stderr, "-f = show process uids, ppids\n"); fprintf (stderr, "-l = show process uids, ppids, pgids, winpids\n"); fprintf (stderr, "-u uid = list processes owned by uid\n"); fprintf (stderr, "-a, -e = show processes of all users\n"); fprintf (stderr, "-s = show process summary\n"); fprintf (stderr, "-W = show windows as well as cygwin processes\n"); exit (1); } if (sflag) printf (dtitle); else if (fflag) printf (ftitle); else if (lflag) printf (ltitle); (void) cygwin_internal (CW_LOCK_PINFO, 1000); if (query == CW_GETPINFO_FULL && !init_win ()) query = CW_GETPINFO; for (int pid = 0; (p = (external_pinfo *) cygwin_internal (query, pid | CW_NEXTPID)); pid = p->pid) { if (!aflag && p->uid != uid) continue; char status = ' '; if (p->process_state & PID_STOPPED) status = 'S'; else if (p->process_state & PID_TTYIN) status = 'I'; else if (p->process_state & PID_TTYOU) status = 'O'; char pname[MAX_PATH]; if (p->process_state & (PID_ZOMBIE | PID_EXITED)) strcpy (pname, ""); else if (p->ctty != -1) /* THIS IS HACK ! REALLY ! */ { char *s; pname[0] = '\0'; cygwin_conv_to_posix_path (p->progname, pname); s = strchr (pname, '\0') - 4; if (s > pname && strcasecmp (s, ".exe") == 0) *s = '\0'; } else if (query == CW_GETPINFO_FULL) { HANDLE h = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, p->dwProcessId); if (!h) continue; HMODULE hm[1000]; DWORD n = p->dwProcessId; if (!myEnumProcessModules (h, hm, sizeof (hm), &n)) n = 0; if (!n || !myGetModuleFileNameEx (h, hm[0], pname, MAX_PATH)) strcpy (pname, "*** unknown ***"); FILETIME ct, et, kt, ut; if (GetProcessTimes (h, &ct, &et, &kt, &ut)) p->start_time = to_time_t (&ct); CloseHandle (h); } char uname[128]; if (fflag) { struct passwd *pw; if ((pw = getpwuid (p->uid))) strcpy (uname, pw->pw_name); else sprintf (uname, "%d", p->uid); } if (sflag) printf (dfmt, p->pid, ttynam (p->ctty), start_time (p), pname); else if (fflag) printf (ffmt, uname, p->pid, p->ppid, ttynam (p->ctty), start_time (p), pname); else if (lflag) printf (lfmt, status, p->pid, p->ppid, p->pgid, p->dwProcessId, ttynam (p->ctty), p->uid, start_time (p), pname); } (void) cygwin_internal (CW_UNLOCK_PINFO); return 0; } --0-1075666131-1002113638=:50756 Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --0-1075666131-1002113638=:50756--