Section C.2. Source Code for msacct


C.2. Source Code for msacct

/*  * Run a command and print all field resource  * usage and microstat accounting fields when process terminates.  *  * Borrowed largely from ptime.c  * (Thanks Roger Faulkner and Mike Shapiro)  *  * Usage: msacct command  *  */ #include <sys/types.h> #include <sys/time.h> #include <procfs.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <errno.h> #include <math.h> #include <wait.h> #include <signal.h> static        int        look(pid_t); static        void        hr_min_sec(char *, long); static        void        prtime(char *, timestruc_t *); static        int        perr(const char *); static        void         tsadd(timestruc_t *result, timestruc_t *a, timestruc_t *b); static        void         tssub(timestruc_t *result, timestruc_t *a, timestruc_t *b); static        char         *command; static        char         procname[64]; main(int argc, char **argv) {         pid_t pid;         struct siginfo info;         int status;         if ((command = strrchr(argv[0], ,ÄÔ/,ÄÔ)) != NULL)                 command++;         else                 command = argv[0];         if (argc <= 1) {                 (void) fprintf(stderr,                          "usage:%s command [ args ... ]\n", command);                 (void) fprintf(stderr,                          "  (time a command using microstate accounting)\n");                 return (1);         }         switch (pid = fork()) {         case -1:                 (void) fprintf(stderr, "%s: cannot fork\n", command);                 return (2);         case 0:                 /* newly created child process */                (void) execvp(argv[1], &argv[1]);                (void) fprintf(stderr, "%s: exec failed\n", command);                if (errno == ENOENT)                        _exit(127);                else                        _exit(126);         }         (void) sprintf("%d", procname, (int)pid);         /* for perr() */         (void) signal(SIGINT, SIG_IGN);         (void) signal(SIGQUIT, SIG_IGN);         (void) waitid(P_PID, pid, &info, WEXITED | WNOWAIT);         (void) look(pid);         (void) waitpid(pid, &status, 0);         if (WIFEXITED(status))                  return (WEXITSTATUS(status));         else                  return ((status & ~WCOREFLG) | 0200); } static int look(pid_t pid) {         char pathname[100];         int rval = 0;         int fd;         prusage_t prusage;         timestruc_t real, user, sys;         prusage_t *pup = &prusage;         (void) sprintf(pathname, "/proc/%d/usage", (int)pid);         if ((fd = open(pathname, O_RDONLY)) < 0)                 return (perr("open usage"));         if (read(fd, &prusage, sizeof (prusage)) != sizeof (prusage))                 rval = perr("read usage");         else {                 real = pup->pr_term;                 tssub(&real, &real, &pup->pr_create);                 user = pup->pr_utime;                 sys = pup->pr_stime;                 tsadd(&sys, &sys, &pup->pr_ttime);                 (void) fprintf(stderr, "\n");                 printf("*** Usage Counters *** \n");                 printf("Minor Faults:................. %ld\n", pup->pr_minf);                 printf("Major Faults:................. %ld\n", pup->pr_majf);                 printf("Swaps:........................ %ld\n", pup->pr_nswap);                 printf("Input Blocks:................. %ld\n", pup->pr_inblk);                 printf("Output Blocks:................ %ld\n", pup->pr_oublk);                 printf("STREAMS Messages Sent:........ %ld\n", pup->pr_msnd);                 printf("STREAMS Messages Received:.... %ld\n", pup->pr_mrcv);                 printf("Signals:...................... %ld\n", pup->pr_sigs);                 printf("Voluntary Context Switches:... %ld\n", pup->pr_vctx);                 printf("Involuntary Context Switches:. %ld\n", pup->pr_ictx);                 printf("System Calls:................. %ld\n", pup->pr_sysc);                 printf("Read/Write Characters:........ %ld\n", pup->pr_ioch);                 printf("*** State Times *** \n");                 prtime("Total Elapsed Time:........... ", &real);                 prtime("Total User Time:.............. ", &user);                 prtime("Total System Time:............ ", &sys);                 prtime("Other System Trap Time:....... ", &pup->pr_ttime);                 prtime("Text Page Fault Sleep Time.... ", &pup->pr_tftime);                 prtime("Data Page Fault Sleep Time.... ", &pup->pr_dftime);                 prtime("Kernel Page Fault Sleep Time.. ", &pup->pr_kftime);                 prtime("User Lock Wait Sleep Time..... ", &pup->pr_ltime);                 prtime("All Other Sleep Time.......... ", &pup->pr_slptime);                 prtime("Time Waiting for a CPU........ ", &pup->pr_wtime);                 prtime("Stopped Time.................. ", &pup->pr_stoptime);          }          (void) close(fd);          return (rval); } static void hr_min_sec(char *buf, long sec) {         if (sec >= 3600)                 (void) sprintf(buf, "%ld:%.2ld:%.2ld",                         sec / 3600, (sec % 3600) / 60, sec % 60);         else if (sec >= 60)                 (void) sprintf(buf, "%ld:%.2ld",                         sec / 60, sec % 60);         else {                 (void) sprintf(buf, "%ld", sec);          } } static void prtime(char *name, timestruc_t *ts) {         char buf[32];         hr_min_sec(buf, ts->tv_sec);         (void) fprintf(stderr, "%s%s.%.3u\n",                 name, buf, (u_int)ts->tv_nsec/1000000); } static int perr(const char *s) {         if (s)                 (void) fprintf(stderr, "%s: ", procname);         else                 s = procname;         perror(s);         return (1); } static void tsadd(timestruc_t *result, timestruc_t *a, timestruc_t *b) {         result->tv_sec = a->tv_sec + b->tv_sec;         if ((result->tv_nsec = a->tv_nsec + b->tv_nsec) >= 1000000000) {                 result->tv_nsec -= 1000000000;                 result->tv_sec += 1;         } } static void tssub(timestruc_t *result, timestruc_t *a, timestruc_t *b) {          result->tv_sec = a->tv_sec - b->tv_sec;                if ((result->tv_nsec = a->tv_nsec - b->tv_nsec) < 0) {                  result->tv_nsec += 1000000000;                  result->tv_sec -= 1;          } } 





SolarisT Internals. Solaris 10 and OpenSolaris Kernel Architecture
Solaris Internals: Solaris 10 and OpenSolaris Kernel Architecture (2nd Edition)
ISBN: 0131482092
EAN: 2147483647
Year: 2004
Pages: 244

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net