c - Completing my own shell code -
i have created shell in c , here code.i have commented code.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> #include <sys/types.h> #include <unistd.h> #include <signal.h> #define path "path=" //just constant string #define delim ":" //just constant string typedef void (*sighandler_t)(int); char* cwdtemp = ""; int false=0; /*structure of functions*/ char* readline(char* line, size_t len); void split(char* input, char *argv[]); int checkpipe( char *input); void run (char* argv[]); void runpipe(char *argv[], char *argv2[]); void setpath(char* inputline); char* getpath(); void changedir(char* dir); char* strcasestr(const char *haystack, const char *needle); void handle_signal(int signo); int main(){ char* input=null; //string save user input char* input2; //string save 2nd command if theres pipe char *argv[50]; //array sabe user input after spliting spaces char *argv2[30]; //array save second command if thrs pipe char argv3[100]; //array use of getcwd function int i; //varibale save index of pipe char* cwd; //variable save current working directory while (1) { //infinite while loop signal(sigint, sig_ign); //capture teh signal , ignore default action signal(sigint, handle_signal); //capture signal , parse handle signal function cwd=getcwd(argv3,100); // current working directory , save cwd cwdtemp=cwd; //save current directory string cwdtemp printf("%s",cwd); //print cwd printf(":~mosh:~$ "); //show prompt input=readline(input, 0); //read user input , save string(char array) if(strcasestr(input, path) == input){ //strcasesrt function check user input , see if has "path="(substring matching) setpath(input); //pass user input setpath function }else{ i=checkpipe(input); //saves index of ' | ' charactor in user input string if(i==0){ //if theres no pipe split(input, argv); //split user input spaces , save them in argv array if(argv[0] == null) { //if user input null continue loop continue; } /* exit shell when "exit" inputed */ if(strcmp(argv[0], "exit") == 0) { exit(0); } if(strcmp(argv[0], "cd") == 0) { //if user entered cd command(its not found in /bin) changedir(argv[1]); //pass name of directory should changed changedir function } run(argv); //pass argv array run function /*checks if command valid*/ if(false==-1 ){ if(strcmp(argv[0], "exit") == 0){} else if(strcmp(argv[0], "cd") == 0){} else{ printf("no such mosh command\n");} false=0; } } else{ //if thers pipe input2=&input[i+1]; //points input2 memory location of charactor after charactor '|' input[i]='\0'; //adds escape charatctor charactor before '|' charactor of input , signal end of input string split(input, argv); //split input spaces , save in argv array split(input2, argv2); //split input2 spaces , save in argv2 array if(fork()){ //creates child process wait(null); //wait till child process terminates } else{ //else execute pipe in parent process runpipe(argv, argv2); } } } } } /*split input space , fill given array*/ void split(char* input, char *argv[]){ char* p; //char array int argc; argc=0; p=strtok(input, " "); //torkanize user input spaces , save p while(p!=null){ //until thrs charactors in p argv[argc]=p; argc++; p=strtok(null, " "); //points torkanizer point stoped before , torkanize p } argv[argc]='\0'; //adds end of string last index of argv } /* read line */ char* readline(char* line, size_t len){ getline(&line, &len, stdin); *(line+strlen(line)-1)='\0'; return line; } /*return array index of | character if any, otherwise 0*/ int checkpipe( char *input){ int = 0; int returnvalue = 0; ( ; < strlen ( input ) ; i++ ){ if ( input[i] == '|' ){ //find index '|' in userinput , retuen index ,if not found return 0 returnvalue = i; break; } } return returnvalue; } /*execute command without | in process*/ void run (char* argv[]){ pid_t pid = fork(); //creats fork , save pid in pid variable if(pid == -1) { perror("fork"); exit(1); } else if(pid == 0) { //if child process created false=execvp(argv[0], argv); //execute command execcvp function //exit(0); } else { wait(null); //wait till child process terminates } } /*execute command | in 2 processes*/ void runpipe(char *argv[], char *argv2[]){ int pfds[2]; //int array used in file descriptors pipe(pfds); //creates pipe int stdin_bak = dup(0); if (fork()==0) { //if creation of fork successfull close(1); //close current stdout dup(pfds[1]); //duplicate stdout write end of pipe close(pfds[0]); //close stdin printf("i'm child\n"); execvp(argv[0], argv); //execute teh command exit(0); } else { //else in parent close(0); //close current stdin dup(pfds[0]); //duplicate stdin read end of pipe close(pfds[1]); //close stdout wait(null); //wait till child process terminates execvp(argv2[0], argv2);//execute command } } /*add given path environmental variable path*/ void setpath(char* inputline){ char* pathin = &inputline[strlen(path)]; //save input path given user(without path=) char* oldpath = getenv("path"); //get current path getenv function , save oldpath int lenpath = strlen(oldpath) + strlen(pathin) + 1 + 1; char* pathout = malloc(sizeof(char) * lenpath); //allocate memoery pathout malloc strcat(pathout, oldpath); //combine oldpath , pathout , save pathout strcat function strcat(pathout, delim); //combine oldpath , delim(constant string) , save pathout strcat(pathout, pathin); //combine oldpath , pathinand save pathout pathout[lenpath - 1] = '\0'; setenv("path", pathout, 1); //set new path setenv function free(pathout); //free memory allocated malloc } /*change directory if possible*/ void changedir(char* dir){ if(dir=='\0'){ //if user entered nothing after cd chdir( "/home/" ); //change home }else{ if(chdir(dir)==-1){ //if chdir function returned error printf("%s:cannot find directory\n",dir); } } } void handle_signal(int signo) { printf("\n"); printf("%s",cwdtemp); printf(":~mosh:~$ "); fflush(stdout); //flush stdout or printf in sameline }
here problem. after compiling code have given command "hdgdg" wrong one.so output "command not found".but when run command "hakka|akjk"(which pipe command),i've got infinite loop output.so how can solve this? thank you.
Comments
Post a Comment