42/PIPEX
[PIPEX / C] Utils & SanityCheck Funcs 구현
by 블로블로글
2024. 3. 23.
t_boolean check_argc(int argc)
{
if (argc != 5)
{
perror("Usage: ./pipex file1 cmd1 cmd2 file2");
return (FALSE);
}
return (TRUE);
}
t_boolean check_open(int *fd)
{
if (*fd == ERROR)
{
perror("open error");
return (FALSE);
}
return (TRUE);
}
t_boolean check_access(char *str[])
{
char *file1;
char *file2;
int read;
int write;
read = R_OK;
write = W_OK;
file1 = str[1];
file2 = str[4];
if (access(file1, read) == ERROR)
{
perror("infile is not exist or permission denied.");
return (FALSE);
}
if (access(file2, write) == ERROR)
{
perror("outfile is not exist or permission denied.");
return (FALSE);
}
return (TRUE);
}
t_boolean check_pipe(int *pipefd)
{
pipe(pipefd);
if (*pipefd == ERROR || *(pipefd + 1) == ERROR)
{
perror("pipe error");
return (FALSE);
}
return (TRUE);
}
t_boolean sanity_check(int argc, char *argv[], t_pipex *pipex)
{
if (!check_argc(argc))
return (FALSE);
if (!check_access(argv))
return (FALSE);
if (!check_open(&pipex->infile) || !check_open(&pipex->outfile))
return (FALSE);
if (!check_pipe(pipex->pipefd))
return (FALSE);
return (TRUE);
}
- check_argc
- check_open
- check_access
- check_pipe
- 파이프를 생성하고, 오류 발생 검사
t_boolean sanity_check(int argc, char *argv[], t_pipex *pipex)
{
if (!check_argc(argc))
return (FALSE);
if (!check_access(argv))
return (FALSE);
if (!check_open(&pipex->infile) || !check_open(&pipex->outfile))
return (FALSE);
if (!check_pipe(pipex->pipefd))
return (FALSE);
return (TRUE);
}
실행 전 여러 조건들에 대한 유효성 검사를 진행한 뒤에 모든 검사가 통과하면 true를 반환한다.
char *find_command_path(char *command, char *envp[])
{
char *path;
char *full_path;
char **paths;
char **tmp;
path = find_path(envp);
paths = ft_split(path, ':');
tmp = paths;
while (*paths)
{
full_path = ft_strjoin(*paths, "/");
full_path = ft_strjoin(full_path, command);
if (access(full_path, X_OK) == 0)
{
free_split(tmp);
return (full_path);
}
free(full_path);
paths++;
}
free_split(tmp);
return (NULL);
}
char *find_path(char *envp[])
{
while (*envp)
{
if (ft_strncmp(*envp, "PATH=", 5) == 0)
return (*envp + 5);
envp++;
}
return (NULL);
}
- find_path
- envp 배열을 순회하면서 각 환경 변수의 이름이 "PATH="으로 시작하는지 검사
- 목표를 찾으면 그 뒤에 이어지는 문자열을 반환, 찾지 못하면 NULL을 반환한다.
- find_command_path
- 주어진 명령어에 대한 실행 파일 경로를 탐색
- 환경 변수로부터 받은 "PATH" 환경 변수 값을 이용하려 탐색
- PATH 환경 변수에서 ":"를 기준으로 분리하여 디렉토리 목록을 생성
- 각 디렉토리에 /과 주어진 명령어를 붙여 전체 경로를 생성한 뒤에 access함수로 실행 권환을 검사
- 실행 권한이 있는 파일 경로를 찾으면 메모리를 정리하고 해당 경로를 반환
- 찾지 못한다면 NULL을 반환한다.
void execute_cmd(t_pipex *pipex, char **envp)
{
char *path;
path = find_command_path(pipex->cmd[0], envp);
if (!path)
{
perror("command not found");
exit(1);
}
if (execve(path, pipex->cmd, envp) == ERROR)
{
perror("execve error");
exit(1);
}
}
- 위의 find_command_path를 통해 찾은 경로를 찾는다.
- 만약 경로가 존재하지 않는다면 에러 메시지를 보여주고 종료시킨다.
- 만약 경로가 존재한다면 execve 호출을 통해 명령어를 실행한다.
- execve는 pipex->cmd의 인자 배열과 envp의 환경 변수 배열을 사용하여 실행
execve