42Seoul/pipex

pipex 구현

재윤 2023. 9. 13. 01:44
반응형

전체 구조

int	main(int argc, char **argv, char **envp)
{
	t_info	loc;

	if (argc != 5)
		error("argument error\\n");
	loc.infile = open(argv[1], O_RDONLY);
	if (loc.infile == -1)
		perror("infile error");
	loc.outfile = open(argv[4], O_RDWR | O_CREAT | O_TRUNC, 0644);
	if (loc.outfile == -1)
		error("outfile error");
	loc.path = find_path(envp);
	loc.argv_command_one = ft_split(argv[2], ' ');
	loc.argv_command_two = ft_split(argv[3], ' ');
	loc.com_path_combine1 = combine_command(loc.argv_command_one[0], loc.path);
	loc.com_path_combine2 = combine_command(loc.argv_command_two[0], loc.path);
	pipe_start(loc, envp);
}
  1. argc가 5개가 아니면 전부 에러 처리
  2. 파일 open을 한다.
  3. outfile 생성
  4. 환경변수에서 ‘PATH’를 찾는다.
  5. cmd 첫 번째 친구들을 split해서 저장을 한다.
  6. combine_command 함수에서 access 함수를 이용해 실행권한이 있는지 체크한다.
  7. pipe_start에서 cmd를 실행시킨다.

find_path 함수

  • path를 찾고 split를 한다
char	**find_path(char **envp)
{
	int		i;
	char	**envp_split_reslt;

	i = 0;
	while (number_compare(envp[i], "PATH", 4) != 0)
		i++;
	envp_split_reslt = envp_split(envp[i]);
	i = 0;
	while (envp_split_reslt[i])
		i++;
	return (envp_split_reslt);
}
char	**envp_split(char *envp_path)
{
	char	**envp_split_result;
	int		malloc_count;
	int		size;

	malloc_count = 0;
	size = ma_count(envp_path);
	envp_split_result = (char **)malloc(sizeof(char *) * (size + 1));
	if (!envp_split_result)
		return (0);
	while (*envp_path)
	{
		while (*envp_path && separator_slash(*envp_path) == 1)
			envp_path++;
		if (*envp_path)
		{
			envp_split_result[malloc_count++] = word_split(envp_path);
			if (envp_split_result[malloc_count - 1] == 0)
				return (ft_free(envp_split_result));
			envp_path++;
		}
		while (*envp_path && separator_colon(*envp_path) == 1)
			envp_path++;
	}
	envp_split_result[malloc_count] = 0;
	return (envp_split_result);
}

combine_command

  • 환경변수에 스플릿한 cmd를 제일 앞에 꺼를 붙여서 실행권한을 확인해본다.
char	*combine_command(char *first_loc_command, char **path)
{
	char	*combine;
	int		i;
	char	*tmp;
	int		fd;

	fd = access(first_loc_command, X_OK);
	if (fd != -1)
		return (first_loc_command);
	combine = ft_strjoin("/", first_loc_command);
	i = 0;
	while (path[i])
	{
		tmp = ft_strjoin(path[i], combine);
		fd = access(tmp, X_OK);
		if (fd != -1)
		{
			free(combine);
			return (tmp);
		}
		close(fd);
		free(tmp);
		i++;
	}
	free(combine);
	return (NULL);
}

pipe_start

  • 파이프를 만들어주고 fork를 하여 부모 프로세스 자식 프로세스를 만들어준다.
  • 분기점을 나누어 코드를 작성한다. (여기서 이제 파이프라인 코딩이다.)
void	pipe_start(t_info loc, char **envp)
{
	if (pipe(loc.pipe_fds) < 0)
		perror("pipe error");
	loc.pid = fork();
	if (loc.pid == -1)
		perror("fork error");
	else if (loc.pid == 0)
		child_process(loc, envp);
	else
		parents_process(loc, envp);
	while (wait(NULL) > 0)
		;
}
반응형

'42Seoul > pipex' 카테고리의 다른 글

main에서 환경변수 얻기  (0) 2023.09.13
exit()  (0) 2023.09.13
perror()  (0) 2023.09.13
waitpid()  (0) 2023.09.13
fork()  (0) 2023.09.13