exec함수 에러발생시 부모 프로세스의 wait 문 뒷부분 실행하지 않는 이유
int main()
{
char cmd[255];
pid_t pid;
int status;
while(1){
pid=fork();
if(pid== 0){
putchar('>'); putchar(' ');
memset(cmd, 0, sizeof(cmd));
fgets(cmd, sizeof(cmd),stdin);
int i=0;
char* args[10];
if(*cmd != '/'){
args[i++]=strtok(cmd," '\n'");
while(args[i++] = strtok(NULL," '\n'"));
if(execvp(args[0],args)==-1){
perror("Excute failed! ");
printf("Exit code 255\n");
}
}
else{
char *tmp;
tmp=strtok(cmd," '\n'");
args[i++]=tmp;
while(args[i++]=strtok(NULL," '\n'"));
if(execv(args[0],args)==-1){///////////////// here!
perror("Excute failed! ");
printf("Exit code 255\n");
}
}
}
else{
wait(&status);
printf("error hi!\n");
if(WIFEXITED(status))
printf("Exit code %d\n",WEXITSTATUS(status));
}
}
}
제가 짠 아주 간단한 쉘 입니다. 다름 아니라 컴파일 후 실행하고나서 adsfsdf같이 아무런 문자열을 입력한 경우 코드의 here부분에서 exec가 -1을 반환하여 perror과 printf를 실행하게 됩니다. 그러고나서 부모프로세스의 wait(&status) 아래부분들은 실행하지 않게 되는걸 printf로 확인했습니다. 왜 exec함수 에러 발생시 wait 뒷부분은 실행이 안되는 건지 아시는 분 계신가요?
힌트
힌트를 흰색으로 써서 필요한 만큼만 긁어서 읽는 재미를 구현하려 했는데, 폰트 색상 태그가 막혀 있군요.
어쩔 수 없지요. 위에서부터 천천히, 필요한 만큼만 읽으세요.
1. wait이 끝나지 않기 때문이지요.
2. wait은 어떨 때 끝날까요?
3. fork가 진행된 후, 부모와 자식은 (거의) 동일합니다.
4. fork 직후에 부모는 무한 루프 안에 있군요. 자식은 어떤가요?
5. perror와 printf를 실행한 후, 자식의 실행 흐름은 어디로 갈까요?
6. exec*가 실패하는 경우, 무한 루프에 출구가 있습니까?
wait은 자식 프로세스가 종료될때 끝납니다. 그런데 wait이 끝나지 않기 때문이라고 하셨으니
wait은 자식 프로세스가 종료될때 끝납니다. 그런데 wait이 끝나지 않기 때문이라고 하셨으니 자식프로세스가 종료가 안된다는 말씀이신거 같은데 그럼 exec에러 발생하면 perror printf 실행한 후 다시 if(fork()==0)로 돌아간다는 말씀이신가요?
exit이용예정
exit를 이용하여 자식 프로세스가 종료될수 있게 구현할 예정인데 혹시 엔터키만 쉘에서 입력시 쉘을 종료할수있게 이 코드를 수정가능할까요? 지금은 자식프로세스에서 fgets로 입력받기 때문에 엔터키를 입력한다해도 자식만 종료될거 같아서요
조금만 더 삽질하고 나면, 애초에 자식 프로세스에서
조금만 더 삽질하고 나면, 애초에 자식 프로세스에서 fgets으로 입력을 받도록 만든 것이 썩 좋지 않은 선택이었다는 걸 깨닫게 될 겁니다.
그런 식으로 만드는 게 불가능하지는 않더라도 굉장히 많이 번거롭습니다.
fgets
댓글 감사합니다 fgets을 사용한게 문제가 아니라 자식프로세스에서 사용한게 문제란 말씀이시죠? 만약 그렇다면 else를 없애고 자식프로세스에서 exit사용하면서 부모프로세스에서 fgets쓸 예정입니다
해결완료
감사합니다. 덕분에 해결하는데 큰 도움이 되었습니다. 좋은 하루 되세요!
댓글 달기