Exemplo n.º 1
0
void execute(char *line) {
	char *cmd;			/* command */
	int start, end;		/* expression delimiters */

	if(setExpressionDelimiters(line, "[^| ]([^|]*[^| ])?", &start, &end)) {
		cmd = getExpression(line, start, end, 0);
		
		ignoreSignals();
		
		if(hasPipe(line)) {
			executePipe(line + end, cmd);
		} else if(!tryInternalCommand(cmd, JOBS_CONTROL)) {
			executeExternalCommand(cmd);
		}
		
		free(cmd);
	}
}
Exemplo n.º 2
0
int main(int argc, char *argv[])
{
    initShell();
    //signal(SIGCHLD, SIG_IGN);
    //Declarations
    int bytes_read,no_of_tokens,no_of_commands=0,redirectFlag=0;
    char uname[80],homedir[256],input[1024],hostname[80],tempstr[256],cwd[256];
    char *cmdline, *sentence, *line, *token,**savedTokens, **command, *cmd, *mcptr, *com;
    size_t length,homedirlen;
    pid_t childPid;
    //Change Shell home dir to ~
    getcwd(homedir , sizeof(homedir) );
    getusername(uname);
    homedirlen=strlen(homedir);
    strcpy(cwd,homedir);

/*    int ptr=0;
    for(ptr=0;ptr<=1000;ptr++)
    {
        jobs[ptr]=NULL;
    }*/
    int exit_flag=0;
    while (1)
    {
        sigset_t mask, prevmask;
        //Initialize mask with just the SIGCHLD signal
        sigemptyset(&mask);
        sigaddset(&mask, SIGCHLD);
        sigprocmask(SIG_BLOCK, &mask, &prevmask); /*block SIGCHLD, get previous mask*/

        no_of_tokens=0;
        command=malloc ( 200 * sizeof(char)); //Number of commands there can be will be stored in 2D Array
        cmdline = (char *) malloc (1025 * sizeof(char));
        line = (char *) malloc (1025 * sizeof(char));
        cmd = (char *) malloc (1025 * sizeof(char));
        savedTokens=malloc ( 100 * sizeof(char)); //Number of tokens there can be
        strcpy(line,"\n");
        gethostname(hostname, sizeof(hostname));
        getcwd(cwd , sizeof(cwd) );
        //printf("PRINT THIS : %s\n",cwd+homedirlen );
        //printf("CWD: %d HOMEDIR: %d\n",strlen(cwd),strlen(homedir) );
        if( strncmp( cwd, homedir, homedirlen-1) == 0) // && strncmp( cwd, homedir, homedirlen-1)!=0) //If the current working directory is not ~
        {
            strcpy(tempstr,"~");
            //printf("HOME DIR IS: %s\n",tempstr );
            strcat(tempstr,cwd+homedirlen);
            strcpy(cwd, tempstr);
        }
        int jumper=setjmp(env);
        printf("<%s@%s:%s>",uname,hostname,cwd ); //PROMPT
        getline (&line, &length+1, stdin);
        //PARSING:
        //Stage 1: Handling multiple commands:

        int k=0;
            token = strtok (line, ";");
            command[k]=token;
            while ( token!=NULL )
            {
                command[k]=token;
                token = strtok (NULL,";");
                k++;
            }
            no_of_commands=k-1;
            if(no_of_commands==-1)
            {
                printf("Exiting main shell!\n");
                printf("\n");
                return 0;
            }
            else if(command[no_of_commands]!=NULL)
            {
                int len=strlen(command[no_of_commands]);
                command[no_of_commands][len-1]=0; //Last token gets an extra \n .. therefore removed here.
            }

        //STAGE 2:
        for(k=0;k<=no_of_commands;k++)
        {
/*            sigset_t mask, prevmask;
            //Initialize mask with just the SIGCHLD signal
            sigemptyset(&mask);
            sigaddset(&mask, SIGCHLD);
            sigprocmask(SIG_BLOCK, &mask, &prevmask); /*block SIGCHLD, get previous mask*/
            cmdline = command[k];
            com = (char *) malloc (1025 * sizeof(char));
            if(command[k]!=NULL)
                strcpy(com,command[k]); //com stores the whole command to be executed
            else
                com=NULL;

            //Stage 3: Piping
            int no_of_pipes=0;
            if(com!=NULL)
            {
                redirectFlag=isRedirect(com);
                no_of_pipes=isPipeJob(com);
            }
            if(no_of_pipes!=0)
            {
                int status;
                pid_t procid=fork();
                if(procid==0)
                {
                    executePipe(no_of_pipes,com,redirectFlag,homedir);
                }
                else
                {
                    sigprocmask(SIG_SETMASK, &prevmask, NULL); //Unblocking
                    wait(&status);
                }
            }
            else
            {
                int i=0;
                token = strtok(cmdline,">");
                token = strtok(cmdline,"<");
                token = strtok(cmdline," \t\n");
                if(token==NULL)
                {
                    no_of_commands=-1;
                }
                while(token != NULL)
                {
                    savedTokens[i]=token;
                    i++;
                    token = strtok (NULL, " \t\n");
                }
                if(i!=0)
                {
                    no_of_tokens=i-1;
                    cmd=savedTokens[0];
                }
                else
                {
                    no_of_tokens=0;
                    cmd=NULL;
                }

                int len=0;

                if(savedTokens[no_of_tokens]!=NULL)
                {
                    len=strlen(savedTokens[no_of_tokens]);
                }
                //savedTokens[no_of_tokens][len-1]=0; //Last token gets an extra \n .. therefore removed here.
                //if ((cmd!=NULL) && ((strcmp("exit",cmd)==0) ||  (strcmp("Exit",cmd)==0) || (strcmp("exit ",cmd)==0) || (strcmp("Exit ",cmd)==0)))
                if ((cmd!=NULL) && ((strcmp("quit",cmd)==0) || (strcmp("quit ",cmd)==0) || (strcmp(" quit",cmd)==0)))
                {
                    //exit(1);
                    exit_flag=1;
                    break;
                }

              /*int j=0;
                while(j<=no_of_tokens)
                {
                    printf("TOKEN %d: %s\n",j,savedTokens[j]);
                    j++;
                } */
        		//record command in history list (GNU readline history ?)
                int std_out;
                if(no_of_commands!=-1)
                {
            		if ( (cmd!=NULL) && isBuiltInCommand(cmd)==1 )
                    {
                            if(redirectFlag!=0)
                            {
                                executeRedirect(cmd,com,redirectFlag);
                            }
                            if(outfile!=0)
                            {
                                int fd1;
                                if(outfile==1)
                                {
                                    fd1=open(output,O_CREAT|O_RDWR|O_TRUNC,00666);
                                    lseek(fd1, 0, SEEK_SET);
                                }
                                else if(outfile==2)
                                {
                                    fd1=open(output,O_APPEND|O_CREAT|O_RDWR,00666);
                                }
                                if(fd1==-1)
                                {
                                    fprintf(stderr, "Can't open file %s for output!\n",output);
                                    memset(output, 0, 10);
                                    outfile=0;
                                    continue;
                                }
                                std_out=dup(1);
                                dup2(fd1,STDOUT_FILENO);
                                close(fd1);
                                memset(output, 0, 10);
                                outfile=0;
                            }
                            if(infile==3)
                            {
                                int fd2;
                                fd2=open(inputfile,O_RDWR,00666);
                                if(fd2==-1)
                                {
                                    fprintf(stderr, "Can't open file for input! 4\n");
                                    memset(inputfile, 0, 10);
                                    infile=0;
                                    continue;
                                }
                                dup2(fd2,STDIN_FILENO);
                                close(fd2);
                                memset(inputfile, 0, 10);
                                infile=0;
                            }
                            job_no++;
                            addJob(0,cmd,0,job_no);
                            executeBuiltInCommand(cmd,savedTokens,no_of_tokens,homedir);
                            dup2(std_out,1);
                    }
                    else
                    {
                        if((com!=NULL) && isBackgroundJob(com)==1)
                        {
                            savedTokens[no_of_tokens]=NULL;
                        }
                        int status;
            		    childPid = fork();
                        switch (childPid)
                        {
                            case 0: //Child Process
                                //setpgid(0,0);  //make the current process the group leader
                                //tcsetpgrp(0,getpid());
                                if(redirectFlag!=0)
                                {
                                    executeRedirect(cmd,com,redirectFlag);
                                }
                                if(outfile!=0)
                                {
                                    int fd1;
                                    if(outfile==1)
                                    {
                                        fd1=open(output,O_CREAT|O_RDWR|O_TRUNC,00666);
                                        lseek(fd1, 0, SEEK_SET);
                                    }
                                    else if(outfile==2)
                                    {
                                        fd1=open(output,O_APPEND|O_CREAT|O_RDWR,00666);
                                    }
                                    if(fd1==-1)
                                    {
                                        fprintf(stderr, "Can't open file for output 6!\n");
                                        memset(output, 0, 10);
                                        outfile=0;
                                        continue;
                                    }
                                    dup2(fd1,STDOUT_FILENO);
                                    close(fd1);
                                    memset(output, 0, 10);
                                    outfile=0;
                                }
                                if(infile==3)
                                {
                                    int fd2;
                                    printf("%s\n",inputfile);
                                    fd2=open(inputfile,O_RDWR,00666);
                                    if(fd2==-1)
                                    {
                                        fprintf(stderr, "Can't open file for input! 5\n");
                                        memset(inputfile, 0, 10);
                                        infile=0;
                                        continue;
                                    }
                                    dup2(fd2,STDIN_FILENO);
                                    close(fd2);
                                    memset(inputfile, 0, 10);
                                    infile=0;
                                }
                                executeCommand(cmd,savedTokens,no_of_tokens); //calls execvp
                                /* if exec returns there was an error. */
                                perror(savedTokens[0]);
                                exit(-1);

                            case -1:
                                perror("Fork");
                                return -1;

                            default: //In Parent
                                sigprocmask(SIG_SETMASK, &prevmask, NULL); //Unblocking
                                //handler(childPid,cmd,job_no,jobs); //Check if any of the childs exited
                                if (isBackgroundJob(com)==1)
                                {
                                    setpgid(childPid,childPid); //added the background process to its own group
                                    //tcsetpgrp(0,childPid);
                                    savedTokens[no_of_tokens]=NULL;
                                //    add pid to some list to track jobs
                                    job_no++;
                                    printf("[%d][proc %d started]\n",job_no, childPid);
                                    addJob(childPid,cmd,1,job_no);
    //                                sigprocmask(SIG_SETMASK, &prevmask, NULL); //Unblocking
                                }
                                else
                                {
                                    //Add foreground jobs to list:
                                    job_no++;
                                    //printf("Parent: Here total jobs are %d \n",job_no );
                                    addJob(childPid,cmd,0,job_no);
                                    curpid=childPid;
                                //    printf("jobs[%d]->cmd: %s\n",job_no,jobs[job_no]->cmd);
                                    sigprocmask(SIG_SETMASK, &prevmask, NULL); //Unblocking
                                    pid_t wpid;
                                    do
                                    {
                                        wpid = waitpid(childPid, &status, WUNTRACED); //WUNTRACED->status of child processes will be reported here!
                                    } while (!WIFEXITED(status) && !WIFSIGNALED(status)); //WIFEXITED reports normal termination and //WIFSIGNALED not 0  status if child process stopped but wasnt caught!
                                    removeJob(wpid);
                                    curpid=getpid();
                                    //printf("I am removing the fg job with pid %d\n",wpid );
                                    //waitpid (childPid);
                                    //printf("HERE! 2\n" );
                                }
                        }
                    }
                }
            }
        }//end of k loop
        if(exit_flag==1)
            break;

        //free(line); //
    } //End of while loop
    return 0;
}