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.
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