Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <iomanip>
- #include <unistd.h>
- #include <cstdlib>
- #include <cstdio>
- #include <cstring>
- #include <sys/types.h>
- #include <sys/wait.h>
- using namespace std;
- // Declare constant values for program
- const unsigned BUFFER_SIZE = 1024;
- const unsigned MAX_ARGUMENT_COUNT = 64;
- const char *SHELL_TITLE = "480SHELL> ";
- const char *QUIT_PROMPT = "quit";
- const char *QUIT_PROMPT2 = "q";
- const char *PIPE_PROMPT = "||";
- /****************************************************************
- FILE: main.cpp
- AUTHOR: Kevin Miyata
- LOGON ID: Z1771936
- DUE DATE: 18 February 2019
- PURPOSE: This file simulates a shell with commands. It allows input from one
- file to be outputted to another file using an operator and file arguments.
- ****************************************************************/
- int main() {
- // Read and write pipes
- int pipeFileDescriptor[2];
- // Fork and exec statuses
- int processId;
- int status;
- // Input buffer
- char buffer[BUFFER_SIZE];
- // Set argument count to maximum
- int argumentCount = MAX_ARGUMENT_COUNT;
- // Print shell name to prompt for commands
- cerr << SHELL_TITLE;
- // Cycle through stdin and feed to buffer to get commands and arguments
- while (fgets(buffer, BUFFER_SIZE, stdin) != nullptr) {
- // Replace final character with null terminator
- buffer[strlen(buffer) - 1] = '\0';
- // Create array for incoming arguments
- char *arguments[argumentCount];
- // Check for argument separation with spacing
- arguments[0] = strtok(buffer, " ");
- // Cycle through arguments to create argument array
- for (int i = 1; arguments[i] != nullptr; i++) {
- arguments[i] = strtok(nullptr, " ");
- }
- // Look for exit command
- if (strcmp(arguments[0], QUIT_PROMPT) == 0 or strcmp(arguments[0], QUIT_PROMPT2) == 0) {
- // Exit if quit prompt was matched to input
- exit(1);
- }
- // Check for pipe index
- int pipeLocation = -1;
- // Scan through all arguments
- for (int i = 1; i < argumentCount; i++) {
- if (arguments[i] != nullptr) {
- if (strcmp(arguments[i], PIPE_PROMPT) == 0) {
- pipeLocation = i;
- arguments[i] = nullptr;
- }
- } else {
- break;
- }
- }
- // Check for pipe command
- if (pipeLocation > 0) {
- // Check for pipe errors
- if (pipe(pipeFileDescriptor) < 0) {
- fprintf(stderr, "ERROR: Could not pipe!");
- return -5;
- }
- // Fork parent process
- processId = fork();
- // Check fork status for failure
- if (processId < 0) {
- fprintf(stderr, "ERROR: Could not fork process!");
- } else if (processId == 0) {
- // Close unused pipes
- close(1);
- close(pipeFileDescriptor[0]);
- // Dup writing pipe
- dup2(pipeFileDescriptor[1], 1);
- // Execute command with arguments
- execvp(arguments[0], arguments);
- } else {
- wait(nullptr);
- }
- // Fork child process
- processId = fork();
- if (processId < 0) {
- fprintf(stderr, "ERROR: Could not fork!");
- } else if (processId == 0) {
- // Close unused pipes
- close(1);
- close(0);
- close(pipeFileDescriptor[0]);
- // Dup write pipe
- dup(pipeFileDescriptor[1]);
- // Run secondary commands
- execvp(arguments[0], &arguments[pipeLocation + 1]);
- } else {
- wait(nullptr);
- }
- // Close parent pipes
- close(pipeFileDescriptor[1]);
- } else {
- // Open write pipe, check for error
- if (pipe(pipeFileDescriptor) < 0) {
- fprintf(stderr, "Could not pipe!");
- return -5;
- }
- // Fork process again
- processId = fork();
- // Check for fork error
- if (processId < 0) {
- fprintf(stderr, "Could not fork process!");
- } else if (processId == 0) {
- // This is the child process!
- // Close unused pipes
- close(1);
- close(pipeFileDescriptor[0]);
- // Duplicate and write to pipe
- dup(pipeFileDescriptor[1]);
- execvp(arguments[0], arguments);
- }
- // Close the parent pipe
- close(pipeFileDescriptor[1]);
- }
- // Wait for parent process
- processId = waitpid(processId, &status, 0);
- // Check for error when waiting for other process
- if (processId < 0) {
- fprintf(stderr, "Wait for process with id %d failed!", processId);
- }
- // Create output buffer, set final character to null terminator
- char output[2];
- output[1] = '\0';
- // Scan through the read pipe and print out the buffer
- while (read(pipeFileDescriptor[0], output, 1) not_eq 0) {
- fprintf(stderr, output);
- }
- // Print out shell title again
- fprintf(stderr, "\n%s", SHELL_TITLE);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement