Skip to content

Commit

Permalink
Added Lab-2 folder from zip archive
Browse files Browse the repository at this point in the history
  • Loading branch information
lariosm committed Jan 27, 2020
1 parent 8efd2df commit 763f45e
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 0 deletions.
32 changes: 32 additions & 0 deletions Lab-2/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app
24 changes: 24 additions & 0 deletions Lab-2/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
DEBUG=y

CC=g++
CFLAGS= -Werror -Wall
LDFLAGS=

ifeq ($DEBUG), y)
CFLAGS += -DDEBUG -g
else
CFLAGS += -O2
endif

.PHONY: all clean

all: bin/shell

bin/shell: obj/shell.o obj/parser.o obj/main.o
$(CC) $^ -o $@

obj/%.o: src/%.cpp
$(CC) -c $(CFLAGS) $< -o $@

clean:
$(RM) *~ src/*~ src/#* obj/*.o bin/*
1 change: 1 addition & 0 deletions Lab-2/bin/BinDir.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is the bin directory.
1 change: 1 addition & 0 deletions Lab-2/obj/ObjDir.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is the obj directory.
6 changes: 6 additions & 0 deletions Lab-2/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
int main()
{
Shell::Run();

return 0;
}
132 changes: 132 additions & 0 deletions Lab-2/src/parser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include "parser.hpp"

#include <stdlib.h> // EXIT_FAILURE
#include <stdio.h> // printf()
#include <string.h> // strlen()
#include <ctype.h> // isspace(),
#include <string.h> // strtok_r()
#include <stdbool.h>

bool Parser::Empty(char *str)
{
while (*str)
{
if (!isspace(*str++))
return false;
}
return true;
}

char *Parser::LeftTrim(char *s)
{
while (isspace((int)*s))
++s;
return s;
}

char *Parser::RightTrim(char *str)
{
if (*str == 0)
return str;
else
{
char *back = str + strlen(str) - 1;

while (isspace(*back))
back--;

*(back + 1) = 0;

return str;
}
}

char *Parser::Trim(char *str)
{
if (str != nullptr)
return (LeftTrim(RightTrim(str)));
else
return nullptr;
}

void Parser::GetArgument(char *str, const char *delim, char *argv[])
{

char *token;
int i = 0;

token = strtok(str, delim);

while (token != nullptr)
{
argv[i] = token;
token = strtok(NULL, delim);
i++;
}
argv[i] = nullptr;
}

void Parser::PrintArgument(char *argv[])
{
int i = 0;
char *s;

while ((s = argv[i]))
{
printf(" argv[%d] = %s\n", i, s);
i++;
}
}

void Parser::PrintArguments(char *argvs[MAX_COMMANDS][MAX_ARGV])
{
int i = 0;
while (argvs[i][0])
{
printf("Command %d\n", i);
PrintArgument(argvs[i]);
i++;
}
}

void Parser::ParseCommands(char *str, const char *delim, char *cmds[])
{

char *token;
int i = 0;

token = strtok(str, delim);

while (token != NULL)
{
if (Empty(token))
{
fprintf(stderr, "Parser error: EMPTY command!\n");
exit(EXIT_FAILURE);
}

cmds[i] = Trim(token);
token = strtok(nullptr, delim);
i++;
}
cmds[i] = nullptr;
}

int Parser::Parse(char *str, char *argvs[MAX_COMMANDS][MAX_ARGV])
{

char *cmds[MAX_COMMANDS];

ParseCommands(str, "|", cmds);

int i = 0;

while (cmds[i])
{
GetArgument(cmds[i], " ", argvs[i]);
i++;
}

argvs[i][0] = nullptr;
return i;
}
23 changes: 23 additions & 0 deletions Lab-2/src/parser.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef PARSER_HPP
#define PARSER_HPP

const int MAX_COMMANDS = 16;
const int MAX_ARGV = 16;

class Parser
{
public:
static int Parse(char *str, char *argvs[MAX_COMMANDS][MAX_ARGV]);
static void PrintArguments(char *argvs[MAX_COMMANDS][MAX_ARGV]);

private:
static void PrintArgument(char *argv[]);
static void ParseCommands(char *str, const char *delim, char *cmds[]);
static bool Empty(char *str);
static char *LeftTrim(char *s);
static char *RightTrim(char *str);
static char *Trim(char *str);
static void GetArgument(char *str, const char *delim, char *argv[]);
};

#endif // PARSER_HPP
125 changes: 125 additions & 0 deletions Lab-2/src/shell.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#include "shell.hpp"

bool DEBUG = false;

void DebugPrint(const char *message)
{
if (DEBUG)
printf("%s\n", message);
}

void Shell::ForkError()
{
perror("fork() failed)");
exit(EXIT_FAILURE);
}

void Shell::CloseError()
{
perror("Couldn't close file descriptor");
exit(EXIT_FAILURE);
}

void Shell::Execute(char *argv[], int number_of_commands, int read_pipe[2], int write_pipe[2], int all_pipes[][2])
{
pid_t pid;

switch (pid = fork())
{
case -1:
ForkError();
case 0:
// if read_pipe is not null
// then duplicate read_pipe (e.g. dup2) for STDIN
// if write_pipe is not null
// then duplicate write_pipe (e.g. dup2) for STDOUT
// Close pipes.

execvp(argv[0], argv);
perror("execvp");
exit(EXIT_FAILURE);

default:
char buffer[MAX_BUFFER];
sprintf(buffer, "Pid of %s: %d\n", argv[0], pid);
DebugPrint(buffer);
break;
}
}

void Shell::ExecuteCommands(char *argvs[MAX_COMMANDS][MAX_ARGV], const size_t &number_of_commands, int all_pipes[][2])
{
// 1. Cases to cover in a loop; for i = 0 to number_of_commands
// |-------------------------------------------------------------------
// | COMMAND | READ PIPE | WRITE PIPE |
// |-------------------------------------------------------------------
// | Only 1 command | null | null |
// |-------------------------------------------------------------------
// | First command | null | current pipe |
// |-------------------------------------------------------------------
// | Last command | previous pipe | null |
// |-------------------------------------------------------------------
// | Middle command | previous pipe | current pipe |
// --------------------------------------------------------------------

// 2. Close pipes.
}

void Shell::GetLine(char *buffer, size_t size)
{
getline(&buffer, &size, stdin);
buffer[strlen(buffer) - 1] = '\0';
}

void Shell::WaitForAllCommands(const size_t &number_of_commands)
{
// for i = 0 to number_of_commands
// call wait()

}

void Shell::InitializePipes(int all_pipes[][2], const size_t &number_of_commands)
{
// for i = 0 to number_of_commands
// init all_pipes[i]
}

void Shell::ClosePipes(int all_pipes[][2], const size_t &number_of_commands)
{
// for i = 0 to number_of_commands
// close read and write ends for pipes
}

void Shell::Run()
{
int number_of_commands = 0;
char *argvs[MAX_COMMANDS][MAX_ARGV];
const size_t size = 128;
char line[size];

while (true)
{
printf(" >> ");

Shell::GetLine(line, size);

number_of_commands = Parser::Parse(line, argvs);

char buffer[MAX_BUFFER];
sprintf(buffer, "%d commands parsed.\n", number_of_commands);
DebugPrint(buffer);

if (DEBUG)
Parser::PrintArguments(argvs);

int(*all_pipes)[2] = new int[number_of_commands][2];
Shell::InitializePipes(all_pipes, number_of_commands);

ExecuteCommands(argvs, number_of_commands, all_pipes);
Shell::WaitForAllCommands(number_of_commands);

delete[] all_pipes;
}

exit(EXIT_SUCCESS);
}
33 changes: 33 additions & 0 deletions Lab-2/src/shell.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef SHELL_HPP
#define SHELL_HPP

#include "parser.hpp"

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/wait.h>

const int READ = 0;
const int WRITE = 1;
const int MAX_BUFFER = 128;

class Shell
{
public:
static void ForkError();
static void CloseError();
static void Execute(char *argv[], int number_of_commands, int read_pipe[2], int write_pipe[2], int all_pipes[][2]);
static void ExecuteCommands(char *argvs[MAX_COMMANDS][MAX_ARGV], const size_t &number_of_commands, int all_pipes[][2]);
static void GetLine(char *buffer, size_t size);
static void WaitForAllCommands(const size_t& n);
static void Run();
static void InitializePipes(int all_pipes[][2], const size_t &number_of_commands);
static void ClosePipes(int all_pipes[][2], const size_t &number_of_commands);
};

#endif

0 comments on commit 763f45e

Please sign in to comment.