ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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
    quit
    

    Trace05는 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
Designed by Tistory.