Making a BASH doppelgangger

09/03/2014 18:46

Making a simple shell that works like BASH using fork() and exec()

 
 
 
So.. I'm back with one of my pet projects. Well in this case more of a 5 minute hackjob. Have you ever wondered how hard it is to write your own shell for POSIX systems?

Disclaimer: Every line of code was written by me. But I did NOT test it extensively. So stuff like piping and extra long comands may not work right. Thios is meant to be more of a pedagogical post.

#include
#include
#include
#include
#include
#include
#include
 
 
void csplit();
void executor();
 
 
 
char* token; /* temporary token to allow command split*/
char* prompttoken="\n?"; /* token of your prompt*/
char comman[40]; /* string stores your command as it was typed*/
char commandparts[4][20]; /* split strings in your command. assumes to have 3 parts. alter if you need more*/
char* delims=" "; /* delimiter of the strtok function*/
int argcount; /* count of the number of arguments */
int pid; /* process id of created child process */
 
int main()
{
 
 
while(1)
{
argcount=0;
printf("%s",prompttoken);      /*adopting this to display console output as opposed to puts cause a blank line is not created */
gets(comman);
printf("%s",prompttoken);
csplit();
if(!(strcmp("exit",commandparts[0])))
{
printf("\n TERMINATED\n");
exit(0);
 
}
executor();
}
 
 
return 0;
}
void csplit()
{
//printf("\n goes to csplit\n");
token=strtok(comman,delims);
strcpy(commandparts[argcount],token);
argcount++;
while(token!=NULL)
{
//puts(token);
 
strcpy(commandparts[argcount],token);
argcount++;
token=strtok(NULL,delims);
/* why copy at the end? because strok does the job of adding a NULL at the end for me */
}
//printf("\n exits csplit no problem \n");
}
 
void executor()
{
//printf("\n enters executor \n");
static char *args[] = {
                    
                    commandparts[1],
                    commandparts[2],
                    (char *) 0 };
 
 
pid=fork();
if(pid==0)
{
                  execvp(commandparts[0], args);
printf("UNKNOWN COMMAND\n");
exit(0);
}
else
{
strcpy(commandparts[0],"");
strcpy(commandparts[1],"");
strcpy(commandparts[2],"");
wait(&pid);
return;
}
}
 
I've used a whole bunch of comments to make stuff simpler to understand. Enjoy