Exemple #1
0
/*===========================================================================*
 *				select_request_pipe			     *
 *===========================================================================*/
static int select_request_pipe(struct filp *f, int *ops, int block)
{
  int orig_ops, r = 0, err;

  orig_ops = *ops;

  if ((*ops & (SEL_RD|SEL_ERR))) {
	/* Check if we can read 1 byte */
	err = pipe_check(f, READING, f->filp_flags & ~O_NONBLOCK, 1,
			 1 /* Check only */);

	if (err != SUSPEND)
		r |= SEL_RD;
	if (err < 0 && err != SUSPEND)
		r |= SEL_ERR;
	if (err == SUSPEND && !(f->filp_mode & R_BIT)) {
		/* A "meaningless" read select, therefore ready
		 * for reading and no error set. */
		r |= SEL_RD;
		r &= ~SEL_ERR;
	}
  }

  if ((*ops & (SEL_WR|SEL_ERR))) {
	/* Check if we can write 1 byte */
	err = pipe_check(f, WRITING, f->filp_flags & ~O_NONBLOCK, 1,
			 1 /* Check only */);

	if (err != SUSPEND)
		r |= SEL_WR;
	if (err < 0 && err != SUSPEND)
		r |= SEL_ERR;
	if (err == SUSPEND && !(f->filp_mode & W_BIT)) {
		/* A "meaningless" write select, therefore ready
                   for writing and no error set. */
		r |= SEL_WR;
		r &= ~SEL_ERR;
	}
  }

  /* Some options we collected might not be requested. */
  *ops = r & orig_ops;

  if (!*ops && block)
	f->filp_pipe_select_ops |= orig_ops;

  return(OK);
}
Exemple #2
0
int	lex(char *str, t_token **token)
{
  int	i;

  i = 0;
  while (str[i])
    {
      i = comma_check(str, i, token);
      i = pipe_check(str, i, token);
      i = red_r(str, i, token);
      i = red_l(str, i, token);
      i = check_and(str, i, token);
      i = word_check(str, i, token);
      i = check_unk(str, i, token);
    }
  return (0);
}
/*
* process_cmd
*
* 명령 라인을 인자 (argument) 배열로 변환한다.
* 내장 명령 처리 함수를 수행한다.
* 내장 명령이 아니면 자식 프로세스를 생성하여 지정된 프로그램을 실행한다.
* 파이프(|)를 사용하는 경우에는 두 개의 자식 프로세스를 생성한다.
*/
void process_cmd(char *cmdline)
{
	int argc;
	char* argv[MAXARGS];
	char* temp[MAXARGS];	

	//파이프를 처리하기 위한 변수들
	int pipe_checker = 0;
	int pipefd[2];
	
	//리다이렉션을 처리하기 위한 변수들.
	int fd;
	int saved_stdout;
	int redi_checker;//redirection checker	

	// 명령 라인을 해석하여 인자 (argument) 배열로 변환한다.
	argc = parse_line(cmdline, argv);

	// 인자 배열에 파이프가 존재하는지 검사한다.
	pipe_checker = pipe_check(argc, argv);
	
	if(pipe_checker > 0)
	{	
		pid_t pipe_pid;

		//명령어 분리
		int temp_i = 0;
		int pipe_i;
		for(pipe_i = pipe_checker+1 ; pipe_i < argc; ++pipe_i)
		{
			temp[temp_i] = argv[pipe_i];
			argv[pipe_i] = NULL;
			++temp_i;
		}
		argv[pipe_checker] = NULL;
		temp[temp_i] = NULL;
		
		//파이프 생성
		if( pipe(pipefd) == -1)
		{
			fprintf(stderr, "pipe creat error\n");
			return;
		}
		
		pipe_pid = fork();
		if(pipe_pid < 0)
		{
			fprintf(stderr, "fork failed\n");
		}	
	
		if(pipe_pid == 0)
		{	
			close(pipefd[0]);
			
			//파이프 출력을 stdout으로 복제
			if( dup2(pipefd[1], STDOUT_FILENO) < 0)
			{
				fprintf(stderr, "pipefd dup error\n");
				exit(1);
			}
			
			//명령 실행
			if(execvp(argv[0], argv) < 0)
			{
				fprintf(stdout, "pipe exec err\n");
				exit(1);
			}
		}	
		
		pipe_pid = fork();
		if(pipe_pid < 0)
		{
			fprintf(stderr, "fork failed\n");
		}

		if(pipe_pid == 0)
		{
			close(pipefd[1]);

			//파이프 입력을 stdin으로 복제
			if (dup2(pipefd[0], STDIN_FILENO) < 0)
			{
				fprintf(stderr, "pipefd2 dup error\n");
				exit(1);
			}

			//명령 실행
			if(execvp(temp[0], temp) < 0)
			{
				fprintf(stdout, "pipe exec2 err\n");
				exit(1);
			}
		}
		
		//부모 프로세스는 파이프의 read / write 모두 닫는다
		close(pipefd[0]);
		close(pipefd[1]);
	
		//부모 프로세스는 두개의 자식 프로세스가 죵료할때까지 기다린다.
		while(wait(NULL) >= 0);
		
		return;
	}

	
	// 인자 배열에 리다이렉션이 존재하는지 검사한다.
	redi_checker = redirection_check(argc, argv);

	// 리다이렉션이 존재 할 경우 파일디스크립터 복제
	// 문자열 처리
	// ">"과 다음 인자를 NULL로 변경
	if(redi_checker > 0)
	{
		//파일디스크립터 복제
		fd = creat(argv[redi_checker+1], DEFAULT_FILE_MODE);
		if(fd < 0)
		{
			fprintf(stderr, "file descriptor creat error\n");
			return;
		}
	
		saved_stdout = dup(1); //stdout

		if( dup2(fd, 1) < 0 )
		{
			fprintf(stderr, "dup error\n");
			return;
		}
		
		//문자열 처리
		argc = redi_checker;
		argv[redi_checker] = NULL;
		argv[redi_checker+1] = NULL;
	}
	else if(redi_checker < 0)
	{	
		//redi_checker error	
		fprintf(stderr, "redirection error\n");
		return;
	}

	/* 내장 명령 처리 함수를 수행한다. */
	int result = builtin_cmd(argc, argv);
	
	if( result == 0 )
	{
		if( redi_checker > 0 )
		{
			//리다이렉션을 수행한 경우 stdout복구
			close(fd);
			dup2(saved_stdout, 1);
		}
	
		//내장명령 처리를 완료하고 리턴
		return;
	}
	else if(result < 0)
	{
		fprintf(stderr, "command try error\n");
		return;
	}
	else
	{
		//내장명령어가 아닌 경우
		//리다이렉션을 사용하였지만 
		//">"가 없었을 경우는 파일디스크립터를 복제 안하였으므로
		//걸러주자.
		if(redi_checker != 0)
		{
			fprintf(stderr, "redirection error\n");
			close(fd);
			dup2(saved_stdout, 1);
			return;
		}
	}
	
	//내장 명령어의 처리가 끝남
	/////////////////////////////////////////////////////////////
	//이 밑으로는 내장 명령어 목록에 존재하지 않는 명령에 대하여
	//외부 프로그램을 실행한다.
	//	

	/*
	* 자식 프로세스를 생성하여 프로그램을 실행한다.
	*/
	fprintf(stderr, "try external program\n");
	
	//백그라운드 명령이 있는지 검사한다.
	int bgchecker = 0;

	if( !strcmp( argv[argc -1], "&") )
	{
		bgchecker = 1;
		argv[argc - 1] = NULL;
		argc--;
	} 	

	pid_t pid, pid1;
	
	// 프로세스 생성
	pid = fork();
	
	if(pid == 0)	//자식 프로세스
	{
		pid1 = getpid();

		/*
		execv 함수를 사용할때 사용된 코드
		//외부 명령어를 실행하기 위하여 argv를 셋팅해준다.
		//char temp[128] = "/bin/";
		
		//strcat(temp, argv[0]);

		//문자열 결합 확인을 위한 출력
		//puts(temp);1
		
		//변경된 문자열을 argv의 첫 인자로 교체해준다.
		//argv[0] = temp;		
		*/

		//외장명령어 실행		

		if (execvp(argv[0], argv) < 0)
		{
			//실행 오류시 자식 에러 메세지를 출력하고
			//자식 프로세스를 종료시킨다.
			fprintf(stdout, "command does not exist\n");
			exit(0);
			return;
		}
		else
		{
			fprintf(stderr, "PID %d is terminated\n", pid1);
		}
		
		return;
	}
	else if(pid > 0)	//부모 프로세스
	{
		//자식 프로세스를 백그라운드로 실행하지 않을 경우
		//자식 프로세스의  종료를 기다린다.
		if(bgchecker == 0)
		{
			wait(NULL);
		}
		
		//wait(NULL);
	}
	else
	{
		fprintf(stderr, "fork error\n");
		return;
	}

	// 자식 프로세스에서 프로그램 실행
	// 파이프 실행이면 자식 프로세스를 하나 더 생성하여 파이프로 연결
	// foreground 실행이면 자식 프로세스가 종료할 때까지 기다린다.

	return;
}