본문 바로가기

C Language

minishell01

int main(int argc, char **argv, char **envp)
{
t_cmd_set p;
char *line;

ft_init(&p, envp, argv, argc);
while (1)
{
ft_set_signals(&p);
if (isatty(0))
p.input_text = readline("m1n1$hell> ");
else
{
p.input_text = get_next_line(0);
if (!p.input_text)
ft_free_exit(&p, p.status_code, NULL);
line = p.input_text;
p.input_text = ft_strtrim(p.input_text, "\n");
if (p.input_text == NULL)
ft_free_exit(&p, 1, "exit");
ft_free_all(line, NULL, NULL, NULL);
}
if (!ft_process_input(p.input_text, &p))
break ;
}
ft_free_exit(&p, p.status_code, NULL);
}

1. 초기화

 
c
t_cmd_set p; ft_init(&p, envp, argv, argc);
  • t_cmd_set 구조체 p를 선언하고 초기화합니다.
  • ft_init 함수를 통해 환경 변수(envp), 명령줄 인자(argv, argc)를 이용해 초기 설정을 합니다.

2. 메인 루프

 
c
while (1) { // ... (루프 내용) }

무한 루프를 시작하여 사용자 입력을 계속 받습니다.

2.1 시그널 설정

 
c
ft_set_signals(&p);

각 반복마다 시그널 핸들러를 설정합니다 (예: Ctrl+C 처리).

2.2 사용자 입력 받기

 
c
if (isatty(0)) p.input_text = readline("m1n1$hell> "); else { // 파일이나 파이프로부터 입력 처리 }
  • 터미널에서 실행 중이면 readline으로 프롬프트를 표시하고 입력을 받습니다.
  • 그렇지 않으면 (예: 파일이나 파이프로부터 입력을 받는 경우) get_next_line을 사용합니다.

예시:

  • 터미널: m1n1$hell> ls -l
  • 파일 입력: ./minishell < commands.txt
  1. isatty(0) 함수 호출:
    • isatty() 함수는 주어진 파일 디스크립터가 터미널과 연관되어 있는지 테스트합니다15.
    • 여기서 0은 표준 입력(stdin)을 나타내는 파일 디스크립터입니다.
    • 이 함수는 파일 디스크립터가 터미널을 가리키면 1(참)을, 그렇지 않으면 0(거짓)을 반환합니다2.
  2. 조건문 if (isatty(0)):
    • 이 조건은 표준 입력이 터미널과 연관되어 있는지 확인합니다.
    • 터미널에서 프로그램을 실행하는 경우 이 조건은 참이 됩니다.
    • 파일이나 파이프를 통해 입력을 받는 경우 이 조건은 거짓이 됩니다.
  3. readline("m1n1$hell> ") 함수 호출:
    • readline() 함수는 사용자로부터 한 줄의 입력을 받는 함수입니다.
    • "m1n1$hell> "는 프롬프트로, 사용자에게 입력을 기다리고 있음을 시각적으로 알려줍니다.
    • 이 함수는 사용자가 엔터를 누를 때까지 입력을 받고, 입력된 문자열을 반환합니다.
  4. p.input_text = ... 할당:
    • readline() 함수로부터 받은 사용자 입력을 p.input_text에 저장합니다.
    • p는 프로그램의 상태를 저장하는 구조체로 보입니다.

이 코드의 목적은 프로그램이 터미널에서 실행될 때 사용자 친화적인 방식으로 입력을 받고, 그렇지 않을 때(예: 파일이나 파이프로부터 입력을 받을 때)는 다른 방식으로 입력을 처리하도록 하는 것입니다. 이를 통해 프로그램은 다양한 환경에서 유연하게 동작할 수 있습니다47.

Citations:

  1. https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/isatty?view=msvc-170
  2. https://docs.oracle.com/cd/E36784_01/html/E36874/isatty-3c.html
  3. https://stackoverflow.com/questions/36258224/what-is-isatty-in-c-for
  4. https://people.cs.rutgers.edu/~pxk/416/notes/c-tutorials/isatty.html
  5. https://www.man7.org/linux/man-pages/man3/isatty.3.html
  6. https://www.qnx.com/developers/docs/7.1/
  7. https://www.qnx.com/developers/docs/8.0/com.qnx.doc.neutrino.lib_ref/topic/i/isatty.html
  8. https://www.ibm.com/docs/en/zos/2.4.0?topic=functions-isatty-test-if-descriptor-represents-terminal

2.3 입력 처리

 
c
if (!ft_process_input(p.input_text, &p)) break;

ft_process_input 함수로 사용자 입력을 처리합니다. 이 함수는 입력을 파싱하고 해당 명령을 실행할 것입니다.

예시:

  1. 사용자 입력: ls -l /home
  2. ft_process_input이 이를 파싱하여 실행
  3. /home 디렉토리의 상세 목록 출력

3. 프로그램 종료

 
c
ft_free_exit(&p, p.status_code, NULL);

루프가 종료되면 (예: 'exit' 명령 입력) 메모리를 해제하고 프로그램을 종료합니다.

주요 함수 설명

  1. ft_init: 환경 설정, 변수 초기화
  2. ft_set_signals: 시그널 핸들러 설정 (예: Ctrl+C 처리)
  3. readline: 사용자로부터 입력 받기
  4. get_next_line: 파일/파이프로부터 한 줄씩 읽기
  5. ft_strtrim: 문자열 앞뒤의 특정 문자 제거 (여기서는 개행 문자)
  6. ft_process_input: 사용자 입력 처리 및 명령 실행
  7. ft_free_exit: 메모리 해제 및 프로그램 종료

이 쉘 프로그램은 사용자 입력을 계속 받아 처리하며, 터미널과 파일 입력 모두를 지원합니다. 'exit' 명령이나 EOF를 만나면 종료됩니다.

'C Language' 카테고리의 다른 글

mutex  (0) 2025.03.10
cpp 01  (0) 2025.03.10
read 함수 설명  (0) 2025.02.27
get_next_line 간단 구현  (0) 2025.02.21
printf 함수 간단 구현  (0) 2025.02.21