운영체제(OS)/with PintOS
(Project2-User Programs) - Argument Passing
스탠딩
2023. 12. 26. 21:18
Argument Passing
process_exec()에서 사용자 프로그램에 대한 인수를 설정하세요.
Implement the argument passing.
현재 process_exec()은 새 프로세스에 대한 인수 전달을 지원하지 않습니다. 이 기능을 구현하려면 process_exec()을 확장하여 단순히 프로그램 파일 이름을 인수로 받는 대신 공백으로 단어로 나누도록 합니다. 첫 번째 단어는 프로그램 이름, 두 번째 단어는 첫 번째 인수가 되는 식으로 말이죠. 즉, process_exec("grep foo bar")는 두 개의 인자 foo와 bar를 전달하여 grep을 실행해야 합니다.
명령줄 내에서 여러 개의 공백은 하나의 공백에 해당하므로 process_exec("grep foo bar")는 원래 예제와 동일합니다. 명령줄 인수의 길이에 합리적인 제한을 둘 수 있습니다. 예를 들어 인수를 한 페이지(4KB)에 들어갈 수 있는 길이로 제한할 수 있습니다. (pintos 유틸리티가 커널에 전달할 수 있는 명령줄 인수는 128바이트로 제한되어 있습니다.)
인자 문자열은 원하는 방식으로 파싱할 수 있습니다. 길을 잃었다면 include/lib/string.h에 프로토타입이 있고 lib/string.c에 철저한 주석으로 구현된 strtok_r()을 참조하세요. 자세한 내용은 man 페이지(프롬프트에서 man strtok_r 실행)에서 확인할 수 있습니다.
int process_exec(void *f_name)
{
char *file_name = f_name;
bool success;
/* We cannot use the intr_frame in the thread structure.
* This is because when current thread rescheduled,
* it stores the execution information to the member. */
struct intr_frame _if;
_if.ds = _if.es = _if.ss = SEL_UDSEG;
_if.cs = SEL_UCSEG;
_if.eflags = FLAG_IF | FLAG_MBS;
int argc = 0;
char *argv[128] = {0}; // 이중 리스트
char *tmp;
char *token = strtok_r(file_name, " ", &tmp);
while (token != NULL)
{
argv[argc] = token;
argc++;
token = strtok_r(NULL, " ", &tmp); // 파싱해서
}
argv[argc] = NULL;
/* We first kill the current context */
process_cleanup();
/* And then load the binary */
success = load((char *)argv[0], &_if); // 패싱
if (success)
{
thread_current()->process_load = true;
argument_stack(argv, argc, (uintptr_t *)(&(_if.rsp)));
set_arg_reg(&_if, argc, argv[0]);
}
/* If load failed, quit. */
palloc_free_page(file_name);
if (!success)
return -1;
/* Start switched process. */
do_iret(&_if);
NOT_REACHED();
}