Skip to content

Instantly share code, notes, and snippets.

@rehrumesh
Created December 20, 2014 07:55
Show Gist options
  • Save rehrumesh/66d00155799bbea558f2 to your computer and use it in GitHub Desktop.
Save rehrumesh/66d00155799bbea558f2 to your computer and use it in GitHub Desktop.
MyOwnShell
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
char *PATH="PATH=/bin:/usr/bin"; //System PATH variable.
void process(char *msg); //function to execute a command without a pipe
void processWithPipe(char *msg); //function to execute commands with a pipe
int numOfPipes(char msg[]); //a simple funtion to count the number of pipes
void startup(); //a simple function to display start up image
void info(); //a simple function to display a brief description on MOSH
int main(){
startup();
int p = putenv(PATH);
if(p !=0){
printf("Error setting the path\n");
exit(0);
}
int loop=1;
while(loop == 1){ //will keep running the shell
char cmd[100]; //char array used to store store the command.
char *workingdir =getcwd(NULL,100);
printf("%s ~ MOSH> ",workingdir);
free(workingdir);
scanf ("%[^\n]%*c", cmd);
if(cmd[strlen(cmd) -1] == '\n'){
cmd[strlen(cmd) -1] = '\0';
}
if(cmd[0] == 'c' && cmd[1] == 'd' && cmd[2]==' '){
if (chdir(&cmd[3]) == 0) {
} else {
printf("Invalid directory \n");
}
}else if(cmd[0] == 'i' && cmd[1] == 'n' && cmd[2] == 'f' && cmd[3] == 'o' ){
info();
}else if(cmd[0] == 'e' && cmd[1] == 'x' && cmd[2] == 'i' && cmd[3] == 't'){
printf("Thank you for using MOSH.\n\n");
exit(0);
}else{
int num = numOfPipes(cmd);
if(num == 0){ //checks if not more than 1 pipe is used
process(cmd);
}else if(num >1){
printf("Version 1.0 supports only 1 pipe.\n");
}else{
processWithPipe(cmd);
}
}
}
return 0;
}
int numOfPipes(char msg[])
{
int i,coun = 0;
for( i = 0; i < strlen(msg)+1;i++){
if(msg[i] == '|'){
coun++;
}
}
return coun;
}
void process(char *msg)
{
char *buffer[25]; //
char *tok; //
char *msgCopy; //
msgCopy =msg; // preperation to torkaniz the command using spaces
tok = strtok(msgCopy," "); //
buffer[0]= tok; //
int i=1;
while((tok = strtok (NULL, " ")) != NULL ){
buffer[i]= tok;
i++;
}
buffer[i]=NULL;
pid_t pid = fork();
if(pid ==0){ //child process
if((execvp(buffer[0],buffer)) == 0){ //checks if the entered command is valid and excutes
}else{
printf("command not found :%s \n",buffer[0]);
exit(0);
}
}else{ //parent process
wait();
}
}
void processWithPipe(char *msg)
{
char *commands[2]; //
char *cmd1args[25]; //
char *cmd2args[25]; //up to first 2 loops, will break the two commands.
char *temp; //
char *msgCopy; //
msgCopy =msg;
temp = strtok(msgCopy,"|");
commands[0] = temp;
temp = strtok(NULL, "|");
commands[1]=temp;
msgCopy = commands[0];
temp = strtok(msgCopy, " ");
cmd1args[0]= temp;
int i=1;
while((temp = strtok (NULL, " ")) != NULL ){
cmd1args[i]= temp;
i++;
}
cmd1args[i]=NULL;
msgCopy = commands[1];
temp = strtok(msgCopy, " ");
cmd2args[0]= temp;
i=1;
while((temp = strtok (NULL, " ")) != NULL ){
cmd2args[i]= temp;
i++;
}
cmd2args[i]=NULL;
char temp1[100];
strcpy(temp1,"which "); //
strcat(temp1,cmd1args[0]); //
strcat(temp1," > /dev/null 2>&1"); //
int ret = system(temp1); //
char temp2[100]; // Check wethr both commands are available.
strcpy(temp2,"which "); // if not, stop the execution and return back to caller funcion
strcat(temp2,cmd2args[0]); //
strcat(temp2," > /dev/null 2>&1"); //
int ret2 = system(temp2);
if(ret != 0){
printf("command not found : %s \n",cmd1args[0]);
return;
}else if(ret2 != 0){
printf("command not found : %s \n",cmd2args[0]);
return;
}
pid_t pid;
if((pid=fork())){ // create a process tree for pipe
wait(pid);
}else{
int fd[2]; //file directory*(explain more?)
pid_t process;
pipe(fd);
if((process = fork()) == -1){
printf("Fork error \n");
}else if(process == 0){ //child process
dup2(fd[1],1); //duplicates standard output so that the output is directed in to the pipe
close(fd[0]); //closes standard input
if((execvp(cmd1args[0],cmd1args)==0)){ //checks if the entered command is valid and excutes
}else{
printf("Command not found: %s \n",cmd1args[0]);
}
}else{ //parent process
dup2(fd[0],0); //duplicates standard input so that the input is directed out of the pipe
close(fd[1]); //closes standard output
wait();
if((execvp(cmd2args[0],cmd2args))==0){ //checks if the entered command is valid and excutes
}else{
printf("Command not found: %s \n",cmd2args[0]);
}
}
}
}
void startup(){
printf("*************************************************\n");
printf("*************************************************\n");
printf("** **\n");
printf("** **\n");
printf("** --- --- ------- ----- | | **\n");
printf("** | \\ / | | | | | | **\n");
printf("** | \\ / | | | | | | **\n");
printf("** | | | | ---- |-----| **\n");
printf("** | | | | | | | **\n");
printf("** | | | | | | | **\n");
printf("** | | ------- ----- | | **\n");
printf("** **\n");
printf("** V 1.0 **\n");
printf("** **\n");
printf("** **\n");
printf("*************************************************\n");
printf("*************************************************\n");
printf("\nUse command 'info' to get information about the shell.\nUse command 'exit' to exit from the shell.\n\n");
}
void info()
{
printf("\n\n\n\n");
printf("MOSH V1.0 was developed by CodeMasters\n");
printf("Features :\n");
printf(" * MOSH is a basic shell which can run basic commands \n");
printf(" * It can handle a single pipe.\n");
printf(" * If a particular command not found in the PATH, mosh will give error message.");
}
/*
*
* References :
*
* http://web.mst.edu/~ercal/284/PipeExamples/Examples.html
* http://www.tldp.org/LDP/lpg/node11.html
* http://www.cs.ecu.edu/karl/4630/sum01/example1.html
* http://stackoverflow.com/questions/7851983/find-out-if-a-certain-application-command-is-available-on-linux
*
*
*
*
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment