본문 바로가기
42/PIPEX

[PIPEX / C] 메인 함수 흐름 및 fork()-wait()에 대하여

by 블로블로글 2024. 3. 23.

우선 파이프 엑스의 main함수를 작성했다.
파이프를 연결해서 출력하는 결과를 저장하려면 우선 읽는 파일 설정과 출력 파일 설정이 필요하다.

pipex 읽기 전용 - 출력 전용 파일 만들기

pipex.infile = open(argv[1], O_RDONLY);
pipex.outfile = open(argv[4], O_WRONLY | O_CREAT | O_TRUNC, 0644);
  • open(fd, open_option, mod);
    • 특정 파일의 옵션과 권한을 설정한다.
if (!sanity_check(argc, argv, &pipex))
    return (0);
if (!check_fork(&pid1))
    return (0);
  • 무결성 검사를 통해 인자의 개수, 파일접근 권한 등 초기 조건을 검사
  • fork함수의 호출이 제대로 이루어졌는지 검사
if (pid1 == 0)
    change_fd_children(&pipex, argv, envp);
else
    change_fd_parent(&pipex, argv, envp);
  • 자식 프로세스인 경우 chilredn을 호출, 부모 프로세스인 경우 parent를 호출하여 실행
    • fork의 반환값을 통해 부모와 자식을 판별
    • fork()호출을 사용하면, 자식 프로세스에겐 0을 반환하고 부모 프로세스에게는 자식 프로세스의 PID를 반환한다.
    • 에러 상황에는 -1을 반환한다.
close(pipex.infile);
close(pipex.outfile);
  • 사용이 완료된 입력 파일과 출력 파일의 파일 디스크립터 닫는다.
waitpid(pid1, NULL, 0);
  • waitpid 시스템 호출을 사용하여 자식 프로세스의 종료를 기다린다.
    • waitpid() 사용 여부에 따른 차이점
    • waitpid()를 사용할 경우
      • 부모 프로세스 동작: pid1 자식 프로세스의 종료를 기다립니다.
      • 실행 흐름: 자식 프로세스가 종료되면, 부모 프로세스는 그 다음 코드를 실행합니다.
      • 장점: 이 방식은 프로세스의 실행 순서를 제어하고, 자식 프로세스가 종료될 때까지 부모 프로세스가 끝나지 않도록 보장합니다.
    • waitpid()를 사용하지 않을 경우
      • 부모 프로세스 동작: 자식 프로세스의 종료를 기다리지 않고 바로 다음 코드를 실행합니다.
      • 결과: 이로 인해 자식 프로세스가 아직 실행 중일 때 부모 프로세스가 종료될 수 있습니다.
      • 고아 프로세스: 자식 프로세스가 종료되기 전에 부모 프로세스가 끝나면, 자식 프로세스는 고아 프로세스가 되거나 init 프로세스의 자식이 됩니다.
  • waitpid를 통해 프로세스의 동작을 제어하고 자원 관리를 최적화할 수 있다.

전체 코드

int    main(int argc, char *argv[], char *envp[])
{
    t_pipex    pipex;
    pid_t    pid1;

    pipex.infile = open(argv[1], O_RDONLY);
    pipex.outfile = open(argv[4], O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (!sanity_check(argc, argv, &pipex))
        return (0);
    if (!check_fork(&pid1))
        return (0);
    if (pid1 == 0)
        change_fd_children(&pipex, argv, envp);
    else
        change_fd_parent(&pipex, argv, envp);
    close(pipex.infile);
    close(pipex.outfile);
    waitpid(pid1, NULL, 0);
    return (0);
}

전체 코드의 흐름은 in,out file들을 지정하고 fork를 한 뒤 execve를 통해 children을 실행하는 구조이다.
pipex 프로젝트를 통해 파일 디스크립터, 프로세스 생성과 관리, 파이프라인을 통한 데이터 전송, 그리고 명령어 실행이라는 시스템 프로그래밍의 주요 요소들을 직접 구현함으로써, 우리는 운영 체제가 어떻게 작동하는지에 대한 공부를 깊게 하게된 것 같다.
main 함수 안의 세부 함수들은 다음 글에서 설명하겠다.