]> granicus.if.org Git - sysstat/blob - pidstat.c
sar: Display values in human readable format
[sysstat] / pidstat.c
1 /*
2  * pidstat: Report statistics for Linux tasks
3  * (C) 2007-2016 by Sebastien GODARD (sysstat <at> orange.fr)
4  *
5  ***************************************************************************
6  * This program is free software; you can redistribute it and/or modify it *
7  * under the terms of the GNU General Public License as published  by  the *
8  * Free Software Foundation; either version 2 of the License, or (at  your *
9  * option) any later version.                                              *
10  *                                                                         *
11  * This program is distributed in the hope that it  will  be  useful,  but *
12  * WITHOUT ANY WARRANTY; without the implied warranty  of  MERCHANTABILITY *
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
14  * for more details.                                                       *
15  *                                                                         *
16  * You should have received a copy of the GNU General Public License along *
17  * with this program; if not, write to the Free Software Foundation, Inc., *
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA              *
19  ***************************************************************************
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <signal.h>
28 #include <dirent.h>
29 #include <ctype.h>
30 #include <sys/types.h>
31 #include <pwd.h>
32 #include <sys/utsname.h>
33 #include <regex.h>
34 #include <linux/sched.h>
35
36 #include "version.h"
37 #include "pidstat.h"
38 #include "common.h"
39 #include "rd_stats.h"
40 #include "count.h"
41
42 #ifdef USE_NLS
43 #include <locale.h>
44 #include <libintl.h>
45 #define _(string) gettext(string)
46 #else
47 #define _(string) (string)
48 #endif
49
50 #define SCCSID "@(#)sysstat-" VERSION ": " __FILE__ " compiled " __DATE__ " " __TIME__
51 char *sccsid(void) { return (SCCSID); }
52
53 unsigned long long uptime[3] = {0, 0, 0};
54 unsigned long long uptime0[3] = {0, 0, 0};
55 struct pid_stats *st_pid_list[3] = {NULL, NULL, NULL};
56 unsigned int *pid_array = NULL;
57 struct pid_stats st_pid_null;
58 struct tm ps_tstamp[3];
59 char commstr[MAX_COMM_LEN];
60 char userstr[MAX_USER_LEN];
61 char procstr[MAX_COMM_LEN];
62 int show_threads = FALSE;
63
64 unsigned int pid_nr = 0;        /* Nb of PID to display */
65 unsigned int pid_array_nr = 0;
66 int cpu_nr = 0;                 /* Nb of processors on the machine */
67 unsigned long tlmkb;            /* Total memory in kB */
68 long interval = -1;
69 long count = 0;
70 unsigned int pidflag = 0;       /* General flags */
71 unsigned int tskflag = 0;       /* TASK/CHILD stats */
72 unsigned int actflag = 0;       /* Activity flag */
73
74 struct sigaction alrm_act, int_act;
75 int sigint_caught = 0;
76
77 /*
78  ***************************************************************************
79  * Print usage and exit.
80  *
81  * IN:
82  * @progname    Name of sysstat command
83  ***************************************************************************
84  */
85 void usage(char *progname)
86 {
87         fprintf(stderr, _("Usage: %s [ options ] [ <interval> [ <count> ] ]\n"),
88                 progname);
89
90         fprintf(stderr, _("Options are:\n"
91                           "[ -d ] [ -h ] [ -I ] [ -l ] [ -R ] [ -r ] [ -s ] [ -t ] [ -U [ <username> ] ]\n"
92                           "[ -u ] [ -V ] [ -v ] [ -w ] [ -C <command> ] [ -G <process_name> ]\n"
93                           "[ -p { <pid> [,...] | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ]\n"));
94         exit(1);
95 }
96
97 /*
98  ***************************************************************************
99  * SIGALRM signal handler. No need to resert the handler here.
100  *
101  * IN:
102  * @sig Signal number.
103  ***************************************************************************
104  */
105 void alarm_handler(int sig)
106 {
107         alarm(interval);
108 }
109
110 /*
111  ***************************************************************************
112  * SIGINT signal handler.
113  *
114  * IN:
115  * @sig Signal number.
116  ***************************************************************************
117  */
118 void int_handler(int sig)
119 {
120         sigint_caught = 1;
121 }
122
123 /*
124  ***************************************************************************
125  * Initialize uptime variables.
126  ***************************************************************************
127  */
128 void init_stats(void)
129 {
130         memset(&st_pid_null, 0, PID_STATS_SIZE);
131 }
132
133 /*
134  ***************************************************************************
135  * Allocate structures for PIDs entered on command line.
136  *
137  * IN:
138  * @len Number of PIDs entered on the command line.
139  ***************************************************************************
140  */
141 void salloc_pid_array(unsigned int len)
142 {
143         if ((pid_array = (unsigned int *) malloc(sizeof(unsigned int) * len)) == NULL) {
144                 perror("malloc");
145                 exit(4);
146         }
147         memset(pid_array, 0, sizeof(int) * len);
148 }
149
150 /*
151  ***************************************************************************
152  * Allocate structures for PIDs to read.
153  *
154  * IN:
155  * @len Number of PIDs (and TIDs) on the system.
156  ***************************************************************************
157  */
158 void salloc_pid(unsigned int len)
159 {
160         short i;
161
162         for (i = 0; i < 3; i++) {
163                 if ((st_pid_list[i] = (struct pid_stats *) calloc(len, PID_STATS_SIZE)) == NULL) {
164                         perror("calloc");
165                         exit(4);
166                 }
167         }
168 }
169
170 /*
171  ***************************************************************************
172  * Reallocate structures for PIDs to read.
173  ***************************************************************************
174  */
175 void realloc_pid(void)
176 {
177         short i;
178         unsigned int new_size = 2 * pid_nr;
179
180         for (i = 0; i < 3; i++) {
181                 if ((st_pid_list[i] = (struct pid_stats *) realloc(st_pid_list[i], PID_STATS_SIZE * new_size)) == NULL) {
182                         perror("realloc");
183                         exit(4);
184                 }
185                 memset(st_pid_list[i] + pid_nr, 0, PID_STATS_SIZE * (new_size - pid_nr));
186         }
187
188         pid_nr = new_size;
189 }
190
191 /*
192  ***************************************************************************
193  * Free PID list structures.
194  ***************************************************************************
195  */
196 void sfree_pid(void)
197 {
198         int i;
199
200         for (i = 0; i < 3; i++) {
201                 free(st_pid_list[i]);
202         }
203 }
204
205 /*
206  ***************************************************************************
207  * Check flags and set default values.
208  ***************************************************************************
209  */
210 void check_flags(void)
211 {
212         unsigned int act = 0;
213
214         /* Display CPU usage for active tasks by default */
215         if (!actflag) {
216                 actflag |= P_A_CPU;
217         }
218
219         if (!DISPLAY_PID(pidflag)) {
220                 pidflag |= P_D_ACTIVE_PID + P_D_PID + P_D_ALL_PID;
221         }
222
223         if (!tskflag) {
224                 tskflag |= P_TASK;
225         }
226
227         /* Check that requested activities are available */
228         if (DISPLAY_TASK_STATS(tskflag)) {
229                 act |= P_A_CPU + P_A_MEM + P_A_IO + P_A_CTXSW
230                      + P_A_STACK + P_A_KTAB + P_A_RT;
231         }
232         if (DISPLAY_CHILD_STATS(tskflag)) {
233                 act |= P_A_CPU + P_A_MEM;
234         }
235
236         actflag &= act;
237
238         if (!actflag) {
239                 fprintf(stderr, _("Requested activities not available\n"));
240                 exit(1);
241         }
242 }
243
244 /*
245  ***************************************************************************
246  * Look for the PID in the list of PIDs entered on the command line, and
247  * store it if necessary.
248  *
249  * IN:
250  * @pid_array_nr        Length of the PID list.
251  * @pid                 PID to search.
252  *
253  * OUT:
254  * @pid_array_nr        New length of the PID list.
255  *
256  * RETURNS:
257  * Returns the position of the PID in the list.
258  ***************************************************************************
259  */
260 int update_pid_array(unsigned int *pid_array_nr, unsigned int pid)
261 {
262         unsigned int i;
263
264         for (i = 0; i < *pid_array_nr; i++) {
265                 if (pid_array[i] == pid)
266                         break;
267         }
268
269         if (i == *pid_array_nr) {
270                 /* PID not found: Store it */
271                 (*pid_array_nr)++;
272                 pid_array[i] = pid;
273         }
274
275         return i;
276 }
277
278 /*
279  ***************************************************************************
280  * Get pointer on task's command string.
281  *
282  * IN:
283  * @pst         Pointer on structure with process stats and command line.
284  ***************************************************************************
285  */
286 char *get_tcmd(struct pid_stats *pst)
287 {
288         if (DISPLAY_CMDLINE(pidflag) && strlen(pst->cmdline))
289                 /* Option "-l" used */
290                 return pst->cmdline;
291         else
292                 return pst->comm;
293 }
294
295 /*
296  ***************************************************************************
297  * Display process command name or command line.
298  *
299  * IN:
300  * @pst         Pointer on structure with process stats and command line.
301  ***************************************************************************
302  */
303 void print_comm(struct pid_stats *pst)
304 {
305         char *p;
306
307         /* Get pointer on task's command string */
308         p = get_tcmd(pst);
309
310         if (pst->tgid) {
311                 cprintf_s(IS_ZERO, "  |__%s\n", p);
312         }
313         else {
314                 cprintf_s(IS_STR, "  %s\n", p);
315         }
316 }
317
318 /*
319  ***************************************************************************
320  * Read /proc/meminfo.
321  ***************************************************************************
322  */
323 void read_proc_meminfo(void)
324 {
325         struct stats_memory st_mem;
326
327         memset(&st_mem, 0, STATS_MEMORY_SIZE);
328         read_meminfo(&st_mem);
329         tlmkb = st_mem.tlmkb;
330 }
331
332 /*
333  ***************************************************************************
334  * Read stats from /proc/#[/task/##]/stat.
335  *
336  * IN:
337  * @pid         Process whose stats are to be read.
338  * @pst         Pointer on structure where stats will be saved.
339  * @tgid        If !=0, thread whose stats are to be read.
340  *
341  * OUT:
342  * @pst         Pointer on structure where stats have been saved.
343  * @thread_nr   Number of threads of the process.
344  *
345  * RETURNS:
346  * 0 if stats have been successfully read, and 1 otherwise.
347  ***************************************************************************
348  */
349 int read_proc_pid_stat(unsigned int pid, struct pid_stats *pst,
350                        unsigned int *thread_nr, unsigned int tgid)
351 {
352         int fd, sz, rc, commsz;
353         char filename[128];
354         static char buffer[1024 + 1];
355         char *start, *end;
356
357         if (tgid) {
358                 sprintf(filename, TASK_STAT, tgid, pid);
359         }
360         else {
361                 sprintf(filename, PID_STAT, pid);
362         }
363
364         if ((fd = open(filename, O_RDONLY)) < 0)
365                 /* No such process */
366                 return 1;
367
368         sz = read(fd, buffer, 1024);
369         close(fd);
370         if (sz <= 0)
371                 return 1;
372         buffer[sz] = '\0';
373
374         if ((start = strchr(buffer, '(')) == NULL)
375                 return 1;
376         start += 1;
377         if ((end = strrchr(start, ')')) == NULL)
378                 return 1;
379         commsz = end - start;
380         if (commsz >= MAX_COMM_LEN)
381                 return 1;
382         memcpy(pst->comm, start, commsz);
383         pst->comm[commsz] = '\0';
384         start = end + 2;
385
386         rc = sscanf(start,
387                     "%*s %*d %*d %*d %*d %*d %*u %llu %llu"
388                     " %llu %llu %llu %llu %lld %lld %*d %*d %u %*u %*d %llu %llu"
389                     " %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u"
390                     " %*u %u %u %u %llu %llu %lld\n",
391                     &pst->minflt, &pst->cminflt, &pst->majflt, &pst->cmajflt,
392                     &pst->utime,  &pst->stime, &pst->cutime, &pst->cstime,
393                     thread_nr, &pst->vsz, &pst->rss, &pst->processor,
394                     &pst->priority, &pst->policy,
395                     &pst->blkio_swapin_delays, &pst->gtime, &pst->cgtime);
396
397         if (rc < 15)
398                 return 1;
399
400         if (rc < 17) {
401                 /* gtime and cgtime fields are unavailable in file */
402                 pst->gtime = pst->cgtime = 0;
403         }
404
405         /* Convert to kB */
406         pst->vsz >>= 10;
407         pst->rss = PG_TO_KB(pst->rss);
408
409         pst->pid = pid;
410         pst->tgid = tgid;
411         return 0;
412 }
413
414 /*
415  *****************************************************************************
416  * Read stats from /proc/#[/task/##]/status.
417  *
418  * IN:
419  * @pid         Process whose stats are to be read.
420  * @pst         Pointer on structure where stats will be saved.
421  * @tgid        If !=0, thread whose stats are to be read.
422  *
423  * OUT:
424  * @pst         Pointer on structure where stats have been saved.
425  *
426  * RETURNS:
427  * 0 if stats have been successfully read, and 1 otherwise.
428  *****************************************************************************
429  */
430 int read_proc_pid_status(unsigned int pid, struct pid_stats *pst,
431                          unsigned int tgid)
432 {
433         FILE *fp;
434         char filename[128], line[256];
435
436         if (tgid) {
437                 sprintf(filename, TASK_STATUS, tgid, pid);
438         }
439         else {
440                 sprintf(filename, PID_STATUS, pid);
441         }
442
443         if ((fp = fopen(filename, "r")) == NULL)
444                 /* No such process */
445                 return 1;
446
447         while (fgets(line, sizeof(line), fp) != NULL) {
448
449                 if (!strncmp(line, "Uid:", 4)) {
450                         sscanf(line + 5, "%u", &pst->uid);
451                 }
452                 else if (!strncmp(line, "Threads:", 8)) {
453                         sscanf(line + 9, "%u", &pst->threads);
454                 }
455                 else if (!strncmp(line, "voluntary_ctxt_switches:", 24)) {
456                         sscanf(line + 25, "%lu", &pst->nvcsw);
457                 }
458                 else if (!strncmp(line, "nonvoluntary_ctxt_switches:", 27)) {
459                         sscanf(line + 28, "%lu", &pst->nivcsw);
460                 }
461         }
462
463         fclose(fp);
464
465         pst->pid = pid;
466         pst->tgid = tgid;
467         return 0;
468 }
469
470 /*
471   *****************************************************************************
472   * Read information from /proc/#[/task/##}/smaps.
473   *
474   * @pid                Process whose stats are to be read.
475   * @pst                Pointer on structure where stats will be saved.
476   * @tgid               If !=0, thread whose stats are to be read.
477   *
478   * OUT:
479   * @pst                Pointer on structure where stats have been saved.
480   *
481   * RETURNS:
482   * 0 if stats have been successfully read, and 1 otherwise.
483   *****************************************************************************
484   */
485 int read_proc_pid_smap(unsigned int pid, struct pid_stats *pst, unsigned int tgid)
486 {
487         FILE *fp;
488         char filename[128], line[256];
489         int state = 0;
490
491         if (tgid) {
492                 sprintf(filename, TASK_SMAP, tgid, pid);
493         }
494         else {
495                 sprintf(filename, PID_SMAP, pid);
496         }
497
498         if ((fp = fopen(filename, "rt")) == NULL)
499                 /* No such process */
500                 return 1;
501
502         while ((state < 3) && (fgets(line, sizeof(line), fp) != NULL)) {
503                 switch (state) {
504                         case 0:
505                                 if (strstr(line, "[stack]")) {
506                                         state = 1;
507                                 }
508                                 break;
509                         case 1:
510                                 if (strstr(line, "Size:")) {
511                                         sscanf(line + sizeof("Size:"), "%lu", &pst->stack_size);
512                                         state = 2;
513                                 }
514                                 break;
515                         case 2:
516                                 if (strstr(line, "Referenced:")) {
517                                         sscanf(line + sizeof("Referenced:"), "%lu", &pst->stack_ref);
518                                         state = 3;
519                                 }
520                                 break;
521                 }
522         }
523
524         fclose(fp);
525
526         pst->pid = pid;
527         pst->tgid = tgid;
528         return 0;
529 }
530
531 /*
532  *****************************************************************************
533  * Read process command line from /proc/#[/task/##]/cmdline.
534  *
535  * IN:
536  * @pid         Process whose command line is to be read.
537  * @pst         Pointer on structure where command line will be saved.
538  * @tgid        If !=0, thread whose command line is to be read.
539  *
540  * OUT:
541  * @pst         Pointer on structure where command line has been saved.
542  *
543  * RETURNS:
544  * 0 if command line has been successfully read (even if the /proc/.../cmdline
545  * is just empty), and 1 otherwise (the process has terminated).
546  *****************************************************************************
547  */
548 int read_proc_pid_cmdline(unsigned int pid, struct pid_stats *pst,
549                           unsigned int tgid)
550 {
551         FILE *fp;
552         char filename[128], line[MAX_CMDLINE_LEN];
553         size_t len;
554         int i;
555
556         if (tgid) {
557                 sprintf(filename, TASK_CMDLINE, tgid, pid);
558         }
559         else {
560                 sprintf(filename, PID_CMDLINE, pid);
561         }
562
563         if ((fp = fopen(filename, "r")) == NULL)
564                 /* No such process */
565                 return 1;
566
567         memset(line, 0, MAX_CMDLINE_LEN);
568
569         len = fread(line, 1, MAX_CMDLINE_LEN - 1, fp);
570         fclose(fp);
571
572         for (i = 0; i < len; i++) {
573                 if (line[i] == '\0') {
574                         line[i] = ' ';
575                 }
576         }
577
578         if (len) {
579                 strncpy(pst->cmdline, line, MAX_CMDLINE_LEN - 1);
580                 pst->cmdline[MAX_CMDLINE_LEN - 1] = '\0';
581         }
582         else {
583                 /* proc/.../cmdline was empty */
584                 pst->cmdline[0] = '\0';
585         }
586         return 0;
587 }
588
589 /*
590  ***************************************************************************
591  * Read stats from /proc/#[/task/##]/io.
592  *
593  * IN:
594  * @pid         Process whose stats are to be read.
595  * @pst         Pointer on structure where stats will be saved.
596  * @tgid        If !=0, thread whose stats are to be read.
597  *
598  * OUT:
599  * @pst         Pointer on structure where stats have been saved.
600  *
601  * RETURNS:
602  * 0 if stats have been successfully read.
603  * Also returns 0 if current process has terminated or if its io file
604  * doesn't exist, but in this case, set process' F_NO_PID_IO flag to
605  * indicate that I/O stats should no longer be read for it.
606  ***************************************************************************
607  */
608 int read_proc_pid_io(unsigned int pid, struct pid_stats *pst,
609                      unsigned int tgid)
610 {
611         FILE *fp;
612         char filename[128], line[256];
613
614         if (tgid) {
615                 sprintf(filename, TASK_IO, tgid, pid);
616         }
617         else {
618                 sprintf(filename, PID_IO, pid);
619         }
620
621         if ((fp = fopen(filename, "r")) == NULL) {
622                 /* No such process... or file non existent! */
623                 pst->flags |= F_NO_PID_IO;
624                 /*
625                  * Also returns 0 since io stats file doesn't necessarily exist,
626                  * depending on the kernel version used.
627                  */
628                 return 0;
629         }
630
631         while (fgets(line, sizeof(line), fp) != NULL) {
632
633                 if (!strncmp(line, "read_bytes:", 11)) {
634                         sscanf(line + 12, "%llu", &pst->read_bytes);
635                 }
636                 else if (!strncmp(line, "write_bytes:", 12)) {
637                         sscanf(line + 13, "%llu", &pst->write_bytes);
638                 }
639                 else if (!strncmp(line, "cancelled_write_bytes:", 22)) {
640                         sscanf(line + 23, "%llu", &pst->cancelled_write_bytes);
641                 }
642         }
643
644         fclose(fp);
645
646         pst->pid = pid;
647         pst->tgid = tgid;
648         pst->flags &= ~F_NO_PID_IO;
649         return 0;
650 }
651
652 /*
653  ***************************************************************************
654  * Count number of file descriptors in /proc/#[/task/##]/fd directory.
655  *
656  * IN:
657  * @pid         Process whose stats are to be read.
658  * @pst         Pointer on structure where stats will be saved.
659  * @tgid        If !=0, thread whose stats are to be read.
660  *
661  * OUT:
662  * @pst         Pointer on structure where stats have been saved.
663  *
664  * RETURNS:
665  * 0 if stats have been successfully read.
666  * Also returns 0 if current process has terminated or if we cannot read its
667  * fd directory, but in this case, set process' F_NO_PID_FD flag to
668  * indicate that fd directory couldn't be read.
669  ***************************************************************************
670  */
671 int read_proc_pid_fd(unsigned int pid, struct pid_stats *pst,
672                      unsigned int tgid)
673 {
674         DIR *dir;
675         struct dirent *drp;
676         char filename[128];
677
678         if (tgid) {
679                 sprintf(filename, TASK_FD, tgid, pid);
680         }
681         else {
682                 sprintf(filename, PID_FD, pid);
683         }
684
685         if ((dir = opendir(filename)) == NULL) {
686                 /* Cannot read fd directory */
687                 pst->flags |= F_NO_PID_FD;
688                 return 0;
689         }
690
691         pst->fd_nr = 0;
692
693         /* Count number of entries if fd directory */
694         while ((drp = readdir(dir)) != NULL) {
695                 if (isdigit(drp->d_name[0])) {
696                         (pst->fd_nr)++;
697                 }
698         }
699
700         closedir(dir);
701
702         pst->pid = pid;
703         pst->tgid = tgid;
704         pst->flags &= ~F_NO_PID_FD;
705         return 0;
706 }
707
708 /*
709  ***************************************************************************
710  * Read various stats for given PID.
711  *
712  * IN:
713  * @pid         Process whose stats are to be read.
714  * @pst         Pointer on structure where stats will be saved.
715  * @tgid        If !=0, thread whose stats are to be read.
716  *
717  * OUT:
718  * @pst         Pointer on structure where stats have been saved.
719  * @thread_nr   Number of threads of the process.
720  *
721  * RETURNS:
722  * 0 if stats have been successfully read, and 1 otherwise.
723  ***************************************************************************
724  */
725 int read_pid_stats(unsigned int pid, struct pid_stats *pst,
726                    unsigned int *thread_nr, unsigned int tgid)
727 {
728         if (read_proc_pid_stat(pid, pst, thread_nr, tgid))
729                 return 1;
730
731         if (DISPLAY_CMDLINE(pidflag)) {
732                 if (read_proc_pid_cmdline(pid, pst, tgid))
733                         return 1;
734         }
735
736         if (read_proc_pid_status(pid, pst, tgid))
737                 return 1;
738
739         if (DISPLAY_STACK(actflag)) {
740                 if (read_proc_pid_smap(pid, pst, tgid))
741                         return 1;
742         }
743
744         if (DISPLAY_KTAB(actflag)) {
745                 if (read_proc_pid_fd(pid, pst, tgid))
746                         return 1;
747         }
748
749         if (DISPLAY_IO(actflag))
750                 /* Assume that /proc/#/task/#/io exists! */
751                 return (read_proc_pid_io(pid, pst, tgid));
752
753         return 0;
754 }
755
756 /*
757  ***************************************************************************
758  * Count number of threads in /proc/#/task directory, including the leader
759  * one.
760  *
761  * IN:
762  * @pid Process number for which the number of threads are to be counted.
763  *
764  * RETURNS:
765  * Number of threads for the given process (min value is 1).
766  * A value of 0 indicates that the process has terminated.
767  ***************************************************************************
768  */
769 unsigned int count_tid(unsigned int pid)
770 {
771         struct pid_stats pst;
772         unsigned int thread_nr;
773
774         if (read_proc_pid_stat(pid, &pst, &thread_nr, 0) != 0)
775                 /* Task no longer exists */
776                 return 0;
777
778         return thread_nr;
779 }
780
781 /*
782  ***************************************************************************
783  * Count number of processes (and threads).
784  *
785  * RETURNS:
786  * Number of processes (and threads if requested).
787  ***************************************************************************
788  */
789 unsigned int count_pid(void)
790 {
791         DIR *dir;
792         struct dirent *drp;
793         unsigned int pid = 0;
794
795         /* Open /proc directory */
796         if ((dir = opendir(PROC)) == NULL) {
797                 perror("opendir");
798                 exit(4);
799         }
800
801         /* Get directory entries */
802         while ((drp = readdir(dir)) != NULL) {
803                 if (isdigit(drp->d_name[0])) {
804                         /* There is at least the TGID */
805                         pid++;
806                         if (DISPLAY_TID(pidflag)) {
807                                 pid += count_tid(atoi(drp->d_name));
808                         }
809                 }
810         }
811
812         /* Close /proc directory */
813         closedir(dir);
814
815         return pid;
816 }
817
818 /*
819  ***************************************************************************
820  * Count number of threads associated with the tasks entered on the command
821  * line.
822  *
823  * RETURNS:
824  * Number of threads (including the leading one) associated with every task
825  * entered on the command line.
826  ***************************************************************************
827  */
828 unsigned int count_tid_in_list(void)
829 {
830         unsigned int p, tid, pid = 0;
831
832         for (p = 0; p < pid_array_nr; p++) {
833
834                 tid = count_tid(pid_array[p]);
835
836                 if (!tid) {
837                         /* PID no longer exists */
838                         pid_array[p] = 0;
839                 }
840                 else {
841                         /* <tid_value> TIDs + 1 TGID */
842                         pid += tid + 1;
843                 }
844         }
845
846         return pid;
847 }
848
849 /*
850  ***************************************************************************
851  * Allocate and init structures according to system state.
852  ***************************************************************************
853  */
854 void pid_sys_init(void)
855 {
856         /* Init stat common counters */
857         init_stats();
858
859         /* Count nb of proc */
860         cpu_nr = get_cpu_nr(~0, FALSE);
861
862         if (DISPLAY_ALL_PID(pidflag)) {
863                 /* Count PIDs and allocate structures */
864                 pid_nr = count_pid() + NR_PID_PREALLOC;
865                 salloc_pid(pid_nr);
866         }
867         else if (DISPLAY_TID(pidflag)) {
868                 /* Count total number of threads associated with tasks in list */
869                 pid_nr = count_tid_in_list() + NR_PID_PREALLOC;
870                 salloc_pid(pid_nr);
871         }
872         else {
873                 pid_nr = pid_array_nr;
874                 salloc_pid(pid_nr);
875         }
876 }
877
878 /*
879  ***************************************************************************
880  * Read stats for threads in /proc/#/task directory.
881  *
882  * IN:
883  * @curr        Index in array for current sample statistics.
884  * @pid         Process number whose threads stats are to be read.
885  * @index       Index in process list where stats will be saved.
886  *
887  * OUT:
888  * @index       Index in process list where next stats will be saved.
889  ***************************************************************************
890  */
891 void read_task_stats(int curr, unsigned int pid, unsigned int *index)
892 {
893         DIR *dir;
894         struct dirent *drp;
895         char filename[128];
896         struct pid_stats *pst;
897         unsigned int thr_nr;
898
899         /* Open /proc/#/task directory */
900         sprintf(filename, PROC_TASK, pid);
901         if ((dir = opendir(filename)) == NULL)
902                 return;
903
904         while ((drp = readdir(dir)) != NULL) {
905                 if (!isdigit(drp->d_name[0])) {
906                         continue;
907                 }
908
909                 pst = st_pid_list[curr] + (*index)++;
910                 if (read_pid_stats(atoi(drp->d_name), pst, &thr_nr, pid)) {
911                         /* Thread no longer exists */
912                         pst->pid = 0;
913                 }
914
915                 if (*index >= pid_nr) {
916                         realloc_pid();
917                 }
918         }
919
920         closedir(dir);
921 }
922
923 /*
924  ***************************************************************************
925  * Read various stats.
926  *
927  * IN:
928  * @curr        Index in array for current sample statistics.
929  ***************************************************************************
930  */
931 void read_stats(int curr)
932 {
933         DIR *dir;
934         struct dirent *drp;
935         unsigned int p = 0, q, pid, thr_nr;
936         struct pid_stats *pst;
937         struct stats_cpu *st_cpu;
938
939         /*
940          * Allocate two structures for CPU statistics.
941          * No need to init them (done by read_stat_cpu() function).
942          */
943         if ((st_cpu = (struct stats_cpu *) malloc(STATS_CPU_SIZE * 2)) == NULL) {
944                 perror("malloc");
945                 exit(4);
946         }
947         /* Read statistics for CPUs "all" and 0 */
948         read_stat_cpu(st_cpu, 2, &uptime[curr], &uptime0[curr]);
949         free(st_cpu);
950
951         if (DISPLAY_ALL_PID(pidflag)) {
952
953                 /* Open /proc directory */
954                 if ((dir = opendir(PROC)) == NULL) {
955                         perror("opendir");
956                         exit(4);
957                 }
958
959                 /* Get directory entries */
960                 while ((drp = readdir(dir)) != NULL) {
961                         if (!isdigit(drp->d_name[0])) {
962                                 continue;
963                         }
964
965                         pst = st_pid_list[curr] + p++;
966                         pid = atoi(drp->d_name);
967
968                         if (read_pid_stats(pid, pst, &thr_nr, 0)) {
969                                 /* Process has terminated */
970                                 pst->pid = 0;
971                         } else if (DISPLAY_TID(pidflag)) {
972                                 /* Read stats for threads in task subdirectory */
973                                 read_task_stats(curr, pid, &p);
974                         }
975
976                         if (p >= pid_nr) {
977                                 realloc_pid();
978                         }
979                 }
980
981                 for (q = p; q < pid_nr; q++) {
982                         pst = st_pid_list[curr] + q;
983                         pst->pid = 0;
984                 }
985
986                 /* Close /proc directory */
987                 closedir(dir);
988         }
989
990         else if (DISPLAY_PID(pidflag)) {
991                 unsigned int op;
992
993                 /* Read stats for each PID in the list */
994                 for (op = 0; op < pid_array_nr; op++) {
995
996                         if (p >= pid_nr)
997                                 break;
998                         pst = st_pid_list[curr] + p++;
999
1000                         if (pid_array[op]) {
1001                                 /* PID should still exist. So read its stats */
1002                                 if (read_pid_stats(pid_array[op], pst, &thr_nr, 0)) {
1003                                         /* PID has terminated */
1004                                         pst->pid = 0;
1005                                         pid_array[op] = 0;
1006                                 }
1007                                 else if (DISPLAY_TID(pidflag)) {
1008                                         read_task_stats(curr, pid_array[op], &p);
1009                                 }
1010                         }
1011                 }
1012                 /* Reset remaining structures */
1013                 for (q = p; q < pid_nr; q++) {
1014                         pst = st_pid_list[curr] + q;
1015                         pst->pid = 0;
1016                 }
1017
1018         }
1019         /* else unknown command */
1020 }
1021
1022 /*
1023  ***************************************************************************
1024  * Get current PID to display.
1025  * First, check that PID exists. *Then* check that it's an active process
1026  * and/or that the string (entered on the command line with option -C)
1027  * is found in command name, or that the process string (entered on the
1028  * command line with option -G) is found either in its command name (in case
1029  * PID is a process) or in command name of its thread leader (in case
1030  * PID is a thread).
1031  *
1032  * IN:
1033  * @prev        Index in array where stats used as reference are.
1034  * @curr        Index in array for current sample statistics.
1035  * @p           Index in process list.
1036  * @activity    Current activity to display (CPU, memory...).
1037  *              Can be more than one if stats are displayed on one line.
1038  * @pflag       Flag indicating whether stats are to be displayed for
1039  *              individual tasks or for all their children.
1040  *
1041  * OUT:
1042  * @pstc        Structure with PID statistics for current sample.
1043  * @pstp        Structure with PID statistics for previous sample.
1044  *
1045  * RETURNS:
1046  *  0 if PID no longer exists.
1047  * -1 if PID exists but should not be displayed.
1048  *  1 if PID can be displayed.
1049  ***************************************************************************
1050  */
1051 int get_pid_to_display(int prev, int curr, int p, unsigned int activity,
1052                        unsigned int pflag,
1053                        struct pid_stats **pstc, struct pid_stats **pstp)
1054 {
1055         int q, rc;
1056         regex_t regex;
1057         struct passwd *pwdent;
1058         char *pc;
1059
1060         *pstc = st_pid_list[curr] + p;
1061
1062         if (!(*pstc)->pid)
1063                 /* PID no longer exists */
1064                 return 0;
1065
1066         if (DISPLAY_ALL_PID(pidflag) || DISPLAY_TID(pidflag)) {
1067
1068                 /* Look for previous stats for same PID */
1069                 q = p;
1070
1071                 do {
1072                         *pstp = st_pid_list[prev] + q;
1073                         if (((*pstp)->pid == (*pstc)->pid) &&
1074                             ((*pstp)->tgid == (*pstc)->tgid))
1075                                 break;
1076                         q++;
1077                         if (q >= pid_nr) {
1078                                 q = 0;
1079                         }
1080                 }
1081                 while (q != p);
1082
1083                 if (((*pstp)->pid != (*pstc)->pid) ||
1084                     ((*pstp)->tgid != (*pstc)->tgid)) {
1085                         /* PID not found (no data previously read) */
1086                         *pstp = &st_pid_null;
1087                 }
1088
1089                 if (DISPLAY_ACTIVE_PID(pidflag)) {
1090                         int isActive = FALSE;
1091
1092                         /* Check that it's an "active" process */
1093                         if (DISPLAY_CPU(activity)) {
1094                                 /* User time already includes guest time */
1095                                 if (((*pstc)->utime != (*pstp)->utime) ||
1096                                     ((*pstc)->stime != (*pstp)->stime)) {
1097                                         isActive = TRUE;
1098                                 }
1099                                 else {
1100                                         /*
1101                                          * Process is not active but if we are showing
1102                                          * child stats then we need to look there.
1103                                          */
1104                                         if (DISPLAY_CHILD_STATS(pflag)) {
1105                                                 /* User time already includes guest time */
1106                                                 if (((*pstc)->cutime != (*pstp)->cutime) ||
1107                                                     ((*pstc)->cstime != (*pstp)->cstime)) {
1108                                                         isActive = TRUE;
1109                                                 }
1110                                         }
1111                                 }
1112                         }
1113
1114                         if (DISPLAY_MEM(activity) && (!isActive)) {
1115                                 if (((*pstc)->minflt != (*pstp)->minflt) ||
1116                                     ((*pstc)->majflt != (*pstp)->majflt)) {
1117                                         isActive = TRUE;
1118                                 }
1119                                 else {
1120                                         if (DISPLAY_TASK_STATS(pflag)) {
1121                                                 if (((*pstc)->vsz != (*pstp)->vsz) ||
1122                                                     ((*pstc)->rss != (*pstp)->rss)) {
1123                                                         isActive = TRUE;
1124                                                 }
1125                                         }
1126                                         else if (DISPLAY_CHILD_STATS(pflag)) {
1127                                                 if (((*pstc)->cminflt != (*pstp)->cminflt) ||
1128                                                     ((*pstc)->cmajflt != (*pstp)->cmajflt)) {
1129                                                         isActive = TRUE;
1130                                                 }
1131                                         }
1132                                 }
1133                         }
1134
1135
1136                         if (DISPLAY_STACK(activity) && (!isActive)) {
1137                                 if (((*pstc)->stack_size  != (*pstp)->stack_size) ||
1138                                     ((*pstc)->stack_ref != (*pstp)->stack_ref)) {
1139                                         isActive = TRUE;
1140                                 }
1141                         }
1142
1143                         if (DISPLAY_IO(activity) && (!isActive)) {
1144                                 if ((*pstc)->blkio_swapin_delays !=
1145                                      (*pstp)->blkio_swapin_delays) {
1146                                         isActive = TRUE;
1147                                 }
1148                                 if (!(NO_PID_IO((*pstc)->flags)) && (!isActive)) {
1149                                         /* /proc/#/io file should exist to check I/O stats */
1150                                         if (((*pstc)->read_bytes  != (*pstp)->read_bytes)  ||
1151                                             ((*pstc)->write_bytes != (*pstp)->write_bytes) ||
1152                                             ((*pstc)->cancelled_write_bytes !=
1153                                              (*pstp)->cancelled_write_bytes)) {
1154                                                 isActive = TRUE;
1155                                         }
1156                                 }
1157                         }
1158
1159                         if (DISPLAY_CTXSW(activity) && (!isActive)) {
1160                                 if (((*pstc)->nvcsw  != (*pstp)->nvcsw) ||
1161                                     ((*pstc)->nivcsw != (*pstp)->nivcsw)) {
1162                                         isActive = TRUE;
1163                                 }
1164                         }
1165
1166                         if (DISPLAY_RT(activity) && (!isActive)) {
1167                                 if (((*pstc)->priority != (*pstp)->priority) ||
1168                                     ((*pstc)->policy != (*pstp)->policy)) {
1169                                         isActive = TRUE;
1170                                 }
1171                         }
1172
1173                         if (DISPLAY_KTAB(activity) && (!isActive) &&
1174                                 /* /proc/#/fd directory should be readable */
1175                                 !(NO_PID_FD((*pstc)->flags))) {
1176                                 if (((*pstc)->threads != (*pstp)->threads) ||
1177                                     ((*pstc)->fd_nr != (*pstp)->fd_nr)) {
1178                                         isActive = TRUE;
1179                                 }
1180                         }
1181
1182                         /* If PID isn't active for any of the activities then return */
1183                         if (!isActive)
1184                                 return -1;
1185                 }
1186         }
1187
1188         else if (DISPLAY_PID(pidflag)) {
1189                 *pstp = st_pid_list[prev] + p;
1190                 if (!(*pstp)->pid) {
1191                         if (interval)
1192                                 /* PID no longer exists */
1193                                 return 0;
1194                         else {
1195                                 /*
1196                                  * If interval is zero, then we are trying to
1197                                  * display stats for a given process since boot time.
1198                                  */
1199                                 *pstp = &st_pid_null;
1200                         }
1201                 }
1202         }
1203
1204         if (COMMAND_STRING(pidflag)) {
1205                 if (regcomp(&regex, commstr, REG_EXTENDED | REG_NOSUB) != 0)
1206                         /* Error in preparing regex structure */
1207                         return -1;
1208
1209                 pc = get_tcmd(*pstc);   /* Get pointer on task's command string */
1210                 rc = regexec(&regex, pc, 0, NULL, 0);
1211                 regfree(&regex);
1212
1213                 if (rc)
1214                         /* regex pattern not found in command name */
1215                         return -1;
1216         }
1217
1218         if (PROCESS_STRING(pidflag)) {
1219                 if (!(*pstc)->tgid) {
1220                         /* This PID is a process ("thread group leader") */
1221                         if (regcomp(&regex, procstr, REG_EXTENDED | REG_NOSUB) != 0) {
1222                                 /* Error in preparing regex structure */
1223                                 show_threads = FALSE;
1224                                 return -1;
1225                         }
1226
1227                         pc = get_tcmd(*pstc);   /* Get pointer on task's command string */
1228                         rc = regexec(&regex, pc, 0, NULL, 0);
1229                         regfree(&regex);
1230
1231                         if (rc) {
1232                                 /* regex pattern not found in command name */
1233                                 show_threads = FALSE;
1234                                 return -1;
1235                         }
1236
1237                         /*
1238                          * This process and all its threads will be displayed.
1239                          * No need to save PID value: For every process read by pidstat,
1240                          * pidstat then immediately reads all its threads.
1241                          */
1242                         show_threads = TRUE;
1243                 }
1244                 else if (!show_threads) {
1245                         /* This pid is a thread and is not part of a process to display */
1246                         return -1;
1247                 }
1248         }
1249
1250         if (USER_STRING(pidflag)) {
1251                 if ((pwdent = getpwuid((*pstc)->uid)) != NULL) {
1252                         if (strcmp(pwdent->pw_name, userstr))
1253                                 /* This PID doesn't belong to user */
1254                                 return -1;
1255                 }
1256         }
1257
1258         return 1;
1259 }
1260
1261 /*
1262  ***************************************************************************
1263  * Display UID/username, PID and TID.
1264  *
1265  * IN:
1266  * @pst         Current process statistics.
1267  * @c           No-op character.
1268  ***************************************************************************
1269  */
1270 void __print_line_id(struct pid_stats *pst, char c)
1271 {
1272         char format[32];
1273         struct passwd *pwdent;
1274
1275         if (DISPLAY_USERNAME(pidflag) && ((pwdent = getpwuid(pst->uid)) != NULL)) {
1276                 cprintf_in(IS_STR, " %8s", pwdent->pw_name, 0);
1277         }
1278         else {
1279                 cprintf_in(IS_INT, " %5d", "", pst->uid);
1280         }
1281
1282         if (DISPLAY_TID(pidflag)) {
1283
1284                 if (pst->tgid) {
1285                         /* This is a TID */
1286                         sprintf(format, "         %c %%9u", c);
1287                 }
1288                 else {
1289                         /* This is a PID (TGID) */
1290                         sprintf(format, " %%9u         %c", c);
1291                 }
1292         }
1293         else {
1294                 strcpy(format, " %9u");
1295         }
1296
1297         cprintf_in(IS_INT, format, "", pst->pid);
1298 }
1299
1300 /*
1301  ***************************************************************************
1302  * Display timestamp, PID and TID.
1303  *
1304  * IN:
1305  * @timestamp   Current timestamp.
1306  * @pst         Current process statistics.
1307  ***************************************************************************
1308  */
1309 void print_line_id(char *timestamp, struct pid_stats *pst)
1310 {
1311         printf("%-11s", timestamp);
1312
1313         __print_line_id(pst, '-');
1314 }
1315
1316 /*
1317  ***************************************************************************
1318  * Display all statistics for tasks in one line format.
1319  *
1320  * IN:
1321  * @prev        Index in array where stats used as reference are.
1322  * @curr        Index in array for current sample statistics.
1323  * @dis         TRUE if a header line must be printed.
1324  * @itv         Interval of time in jiffies.
1325  * @g_itv       Interval of time in jiffies multiplied by the number of
1326  *              processors.
1327  *
1328  * RETURNS:
1329  * 0 if all the processes to display have terminated.
1330  * <> 0 if there are still some processes left to display.
1331  ***************************************************************************
1332  */
1333 int write_pid_task_all_stats(int prev, int curr, int dis,
1334                              unsigned long long itv,
1335                              unsigned long long g_itv)
1336 {
1337         struct pid_stats *pstc, *pstp;
1338         char dstr[32];
1339         unsigned int p;
1340         int again = 0;
1341
1342         if (dis) {
1343                 PRINT_ID_HDR("#      Time", pidflag);
1344                 if (DISPLAY_CPU(actflag)) {
1345                         printf("    %%usr %%system  %%guest    %%CPU   CPU");
1346                 }
1347                 if (DISPLAY_MEM(actflag)) {
1348                         printf("  minflt/s  majflt/s     VSZ     RSS   %%MEM");
1349                 }
1350                 if (DISPLAY_STACK(actflag)) {
1351                         printf(" StkSize  StkRef");
1352                 }
1353                 if (DISPLAY_IO(actflag)) {
1354                         printf("   kB_rd/s   kB_wr/s kB_ccwr/s iodelay");
1355                 }
1356                 if (DISPLAY_CTXSW(actflag)) {
1357                         printf("   cswch/s nvcswch/s");
1358                 }
1359                 if (DISPLAY_KTAB(actflag)) {
1360                         printf(" threads   fd-nr");
1361                 }
1362                 if (DISPLAY_RT(actflag)) {
1363                         printf(" prio policy");
1364                 }
1365                 printf("  Command\n");
1366         }
1367
1368         for (p = 0; p < pid_nr; p++) {
1369
1370                 if (get_pid_to_display(prev, curr, p, actflag, P_TASK,
1371                                        &pstc, &pstp) <= 0)
1372                         continue;
1373
1374                 printf("%11ld", (long) time(NULL));
1375                 __print_line_id(pstc, '0');
1376
1377                 if (DISPLAY_CPU(actflag)) {
1378                         cprintf_pc(4, 7, 2,
1379                                    (pstc->utime - pstc->gtime) < (pstp->utime - pstp->gtime) ?
1380                                    0.0 :
1381                                    SP_VALUE_100(pstp->utime - pstp->gtime,
1382                                             pstc->utime - pstc->gtime, itv),
1383                                    SP_VALUE_100(pstp->stime,  pstc->stime, itv),
1384                                    SP_VALUE_100(pstp->gtime,  pstc->gtime, itv),
1385                                    /* User time already includes guest time */
1386                                    IRIX_MODE_OFF(pidflag) ?
1387                                    SP_VALUE_100(pstp->utime + pstp->stime,
1388                                             pstc->utime + pstc->stime, g_itv) :
1389                                    SP_VALUE_100(pstp->utime + pstp->stime,
1390                                             pstc->utime + pstc->stime, itv));
1391
1392                         cprintf_in(IS_INT, "   %3d", "", pstc->processor);
1393                 }
1394
1395                 if (DISPLAY_MEM(actflag)) {
1396                         cprintf_f(-1, 2, 9, 2,
1397                                   S_VALUE(pstp->minflt, pstc->minflt, itv),
1398                                   S_VALUE(pstp->majflt, pstc->majflt, itv));
1399                         cprintf_u64(-1, 2, 7,
1400                                     (unsigned long long) pstc->vsz,
1401                                     (unsigned long long) pstc->rss);
1402                         cprintf_pc(1, 6, 2,
1403                                    tlmkb ? SP_VALUE(0, pstc->rss, tlmkb) : 0.0);
1404                 }
1405
1406                 if (DISPLAY_STACK(actflag)) {
1407                         cprintf_u64(-1, 2, 7,
1408                                     (unsigned long long) pstc->stack_size,
1409                                     (unsigned long long) pstc->stack_ref);
1410                 }
1411
1412                 if (DISPLAY_IO(actflag)) {
1413                         if (!NO_PID_IO(pstc->flags))
1414                         {
1415                                 cprintf_f(-1, 3, 9, 2,
1416                                           S_VALUE(pstp->read_bytes,  pstc->read_bytes, itv)  / 1024,
1417                                           S_VALUE(pstp->write_bytes, pstc->write_bytes, itv) / 1024,
1418                                           S_VALUE(pstp->cancelled_write_bytes,
1419                                                   pstc->cancelled_write_bytes, itv) / 1024);
1420                         }
1421                         else {
1422                                 /*
1423                                  * Keep the layout even though this task has no I/O
1424                                  * typically threads with no I/O measurements.
1425                                  */
1426                                 sprintf(dstr, " %9.2f %9.2f %9.2f", -1.0, -1.0, -1.0);
1427                                 cprintf_s(IS_ZERO, "%s", dstr);
1428                         }
1429                         /* I/O delays come from another file (/proc/#/stat) */
1430                         cprintf_u64(-1, 1, 7,
1431                                     (unsigned long long) (pstc->blkio_swapin_delays - pstp->blkio_swapin_delays));
1432                 }
1433
1434                 if (DISPLAY_CTXSW(actflag)) {
1435                         cprintf_f(-1, 2, 9, 2,
1436                                   S_VALUE(pstp->nvcsw, pstc->nvcsw, itv),
1437                                   S_VALUE(pstp->nivcsw, pstc->nivcsw, itv));
1438                 }
1439
1440                 if (DISPLAY_KTAB(actflag)) {
1441                         cprintf_u64(-1, 1, 7,
1442                                     (unsigned long long) pstc->threads);
1443                         if (NO_PID_FD(pstc->flags)) {
1444                                 /* /proc/#/fd directory not readable */
1445                                 cprintf_s(IS_ZERO, " %7s", "-1");
1446                         }
1447                         else {
1448                                 cprintf_u64(-1, 1, 7, (unsigned long long) pstc->fd_nr);
1449                         }
1450                 }
1451
1452                 if (DISPLAY_RT(actflag)) {
1453                         cprintf_u64(-1, 1, 4,
1454                                     (unsigned long long) pstc->priority);
1455                         cprintf_s(IS_STR, " %6s",
1456                                   GET_POLICY(pstc->policy));
1457                 }
1458
1459                 print_comm(pstc);
1460                 again = 1;
1461         }
1462
1463         return again;
1464 }
1465
1466 /*
1467  ***************************************************************************
1468  * Display all statistics for tasks' children in one line format.
1469  *
1470  * IN:
1471  * @prev        Index in array where stats used as reference are.
1472  * @curr        Index in array for current sample statistics.
1473  * @dis         TRUE if a header line must be printed.
1474  * @itv         Interval of time in jiffies.
1475  *
1476  * RETURNS:
1477  * 0 if all the processes to display have terminated.
1478  * <> 0 if there are still some processes left to display.
1479  ***************************************************************************
1480  */
1481 int write_pid_child_all_stats(int prev, int curr, int dis,
1482                               unsigned long long itv)
1483 {
1484         struct pid_stats *pstc, *pstp;
1485         unsigned int p;
1486         int again = 0;
1487
1488         if (dis) {
1489                 PRINT_ID_HDR("#      Time", pidflag);
1490                 if (DISPLAY_CPU(actflag))
1491                         printf("    usr-ms system-ms  guest-ms");
1492                 if (DISPLAY_MEM(actflag))
1493                         printf(" minflt-nr majflt-nr");
1494                 printf("  Command\n");
1495         }
1496
1497         for (p = 0; p < pid_nr; p++) {
1498
1499                 if (get_pid_to_display(prev, curr, p, actflag, P_CHILD,
1500                                        &pstc, &pstp) <= 0)
1501                         continue;
1502
1503                 printf("%11ld", (long) time(NULL));
1504                 __print_line_id(pstc, '0');
1505
1506                 if (DISPLAY_CPU(actflag)) {
1507                         cprintf_f(-1, 3, 9, 0,
1508                                   (pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) <
1509                                   (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime) ?
1510                                   0.0 :
1511                                   (double) ((pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) -
1512                                             (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime)) /
1513                                             HZ * 1000,
1514                                   (double) ((pstc->stime + pstc->cstime) -
1515                                             (pstp->stime + pstp->cstime)) / HZ * 1000,
1516                                   (double) ((pstc->gtime + pstc->cgtime) -
1517                                             (pstp->gtime + pstp->cgtime)) / HZ * 1000);
1518                 }
1519
1520                 if (DISPLAY_MEM(actflag)) {
1521                         cprintf_u64(-1, 2, 9,
1522                                     (unsigned long long) ((pstc->minflt + pstc->cminflt) - (pstp->minflt + pstp->cminflt)),
1523                                     (unsigned long long) ((pstc->majflt + pstc->cmajflt) - (pstp->majflt + pstp->cmajflt)));
1524                 }
1525
1526                 print_comm(pstc);
1527                 again = 1;
1528         }
1529
1530         return again;
1531 }
1532
1533 /*
1534  ***************************************************************************
1535  * Display CPU statistics for tasks.
1536  *
1537  * IN:
1538  * @prev        Index in array where stats used as reference are.
1539  * @curr        Index in array for current sample statistics.
1540  * @dis         TRUE if a header line must be printed.
1541  * @disp_avg    TRUE if average stats are displayed.
1542  * @prev_string String displayed at the beginning of a header line. This is
1543  *              the timestamp of the previous sample, or "Average" when
1544  *              displaying average stats.
1545  * @curr_string String displayed at the beginning of current sample stats.
1546  *              This is the timestamp of the current sample, or "Average"
1547  *              when displaying average stats.
1548  * @itv         Interval of time in jiffies.
1549  * @g_itv       Interval of time in jiffies multiplied by the number of
1550  *              processors.
1551  *
1552  * RETURNS:
1553  * 0 if all the processes to display have terminated.
1554  * <> 0 if there are still some processes left to display.
1555  ***************************************************************************
1556  */
1557 int write_pid_task_cpu_stats(int prev, int curr, int dis, int disp_avg,
1558                              char *prev_string, char *curr_string,
1559                              unsigned long long itv,
1560                              unsigned long long g_itv)
1561 {
1562         struct pid_stats *pstc, *pstp;
1563         unsigned int p;
1564         int again = 0;
1565
1566         if (dis) {
1567                 PRINT_ID_HDR(prev_string, pidflag);
1568                 printf("    %%usr %%system  %%guest    %%CPU   CPU  Command\n");
1569         }
1570
1571         for (p = 0; p < pid_nr; p++) {
1572
1573                 if (get_pid_to_display(prev, curr, p, P_A_CPU, P_TASK,
1574                                        &pstc, &pstp) <= 0)
1575                         continue;
1576
1577                 print_line_id(curr_string, pstc);
1578                 cprintf_pc(4, 7, 2,
1579                            (pstc->utime - pstc->gtime) < (pstp->utime - pstp->gtime) ?
1580                            0.0 :
1581                            SP_VALUE_100(pstp->utime - pstp->gtime,
1582                                     pstc->utime - pstc->gtime, itv),
1583                            SP_VALUE_100(pstp->stime, pstc->stime, itv),
1584                            SP_VALUE_100(pstp->gtime, pstc->gtime, itv),
1585                            /* User time already includes guest time */
1586                            IRIX_MODE_OFF(pidflag) ?
1587                            SP_VALUE_100(pstp->utime + pstp->stime,
1588                                     pstc->utime + pstc->stime, g_itv) :
1589                            SP_VALUE_100(pstp->utime + pstp->stime,
1590                                     pstc->utime + pstc->stime, itv));
1591
1592                 if (!disp_avg) {
1593                         cprintf_in(IS_INT, "   %3d", "", pstc->processor);
1594                 }
1595                 else {
1596                         cprintf_in(IS_STR, "%s", "     -", 0);
1597                 }
1598                 print_comm(pstc);
1599                 again = 1;
1600         }
1601
1602         return again;
1603 }
1604
1605 /*
1606  ***************************************************************************
1607  * Display CPU statistics for tasks' children.
1608  *
1609  * IN:
1610  * @prev        Index in array where stats used as reference are.
1611  * @curr        Index in array for current sample statistics.
1612  * @dis         TRUE if a header line must be printed.
1613  * @disp_avg    TRUE if average stats are displayed.
1614  * @prev_string String displayed at the beginning of a header line. This is
1615  *              the timestamp of the previous sample, or "Average" when
1616  *              displaying average stats.
1617  * @curr_string String displayed at the beginning of current sample stats.
1618  *              This is the timestamp of the current sample, or "Average"
1619  *              when displaying average stats.
1620  *
1621  * RETURNS:
1622  * 0 if all the processes to display have terminated.
1623  * <> 0 if there are still some processes left to display.
1624  ***************************************************************************
1625  */
1626 int write_pid_child_cpu_stats(int prev, int curr, int dis, int disp_avg,
1627                               char *prev_string, char *curr_string)
1628 {
1629         struct pid_stats *pstc, *pstp;
1630         unsigned int p;
1631         int rc, again = 0;
1632
1633         if (dis) {
1634                 PRINT_ID_HDR(prev_string, pidflag);
1635                 printf("    usr-ms system-ms  guest-ms  Command\n");
1636         }
1637
1638         for (p = 0; p < pid_nr; p++) {
1639
1640                 if ((rc = get_pid_to_display(prev, curr, p, P_A_CPU, P_CHILD,
1641                                              &pstc, &pstp)) == 0)
1642                         /* PID no longer exists */
1643                         continue;
1644
1645                 /* This will be used to compute average */
1646                 if (!disp_avg) {
1647                         pstc->uc_asum_count = pstp->uc_asum_count + 1;
1648                 }
1649
1650                 if (rc < 0)
1651                         /* PID should not be displayed */
1652                         continue;
1653
1654                 print_line_id(curr_string, pstc);
1655                 if (disp_avg) {
1656                         cprintf_f(-1, 3, 9, 0,
1657                                   (pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) <
1658                                   (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime) ?
1659                                   0.0 :
1660                                   (double) ((pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) -
1661                                             (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime)) /
1662                                             (HZ * pstc->uc_asum_count) * 1000,
1663                                   (double) ((pstc->stime + pstc->cstime) -
1664                                             (pstp->stime + pstp->cstime)) /
1665                                             (HZ * pstc->uc_asum_count) * 1000,
1666                                   (double) ((pstc->gtime + pstc->cgtime) -
1667                                             (pstp->gtime + pstp->cgtime)) /
1668                                             (HZ * pstc->uc_asum_count) * 1000);
1669                 }
1670                 else {
1671                         cprintf_f(-1, 3, 9, 0,
1672                                   (pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) <
1673                                   (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime) ?
1674                                   0.0 :
1675                                   (double) ((pstc->utime + pstc->cutime - pstc->gtime - pstc->cgtime) -
1676                                             (pstp->utime + pstp->cutime - pstp->gtime - pstp->cgtime)) /
1677                                             HZ * 1000,
1678                                   (double) ((pstc->stime + pstc->cstime) -
1679                                             (pstp->stime + pstp->cstime)) / HZ * 1000,
1680                                   (double) ((pstc->gtime + pstc->cgtime) -
1681                                             (pstp->gtime + pstp->cgtime)) / HZ * 1000);
1682                 }
1683                 print_comm(pstc);
1684                 again = 1;
1685         }
1686
1687         return again;
1688 }
1689
1690 /*
1691  ***************************************************************************
1692  * Display memory statistics for tasks.
1693  *
1694  * IN:
1695  * @prev        Index in array where stats used as reference are.
1696  * @curr        Index in array for current sample statistics.
1697  * @dis         TRUE if a header line must be printed.
1698  * @disp_avg    TRUE if average stats are displayed.
1699  * @prev_string String displayed at the beginning of a header line. This is
1700  *              the timestamp of the previous sample, or "Average" when
1701  *              displaying average stats.
1702  * @curr_string String displayed at the beginning of current sample stats.
1703  *              This is the timestamp of the current sample, or "Average"
1704  *              when displaying average stats.
1705  * @itv         Interval of time in jiffies.
1706  *
1707  * RETURNS:
1708  * 0 if all the processes to display have terminated.
1709  * <> 0 if there are still some processes left to display.
1710  ***************************************************************************
1711  */
1712 int write_pid_task_memory_stats(int prev, int curr, int dis, int disp_avg,
1713                                 char *prev_string, char *curr_string,
1714                                 unsigned long long itv)
1715 {
1716         struct pid_stats *pstc, *pstp;
1717         unsigned int p;
1718         int rc, again = 0;
1719
1720         if (dis) {
1721                 PRINT_ID_HDR(prev_string, pidflag);
1722                 printf("  minflt/s  majflt/s     VSZ     RSS   %%MEM  Command\n");
1723         }
1724
1725         for (p = 0; p < pid_nr; p++) {
1726
1727                 if ((rc = get_pid_to_display(prev, curr, p, P_A_MEM, P_TASK,
1728                                              &pstc, &pstp)) == 0)
1729                         /* PID no longer exists */
1730                         continue;
1731
1732                 /* This will be used to compute average */
1733                 if (!disp_avg) {
1734                         pstc->total_vsz = pstp->total_vsz + pstc->vsz;
1735                         pstc->total_rss = pstp->total_rss + pstc->rss;
1736                         pstc->rt_asum_count = pstp->rt_asum_count + 1;
1737                 }
1738
1739                 if (rc < 0)
1740                         /* PID should not be displayed */
1741                         continue;
1742
1743                 print_line_id(curr_string, pstc);
1744
1745                 cprintf_f(-1, 2, 9, 2,
1746                           S_VALUE(pstp->minflt, pstc->minflt, itv),
1747                           S_VALUE(pstp->majflt, pstc->majflt, itv));
1748
1749                 if (disp_avg) {
1750                         cprintf_f(-1, 2, 7, 0,
1751                                   (double) pstc->total_vsz / pstc->rt_asum_count,
1752                                   (double) pstc->total_rss / pstc->rt_asum_count);
1753
1754                         cprintf_pc(1, 6, 2,
1755                                    tlmkb ?
1756                                    SP_VALUE(0, pstc->total_rss / pstc->rt_asum_count, tlmkb)
1757                                    : 0.0);
1758                 }
1759                 else {
1760                         cprintf_u64(-1, 2, 7,
1761                                     (unsigned long long) pstc->vsz,
1762                                     (unsigned long long) pstc->rss);
1763
1764                         cprintf_pc(1, 6, 2,
1765                                    tlmkb ? SP_VALUE(0, pstc->rss, tlmkb) : 0.0);
1766                 }
1767
1768                 print_comm(pstc);
1769                 again = 1;
1770         }
1771
1772         return again;
1773 }
1774
1775 /*
1776  ***************************************************************************
1777  * Display memory statistics for tasks' children.
1778  *
1779  * IN:
1780  * @prev        Index in array where stats used as reference are.
1781  * @curr        Index in array for current sample statistics.
1782  * @dis         TRUE if a header line must be printed.
1783  * @disp_avg    TRUE if average stats are displayed.
1784  * @prev_string String displayed at the beginning of a header line. This is
1785  *              the timestamp of the previous sample, or "Average" when
1786  *              displaying average stats.
1787  * @curr_string String displayed at the beginning of current sample stats.
1788  *              This is the timestamp of the current sample, or "Average"
1789  *              when displaying average stats.
1790  *
1791  * RETURNS:
1792  * 0 if all the processes to display have terminated.
1793  * <> 0 if there are still some processes left to display.
1794  ***************************************************************************
1795  */
1796 int write_pid_child_memory_stats(int prev, int curr, int dis, int disp_avg,
1797                                  char *prev_string, char *curr_string)
1798 {
1799         struct pid_stats *pstc, *pstp;
1800         unsigned int p;
1801         int rc, again = 0;
1802
1803         if (dis) {
1804                 PRINT_ID_HDR(prev_string, pidflag);
1805                 printf(" minflt-nr majflt-nr  Command\n");
1806         }
1807
1808         for (p = 0; p < pid_nr; p++) {
1809
1810                 if ((rc = get_pid_to_display(prev, curr, p, P_A_MEM, P_CHILD,
1811                                              &pstc, &pstp)) == 0)
1812                         /* PID no longer exists */
1813                         continue;
1814
1815                 /* This will be used to compute average */
1816                 if (!disp_avg) {
1817                         pstc->rc_asum_count = pstp->rc_asum_count + 1;
1818                 }
1819
1820                 if (rc < 0)
1821                         /* PID should not be displayed */
1822                         continue;
1823
1824                 print_line_id(curr_string, pstc);
1825                 if (disp_avg) {
1826                         cprintf_f(-1, 2, 9, 0,
1827                                   (double) ((pstc->minflt + pstc->cminflt) -
1828                                             (pstp->minflt + pstp->cminflt)) / pstc->rc_asum_count,
1829                                   (double) ((pstc->majflt + pstc->cmajflt) -
1830                                             (pstp->majflt + pstp->cmajflt)) / pstc->rc_asum_count);
1831                 }
1832                 else {
1833                         cprintf_u64(-1, 2, 9,
1834                                     (unsigned long long) ((pstc->minflt + pstc->cminflt) - (pstp->minflt + pstp->cminflt)),
1835                     (unsigned long long) ((pstc->majflt + pstc->cmajflt) - (pstp->majflt + pstp->cmajflt)));
1836                 }
1837                 print_comm(pstc);
1838                 again = 1;
1839         }
1840
1841         return again;
1842 }
1843
1844 /*
1845  ***************************************************************************
1846  * Display stack size statistics for tasks.
1847  *
1848  * IN:
1849  * @prev        Index in array where stats used as reference are.
1850  * @curr        Index in array for current sample statistics.
1851  * @dis         TRUE if a header line must be printed.
1852  * @disp_avg    TRUE if average stats are displayed.
1853  * @prev_string String displayed at the beginning of a header line. This is
1854  *              the timestamp of the previous sample, or "Average" when
1855  *              displaying average stats.
1856  * @curr_string String displayed at the beginning of current sample stats.
1857  *              This is the timestamp of the current sample, or "Average"
1858  *              when displaying average stats.
1859  * @itv         Interval of time in jiffies.
1860  *
1861  * RETURNS:
1862  * 0 if all the processes to display have terminated.
1863  * <> 0 if there are still some processes left to display.
1864  ***************************************************************************
1865  */
1866 int write_pid_stack_stats(int prev, int curr, int dis, int disp_avg,
1867                           char *prev_string, char *curr_string,
1868                           unsigned long long itv)
1869 {
1870         struct pid_stats *pstc, *pstp;
1871         unsigned int p;
1872         int rc, again = 0;
1873
1874         if (dis) {
1875                 PRINT_ID_HDR(prev_string, pidflag);
1876                 printf(" StkSize  StkRef  Command\n");
1877         }
1878
1879         for (p = 0; p < pid_nr; p++) {
1880
1881                 if ((rc = get_pid_to_display(prev, curr, p, P_A_STACK, P_NULL,
1882                                              &pstc, &pstp)) == 0)
1883                         /* PID no longer exists */
1884                         continue;
1885
1886                 /* This will be used to compute average */
1887                 if (!disp_avg) {
1888                         pstc->total_stack_size = pstp->total_stack_size + pstc->stack_size;
1889                         pstc->total_stack_ref  = pstp->total_stack_ref  + pstc->stack_ref;
1890                         pstc->sk_asum_count = pstp->sk_asum_count + 1;
1891                 }
1892
1893                 if (rc < 0)
1894                         /* PID should not be displayed */
1895                         continue;
1896
1897                 print_line_id(curr_string, pstc);
1898
1899                 if (disp_avg) {
1900                         cprintf_f(-1, 2, 7, 0,
1901                                   (double) pstc->total_stack_size / pstc->sk_asum_count,
1902                                   (double) pstc->total_stack_ref  / pstc->sk_asum_count);
1903                 }
1904                 else {
1905                         cprintf_u64(-1, 2, 7,
1906                                     (unsigned long long) pstc->stack_size,
1907                                     (unsigned long long) pstc->stack_ref);
1908                 }
1909
1910                 print_comm(pstc);
1911                 again = 1;
1912         }
1913
1914         return again;
1915 }
1916
1917 /*
1918  ***************************************************************************
1919  * Display I/O statistics.
1920  *
1921  * IN:
1922  * @prev        Index in array where stats used as reference are.
1923  * @curr        Index in array for current sample statistics.
1924  * @dis         TRUE if a header line must be printed.
1925  * @disp_avg    TRUE if average stats are displayed.
1926  * @prev_string String displayed at the beginning of a header line. This is
1927  *              the timestamp of the previous sample, or "Average" when
1928  *              displaying average stats.
1929  * @curr_string String displayed at the beginning of current sample stats.
1930  *              This is the timestamp of the current sample, or "Average"
1931  *              when displaying average stats.
1932  * @itv         Interval of time in jiffies.
1933  *
1934  * RETURNS:
1935  * 0 if all the processes to display have terminated.
1936  * <> 0 if there are still some processes left to display.
1937  ***************************************************************************
1938  */
1939 int write_pid_io_stats(int prev, int curr, int dis, int disp_avg,
1940                        char *prev_string, char *curr_string,
1941                        unsigned long long itv)
1942 {
1943         struct pid_stats *pstc, *pstp;
1944         char dstr[32];
1945         unsigned int p;
1946         int rc, again = 0;
1947
1948         if (dis) {
1949                 PRINT_ID_HDR(prev_string, pidflag);
1950                 printf("   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command\n");
1951         }
1952
1953         for (p = 0; p < pid_nr; p++) {
1954
1955                 if ((rc = get_pid_to_display(prev, curr, p, P_A_IO, P_NULL,
1956                                              &pstc, &pstp)) == 0)
1957                         /* PID no longer exists */
1958                         continue;
1959
1960                 /* This will be used to compute average delays */
1961                 if (!disp_avg) {
1962                         pstc->delay_asum_count = pstp->delay_asum_count + 1;
1963                 }
1964
1965                 if (rc < 0)
1966                         /* PID should not be displayed */
1967                         continue;
1968
1969                 print_line_id(curr_string, pstc);
1970                 if (!NO_PID_IO(pstc->flags)) {
1971                         cprintf_f(-1, 3, 9, 2,
1972                                   S_VALUE(pstp->read_bytes,  pstc->read_bytes, itv)  / 1024,
1973                                   S_VALUE(pstp->write_bytes, pstc->write_bytes, itv) / 1024,
1974                                   S_VALUE(pstp->cancelled_write_bytes,
1975                                           pstc->cancelled_write_bytes, itv) / 1024);
1976                 }
1977                 else {
1978                         /* I/O file not readable (permission denied or file non existent) */
1979                         sprintf(dstr, " %9.2f %9.2f %9.2f", -1.0, -1.0, -1.0);
1980                         cprintf_s(IS_ZERO, "%s", dstr);
1981                 }
1982                 /* I/O delays come from another file (/proc/#/stat) */
1983                 if (disp_avg) {
1984                         cprintf_f(-1, 1, 7, 0,
1985                                   (double) (pstc->blkio_swapin_delays - pstp->blkio_swapin_delays) /
1986                                             pstc->delay_asum_count);
1987                 }
1988                 else {
1989                         cprintf_u64(-1, 1, 7,
1990                                     (unsigned long long) (pstc->blkio_swapin_delays - pstp->blkio_swapin_delays));
1991                 }
1992
1993                 print_comm(pstc);
1994                 again = 1;
1995         }
1996
1997         return again;
1998 }
1999
2000 /*
2001  ***************************************************************************
2002  * Display context switches statistics.
2003  *
2004  * IN:
2005  * @prev        Index in array where stats used as reference are.
2006  * @curr        Index in array for current sample statistics.
2007  * @dis         TRUE if a header line must be printed.
2008  * @prev_string String displayed at the beginning of a header line. This is
2009  *              the timestamp of the previous sample, or "Average" when
2010  *              displaying average stats.
2011  * @curr_string String displayed at the beginning of current sample stats.
2012  *              This is the timestamp of the current sample, or "Average"
2013  *              when displaying average stats.
2014  * @itv         Interval of time in jiffies.
2015  *
2016  * RETURNS:
2017  * 0 if all the processes to display have terminated.
2018  * <> 0 if there are still some processes left to display.
2019  ***************************************************************************
2020  */
2021 int write_pid_ctxswitch_stats(int prev, int curr, int dis,
2022                               char *prev_string, char *curr_string,
2023                               unsigned long long itv)
2024 {
2025         struct pid_stats *pstc, *pstp;
2026         unsigned int p;
2027         int again = 0;
2028
2029         if (dis) {
2030                 PRINT_ID_HDR(prev_string, pidflag);
2031                 printf("   cswch/s nvcswch/s  Command\n");
2032         }
2033
2034         for (p = 0; p < pid_nr; p++) {
2035
2036                 if (get_pid_to_display(prev, curr, p, P_A_CTXSW, P_NULL,
2037                                        &pstc, &pstp) <= 0)
2038                         continue;
2039
2040                 print_line_id(curr_string, pstc);
2041                 cprintf_f(-1, 2, 9, 2,
2042                           S_VALUE(pstp->nvcsw, pstc->nvcsw, itv),
2043                           S_VALUE(pstp->nivcsw, pstc->nivcsw, itv));
2044                 print_comm(pstc);
2045                 again = 1;
2046         }
2047
2048         return again;
2049 }
2050
2051 /*
2052  ***************************************************************************
2053  * Display scheduling priority and policy information.
2054  *
2055  * IN:
2056  * @prev        Index in array where stats used as reference are.
2057  * @curr        Index in array for current sample statistics.
2058  * @dis         TRUE if a header line must be printed.
2059  * @prev_string String displayed at the beginning of a header line. This is
2060  *              the timestamp of the previous sample, or "Average" when
2061  *              displaying average stats.
2062  * @curr_string String displayed at the beginning of current sample stats.
2063  *              This is the timestamp of the current sample, or "Average"
2064  *              when displaying average stats.
2065  * @itv         Interval of time in jiffies.
2066  *
2067  * RETURNS:
2068  * 0 if all the processes to display have terminated.
2069  * <> 0 if there are still some processes left to display.
2070  ***************************************************************************
2071  */
2072 int write_pid_rt_stats(int prev, int curr, int dis,
2073                        char *prev_string, char *curr_string,
2074                        unsigned long long itv)
2075 {
2076         struct pid_stats *pstc, *pstp;
2077         unsigned int p;
2078         int again = 0;
2079
2080         if (dis) {
2081                 PRINT_ID_HDR(prev_string, pidflag);
2082                 printf(" prio policy  Command\n");
2083         }
2084
2085         for (p = 0; p < pid_nr; p++) {
2086
2087                 if (get_pid_to_display(prev, curr, p, P_A_RT, P_NULL,
2088                                        &pstc, &pstp) <= 0)
2089                         continue;
2090
2091                 print_line_id(curr_string, pstc);
2092                 cprintf_u64(-1, 1, 4,
2093                             (unsigned long long) pstc->priority);
2094                 cprintf_s(IS_STR, " %6s", GET_POLICY(pstc->policy));
2095                 print_comm(pstc);
2096                 again = 1;
2097         }
2098
2099         return again;
2100 }
2101
2102 /*
2103  ***************************************************************************
2104  * Display some kernel tables values for tasks.
2105  *
2106  * IN:
2107  * @prev        Index in array where stats used as reference are.
2108  * @curr        Index in array for current sample statistics.
2109  * @dis         TRUE if a header line must be printed.
2110  * @disp_avg    TRUE if average stats are displayed.
2111  * @prev_string String displayed at the beginning of a header line. This is
2112  *              the timestamp of the previous sample, or "Average" when
2113  *              displaying average stats.
2114  * @curr_string String displayed at the beginning of current sample stats.
2115  *              This is the timestamp of the current sample, or "Average"
2116  *              when displaying average stats.
2117  * @itv         Interval of time in jiffies.
2118  *
2119  * RETURNS:
2120  * 0 if all the processes to display have terminated.
2121  * <> 0 if there are still some processes left to display.
2122  ***************************************************************************
2123  */
2124 int write_pid_ktab_stats(int prev, int curr, int dis, int disp_avg,
2125                          char *prev_string, char *curr_string,
2126                          unsigned long long itv)
2127 {
2128         struct pid_stats *pstc, *pstp;
2129         unsigned int p;
2130         int rc, again = 0;
2131
2132         if (dis) {
2133                 PRINT_ID_HDR(prev_string, pidflag);
2134                 printf(" threads   fd-nr");
2135                 printf("  Command\n");
2136         }
2137
2138         for (p = 0; p < pid_nr; p++) {
2139
2140                 if ((rc = get_pid_to_display(prev, curr, p, P_A_KTAB, P_NULL,
2141                                              &pstc, &pstp)) == 0)
2142                         /* PID no longer exists */
2143                         continue;
2144
2145                 /* This will be used to compute average */
2146                 if (!disp_avg) {
2147                         pstc->total_threads = pstp->total_threads + pstc->threads;
2148                         pstc->total_fd_nr = pstp->total_fd_nr + pstc->fd_nr;
2149                         pstc->tf_asum_count = pstp->tf_asum_count + 1;
2150                 }
2151
2152                 if (rc < 0)
2153                         /* PID should not be displayed */
2154                         continue;
2155
2156                 print_line_id(curr_string, pstc);
2157
2158                 if (disp_avg) {
2159                         cprintf_f(-1, 2, 7, 0,
2160                                   (double) pstc->total_threads / pstc->tf_asum_count,
2161                                   NO_PID_FD(pstc->flags) ?
2162                                   -1.0 :
2163                                   (double) pstc->total_fd_nr / pstc->tf_asum_count);
2164                 }
2165                 else {
2166                         cprintf_u64(-1, 1, 7,
2167                                     (unsigned long long) pstc->threads);
2168                         if (NO_PID_FD(pstc->flags)) {
2169                                 cprintf_s(IS_ZERO, " %7s", "-1");
2170                         }
2171                         else {
2172                                 cprintf_u64(-1, 1, 7,
2173                                             (unsigned long long) pstc->fd_nr);
2174                         }
2175                 }
2176
2177                 print_comm(pstc);
2178                 again = 1;
2179         }
2180
2181         return again;
2182 }
2183
2184 /*
2185  ***************************************************************************
2186  * Display statistics.
2187  *
2188  * IN:
2189  * @prev        Index in array where stats used as reference are.
2190  * @curr        Index in array for current sample statistics.
2191  * @dis         TRUE if a header line must be printed.
2192  * @disp_avg    TRUE if average stats are displayed.
2193  * @prev_string String displayed at the beginning of a header line. This is
2194  *              the timestamp of the previous sample, or "Average" when
2195  *              displaying average stats.
2196  * @curr_string String displayed at the beginning of current sample stats.
2197  *              This is the timestamp of the current sample, or "Average"
2198  *              when displaying average stats.
2199  *
2200  * RETURNS:
2201  * 0 if all the processes to display have terminated.
2202  * <> 0 if there are still some processes left to display.
2203  ***************************************************************************
2204  */
2205 int write_stats_core(int prev, int curr, int dis, int disp_avg,
2206                      char *prev_string, char *curr_string)
2207 {
2208         unsigned long long itv, g_itv;
2209         int again = 0;
2210
2211         /* Test stdout */
2212         TEST_STDOUT(STDOUT_FILENO);
2213
2214         /* g_itv is multiplied by the number of processors */
2215         g_itv = get_interval(uptime[prev], uptime[curr]);
2216
2217         if (cpu_nr > 1) {
2218                 /* SMP machines */
2219                 itv = get_interval(uptime0[prev], uptime0[curr]);
2220         }
2221         else {
2222                 /* UP machines */
2223                 itv = g_itv;
2224         }
2225
2226         if (PROCESS_STRING(pidflag)) {
2227                 /* Reset "show threads" flag */
2228                 show_threads = FALSE;
2229         }
2230
2231         if (DISPLAY_ONELINE(pidflag)) {
2232                 if (DISPLAY_TASK_STATS(tskflag)) {
2233                         again += write_pid_task_all_stats(prev, curr, dis,
2234                                                          itv, g_itv);
2235                 }
2236                 if (DISPLAY_CHILD_STATS(tskflag)) {
2237                         again += write_pid_child_all_stats(prev, curr, dis, itv);
2238                 }
2239         }
2240         else {
2241                 /* Display CPU stats */
2242                 if (DISPLAY_CPU(actflag)) {
2243
2244                         if (DISPLAY_TASK_STATS(tskflag)) {
2245                                 again += write_pid_task_cpu_stats(prev, curr, dis, disp_avg,
2246                                                                   prev_string, curr_string,
2247                                                                   itv, g_itv);
2248                         }
2249                         if (DISPLAY_CHILD_STATS(tskflag)) {
2250                                 again += write_pid_child_cpu_stats(prev, curr, dis, disp_avg,
2251                                                                    prev_string, curr_string);
2252                         }
2253                 }
2254
2255                 /* Display memory stats */
2256                 if (DISPLAY_MEM(actflag)) {
2257
2258                         if (DISPLAY_TASK_STATS(tskflag)) {
2259                                 again += write_pid_task_memory_stats(prev, curr, dis, disp_avg,
2260                                                                      prev_string, curr_string, itv);
2261                         }
2262                         if (DISPLAY_CHILD_STATS(tskflag) && DISPLAY_MEM(actflag)) {
2263                                 again += write_pid_child_memory_stats(prev, curr, dis, disp_avg,
2264                                                                       prev_string, curr_string);
2265                         }
2266                 }
2267
2268                 /* Display stack stats */
2269                 if (DISPLAY_STACK(actflag)) {
2270                         again += write_pid_stack_stats(prev, curr, dis, disp_avg,
2271                                                        prev_string, curr_string, itv);
2272                 }
2273
2274                 /* Display I/O stats */
2275                 if (DISPLAY_IO(actflag)) {
2276                         again += write_pid_io_stats(prev, curr, dis, disp_avg, prev_string,
2277                                                     curr_string, itv);
2278                 }
2279
2280                 /* Display context switches stats */
2281                 if (DISPLAY_CTXSW(actflag)) {
2282                         again += write_pid_ctxswitch_stats(prev, curr, dis, prev_string,
2283                                                            curr_string, itv);
2284                 }
2285
2286                 /* Display kernel table stats */
2287                 if (DISPLAY_KTAB(actflag)) {
2288                         again += write_pid_ktab_stats(prev, curr, dis, disp_avg,
2289                                                       prev_string, curr_string, itv);
2290                 }
2291
2292                 /* Display scheduling priority and policy information */
2293                 if (DISPLAY_RT(actflag)) {
2294                         again += write_pid_rt_stats(prev, curr, dis, prev_string,
2295                                                     curr_string, itv);
2296                 }
2297         }
2298
2299         if (DISPLAY_ALL_PID(pidflag)) {
2300                 again = 1;
2301         }
2302
2303         return again;
2304 }
2305
2306 /*
2307  ***************************************************************************
2308  * Print statistics average.
2309  *
2310  * IN:
2311  * @curr        Index in array for current sample statistics.
2312  * @dis         TRUE if a header line must be printed.
2313  ***************************************************************************
2314  */
2315 void write_stats_avg(int curr, int dis)
2316 {
2317         char string[16];
2318
2319         strncpy(string, _("Average:"), 16);
2320         string[15] = '\0';
2321         write_stats_core(2, curr, dis, TRUE, string, string);
2322 }
2323
2324 /*
2325  ***************************************************************************
2326  * Get previous and current timestamps, then display statistics.
2327  *
2328  * IN:
2329  * @curr        Index in array for current sample statistics.
2330  * @dis         TRUE if a header line must be printed.
2331  *
2332  * RETURNS:
2333  * 0 if all the processes to display have terminated.
2334  * <> 0 if there are still some processes left to display.
2335  ***************************************************************************
2336  */
2337 int write_stats(int curr, int dis)
2338 {
2339         char cur_time[2][TIMESTAMP_LEN];
2340
2341         /* Get previous timestamp */
2342         if (is_iso_time_fmt()) {
2343                 strftime(cur_time[!curr], sizeof(cur_time[!curr]), "%H:%M:%S", &ps_tstamp[!curr]);
2344         }
2345         else {
2346                 strftime(cur_time[!curr], sizeof(cur_time[!curr]), "%X", &ps_tstamp[!curr]);
2347         }
2348
2349         /* Get current timestamp */
2350         if (is_iso_time_fmt()) {
2351                 strftime(cur_time[curr], sizeof(cur_time[curr]), "%H:%M:%S", &ps_tstamp[curr]);
2352         }
2353         else {
2354                 strftime(cur_time[curr], sizeof(cur_time[curr]), "%X", &ps_tstamp[curr]);
2355         }
2356
2357         return (write_stats_core(!curr, curr, dis, FALSE,
2358                                  cur_time[!curr], cur_time[curr]));
2359 }
2360
2361 /*
2362  ***************************************************************************
2363  * Main loop: Read and display PID stats.
2364  *
2365  * IN:
2366  * @dis_hdr     Set to TRUE if the header line must always be printed.
2367  * @rows        Number of rows of screen.
2368  ***************************************************************************
2369  */
2370 void rw_pidstat_loop(int dis_hdr, int rows)
2371 {
2372         int curr = 1, dis = 1;
2373         int again;
2374         unsigned long lines = rows;
2375
2376         /* Don't buffer data if redirected to a pipe */
2377         setbuf(stdout, NULL);
2378
2379         if (cpu_nr > 1) {
2380                 /*
2381                  * Read system uptime (only for SMP machines).
2382                  * Init uptime0. So if /proc/uptime cannot fill it, this will be
2383                  * done by /proc/stat.
2384                  */
2385                 uptime0[0] = 0;
2386                 read_uptime(&uptime0[0]);
2387         }
2388         read_stats(0);
2389
2390         if (DISPLAY_MEM(actflag)) {
2391                 /* Get total memory */
2392                 read_proc_meminfo();
2393         }
2394
2395         if (!interval) {
2396                 /* Display since boot time */
2397                 ps_tstamp[1] = ps_tstamp[0];
2398                 memset(st_pid_list[1], 0, PID_STATS_SIZE * pid_nr);
2399                 write_stats(0, DISP_HDR);
2400                 exit(0);
2401         }
2402
2403         /* Set a handler for SIGALRM */
2404         memset(&alrm_act, 0, sizeof(alrm_act));
2405         alrm_act.sa_handler = alarm_handler;
2406         sigaction(SIGALRM, &alrm_act, NULL);
2407         alarm(interval);
2408
2409         /* Save the first stats collected. Will be used to compute the average */
2410         ps_tstamp[2] = ps_tstamp[0];
2411         uptime[2] = uptime[0];
2412         uptime0[2] = uptime0[0];
2413         memcpy(st_pid_list[2], st_pid_list[0], PID_STATS_SIZE * pid_nr);
2414
2415         /* Set a handler for SIGINT */
2416         memset(&int_act, 0, sizeof(int_act));
2417         int_act.sa_handler = int_handler;
2418         sigaction(SIGINT, &int_act, NULL);
2419
2420         /* Wait for SIGALRM (or possibly SIGINT) signal */
2421         pause();
2422
2423         if (sigint_caught)
2424                 /* SIGINT signal caught during first interval: Exit immediately */
2425                 return;
2426
2427         do {
2428                 /* Get time */
2429                 get_localtime(&ps_tstamp[curr], 0);
2430
2431                 if (cpu_nr > 1) {
2432                         /*
2433                          * Read system uptime (only for SMP machines).
2434                          * Init uptime0. So if /proc/uptime cannot fill it, this will be
2435                          * done by /proc/stat.
2436                          */
2437                         uptime0[curr] = 0;
2438                         read_uptime(&(uptime0[curr]));
2439                 }
2440
2441                 /* Read stats */
2442                 read_stats(curr);
2443
2444                 if (!dis_hdr) {
2445                         dis = lines / rows;
2446                         if (dis) {
2447                                 lines %= rows;
2448                         }
2449                         lines++;
2450                 }
2451
2452                 /* Print results */
2453                 again = write_stats(curr, dis);
2454
2455                 if (!again)
2456                         return;
2457
2458                 if (count > 0) {
2459                         count--;
2460                 }
2461
2462                 if (count) {
2463
2464                         pause();
2465
2466                         if (sigint_caught) {
2467                                 /* SIGINT signal caught => Display average stats */
2468                                 count = 0;
2469                                 printf("\n");   /* Skip "^C" displayed on screen */
2470                         }
2471                         else {
2472                                 curr ^= 1;
2473                         }
2474                 }
2475         }
2476         while (count);
2477
2478         /*
2479          * The one line format uses a raw time value rather than time strings
2480          * so the average doesn't really fit.
2481          */
2482         if (!DISPLAY_ONELINE(pidflag))
2483         {
2484                 /* Write stats average */
2485                 write_stats_avg(curr, dis_hdr);
2486         }
2487 }
2488
2489 /*
2490  ***************************************************************************
2491  * Main entry to the pidstat program.
2492  ***************************************************************************
2493  */
2494 int main(int argc, char **argv)
2495 {
2496         int opt = 1, dis_hdr = -1;
2497         int i;
2498         unsigned int pid;
2499         struct utsname header;
2500         int rows = 23;
2501         char *t;
2502
2503 #ifdef USE_NLS
2504         /* Init National Language Support */
2505         init_nls();
2506 #endif
2507
2508         /* Init color strings */
2509         init_colors();
2510
2511         /* Get HZ */
2512         get_HZ();
2513
2514         /* Compute page shift in kB */
2515         get_kb_shift();
2516
2517         /* Allocate structures for device list */
2518         if (argc > 1) {
2519                 salloc_pid_array((argc / 2) + count_csvalues(argc, argv));
2520         }
2521
2522         /* Process args... */
2523         while (opt < argc) {
2524
2525                 if (!strcmp(argv[opt], "-p")) {
2526                         pidflag |= P_D_PID;
2527                         if (argv[++opt]) {
2528
2529                                 for (t = strtok(argv[opt], ","); t; t = strtok(NULL, ",")) {
2530                                         if (!strcmp(t, K_ALL)) {
2531                                                 pidflag |= P_D_ALL_PID;
2532                                         }
2533                                         else if (!strcmp(t, K_SELF)) {
2534                                                 update_pid_array(&pid_array_nr, getpid());
2535                                         }
2536                                         else {
2537                                                 if (strspn(t, DIGITS) != strlen(t)) {
2538                                                         usage(argv[0]);
2539                                                 }
2540                                                 pid = atoi(t);
2541                                                 if (pid < 1) {
2542                                                         usage(argv[0]);
2543                                                 }
2544                                                 update_pid_array(&pid_array_nr, pid);
2545                                         }
2546                                 }
2547                                 opt++;
2548                         }
2549                         else {
2550                                 usage(argv[0]);
2551                         }
2552                 }
2553
2554                 else if (!strcmp(argv[opt], "-C")) {
2555                         if (argv[++opt]) {
2556                                 strncpy(commstr, argv[opt++], MAX_COMM_LEN);
2557                                 commstr[MAX_COMM_LEN - 1] = '\0';
2558                                 pidflag |= P_F_COMMSTR;
2559                                 if (!strlen(commstr)) {
2560                                         usage(argv[0]);
2561                                 }
2562                         }
2563                         else {
2564                                 usage(argv[0]);
2565                         }
2566                 }
2567
2568                 else if (!strcmp(argv[opt], "-G")) {
2569                         if (argv[++opt]) {
2570                                 strncpy(procstr, argv[opt++], MAX_COMM_LEN);
2571                                 procstr[MAX_COMM_LEN - 1] = '\0';
2572                                 pidflag |= P_F_PROCSTR;
2573                                 if (!strlen(procstr)) {
2574                                         usage(argv[0]);
2575                                 }
2576                         }
2577                         else {
2578                                 usage(argv[0]);
2579                         }
2580                 }
2581
2582                 else if (!strcmp(argv[opt], "-T")) {
2583                         if (argv[++opt]) {
2584                                 if (tskflag) {
2585                                         dis_hdr++;
2586                                 }
2587                                 if (!strcmp(argv[opt], K_P_TASK)) {
2588                                         tskflag |= P_TASK;
2589                                 }
2590                                 else if (!strcmp(argv[opt], K_P_CHILD)) {
2591                                         tskflag |= P_CHILD;
2592                                 }
2593                                 else if (!strcmp(argv[opt], K_P_ALL)) {
2594                                         tskflag |= P_TASK + P_CHILD;
2595                                         dis_hdr++;
2596                                 }
2597                                 else {
2598                                         usage(argv[0]);
2599                                 }
2600                                 opt++;
2601                         }
2602                         else {
2603                                 usage(argv[0]);
2604                         }
2605                 }
2606
2607                 /* Option used individually. See below for grouped option */
2608                 else if (!strcmp(argv[opt], "-U")) {
2609                         /* Display username instead of UID */
2610                         pidflag |= P_D_USERNAME;
2611                         if (argv[++opt] && (argv[opt][0] != '-') &&
2612                             (strspn(argv[opt], DIGITS) != strlen(argv[opt]))) {
2613                                 strncpy(userstr, argv[opt++], MAX_USER_LEN);
2614                                 userstr[MAX_USER_LEN - 1] = '\0';
2615                                 pidflag |= P_F_USERSTR;
2616                                 if (!strlen(userstr)) {
2617                                         usage(argv[0]);
2618                                 }
2619                         }
2620                 }
2621
2622                 else if (!strncmp(argv[opt], "-", 1)) {
2623                         for (i = 1; *(argv[opt] + i); i++) {
2624
2625                                 switch (*(argv[opt] + i)) {
2626
2627                                 case 'd':
2628                                         /* Display I/O usage */
2629                                         actflag |= P_A_IO;
2630                                         dis_hdr++;
2631                                         break;
2632
2633                                 case 'h':
2634                                         /* Display stats on one line */
2635                                         pidflag |= P_D_ONELINE;
2636                                         break;
2637
2638                                 case 'I':
2639                                         /* IRIX mode off */
2640                                         pidflag |= P_F_IRIX_MODE;
2641                                         break;
2642
2643                                 case 'l':
2644                                         /* Display whole command line */
2645                                         pidflag |= P_D_CMDLINE;
2646                                         break;
2647
2648                                 case 'R':
2649                                         /* Display priority and policy info */
2650                                         actflag |= P_A_RT;
2651                                         dis_hdr++;
2652                                         break;
2653
2654                                 case 'r':
2655                                         /* Display memory usage */
2656                                         actflag |= P_A_MEM;
2657                                         dis_hdr++;
2658                                         break;
2659
2660                                 case 's':
2661                                         /* Display stack sizes */
2662                                         actflag |= P_A_STACK;
2663                                         dis_hdr++;
2664                                         break;
2665
2666                                 case 't':
2667                                         /* Display stats for threads */
2668                                         pidflag |= P_D_TID;
2669                                         break;
2670
2671                                 case 'U':
2672                                         /* When option is grouped, it cannot take an arg */
2673                                         pidflag |= P_D_USERNAME;
2674                                         break;
2675
2676                                 case 'u':
2677                                         /* Display CPU usage */
2678                                         actflag |= P_A_CPU;
2679                                         dis_hdr++;
2680                                         break;
2681
2682                                 case 'V':
2683                                         /* Print version number and exit */
2684                                         print_version();
2685                                         break;
2686
2687                                 case 'v':
2688                                         /* Display some kernel tables values */
2689                                         actflag |= P_A_KTAB;
2690                                         dis_hdr++;
2691                                         break;
2692
2693                                 case 'w':
2694                                         /* Display context switches */
2695                                         actflag |= P_A_CTXSW;
2696                                         dis_hdr++;
2697                                         break;
2698
2699                                 default:
2700                                         usage(argv[0]);
2701                                 }
2702                         }
2703                         opt++;
2704                 }
2705
2706                 else if (interval < 0) {        /* Get interval */
2707                         if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) {
2708                                 usage(argv[0]);
2709                         }
2710                         interval = atol(argv[opt++]);
2711                         if (interval < 0) {
2712                                 usage(argv[0]);
2713                         }
2714                         count = -1;
2715                 }
2716
2717                 else if (count <= 0) {  /* Get count value */
2718                         if ((strspn(argv[opt], DIGITS) != strlen(argv[opt])) ||
2719                             !interval) {
2720                                 usage(argv[0]);
2721                         }
2722                         count = atol(argv[opt++]);
2723                         if (count < 1) {
2724                                 usage(argv[0]);
2725                         }
2726                 }
2727                 else {
2728                         usage(argv[0]);
2729                 }
2730         }
2731
2732         if (interval < 0) {
2733                 /* Interval not set => display stats since boot time */
2734                 interval = 0;
2735         }
2736
2737         /* Check flags and set default values */
2738         check_flags();
2739
2740         /* Init structures */
2741         pid_sys_init();
2742
2743         if (dis_hdr < 0) {
2744                 dis_hdr = 0;
2745         }
2746         if (!dis_hdr) {
2747                 if (pid_nr > 1) {
2748                         dis_hdr = 1;
2749                 }
2750                 else {
2751                         rows = get_win_height();
2752                 }
2753         }
2754
2755         /* Get time */
2756         get_localtime(&(ps_tstamp[0]), 0);
2757
2758         /* Get system name, release number and hostname */
2759         uname(&header);
2760         print_gal_header(&(ps_tstamp[0]), header.sysname, header.release,
2761                          header.nodename, header.machine, cpu_nr,
2762                          PLAIN_OUTPUT);
2763
2764         /* Main loop */
2765         rw_pidstat_loop(dis_hdr, rows);
2766
2767         /* Free structures */
2768         free(pid_array);
2769         sfree_pid();
2770
2771         return 0;
2772 }