char *
strtok_r(char *s, const char *delimiters, char **save_ptr)
{
char *token;
ASSERT(delimiters != NULL);
ASSERT(save_ptr != NULL);
/* S가 NULL이 아니면 S에서 시작합니다.
S가 NULL이면 저장된 위치에서 시작합니다. */
if (s == NULL)
s = *save_ptr;
ASSERT(s != NULL);
/* 현재 위치에서 모든 DELIMITERS(구분자)를 건너뜁니다. */
while (strchr(delimiters, *s) != NULL)
{
/* 만약 null 바이트('\\0')를 찾고 있다면, 모든 문자열은 끝에 null 바이트를
포함하므로 strchr()는 항상 NULL이 아닌 값을 반환합니다. */
if (*s == '\\0')
{
*save_ptr = s;
return NULL;
}
s++;
}
/* 문자열 끝까지 DELIMITERS가 아닌 문자를 건너뜁니다. */
token = s;
while (strchr(delimiters, *s) == NULL)
s++;
if (*s != '\\0')
{
*s = '\\0';
*save_ptr = s + 1;
}
else
*save_ptr = s;
return token;
}
사용 방법
char s[] = " String to tokenize. ";
char *token, *save_ptr;
for (token = strtok_r (s, " ", &save_ptr); token != NULL;
token = strtok_r (NULL, " ", &save_ptr))
printf ("'%s'\\n", token);
'String'
'to'
'tokenize.'
현재 인자 전달을 지원하지 않음 !!
이 함수를 수정하며 다음과 같이 유저 프로그램을 실행토록 해야함
process_exec("grep foo bar")
strtok 함수를 이용하여 파싱할수 있음
이 함수는 파일이름(grep foo bar)을 전달받음
이것을 파싱하여 argc와 argv를 만들어내야함
파싱한 문자열들을 유저 스택에 푸시해야함
| "c" | ← 문자열 복사 (가장 아래)
| "b" |
| "a" |
| "./prog"|
| argv[4]=NULL | ← 포인터 배열
| argv[3]------| ← "c"의 주소
| argv[2]------| ← "b"의 주소
| argv[1]------| ← "a"의 주소
| argv[0]------| ← "./prog"의 주소
| argv | ← &argv[0] (포인터 배열의 시작 주소)
| argc | ← rsp (main에서 첫 번째 인자로 받게 됨)
(높은 주소, USER_STACK)
푸시는 어떻게 해야하나?
rsp -= strlen(word) + 1; // 스택 공간 확보
memcpy(rsp, word, strlen(word) + 1); // 스택에 복사
rsp (스택 끝 포인터) 는 아래로 자라니까 먼저 공간을 확보하고, memcpy로 스택에 복사
rsp 값은 어디에서 알 수 있지??
uint8_t *rsp = (uint8_t *)USER_STACK;
유저 스택의 최상단 값 !!
if_->rsp = (uintptr_t)rsp;
최종 rsp값을 intr_frame 구조체의 rsp 멤버에 저장