Results 1 to 2 of 2
Hi,
i am trying to build a simple shell program that allow me to run commands in foreground and background modes .
in case of foreground i think its work ...
- 05-30-2007 #1Just Joined!
- Join Date
- May 2007
- Posts
- 1
simple command interpreter
Hi,
i am trying to build a simple shell program that allow me to run commands in foreground and background modes .
in case of foreground i think its work fine but when i run a command i a background mode by adding & at the end of the command the program freezes until i press enter then i get the segmentaion fault error .
kindly take a look at this code an let me know where is the mistake .
thanks
Code:// simple shell // executes one command a time without arguments and flags // not supports pipelines // not supports input/output redirection #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXLINE 2048 enum {FOREGROUND,BACKGROUND}; static volatile sig_atomic_t sigflag; /* set nonzero by sig handler */ static sigset_t newmask, oldmask, zeromask; void executeCommand(char *cmd); void forkProcess(char **,int cnt); void wait_child(void); void collect_child(); void sig_handler(); int main(void) { char buf[MAXLINE]; printf("smash:>"); /* print prompt (printf requires %% to print %) */ while (fgets(buf, MAXLINE, stdin)!=NULL) { buf[strlen(buf) - 1] = 0; /* replace newline with null */ executeCommand(buf); printf("smash:>"); } exit(0); } void executeCommand(char *cmd) { char **argsList=NULL; int argsCnt=0; char *ptr; char *tmpCmd=strdup(cmd); ptr=strtok(tmpCmd," "); while(ptr!=NULL) { argsList=(char**)realloc(argsList,sizeof(char**)*(++argsCnt)+1); argsList[argsCnt-1]=strdup(ptr); ptr=strtok(NULL," "); } argsList[argsCnt]=NULL; if(strcmp(argsList[0],"exit")==0) { if(argsCnt==1) { printf("Bye\n"); exit(0); } else printf("error : exit does'nt accept arguments.\n") ; } else if(strcmp(argsList[0],"cd")==0) { if(argsCnt==2) chdir(argsList[1]); else printf("error : invalid number of arguments for cd.\n"); } else forkProcess(argsList,argsCnt); } void forkProcess(char **argsList,int cnt) { pid_t pid; int runStyle; if(strcmp(argsList[cnt-1],"&")==0) { runStyle=BACKGROUND ; argsList[cnt-1]=NULL; } else runStyle=FOREGROUND; if ( (pid = fork()) < 0) fprintf(stderr,"fork error"); if (pid == 0) { if (execvp(argsList[0], argsList)< 0) fprintf(stderr,"execl error"); } else //parent { if(runStyle==FOREGROUND) { printf("waitttt\n"); wait_child(); } else { if (signal(SIGCHLD, sig_handler) == SIG_ERR) printf("signal(SIGUSR1) error"); } } } void sig_handler() { pid_t pid; int status; printf("sig handler\n"); sigflag = 1; if ((pid=wait(&status)) < 0) { perror("Wait failed\n"); exit(3); } else { if (WIFEXITED(status)) printf ("Pid %d terminated with status %d\n", pid, WEXITSTATUS(status)); else if (WIFSIGNALED(status)) printf ("Pid %d terminated by signal %d\n", pid, WTERMSIG(status)); } } void wait_child(void){ if (signal(SIGCHLD, sig_handler) == SIG_ERR) printf("signal(SIGUSR1) error"); sigemptyset(&zeromask); sigemptyset(&newmask); sigaddset(&newmask, SIGCHLD); if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) printf("SIG_BLOCK error"); while (sigflag == 0) sigsuspend(&zeromask); /* and wait for child */ sigflag = 0; /* * Reset signal mask to original value. */ if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) printf("SIG_SETMASK error"); }
- 05-31-2007 #2
I can't find the exact error, but I advise you to throw in some debug statements to ensure that background processes are being properly detected, and that the '&' is actually being removed. Because I suspect that the probably lies there.
DISTRO=Arch
Registered Linux User #388732


Reply With Quote