|
CS471/571 - Operating Systems
| Displaying exercises/e2/solution/rusage-opts.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdbool.h>
#include <string.h>
void run(char *argv[])
{
execvp(argv[0], argv);
perror("exec");
exit(1);
}
double ftime(struct timeval t)
{
double s = t.tv_sec + (double)t.tv_usec/1000000.0;
return s;
}
void usage(void)
{
printf("Usage: rusage [-mpic] [--mem] [--io] [--pfaults] [--ctxtsw] [--help] [--] <cmd...>\n");
exit(0);
}
int main(int argc, char *argv[])
{
if (argc < 2) {
usage();
}
int mflag = false, pflag = false, ioflag = false, cflag = false;
int optf = true;
int nwords = 0, maxwords;
char **words = malloc(sizeof(char *) * (maxwords=10));
int i, j, n;
for(n=i=1; i<argc; i=n) {
n++;
if (optf && argv[i][0] == '-' && argv[i][1]) {
for(j=1; argv[i][j]; j++) {
switch(argv[i][j]) {
case 'm':
mflag = true;
break;
case 'p':
pflag = true;
break;
case 'i':
ioflag = true;
break;
case 'c':
cflag = true;
break;
case '-':
if (j != 1) {
printf("Invalid switch j=%d\n", j);
exit(1);
}
if (strncmp("--mem", argv[i], 5) == 0) {
j = strlen(argv[i])-1;
mflag = true;
break;
}
if (strncmp("--io", argv[i], 4) == 0) {
j = strlen(argv[i])-1;
ioflag = true;
break;
}
if (strncmp("--pfaults", argv[i], 9) == 0) {
j = strlen(argv[i])-1;
pflag = true;
break;
}
if (strncmp("--ctxtsw", argv[i], 8) == 0) {
j = strlen(argv[i])-1;
cflag = true;
break;
}
if (strncmp("--help", argv[i], 6) == 0) {
j = strlen(argv[i])-1;
usage();
break;
}
if (!strcmp("--", argv[i])) {
optf = false;
break;
}
default:
printf("Invalid switch [%c].\n", argv[i][j]);
exit(1);
}
}
} else {
// argv[i] is not a switch word:
if (nwords >= maxwords-2) words = realloc(words, sizeof(char *) * (maxwords += 10));
words[nwords++] = argv[i];
}
}
words[nwords] = NULL;
pid_t pid = fork();
if (pid < 0) {
perror("fork");
return 1;
}
if (pid == 0) run(words);
int status = 0;
waitpid(pid, &status, 0);
printf("--\n Exit status: %d\n", WEXITSTATUS(status));
struct rusage u;
if (getrusage(RUSAGE_CHILDREN, &u) < 0) {
perror("rusage");
return 1;
}
printf(" CPU time: user: %.3fs, sys: %.3fs\n", ftime(u.ru_utime), ftime(u.ru_stime));
if (mflag) printf(" Max RSS: %ldK\n", u.ru_maxrss);
if (pflag) printf(" Page faults: minor: %d, major: %d\n", u.ru_minflt, u.ru_majflt);
if (ioflag) printf(" I/O blocks: in: %d, out: %d\n", u.ru_inblock, u.ru_oublock);
if (cflag) printf("Context switches: voluntary: %d, involuntary: %d\n", u.ru_nvcsw, u.ru_nivcsw);
return 0;
}
|