From: Sebastien GODARD Date: Mon, 17 Jul 2017 15:44:56 +0000 (+0200) Subject: Add new option "-e" to pidstat, which can be used to pass a program X-Git-Tag: v11.6.0~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=da65dcc109359f3c55b613c2699209f895028e80;p=sysstat Add new option "-e" to pidstat, which can be used to pass a program to execute and make pidstat monitor it. When the program terminates, pidstat will catch the SIGCHLD signal and display the average statistics. Signed-off-by: Sebastien GODARD --- diff --git a/pidstat.c b/pidstat.c index c718147..c512b47 100644 --- a/pidstat.c +++ b/pidstat.c @@ -71,8 +71,8 @@ unsigned int pidflag = 0; /* General flags */ unsigned int tskflag = 0; /* TASK/CHILD stats */ unsigned int actflag = 0; /* Activity flag */ -struct sigaction alrm_act, int_act; -int sigint_caught = 0; +struct sigaction alrm_act, int_act, chld_act; +int signal_caught = 0; /* *************************************************************************** @@ -84,7 +84,7 @@ int sigint_caught = 0; */ void usage(char *progname) { - fprintf(stderr, _("Usage: %s [ options ] [ [ ] ]\n"), + fprintf(stderr, _("Usage: %s [ options ] [ [ ] ] [ -e ]\n"), progname); fprintf(stderr, _("Options are:\n" @@ -109,15 +109,15 @@ void alarm_handler(int sig) /* *************************************************************************** - * SIGINT signal handler. + * SIGINT and SIGCHLD signals handler. * * IN: * @sig Signal number. *************************************************************************** */ -void int_handler(int sig) +void sig_handler(int sig) { - sigint_caught = 1; + signal_caught = 1; } /* @@ -2512,14 +2512,14 @@ void rw_pidstat_loop(int dis_hdr, int rows) /* Set a handler for SIGINT */ memset(&int_act, 0, sizeof(int_act)); - int_act.sa_handler = int_handler; + int_act.sa_handler = sig_handler; sigaction(SIGINT, &int_act, NULL); /* Wait for SIGALRM (or possibly SIGINT) signal */ pause(); - if (sigint_caught) - /* SIGINT signal caught during first interval: Exit immediately */ + if (signal_caught) + /* SIGINT/SIGCHLD signals caught during first interval: Exit immediately */ return; do { @@ -2561,8 +2561,8 @@ void rw_pidstat_loop(int dis_hdr, int rows) pause(); - if (sigint_caught) { - /* SIGINT signal caught => Display average stats */ + if (signal_caught) { + /* SIGINT/SIGCHLD signals caught => Display average stats */ count = 0; printf("\n"); /* Skip "^C" displayed on screen */ } @@ -2584,6 +2584,61 @@ void rw_pidstat_loop(int dis_hdr, int rows) } } +/* + *************************************************************************** + * Start a program that will be monitored by pidstat. + * + * IN: + * @argc Number of arguments. + * @argv Arguments values. + * + * RETURNS: + * The PID of the program executed. + *************************************************************************** + */ +pid_t exec_pgm(int argc, char **argv) +{ + pid_t child; + char *args[argc + 1]; + int i; + + child = fork(); + + switch(child) { + + case -1: + perror("fork"); + exit(4); + break; + + case 0: + /* Child */ + for (i = 0; i < argc; i++) { + args[i] = argv[i]; + } + args[argc] = NULL; + + execvp(args[0], args); + perror("exec"); + exit(4); + break; + + default: + /* + * Parent. + * Set a handler for SIGCHLD (signal that will be received + * by pidstat when the child program terminates). + * The handler is the same as for SIGINT: Stop and display + * average statistics. + */ + memset(&chld_act, 0, sizeof(chld_act)); + chld_act.sa_handler = sig_handler; + sigaction(SIGCHLD, &chld_act, NULL); + + return child; + } +} + /* *************************************************************************** * Main entry to the pidstat program. @@ -2620,7 +2675,16 @@ int main(int argc, char **argv) /* Process args... */ while (opt < argc) { - if (!strcmp(argv[opt], "-p")) { + if (!strcmp(argv[opt], "-e")) { + if (!argv[++opt]) { + usage(argv[0]); + } + pidflag |= P_D_PID; + update_pid_array(&pid_array_nr, exec_pgm(argc - opt, argv + opt)); + break; + } + + else if (!strcmp(argv[opt], "-p")) { pidflag |= P_D_PID; if (argv[++opt]) {