struct tm ps_tstamp[3];
char commstr[MAX_COMM_LEN];
char userstr[MAX_USER_LEN];
+char procstr[MAX_COMM_LEN];
+int show_threads = FALSE;
unsigned int pid_nr = 0; /* Nb of PID to display */
unsigned int pid_array_nr = 0;
fprintf(stderr, _("Options are:\n"
"[ -d ] [ -h ] [ -I ] [ -l ] [ -r ] [ -s ] [ -t ] [ -U [ <username> ] ] [ -u ]\n"
- "[ -V ] [ -v ] [ -w ] [ -C <command> ] [ -p { <pid> [,...] | SELF | ALL } ]\n"
- "[ -T { TASK | CHILD | ALL } ]\n"));
+ "[ -V ] [ -v ] [ -w ] [ -C <command> ] [ -G <process_name> ]\n"
+ "[ -p { <pid> [,...] | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ]\n"));
exit(1);
}
* Get current PID to display.
* First, check that PID exists. *Then* check that it's an active process
* and/or that the string (entered on the command line with option -C)
- * is found in command name.
+ * is found in command name, or that the process string (entered on the
+ * command line with option -G) is found either in its command name (in case
+ * PID is a process) or in command name of its thread leader (in case
+ * PID is a thread).
*
* IN:
* @prev Index in array where stats used as reference are.
return -1;
}
+ if (PROCESS_STRING(pidflag)) {
+ if (!(*pstc)->tgid) {
+ /* This PID is a process ("thread group leader") */
+ if (regcomp(®ex, procstr, REG_EXTENDED | REG_NOSUB) != 0) {
+ /* Error in preparing regex structure */
+ show_threads = FALSE;
+ return -1;
+ }
+
+ rc = regexec(®ex, (*pstc)->comm, 0, NULL, 0);
+ regfree(®ex);
+
+ if (rc) {
+ /* regex pattern not found in command name */
+ show_threads = FALSE;
+ return -1;
+ }
+
+ /*
+ * This process and all its threads will be displayed.
+ * No need to save PID value: For every process read by pidstat,
+ * pidstat then immediately reads all its threads.
+ */
+ show_threads = TRUE;
+ }
+ else if (!show_threads) {
+ /* This pid is a thread and is not part of a process to display */
+ return -1;
+ }
+ }
+
if (USER_STRING(pidflag)) {
if ((pwdent = getpwuid((*pstc)->uid)) != NULL) {
if (strcmp(pwdent->pw_name, userstr))
itv = g_itv;
}
+ if (PROCESS_STRING(pidflag)) {
+ /* Reset "show threads" flag */
+ show_threads = FALSE;
+ }
+
if (DISPLAY_ONELINE(pidflag)) {
if (DISPLAY_TASK_STATS(tskflag)) {
again += write_pid_task_all_stats(prev, curr, dis,
}
}
+ else if (!strcmp(argv[opt], "-G")) {
+ if (argv[++opt]) {
+ strncpy(procstr, argv[opt++], MAX_COMM_LEN);
+ procstr[MAX_COMM_LEN - 1] = '\0';
+ pidflag |= P_F_PROCSTR;
+ if (!strlen(procstr)) {
+ usage(argv[0]);
+ }
+ }
+ else {
+ usage(argv[0]);
+ }
+ }
+
else if (!strcmp(argv[opt], "-T")) {
if (argv[++opt]) {
if (tskflag) {
#define P_D_CMDLINE 0x080
#define P_D_USERNAME 0x100
#define P_F_USERSTR 0x200
+#define P_F_PROCSTR 0x400
#define DISPLAY_PID(m) (((m) & P_D_PID) == P_D_PID)
#define DISPLAY_ALL_PID(m) (((m) & P_D_ALL_PID) == P_D_ALL_PID)
#define DISPLAY_CMDLINE(m) (((m) & P_D_CMDLINE) == P_D_CMDLINE)
#define DISPLAY_USERNAME(m) (((m) & P_D_USERNAME) == P_D_USERNAME)
#define USER_STRING(m) (((m) & P_F_USERSTR) == P_F_USERSTR)
+#define PROCESS_STRING(m) (((m) & P_F_PROCSTR) == P_F_PROCSTR)
/* Per-process flags */
#define F_NO_PID_IO 0x01