-
[Shell Lab] Trace05, Trace 06시스템 프로그래밍 2022. 11. 15. 21:59
Trace05 는 실행파일을 Background job 으로 실행시키는 문제입니다.
trace05는 특정 형태로 출력할 것을 요구합니다. 이 형식을 확인하기 위해서 trace05.txt 파일을 열어봅시다.
# # trace05.txt - Run a background job. # /bin/echo -e tsh\076 ./myspin1 \046 NEXT ./myspin1 & NEXT WAIT SIGNAL /bin/echo -e tsh\076 quit NEXT quitTrace05는 myspin1 실행파일을 & 를 이용해 백그라운드 job으로 실행시키는 것을 알 수 있습니다.
tshref가 ./myspin1 &을 입력하면 어떤 것을 출력하는지 확인해봅시다.

[숫자] (숫자) command 형태로 출력하는 것을 알 수 있습니다. 논리적인 근거가 되지는 못하지만... 숫자의 모양새를 보아하니 jid, pid 를 출력하는 것 같습니다. 그러므로 출력인자에 pid2jid(pid)와, pid를 입력해줍니다. 참고로 pid2jid는 tsh.c에 이미 정의되어있는 pid를 인자로 받아 jid를 출력해주는 함수입니다.
명령어 뒤에 & 을 붙여 실행시키면 Background job으로 실행시킬 수 있었던 점을 떠올리며 Trace05번을 해결해봅시다.
Background 형태로 프로세스를 생성하기 위해서는 쉘에서 작업들을 관리하는 부분이 구현되어있어야합니다. tsh.c 파일의 struct job_t 구조체를 살펴봅시다.

job_t 구조체 내에 process id 를 저장할 변수 pid, 작업 아이디를 저장할 변수 jid(job id), 어떤 형태로 작업이 수행되는지 상태를 저장할 변수 state, 입력된 명령어를 저장할 변수 cmdline이 선언되어 있는 것을 확인할 수 있습니다.
그리고 jobs라는 job_t type의 배열을 선언함을 통해 job들을 등록 / 제거할 것임을 예상할 수 있습니다!
job을 관리하기 위한 함수들로는 다음과 같은 것들이 있습니다.

쉘의 기본구조는 cmdline을 받아 eval 하는 것이므로 eval 함수로 가서 background로 실행할 수 있도록 처리해봅시다.
최종코드
void eval(char *cmdline) { char *argv[MAXARGS]; //command 저장 pid_t pid; // pid 이용해야함. int bg; //명령어를 parseline을 통해 분리 bg = parseline(cmdline, argv); // parseline을 뜯어보면 bg 여부를 리턴하는 것을 확인할 수 있음. //parsing된 명령어를 전달 if(!builtin_cmd(argv)) { if ( (pid=fork()) == 0/*Child Process 체크*/) { //Child Process인 경우, execve()수행 if ( execve(argv[0], argv, environ) < 0) { printf("%s : Command not found\n\n", argv); exit(0); } } //addjob() 함수를 이용해서 joblist에 job을 추가한다 addjob(jobs, pid, (bg==1?BG:FG), cmdline); if (!bg) { // foreground로 실행해야 한다면 waitpid(pid, NULL, 0); // 자식 프로세스가 종료될 때까지 대기 deletejob(jobs, pid); // 자식 프로세스 종료 후 job 에서 제거 } else { printf("[%d] (%d) %s", pid2jid(pid), pid, cmdline); //trace05가 요구하는 출력양식에 맞추어 출력 //pid2jid() 함수를 이용해서 양식에 맞추어 출력 } }; return; }Trace 06 는 Background job 하나와 Foreground job 하나를 동시에 실행시키는 문제입니다. 먼저 trace06.txt 파일을 확인해보겠습니다.

trace06.txt myspin1 을 background 로 실행시키고 myspin2 를 argument 1과 함께 foreground job 으로 실행시키는 것을 확인할 수 있습니다.
Trace 05 에서 background 로 프로세스를 실행시키는 것을 잘 정의했으면 Trace 06 는 자동으로 통과합니다.
'시스템 프로그래밍' 카테고리의 다른 글
[System Programming] Shell (1) 2022.11.22 [Shell Lab] Trace07 (0) 2022.11.15 [Shell Lab] Trace02, Trace03, Trace04 (0) 2022.11.15 [Shell Lab] Trace01 (0) 2022.11.15 [Shell Lab] Trace00 (0) 2022.11.15