void executeCommand(_Bool in_background, char *tokens[]) {
	if (isBuiltInCommand(tokens)) {
		executeBuiltInCommand(tokens);
	} else {
		//external command, execute as separate process

		pid_t pID = fork();
		if (pID == 0) {
			//in child

			/* execvp() ONLY returns is an error has occurred. Otherwise child
			 * process is chest-popped by the call to execvp (it is terminated)*/
			if (execvp(tokens[0], tokens) == -1) {
				write(STDOUT_FILENO, strerror(errno), strlen(strerror(errno)));
				write(STDOUT_FILENO, "\n", strlen("\n"));
				exit(0);
			}
		} else if (pID < 0) {
			perror("Failed to fork");
			return;
		}

		//parent
		if (!in_background) {
			if (waitpid(pID, NULL, 0) == -1)
				perror("Error waiting for child to exit");
		} else {
			//give time for child to finish executing before returning to loop
			//to ensure new prompt is printed after results of previous command
			usleep(10000);
		}

		cleanupZombies();
	}
}
Example #2
0
void where(char *arg,  struct pathelement *pathlist )
{
  struct stat sb;
   /* loop through pathlist until finding command and return it.  Return
   NULL when not found. */
  // if(argCount==1){
  //   fprintf(stderr,"%s\n", "Usage: where [name]");
  //   return;
  // }
  if(!pathlist){
    fprintf(stderr, "%s\n", "PATH is empty.");
    return;
  }

  char *cmd = malloc((strlen(arg)+1)*sizeof(char));
  strncpy(cmd,arg,strlen(arg));
  cmd[strlen(arg)] = '\0';

  int found = 0;
  if(isBuiltInCommand(cmd)!=-1){
    printf("%s: %s\n", cmd,"shell built-in Command.");
    found++;
  }
  
  struct pathelement *path_head = pathlist;
  DIR *dirp;
  struct dirent *entry;
  while(path_head){//iterate each path element
    //open one directory stream.
    if(!isDir(path_head->element, &sb)){
      path_head = path_head->next;
      continue;
    }


    dirp = opendir(path_head->element);

    // read each of the entry in DIR
    while((entry = readdir(dirp)) != NULL){
      // if(path_head->)
      if(strcmp(entry->d_name,cmd)==0){
        // found
        found++;
        printf("%s/%s\n", path_head->element, cmd);
        break;
      }
    }

    //move to next.
    closedir(dirp);
    path_head = path_head->next;
  }
  if(!found){
    fprintf(stderr,"%s: %s\n", cmd,"Not found.");
    // printf("%s\n", arg);
  }

  free(cmd);
}
Example #3
0
void which(char *arg, struct pathelement *pathlist )
{
  struct stat sb;
   /* loop through pathlist until finding command and return it.  Return
   NULL when not found. */
  if(pathlist==NULL){
    fprintf(stderr, "%s\n", "PATH is empty.");
    return;
  }

  char *cmd = malloc(ARG_MAX_LENGTH*sizeof(char));
  strncpy(cmd,arg,strlen(arg));
  cmd[strlen(arg)] = '\0';

  if(isBuiltInCommand(cmd)!=-1){
    printf("%s: %s\n", cmd,"shell built-in Command.");
    free(cmd);
    return;
  }

  struct pathelement *path_head = pathlist;
  DIR *dirp;
  struct dirent *entry;
  // int len = strlen(arg);

  while(path_head){//iterate each path element

    // printf("%s\n", "here!!");
    if(!isDir(path_head->element, &sb)){
      path_head = path_head->next;
      continue;
    }

    dirp = opendir(path_head->element);//open one directory stream.

    while((entry = readdir(dirp)) != NULL){
      // read each of the entry in DIR
      if(strcmp(entry->d_name,cmd)==0){
        // found
        printf("%s/%s\n", path_head->element, cmd);
        closedir(dirp);
        free(cmd);
        return;
      }
    }

    closedir(dirp);
    path_head = path_head->next;
  }
  fprintf(stderr,"%s: %s\n", cmd,"Not found.");
  free(cmd);
}
Example #4
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;
}
Example #5
0
int executePipe( int no_of_pipes, char *com, int redirectFlag,char *homedir)
{
    pc *pcmd=malloc(100 * sizeof(pc));
    int fd[2];
    int isFirstPipe=1;
    int count = 0;
    char *commandline=malloc(1024*sizeof(char));
    strcpy(commandline,com);

    char *command=malloc(1024*sizeof(char));
    char **argv=malloc ( 100 * sizeof(char)); //Number of tokens there can be
    char *token=malloc(1024*sizeof(char));
    int i=0,j=0;
    command = strtok ( com,"|");  //first command
    while( command!=NULL)
    {
        pcmd[i].argv=command;
        pcmd[i].redirectFlag=isRedirect(command);
        command = strtok (NULL, "|");
        i++;
    }
    //Tokenise command for execution
    //parseCommand(pcmd[0].argv,argv);

    int in=0;
    for(i=0;i<no_of_pipes;i++)
    {
        pipe(fd);
        spawn_proc(in,fd[1],pcmd[i],pcmd[i].redirectFlag,homedir);
        close(fd[1]);
        in=fd[0];
    }
    if(in!=0)
        dup2(in,0);
    //last command
    infile=0;
    outfile=0;
    int random=isRedirect(pcmd[i].argv);
    int no_of_tokens=parseCommand(pcmd[i].argv,argv,pcmd[i].redirectFlag);
    int std_out=dup(1);
    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 1!\n");
            memset(output, 0, 10);
            outfile=0;
            return;
        }
        dup2(fd1,STDOUT_FILENO);
        close(fd1);
        memset(output, 0, 10);
        outfile=0;
        //redirectFlag=0;
    }
    if(infile==3)
    {
        int fd2;
        fd2=open(inputfile,O_RDWR,00666);
        if(fd2==-1)
        {
            fprintf(stderr, "Can't open file for input! 3\n");
            memset(inputfile, 0, 10);
            infile=0;
            return;
        }
        dup2(fd2,STDIN_FILENO);
        close(fd2);
        memset(inputfile, 0, 10);
        infile=0;
        //redirectFlag=0;
    }

    if(isBuiltInCommand(argv[0])==1)
    {
        job_no++;
        addJob(0,argv[0],0,job_no);
        executeBuiltInCommand(argv[0],argv,no_of_tokens,homedir);
        _exit(1);
        dup2(std_out,1);
        return(0);
    }
    else
        return(execvp(argv[0],argv));
}
Example #6
0
int spawn_proc(int in,int out,pc node,int redirectFlag,char *homedir)
{
    int no_of_tokens=0,std_out;
    pid_t pid;
    char **argv=malloc ( 100 * sizeof(char)); //Number of tokens there can be
    pid=fork();
    if(pid<0)
    {
        fprintf(stderr, "Error in Piping!\n" );
    }
    else if(pid==0) /* Child */
    {
        infile=0;
        outfile=0;
        int random=isRedirect(node.argv);
        no_of_tokens=parseCommand(node.argv,argv,redirectFlag);
        if(in!=0)
        {
            dup2(in,0);
            close(in);
        }
        if(out!=1)
        {
            dup2(out,1);
            close(out);
        }
        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!\n");
                memset(output, 0, 10);
                outfile=0;
                return;
            }
            int std_out=dup(1);
            dup2(fd1,STDOUT_FILENO);
            close(fd1);
            memset(output, 0, 10);
            outfile=0;
            //redirectFlag=0;
        }
        if(infile==3)
        {
            int fd2;
            fd2=open(inputfile,O_RDWR,00666);
            if(fd2==-1)
            {
                fprintf(stderr, "Can't open file for input! 2\n");
                memset(inputfile, 0, 10);
                infile=0;
                return;
            }
            dup2(fd2,STDIN_FILENO);
            close(fd2);
            memset(inputfile, 0, 10);
            infile=0;
            //redirectFlag=0;
        }
        if(isBuiltInCommand(argv[0])==1)
        {
            job_no++;
            addJob(0,argv[0],0,job_no);
            executeBuiltInCommand(argv[0],argv,no_of_tokens,homedir);
            dup2(std_out,1);
            _exit(1);
        }
        else
            return (execvp(argv[0],argv));
    }
    return pid;
}