Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielVukelich committed Nov 12, 2016
1 parent eb98032 commit cf96645
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.o
vsh
*~
22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
CC=gcc
CFLAGS=-Wall -Werror -std=c99
OBJS=argbuild.o vsh.o
BINARY=vsh

.PHONY: clean all debug release

all: debug

release: $(BINARY)

debug: CFLAGS += -g
debug: $(BINARY)

$(BINARY): $(OBJS)
$(CC) -o $@ $(CFLAGS) $(OBJS) $(LDLIBS)

%.o: %.c %.h
$(CC) -c $< -o $@ $(CFLAGS)

clean:
rm $(OBJS) $(BINARY)
96 changes: 96 additions & 0 deletions argbuild.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include "argbuild.h"

#include <stdlib.h>
#include <string.h>

void add_arg(char* argument, arg_t* args){
arg_elt_t* toadd = malloc(sizeof(arg_elt_t));
toadd->arg = argument;
toadd->next = NULL;
if(args->end != NULL){
args->end->next = toadd;
}
args->end = toadd;
if(args->first == NULL){
args->first = toadd;
}
++(args->argc);
}

arg_t* build_args(char* cmd, unsigned int cmd_max_len){
arg_t* to_return = malloc(sizeof(arg_t));
to_return->first = NULL;
to_return->end = NULL;
to_return->argc = 0;

int sub_start = 0;
int sub_end = 0;

for(unsigned int i = 0; i < cmd_max_len; ++i){
if(cmd[i] == '\0'){
break;
}
if(cmd[i] == ' ' || cmd[i] == '\n'){

//Ignore multiple spaces between arguments
if(cmd[i] == ' ' && cmd[i + 1] == ' '){
continue;
}

char delineate = cmd[i];

sub_end = i;
int new_str_siz = (sub_end - sub_start) + 1;

//Make sure the string is not empty
if(new_str_siz > 1){
//Temporarily add a null terminator in the cmd string to make
//strncpy's job easier
cmd[i] = '\0';
char* arg_str = malloc(sizeof(char) * new_str_siz);
//Copy the argument into the new string
strncpy(arg_str, &cmd[sub_start], new_str_siz);
//Add back in the space char that was replaced by null
//terminator
cmd[i] = delineate;
//Now add the string to our linked list of arg elts
add_arg(arg_str, to_return);
//Make sub_start point to the next char after cmd[i], which is
//a space
sub_start = i + 1;
}
}
}

return to_return;
}

char** get_args(arg_t* args, int* numargs){
if(args->argc <= 0){
return NULL;
}

char** to_return = malloc(sizeof(char) * (args->argc + 1));
*numargs = 0;
for(arg_elt_t* it = args->first; it != NULL; it = it->next){
to_return[(*numargs)++] = it->arg;
}

//The last elt in this array is a null pointer
to_return[args->argc] = '\0';

return to_return;
}

void free_args(arg_t* tofree){
arg_elt_t* it = tofree->first;
while(it != NULL){
arg_elt_t* next = it->next;
if(it != NULL){
free(it->arg);
}
free(it);
it = next;
}
free(tofree);
}
19 changes: 19 additions & 0 deletions argbuild.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef ARG_BUILD_H
#define ARG_BUILD_H

typedef struct arg_elt{
struct arg_elt* next;
char* arg;
} arg_elt_t;

typedef struct args{
arg_elt_t* first;
arg_elt_t* end;
int argc;
} arg_t;

arg_t* build_args(char* cmd, unsigned int cmd_max_len);
char** get_args(arg_t* args, int* numargs);
void free_args(arg_t* tofree);

#endif
56 changes: 56 additions & 0 deletions vsh.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <assert.h>

#include "argbuild.h"

#define DIR_STR_SIZ 1024

int main(int argc, char** argv, char** envp){
char running = 1;
char pwd[DIR_STR_SIZ];
const long ARG_MAX = sysconf(_SC_ARG_MAX);
char cmdbuf[ARG_MAX];

char user_prompt = '$';
if(geteuid() == 0)
user_prompt = '#';

puts("Welcome to vsh, the Vukelich Shell.\n");


while(running){

//Get the current working directory. If an error occurs, then
//set the pwd string to empty
if(getcwd(pwd, DIR_STR_SIZ) != pwd){
pwd[0] = '\0';
}

printf("%s %c ", pwd, user_prompt);

if(fgets(cmdbuf, ARG_MAX, stdin) != cmdbuf){
puts("\nExiting");
running = 0;
continue;
}

arg_t* args = build_args(cmdbuf, ARG_MAX);
int child_argc;
char** arg_ary = get_args(args, &child_argc);

if(!fork()){
execve(arg_ary[0], arg_ary, envp);
printf("%s: %s: Command not found\n", argv[0], arg_ary[0]);
return 1;
}
wait(NULL);
free(arg_ary);
free_args(args);

}

return 0;
}

0 comments on commit cf96645

Please sign in to comment.