[완료] exec 계열 함수의 오류 처리
현재 리눅스 프로그래밍 초보라서 모르는 것이 많습니다.
현재 졸업과제로 웹서버를 만들고 있는데 CGI 처리 부분을 구현하고 있습니다.
내용은 프로세스를 분기한 다음 exec함수로 다른 프로그램을 실행하는 것입니다.
개요를 말씀드리자면...
1. fork 함수로 프로세스를 분기합니다.
2. execl 함수로 자식 프로세스에서 다른 프로그램을 실행합니다.
3. 만약 execl로 실행하려는 프로그램이 존재하지 않는다면 자식 프로세스를 비정상 종료합니다.
4. 자식 프로세스의 비정상 종료에 대한 처리는 부모 프로세스에서 합니다.
부모 프로세스에서 WIFEXITED 등의 매크로를 이용하여 자식 프로세스의 종료 상황을 알 수 있다는 것은 책을 통해 알았습니다.
그런데 자식 프로세스를 비정상적으로 종료하는 방법을 잘 모르겠습니다.
제가 작성한 코드의 일부분입니다.
1) 자식 프로세스 부분
if(execl(filename, req->uri+5, (char*) 0) == -1) abort();
2) 부모 프로세스 부분
wait(&status); if(WIFEXITED(status) == 0) { req->uri[query_index] = '\0'; make_response_header(404, req, NULL, send_buf); write(csock, send_buf, strlen(send_buf)); return ; }
execl 함수가 오류를 일으키면 -1을 반환한다고 하더군요.(해당 파일이 없을 경우에도 이렇게 되는지는 모르겠습니다.)
그래서 자식 프로세스 부분에서 execl 함수의 반환값이 -1이면 비정상적으로 종료하도록 abort() 함수를 넣었습니다.
파일을 제대로 지정했을 때에는 정상적으로 동작하는데 틀린 파일 이름을 주었을 때에는 웹브라우저에서 처리를 못하고 무한 루프를 돕니다. 그리고 자식 프로세스도 종료가 되지 않습니다.
아무래도 오류 발생 시 자식 프로세스 종료가 잘못된 것 같은데 부모 프로세스에서 WIFEXITED를 이용하여 오류처리를 하려면 어떻게 해야 할까요?
음.
실행하고자 하는 해당 파일이 없는 경우에는 에러 처리를 할 수 없습니다. 저도 예전에 그거에 대해서 고민을 해봤는데. 프로그램이 실행되었을때 해당 프로그램에 대한 결과값을 받아 올 수 있지만, 프로그램이 있는지 없는지에 대해서는 exec() 가 결과를 리턴하지 않는 걸로 알고 있습니다. 차라리 access() 를 이용해서 파일이 존재하는지 알아 보시고 있으면 exec() 로 실행하는 방향으로 하시는게 좋을듯 싶습니다.
제가 잘못 알고 있을 수도 있으니.. 다른 분들께도 조언들어 보세요. ㅎㅎ
답변 감사합니다.
답변 감사합니다.
올해에는 꼭 노트북이 생기게 해 주세요.
갖은 노력 끝에 결국
갖은 노력 끝에 결국 해결했습니다.
exec 계열 함수들은 오류가 발생될 시 -1을 반환하고 errno에 다음과 같은 오류 코드를 넣는다는군요.
웹 브라우저에서 무한 루프를 돌던 이유는 이전에 따로 설정해 놓은 SIGCHLD 신호 핸들러가 문제였습니다. 프로세스를 두 번 분기했는데 첫 번째 분기 시 설정해 놓은 신호 처리 함수 때문에 두 번째 분기된 프로세스가 종료 정보를 제대로 전달하지 못하더군요. 그래서
로 기본 동작으로 복구한 다음에 실행하니 종료 코드를 제대로 반환합니다.
올해에는 꼭 노트북이 생기게 해 주세요.
아, 그런데 파일이
아, 그런데 파일이 없는 것을 처리할 때 abort()를 사용하는 것은 약간 어울리지 않는 면이 있는 것 같습니다. 보통 abort()는 더 이상 해결할 수 없는 상태가 되었을 때 core dump를 내고 강제로 죽이는 용도로 사용하지, 앞 상황처럼 정상적인 에러 처리로 사용하는 함수는 아닙니다.
이와 같은 경우에는 exit(error_code); 이런 식으로 종료시킨 다음에 error_code를 검사하는 방법이 더 좋아보입니다.
아니면 아예 fork()를 하기 전에 파일이 존재하고 실행 가능한지 살펴보고 그렇지 않으면 fork() 자체를 하지 않는게 퍼포먼스 측면에서는 좋아보이네요. 물론 fork() 후 다시 한번 에러 처리를 하긴 해야겠지만요.
충고 감사합니다.
충고 감사합니다. 현재 abort() 함수는 뺐고요. 말씀하신 대로 exit() 함수로 처리를 했습니다.
저도 fork()로 프로세스를 분기하기 전에 파일 존재 여부와 실행 가능 여부를 조사해서 미리 프로세스를 종료하는 방법을 생각하긴 했는데 exec 함수 연습 겸 그냥 이런 식으로 했습니다.
임베디드 시스템에 들어갈 소스라서 분기 전에 조사하는 것이 좋을 것 같기도 합니다.
올해에는 꼭 노트북이 생기게 해 주세요.
댓글 달기