void closeFile(void) { /* ** Closes the GCM for when we're done... */ verbosePrint("Closing GCM..."); fclose(gcmFile); }
void extractFile(GCMFileEntryStruct *e, char *dest) { /* ** extract files from source (in GCM) to dest (in the local filesystem) */ char vstring[1024] = "Extracting "; strcat(vstring, e->filename); strcat(vstring, " from GCM to "); strcat(vstring, dest); verbosePrint(vstring); //check to see if the file was actually found... if (!e) { printf("File not found (%s)\n", e->filename); return; } //this way is fast, but uses up wayyyyyy too much memory. //fetch the data /*GCMFetchDataForFileEntry(gcmFile, e); WriteDataToFile(e->data, e->length, dest); free(e->data);*/ //this thing is wayyyyyyyyy too slow: /*FILE *ofile = NULL; if (!(ofile = fopen(dest, "w+"))) { perror(dest); exit(1); } fseek(gcmFile, e->offset, SEEK_SET); while (ftell(gcmFile) < (e->offset + e->length)) { fputc(fgetc(gcmFile), ofile); } fclose(ofile);*/ //this uses buffered reads to copy data in chunks... FILE *ofile = NULL; if (!(ofile = fopen(dest, "w+"))) { perror(dest); exit(1); } fseek(gcmFile, e->offset, SEEK_SET); if (CopyData(gcmFile, ofile, e->length) != e->length) { printf("ERROR COPYING DATA!\n"); } fclose(ofile); }
void injectApploader(char *sourcePath) { /* ** this doesn't work, yet... requires some serious shifting of other data... */ verbosePrint("Injecting the apploader..."); //first, load the file into memory... u32 length = GetFilesizeFromPath(sourcePath); char *data = (char*)malloc(length); if (ReadDataFromFile(sourcePath, data) != length) { printf("An error occurred reading the file (%s)", sourcePath); free(data); return; } free(data); }
void extractBootDol(char *path) { /* ** extracts the boot DOL from the GCM and saves it to path... */ verbosePrint("Extracting the boot DOL..."); if (!path) return; u32 length = GCMGetBootDolLength(gcmFile); char *buf = (char*)malloc(length); if (GCMGetBootDol(gcmFile, buf) != length) { free(buf); printf("An error occurred when getting the DOL. (%d)\n", GCMErrno); exit(EXIT_FAILURE); } WriteDataToFile(buf, length, path); }
void extractDiskHeaderInfo(char *path) { /* ** extracts the diskheaderinfo to bi2.bin */ verbosePrint("Extracting the disk header info..."); //get the data... char *buf = (char*)malloc(GCM_DISK_HEADER_INFO_LENGTH); if (GCMGetDiskHeaderInfo(gcmFile, buf) != GCM_SUCCESS) { free(buf); printf("An error occurred while reading the disk header info (%d)\n", GCMErrno); exit(EXIT_FAILURE); } WriteDataToFile(buf, GCM_DISK_HEADER_INFO_LENGTH, path); free(buf); }
void openFile(char *mode) { /* ** opens the GCM file with the mode set to mode ** if we were to open it for reading AND writing, ** it would error out if we didn't have write permission */ verbosePrint("Opening GCM..."); if (!filepath) { printUsage(); exit(1); } if (!(gcmFile = fopen(filepath, mode))) { //open as r+ so we can inject data, too... perror(filepath); exit(1); } }
void extractApploader(char *path) { /* ** extracts the apploader to appldr.bin */ verbosePrint("Extracting the apploader..."); //get the data... u32 apploaderLength = GCMGetApploaderSize(gcmFile) + GCM_APPLOADER_CODE_OFFSET; char *buf = (char*)malloc(apploaderLength); if (GCMGetApploader(gcmFile, buf) != GCM_SUCCESS) { free(buf); printf("An error occurred while reading the apploader (%d)\n", GCMErrno); exit(EXIT_FAILURE); } WriteDataToFile(buf, apploaderLength, path); free(buf); }
void injectDiskHeaderInfo(char *sourcePath) { /* ** take a diskHeaderInfo (bi2.bin) from sourcePath and inject it into gcmFile. */ verbosePrint("Injecting the disk header info..."); char *buf = (char*)malloc(GetFilesizeFromPath(sourcePath)); if (ReadDataFromFile(buf, sourcePath) != GCM_DISK_HEADER_INFO_LENGTH) { free(buf); printf("This does not appear to be a diskheaderinfo (%s)\n", sourcePath); exit(EXIT_FAILURE); } if (GCMPutDiskHeaderInfo(gcmFile, buf) != GCM_SUCCESS) { free(buf); printf("An error occurred when writing the disk header info! (%d)\n", GCMErrno); exit(EXIT_FAILURE); } free(buf); return; }
int main (int argc, char **argv) { // start flags declarations... gDataOffset = 0; //globally declared in GCMutils.h; Must be initialized before use... int hexFlag = 0; //for extracting: char *extractFileFrom = NULL; char *extractFileTo = NULL; char *fsReplacePath = NULL; verboseFlag = 0; int showInfoFlag = 1; int extractDiskHeaderFlag = 0; char *extractDiskHeaderFile = GCM_DISK_HEADER_FILENAME; int extractDiskHeaderInfoFlag = 0; char *extractDiskHeaderInfoFile = GCM_DISK_HEADER_INFO_FILENAME; int extractApploaderFlag = 0; char *extractApploaderFile = GCM_APPLOADER_FILENAME; int extractBootDolFlag = 0; char *extractBootDolFile = GCM_BOOT_DOL_FILENAME; int injectDiskHeaderFlag = 0; char *injectDiskHeaderFile = GCM_DISK_HEADER_FILENAME; int injectDiskHeaderInfoFlag = 0; char *injectDiskHeaderInfoFile = GCM_DISK_HEADER_INFO_FILENAME; int injectApploaderFlag = 0; char *injectApploaderFile = GCM_APPLOADER_FILENAME; char *replaceFileLocalPath = NULL; char *replaceFileGCMPath = NULL; int listFilesFlag = 0; listInfoFlag = 0; listPathFlag = 0; // end flag declarations //start argument parsing... char *currentArg = NULL; do { currentArg = GET_NEXT_ARG; if (!currentArg) { //there's no args! uh oh! //printf("No arguments...\n"); printUsage(); exit(0); } else if (CHECK_ARG(ARG_VERBOSE)) { //turn on verbosity! verboseFlag++; verbosePrint("Verbose output ON."); } else if (CHECK_ARG(ARG_HELP)) { // print extended help printExtendedUsage(); exit(0); } else if (CHECK_ARG(ARG_INFO)) { //they want to see info... showInfoFlag++; verbosePrint("Show info flag ON."); } else if (CHECK_ARG(ARG_HEX)) { //they want hex notation... hexFlag = 1; verbosePrint("Hex notation ON."); } else if (CHECK_ARG(ARG_OFFSET)) { //change the data offset gDataOffset = strtoul(GET_NEXT_ARG, NULL, 0); char verboseMsg[32] = ""; sprintf(verboseMsg, "Data offset changed to: %d", gDataOffset); verbosePrint(verboseMsg); } else if (CHECK_ARG(ARG_REPLACE_FILESYSTEM)) { // they want to replace the filesystem fsReplacePath = GET_NEXT_ARG; if (!fsReplacePath) { printf("Argument error...\n"); printUsage(); exit(1); } } else if (CHECK_ARG(ARG_EXTRACT)) { // extract files... // usage: -e <path> <destPath> extractFileFrom = GET_NEXT_ARG; extractFileTo = GET_NEXT_ARG; if (!extractFileFrom || !extractFileTo) { //argument error... something was omitted... printf("Argument error.\n"); printUsage(); exit(1); } } else if (CHECK_ARG(ARG_EXTRACT_DISK_HEADER)) { // extract disk header... (to a file called "boot.bin") extractDiskHeaderFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { // if they're specifying a file... SKIP_NARG(1); //skip that -f we just looked at... extractDiskHeaderFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_EXTRACT_DISK_HEADER_INFO)) { // extract disk header info... (to a file called "bi2.bin") extractDiskHeaderInfoFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { // if they're specifying a file... SKIP_NARG(1); //skip that -f we just looked at... extractDiskHeaderInfoFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_EXTRACT_APPLOADER)) { //extract apploader... (to a file called "appldr.bin") extractApploaderFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { // if they're specifying a file... SKIP_NARG(1); //skip that -f we just looked at... extractApploaderFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_EXTRACT_BOOT_DOL)) { //extract the boot dol... extractBootDolFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { //if they specify a file... SKIP_NARG(1); //skip that -f extractBootDolFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_INJECT_DISK_HEADER)) { //inject the diskheader injectDiskHeaderFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { //if they're specifying a file... (otherwise use the default); SKIP_NARG(1); //skip the -f we just looked at... injectDiskHeaderFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_INJECT_DISK_HEADER_INFO)) { //inject the diskheaderinfo... injectDiskHeaderInfoFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { // if they're specifying a file... SKIP_NARG(1); injectDiskHeaderInfoFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_INJECT_APPLOADER)) { //inject the apploader... injectApploaderFlag++; if (PEEK_ARG && strcmp(PEEK_ARG, OPT_FILE) == 0) { //if they're specifying a file... SKIP_NARG(1); injectApploaderFile = GET_NEXT_ARG; } } else if (CHECK_ARG(ARG_REPLACE_FILE)) { //they want to replace a file... replaceFileGCMPath = GET_NEXT_ARG; replaceFileLocalPath = GET_NEXT_ARG; if (!replaceFileGCMPath || !replaceFileLocalPath) { printf("Argument error!\n"); printUsage(); exit(1); } } else if (CHECK_ARG(ARG_LIST)) { // list filesystem listFilesFlag++; //turn the listFiles flag on. while(1) { if (PEEK_ARG && (strcmp(PEEK_ARG, OPT_FILE_INFO) == 0 || strcmp(PEEK_ARG, OPT_FILE_INFO_SYN) == 0)) { SKIP_NARG(1); listInfoFlag++; } else if (PEEK_ARG && (strcmp(PEEK_ARG, OPT_FULL_PATH) == 0 || strcmp(PEEK_ARG, OPT_FULL_PATH_SYN) == 0)) { SKIP_NARG(1); listPathFlag++; } else { break; } } } else { // do it to this file... this is the last argument... just ignore the rest... filepath = currentArg; filename = lastPathComponent(filepath); break; } } while(*argv); //end parsing arguments... //open the file for reading and start doing read operations! openFile("r"); // print the info... if (showInfoFlag) { printGCMInfo(hexFlag); } // list the files, if necesary... if (listFilesFlag) { listFiles(); } // extract files... if (extractFileFrom && extractFileTo) { //testing recursive extraction... GCMFileEntryStruct *e = NULL; if (strcmp(extractFileFrom, "/") == 0) { e = GCMGetRootFileEntry(gcmFile); printf("root file entry index: %d\n", e->index); } else { e = GCMGetFileEntryAtPath(gcmFile, extractFileFrom); } strcpy(extractRootPath, extractFileTo); recurseFileEntry(e, extractFileEntry); free(e); //extractFile(extractFileFrom, extractFileTo); } //extract diskheader if (extractDiskHeaderFlag) { extractDiskHeader(extractDiskHeaderFile); } //extract diskheaderinfo if (extractDiskHeaderInfoFlag) { extractDiskHeaderInfo(extractDiskHeaderInfoFile); } //extract apploader if (extractApploaderFlag) { extractApploader(extractApploaderFile); } //extract main executable DOL if (extractBootDolFlag) { extractBootDol(extractBootDolFile); } //close the file and open it again for read/write closeFile(); openFile("r+"); //inject the diskheader if (injectDiskHeaderFlag) { injectDiskHeader(injectDiskHeaderFile); } //inject the diskheaderinfo if (injectDiskHeaderInfoFlag) { injectDiskHeaderInfo(injectDiskHeaderInfoFile); } //inject the apploader if (injectApploaderFlag) { injectApploader(injectApploaderFile); } if (replaceFileLocalPath && replaceFileGCMPath) { replaceFile(replaceFileGCMPath, replaceFileLocalPath); } //replace the filesystem if (fsReplacePath) { GCMReplaceFilesystem(gcmFile, fsReplacePath); } closeFile(); return 0; }
int main(int argc, char **argv){ int optwait = 0; int numArgs = 0, start; open_files = (struct file_info*)malloc(maxfiles*sizeof(struct file_info)); running_threads = (struct thread_info*)malloc(maxthreads*sizeof(struct thread_info)); char option = 0; int i = 0, a; while ((option = (char)getopt_long(argc, argv, "", long_options, &i)) != -1) { switch (option){ case 'a':{ int b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec/1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec/1000000.0; verbosePrint(option, optind, argv, i, argc); if ((argv[optind - 1][0] == '-' && argv[optind - 1][1] == '-') || (optind < argc && argv[optind][0] != '-' && argv[optind][1] != '-')) { optind--; fprintf(stderr, "Error: Wrong number of operands\n"); errors++; break; } if (curfiles >= maxfiles){ open_files = (struct file_info*)realloc(open_files, (maxfiles *= 2)*sizeof(struct file_info)); if (open_files == NULL){ fprintf(stderr, "Error: Unable to reallocate memory; file was not opened.\n"); errors++; break; } } a = open(optarg, O_RDONLY | (O_APPEND & append) | (O_CLOEXEC & cloexec) | (O_CREAT & create) | (O_DIRECTORY & directory) | (O_DSYNC & dsyc) | (O_EXCL & excl) | (O_NOFOLLOW & nofollow) | (O_NONBLOCK & nonblock) | (O_RSYNC & rsync) | (O_SYNC & syc) | (O_TRUNC & trun)); if (a == -1){ errors++; fprintf(stderr, "Error: Unable to open file\n"); errors++; break; } open_files[curfiles].descriptor = a; open_files[curfiles].readable = 1; open_files[curfiles].writable = 0; open_files[curfiles].open = 1; curfiles++; append = cloexec = create = directory = dsyc = excl = nofollow = nonblock = rsync = syc = trun = 0; //some storage of the open value into some global int array. if (profile){ b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f for --rdonly\n", kertime); } break; } case 'b':{ int b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0; verbosePrint(option, optind, argv, i, argc); if ((argv[optind - 1][0] == '-' && argv[optind - 1][1] == '-') || (optind < argc && argv[optind][0] != '-' && argv[optind][1] != '-')) { optind--; fprintf(stderr, "Error: Wrong number of operands\n"); errors++; break; } if (curfiles >= maxfiles){ open_files = (struct file_info*)realloc(open_files, (maxfiles *= 2)*sizeof(struct file_info)); if (open_files == NULL){ fprintf(stderr, "Error: Unable to reallocate memory; file was not opened.\n"); errors++; break; } } a = open(optarg, O_WRONLY | (O_APPEND & append) | (O_CLOEXEC & cloexec) | (O_CREAT & create) | (O_DIRECTORY & directory) | (O_DSYNC & dsyc) | (O_EXCL & excl) | (O_NOFOLLOW & nofollow) | (O_NONBLOCK & nonblock) | (O_RSYNC & rsync) | (O_SYNC & syc) | (O_TRUNC & trun)); if (a == -1){ errors++; fprintf(stderr, "Error: Unable to create file\n"); errors++; break; } open_files[curfiles].descriptor = a; open_files[curfiles].readable = 0; open_files[curfiles].writable = 1; open_files[curfiles].open = 1; curfiles++; append = cloexec = create = directory = dsyc = excl = nofollow = nonblock = rsync = syc = trun = 0; if (profile){ b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f for --wronly\n", kertime); } break; } case 'p':{ int b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0; verbosePrint(option, optind, argv, i, argc); if ((argv[optind - 1][0] == '-' && argv[optind - 1][1] == '-') || (optind < argc && argv[optind][0] != '-' && argv[optind][1] != '-')) { optind--; fprintf(stderr, "Error: Wrong number of operands\n"); errors++; break; } if (curfiles >= maxfiles){ open_files = (struct file_info*)realloc(open_files, (maxfiles *= 2)*sizeof(struct file_info)); if (open_files == NULL){ fprintf(stderr, "Error: Unable to reallocate memory; file was not opened.\n"); errors++; break; } } a = open(optarg, O_RDWR | (O_APPEND & append) | (O_CLOEXEC & cloexec) | (O_CREAT & create) | (O_DIRECTORY & directory) | (O_DSYNC & dsyc) | (O_EXCL & excl) | (O_NOFOLLOW & nofollow) | (O_NONBLOCK & nonblock) | (O_RSYNC & rsync) | (O_SYNC & syc) | (O_TRUNC & trun)); if (a == -1){ errors++; fprintf(stderr, "Error: Unable to create file\n"); errors++; break; } open_files[curfiles].descriptor = a; open_files[curfiles].readable = 1; open_files[curfiles].writable = 1; open_files[curfiles].open = 1; curfiles++; append = cloexec = create = directory = dsyc = excl = nofollow = nonblock = rsync = syc = trun = 0; if (profile){ b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f\n", kertime); } break; } //COMMAND case 'c':{ int b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0; verbosePrint(option, optind, argv, i, argc); int index, count=0; int oldoptind = optind; for (index = optind - 1; index < argc; index++, count++){ if (argv[index][0] == '-' && argv[index][1] == '-') break; } optind = index; if (count < 4){ fprintf(stderr, "Error: --command requires at least 4 options.\n"); errors++; break; } int openCheck = 0, i; for (i = oldoptind - 1; i < (oldoptind + 2) && i < argc; i++){ if (atoi(argv[i]) >= curfiles || open_files[atoi(argv[i])].open==0){ openCheck = 1; break; } } if (openCheck){ fprintf(stderr, "Error: File not open\n"); errors++; break; } int stdinFilePos = atoi(argv[oldoptind - 1]), stdoutFilePos = atoi(argv[oldoptind]), stderrFilePos = atoi(argv[oldoptind + 1]); /*if (!open_files[stdinFilePos].readable || !open_files[stdoutFilePos].writable || !open_files[stderrFilePos].writable){ fprintf(stderr, "Error: File permission denied\n"); break; } */ ////////////////////////////////////////////////////////////////////////Executable Processing//////////////////////////////////////////////////////////////////// int childPID = fork(); //int fd[2]; //pipe(fd); if (childPID < 0){ fprintf(stderr, "Error: Unable to fork child process\n"); errors++; break; } else if (childPID == 0){ //close(fd[1]); int b=dup2(open_files[stdinFilePos].descriptor, STDIN_FILENO), c=dup2(open_files[stdoutFilePos].descriptor, STDOUT_FILENO), d=dup2(open_files[stderrFilePos].descriptor, STDERR_FILENO); int j; for (j = 0; j < curfiles; j++){ open_files[j].open = 0; close(open_files[j].descriptor); } if (d == -1 || b == -1 || c == -1){ fprintf(stderr, "Error: unable to open file"); errors++; break; } argv[optind] = '\0'; if (curfiles >= maxfiles){ open_files = (struct file_info*)realloc(open_files, (maxfiles *= 2)*sizeof(struct file_info)); if (open_files == NULL){ fprintf(stderr, "Error: Unable to reallocate memory; file was not opened.\n"); errors++; break; } } execvp(argv[oldoptind+2], &argv[oldoptind+2]); } else{ /*int status; int returnedPid=waitpid(childPID, &status, 0); if (status > maxExit) maxExit = status;*/ //removed exit status because they get reaped which makes it so i can't access them in wait running_threads[curthreads].start_ind = oldoptind + 2; running_threads[curthreads].end_ind = optind; running_threads[curthreads].threadnum = childPID; curthreads++; if (profile){ b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f for --command\n", kertime); } break; } } case 'd':{ verbose = 1; break; } //dealing with file opening options. case 'e':{ append = -1; break; } case 'f':{ cloexec = -1; break; } case 'g':{ create = -1; break; } case 'h':{ directory = -1; break; } case 'i':{ dsyc = -1; break; } case 'j':{ excl = -1; break; } case 'k':{ nofollow = -1; break; } case 'l':{ nonblock = -1; break; } case 'm':{ rsync = -1; break; } case 'n':{ syc = -1; break; } case 'o':{ trun = -1; break; } case 'q':{ int b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0; verbosePrint(option, optind, argv, i, argc); if (atoi(optarg) >= curfiles || open_files[atoi(optarg)].open==0){ fprintf(stderr, "Error: File not opened\n"); break; } open_files[atoi(optarg)].open = 0; close(open_files[atoi(optarg)].descriptor); if (profile){ b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f\n", kertime); } break; } case 'r':{ int b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0; verbosePrint(option, optind, argv, i, argc); raise(SIGSEGV); if (profile){ b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f\n", kertime); } break; } case 's':{ //catch int b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0; verbosePrint(option, optind, argv, i, argc); signal(atoi(optarg), sig_handler); if (profile){ b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f\n", kertime); } break; } case 't': {//ignore int b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0; verbosePrint(option, optind, argv, i, argc); signal(atoi(optarg), SIG_IGN); if (profile){ b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f\n", kertime); } break; } case 'u':{ //default int b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0; verbosePrint(option, optind, argv, i, argc); signal(atoi(optarg), SIG_DFL); if (profile){ b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f\n", kertime); } break; } case 'v':{ int b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0; verbosePrint(option, optind, argv, i, argc); pause(); if (profile){ b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f\n", kertime); } break; } case 'w':{ int b = getrusage(RUSAGE_CHILDREN, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0; verbosePrint(option, optind, argv, i, argc); optwait = 1; for (int i = 0; i < curfiles; i++){ if (open_files[i].open) close(open_files[i].descriptor); } for (int i = 0; i < curthreads; i++){ int status; pid_t thrd = waitpid(-1, &status, 0); if (status > maxExit) maxExit = status; for (int i = 0; i < curthreads;i++) if (thrd == running_threads[i].threadnum){ fprintf(stdout, "%d", status); for (int b = running_threads[i].start_ind; b < running_threads[i].end_ind; b++) fprintf(stdout, " %s", argv[b]); fprintf(stdout, "\n"); } } if (profile){ b = getrusage(RUSAGE_CHILDREN, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f\n", kertime); } break; } case 'x':{ //pipe int b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } double usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0; double kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0; verbosePrint(option, optind, argv, i, argc); if (argv[optind][0] != '-' && argv[optind][1] != '-') { fprintf(stderr, "Error: Pipe should not have operands\n"); errors++; break; } int fd[2]; int p = pipe(fd); if (p){ fprintf(stderr, "Error: Unable to create file descriptors.\n"); errors++; break; } int i; for (i = 0; i < 2; i++){ // add two file descriptors to the open_files array if (curfiles >= maxfiles){ open_files = (struct file_info*)realloc(open_files, (maxfiles *= 2)*sizeof(struct file_info)); if (open_files == NULL){ fprintf(stderr, "Error: Unable to reallocate memory; file was not opened.\n"); errors++; break; } } open_files[curfiles].descriptor = fd[i]; if (i){ // when i is 0 and the read end of the pipe open_files[curfiles].readable = 1; open_files[curfiles].writable = 0; } else {// when i is 1 and the write end of the pipe open_files[curfiles].readable = 0; open_files[curfiles].writable = 1; } open_files[curfiles].open = 1; curfiles++; } if (profile){ b = getrusage(RUSAGE_SELF, &thread_timer); if (b == -1){ errors++; fprintf(stderr, "Error: Could not get resource usage data\n"); errors++; break; } usrtime = thread_timer.ru_utime.tv_sec + thread_timer.ru_utime.tv_usec / 1000000.0 - usrtime; kertime = thread_timer.ru_stime.tv_sec + thread_timer.ru_stime.tv_usec / 1000000.0 - kertime; fprintf(stdout, "user time: %f ", usrtime); fprintf(stdout, "kernel time: %f\n", kertime); } break; } case 'y':{ profile = 1; break; } default:{ break; } } } if (!optwait){ for (int i = 0; i < curfiles; i++){ if (open_files[i].open) close(open_files[i].descriptor); } for (int i = 0; i < curthreads; i++){ int status; pid_t thrd = waitpid(-1, &status, 0); if (status > maxExit) maxExit = status; } } free(open_files); if (errors > 0 && maxExit == 0) maxExit = 1; exit(maxExit); }