tmem_template - copy

Download Tmem_template - Copy

If you can't read please download the document

Upload: chin-to

Post on 23-Jan-2016

213 views

Category:

Documents


0 download

DESCRIPTION

txt

TRANSCRIPT

/* Utility to print running total of VmPeak and VmSize of a program */#define _GNU_SOURCE#include #include #include #include #include #include #include #define PATH_MAX 2048int child_pid;int terminal_pid; //Used for exec terminalint last_pid = -1; //Used to store the pid of the last target applicationstatic int usage(char *me){fprintf(stderr, "%s: filename args\n", me);fprintf(stderr, "Run program, and print VmSize, VmData and VmStk (in KiB) to stdout\n");return 0;}static int child(int argc, char **argv){char **newargs = malloc(sizeof(char *) * argc);int i;/* We can't be certain that argv is NULL-terminated, so do that now */for (i = 0; i < argc - 1; i++){newargs[i] = argv[i+1];}newargs[argc - 1] = NULL;/* Launch the child */execvp(argv[1], newargs);return 0;}static void sig_chld(int dummy){ int status, child_val;int pid;(void) dummy;pid = waitpid(-1, &status, WNOHANG); if (pid < 0) { fprintf(stderr, "waitpid failed\n"); return; }/* Only worry about alive child */if(pid == terminal_pid || pid == last_pid)return;else if (pid != child_pid ) return;//ToDo//Task 2: Use the new terminal to send SIGCHLD to parent. Replace "return;" with a clause to handle SIGCHLD from terminal// 1. Read and store the path to new program and arguments from the original terminal// 2. Fork a new process to run it.// 3. last_pid = child_pid// 4. Update child_pid// 5. Kill original child/* Get child status value */ if (WIFEXITED(status)) { child_val = WEXITSTATUS(status); exit(child_val); }}static int main_loop(char *filename){char *line;char *vmsize;char *vmdata;char *vmstk;size_t len;FILE *f;vmsize = NULL;vmdata = NULL;vmstk = NULL;line = malloc(128);len = 128;f = fopen(filename, "r");if (!f) return 1;/* Read memory size data from /proc/pid/status */while (!vmsize || !vmdata || !vmstk){if (getline(&line, &len, f) == -1){/* Some of the information isn't there, die */return 1;}/* Find VmSize */if (!strncmp(line, "VmSize:", 7)){vmsize = strdup(&line[7]);}/* Find VmData */else if (!strncmp(line, "VmData:", 7)){vmdata = strdup(&line[7]);}/* Find VmStk */else if (!strncmp(line, "VmStk:", 6)){vmstk = strdup(&line[6]);}}free(line);fclose(f);/* Get rid of " kB\n"*/len = strlen(vmsize);vmsize[len - 4] = 0;len = strlen(vmdata);vmdata[len - 4] = 0;len = strlen(vmstk);vmstk[len - 4] = 0;/* Output results to stdout */printf("0:%s\n1:%s\n2:%s\n", vmsize, vmdata, vmstk);free(vmsize);free(vmdata);free(vmstk);/* Success */return 0;}int main(int argc, char **argv){char filename[PATH_MAX];struct sigaction act;if (argc < 2) return usage(argv[0]);//ToDo//Task 1: Fork a new process and spawn a terminal. Display the pid of main process.//Set the signal handler function as sig_chldact.sa_handler = sig_chld; /* We don't want to block any other signals */ sigemptyset(&act.sa_mask);act.sa_flags = SA_NOCLDSTOP;if (sigaction(SIGCHLD, &act, NULL) < 0) { fprintf(stderr, "sigaction failed\n"); return 1; }child_pid = fork();if (!child_pid) return child(argc, argv);snprintf(filename, PATH_MAX, "/proc/%d/status", child_pid);/* Continual scan of proc */while (!main_loop(filename)){/* Wait for 0.1 sec */usleep(100000);snprintf(filename, PATH_MAX, "/proc/%d/status", child_pid);}return 1;}