Пример #1
0
/*
 * Prepares i/o redirection for a single
 * i/o redirect.
 */
void prepare_one_io(char* command, int fd[])
{
    int n;
    int status = -1;
    char* tokens[CMD_MAX];
    char copy[CMD_MAX];     //A copy of the command
    char* io[CMD_MAX];

    //Make a copy of the command
    //It will be needed if the first condition fails.
    strcpy(copy,command);

    //Check to see if there is a '<'
    n = make_tokenlist(command,tokens, "<");
    if(n < 1)
    {
        perror("Cannot tokenize");
        exit(EXIT_FAILURE);
    }
    //If there is more than one token, then a '<'
    //is present. Parse the token.
    if(n>1)
    {
        status = 0;
        prepare_io(tokens[1], io);
    }
    //In this case, there must be a '>' present
    else
    {
        //Check to make sure this is true
        n = make_tokenlist(copy,tokens, ">");
        if(n < 1)
        {
            perror("Cannot tokenize");
            exit(EXIT_FAILURE);
        }
        if(n>1)
        {
            status = 1;
            prepare_io(tokens[1], io);
        }
    }
    //If there is a '<'
    //Redirect the input and execute command
    if (status == 0)
    {
        redir_in(io[0],fd);
        exec_pipes(tokens[0]);

    }
    //If there is a '>'
    //Redirect the output and execute command
    else if (status == 1)
    {
        redir_out(io[0],fd);
        exec_pipes(tokens[0]);
    }
}
Пример #2
0
static BOOL	and_or(t_exec *e, t_info *info, BOOL in)
{
  FD	p[3];
  FD	w[3];

  if (!e)
    return (TRUE);
  to_fd(w, in);
  p[W_IN] = W_IN;
  p[W_OUT] = W_OUT;
  p[W_ERR] = W_ERR;
  if (exec_pipes(e->pipes, info, 0, (info->wr = p)) == FALSE)
    {
      while (waitpid(-1, NULL, WNOHANG) >= 0);
      return (FALSE);
    }
  fd_to(w, in);
  if (e->type == OR && info->st == EXIT_FAILURE)
    return (and_or(e->next, info, in));
  else if (e->type == OR && info->st == EXIT_SUCCESS)
    return (and_or(two(e), info, in));
  if (e->type == AND && info->st == EXIT_SUCCESS)
    return (and_or(e->next, info, in));
  else if (e->type == AND && info->st == EXIT_FAILURE)
    return (and_or(two(e), info, in));
  return (TRUE);
}
Пример #3
0
BOOL	exec_pipes(t_pipes *p, t_info *info, FLAG son, FD pi[3])
{
  STATUS	status_quo;
  pid_t		pid;
  FD		w[2];

  if (!(pid = -(!((unsigned long)(p->next != NULL)))))
    {
      if (pipe(w) == -1)
	return (FALSE);
      if ((pid = xfork()) < 0)
	return (FALSE);
    }
  if (!pid)
    {
      init_pipe(w, pi, W_IN);
      exec_pipes(p->next, info, SON, pi);
      return (FALSE);
    }
  if (p->next)
    init_pipe(w, pi, W_OUT);
  if (exec_cmd(p->cmd, info, info->son = (son | (2 * (pid > 0))), pi) == FALSE)
    return (FALSE);
  my_wait(pid, &status_quo);
  if (pid < 0)
    return (TRUE);
  return (get_status(info, status_quo));
}
Пример #4
0
int		exec_fath(char *line, t_sh *t)
{
	if (t->save_c)
		wait(0);
	t->pv = ++t->pv2;
	while (line[t->pv2]
		&& !search_ope(&line[t->pv2], t->ope, 1))
		t->pv2++;
	close(t->pipe_fd[1]);
	dup2(t->pipe_fd[0], 0);
	close(t->pipe_fd[1]);
	t->args = ft_strsplitsh(ft_strsub(line, t->pv, t->pv2 - t->pv));
	if (line[t->pv2] == '|' || line[t->pv2] == '>')
	{
		if (line[t->pv2] != '|')
			return (ft_red(line, t));
		else if (line[t->pv2 + 1] && !search_ope(&line[t->pv2 + 1], t->ope, 1))
			return (exec_pipes(line, t));
		else if (line[t->pv2 + 1] && line[t->pv2 + 1] != '|')
			return (parse_error(line, t, t->pv2 + 1));
		t->flag = line[t->pv2];
	}
	exec_cmd(t);
	return (t->pv2);
}
Пример #5
0
/**
 * Quash entry point
 *
 * @param argc argument count from the command line
 * @param argv argument vector from the command line
 * @return program exit status
 */
int main(int argc, char** argv) { 
    command_t cmd; //< Command holder argument
      
    start();
    struct sigaction NULL_sa;
    struct sigaction sa;
    sigset_t mask_set;
    sigfillset(&mask_set);
    sigdelset(&mask_set,SIGINT);
    sigdelset(&mask_set,SIGTSTP);
    sa.sa_handler = catchChild;
    sigprocmask(SIG_SETMASK, &mask_set, NULL);
    //TODO: this is involved withe the error 10 problem. Removing it remedies the issue for now but breaks other things.
    sigaction(SIGCHLD, &sa,NULL);//child termination calls catchChild;

    setenv( "WKDIR", getenv("HOME"), 1 );

    puts("hOi! Welcome to Quash!");

    // Main execution loop
    while (is_running()) 
    {
        // NOTE: I would not recommend keeping anything inside the body of
        // this while loop. It is just an example.

        // The commands should be parsed, then executed.
        if( !get_command(&cmd, stdin) );
        else if (!strcmp(cmd.cmdstr, "q")||!strcmp(cmd.cmdstr, "exit")||!strcmp(cmd.cmdstr, "quit"))
            terminate(); // Exit Quash
        else if(!strcmp(cmd.execArgs[0], "set"))
            set(cmd);//set environment variables
        else if(!strcmp(cmd.execArgs[0], "echo"))
            echo(cmd);//echos environment variables
        else if(!strcmp(cmd.execArgs[0], "pwd"))
            pwd(cmd);//prints current working directory
        else if(!strcmp(cmd.execArgs[0], "cd"))
            cd(cmd);//changes the working directory
        else if(!strcmp(cmd.execArgs[0], "jobs"))
            jobs();//prints out a list of currently running jobs
        else if(!strcmp(cmd.execArgs[0], "kill"))
            killChild(cmd);//kills specified job
        else if (!strcmp(cmd.execArgs[0], "wait"))
            sleep(atoi(cmd.execArgs[1]));
        else if (strchr(cmd.cmdstr,'|')!= NULL)
            exec_pipes(cmd);//executes piped commands
        else 
            exec_cmd(cmd);//executes normal commands
    }

    return EXIT_SUCCESS;
}
Пример #6
0
/*
 * Handles i/o redirection.
 */
void handle_io(char* input_line, char* tokens[], int numTokens)
{
    char* input[CMD_MAX];   //Stores input tokens
    char* output[CMD_MAX];  //Stores output tokens
    int fd[2];              //Stores file descriptor
    pid_t pid;              //Process ID

    //Fork a process.
    pid = fork();
    if (pid < 0)
    {
        perror("Fork error");
        exit(EXIT_FAILURE);
    }
    //If child
    if (pid == 0)
    {
        //If there is both input and output redirection
        if(numTokens == 3)
        {
            //Prepare i/o tokens (make sure they
            //are correctly formated)
            prepare_io(tokens[1], input);
            prepare_io(tokens[2], output);
            //Redirect i/o
            redir_both(input[0],output[0], fd);
            //Execute
            exec_pipes(tokens[0]);
        }
        else
        {
            //Prepare a single i/o redirection
            //and execute.
            prepare_one_io(input_line, fd);
        }
    }
    else
    {
        //Wait for child process to finish.
        wait(0);
    }
}
Пример #7
0
/*
 * Handles pipe execution
 */
void handle_pipes(char *tokens[], int numTokens)
{
    int i = 0;
    int k = 0;
    int numPipes = numTokens - 1;
    pid_t pid;
    int status;
    int pipefds[2*numPipes];    //Stores file descriptors for pipes


    //Loop through and create each pipe.
    for(i=0;i < numPipes; i++)
    {
        if(pipe(pipefds + i*2) < 0)
        {
            perror("Fatal error");
            exit(EXIT_FAILURE);
        }
    }

    int j=0; //Used to access appropriate file descriptors in pipefds.

    //Loop through number of tokens (number of commands)
    for(i=0; i<numTokens;i++)
    {
        //Fork a process.
        pid = fork();
        if (pid < 0)
        {
            perror("Fork error");
            exit(EXIT_FAILURE);
        }
        //If process is the child
        else if (pid == 0)
        {
            //If not the last command
            if (i < numTokens-1)
            {
                if(dup2(pipefds[j+1], 1) < 0)
                {
                    perror("dup error");
                    exit(EXIT_FAILURE);
                }
            }

            //If not the first command
            if (j!=0)
            {
                if(dup2(pipefds[j-2], 0) < 0)
                {
                    perror("dup error");
                    exit(EXIT_FAILURE);
                }
            }
            //Loop through and close the pipes.
            for(k=0; k < 2*numPipes; k++)
            {
                close(pipefds[k]);
            }
            //Execute command
            exec_pipes(tokens[i]);
        }
        //Increment j by two in order to access file descriptor
        //for next pipe.
        j+=2;
    }

    //Close all pipes.
    for(i=0;i < 2*numPipes; i++)
    {
        close(pipefds[i]);
    }
    //Wait for child to finish.
    for(i=0;i < numPipes + 1; i++)
    {
        wait(&status);
    }
}