char * get_input() { unsigned int bufferSize = BUFFER_START, bufferUsed = 0; // Buffer tracking. char * buffer = calloc(bufferSize, sizeof(char)); // Hi, could I get a 00000000000000000000? while(1) { char currentChar = getchar(); // Dear user, Please press a button. Kthxbye. if(currentChar == '\n') // User be done. break; // gtfo buffer[bufferUsed] = currentChar; if(bufferUsed == bufferSize - 1) { // A little big there, champ? bufferSize *= 2; // Double the size. // Bigger buffer, please! :D buffer = (char *) realloc(buffer, bufferSize); if(buffer == NULL) // Aw, por que no? { fail_with_error("Could not get memory space for buffer."); } } bufferUsed++; } buffer[bufferUsed] = '\0'; // Zero string. return buffer; }
/* * Method: main * Purpose: Handles primary functionality. * Parameters: * int argc: The count of arguments. * char *argv[]: The array of arguments. */ int main(int argc, char *argv[]) { Settings settings; // The passed settings. int * filenameIndices; // Will hold indices of filename locations in argv. int filenameIndicesCount = 0; // The count of indices. // Grabs settings. handle_arguments(argc, argv, &settings, &filenameIndices, &filenameIndicesCount); if(settings.ignoreInterrupts) { signal(SIGINT, SIG_IGN); // Ignore signals if asked of us. } FILE *openFiles[filenameIndicesCount]; // The set of open file descriptors. // Open files. int index; for(index = 0; index < filenameIndicesCount; index++) { int argIndex = filenameIndices[index]; char * mode = (settings.append) ? "a" : "w"; // Chose write mode based on flags. openFiles[index] = fopen(argv[argIndex], mode); // Open the file with mode. if(!openFiles[index]) { fail_with_error("Could not open file."); } } if(filenameIndices) free(filenameIndices); // Free calloced data. char inputBuffer[BUFFER_SIZE]; while(fgets(inputBuffer, BUFFER_SIZE, stdin)) // Receive input. { for(index = 0; index < filenameIndicesCount; index++) { // Print input to each file. fwrite(inputBuffer, sizeof(char), strlen(inputBuffer), openFiles[index]); fflush(openFiles[index]); } printf("%s", inputBuffer); // Print out the input. } return 0; }
void execute(char ** args) { pid_t pid; int background = 0; char ** argsInd = args; while(*argsInd != '\0') { if(background) { background = 0; } if(strcmp(*argsInd, "&") == 0) { background = 1; } argsInd++; } if(background) { *(argsInd - 1) = '\0'; } if((pid = fork()) < 0) { fail_with_error("Could not fork new process."); } else if(pid == 0) { if(execvp(*args, args) < 0) // Check execution success. { display_error("Execution failed."); } } else if(!background) { if(wait(NULL) == -1) { display_error("Process did not return on wait."); } } }
/* * Method: handle_arguments * Purpose: Handles passed args. * Parameters: * int argc: The count of arguments. * char *argv[]: The array of arguments. * PSettings pSettings: Pointer to settings struct. */ void handle_arguments(int argc, char *argv[], PSettings pSettings, int **filenameIndices, int *filenameIndicesCount) { int index; // The index. int foundFilename = FALSE; // Whether we found a filename. int filenameArraySize = 5; *filenameIndicesCount = 0; *filenameIndices = (int *) calloc(filenameArraySize, sizeof(int)); for(index = 1; index < argc; index++) { char * currentArgument = argv[index]; if(currentArgument[0] == '-') // Is a flag. { if(strcmp(currentArgument, "-a") == 0) { pSettings->append = TRUE; } else if(strcmp(currentArgument, "-i") == 0) { pSettings->ignoreInterrupts = TRUE; } else { // Invalid flag. free(*filenameIndices); fail_with_error("The passed flag was invalid."); } } else // Should be a filename. { if(*filenameIndicesCount >= filenameArraySize) { // Double the size of the array. *filenameIndices = (int *) realloc(*filenameIndices, sizeof(int) * filenameArraySize * 2); filenameArraySize *= 2; } (*filenameIndices)[*filenameIndicesCount] = index; (*filenameIndicesCount)++; } } }