I have written a basic C Shell. It features the builtins cd
, programmer
, ver
and exit
. The code for the shell, named vsh
, is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#define BUFSIZE 1024
#define TOK_BUFSIZE 64
#define TOK_DELIM " \t\r\n\a"
char **split_line(char *line)
{
int bufsize = TOK_BUFSIZE, position = 0;
char **tokens = malloc(bufsize * sizeof(char*));
char *token, **tokens_backup;
if (!tokens) {
fprintf(stderr, "vsh: allocation error\n");
exit(EXIT_FAILURE);
}
token = strtok(line, TOK_DELIM);
while (token != NULL) {
tokens[position] = token;
position++;
if (position >= bufsize) {
bufsize += TOK_BUFSIZE;
tokens_backup = tokens;
tokens = realloc(tokens, bufsize * sizeof(char*));
if (!tokens) {
free(tokens_backup);
fprintf(stderr, "vsh: allocation error\n");
exit(EXIT_FAILURE);
}
}
token = strtok(NULL, TOK_DELIM);
}
tokens[position] = NULL;
return tokens;
}
int main(int argc, char **argv)
{
int finish = 0;
char *user = getenv("USER");
char hostname[BUFSIZE];
char *cwd;
char line[BUFSIZE] = {0};
char **args;
char *directory;
printf("Welcome to vsh\n");
system("/bin/cat /etc/motd");
printf("\n");
gethostname(hostname, BUFSIZE);
while (!finish)
{
cwd = getcwd(cwd, BUFSIZE);
printf("[");
printf(user);
printf("@");
printf(hostname);
printf("] ");
printf(cwd);
printf(" $ ");
fflush(stdout);
if(NULL == fgets(line, sizeof line, stdin))
{
finish = 1;
printf("\nLeaving vsh\n");
}
else
{
printf("The command read was %s", line);
printf("\n");
args = split_line(line);
if(strcmp(line, "") == 0) {
fprintf(stderr, "vsh: Expected command\n");
}
else if(strcmp(args[0], "cd") == 0)
{
directory = args[1];
chdir(directory);
}
else if(strcmp(line,"programmer") == 0)
{
printf("The programmer of vsh is George Gibson\n");
}
else if(strcmp(line,"ver") == 0)
{
printf("The current version is 1.0\n");
}
else if(strcmp(line,"exit") == 0)
{
finish = 1;
printf("\nLeaving vsh...\n");
getchar();
}
else
{
pid_t pid;
int err;
pid = fork();
if(pid == -1) {
perror("vsh");
}
else if(pid == 0) {
execvp(args[0], args);
perror("vsh");
}
else {
waitpid(pid, &err, 0);
}
}
}
}
return 0;
}
I'm particularly looking for reviews relating to bugs, optimizations and general improvements.