The Pattern

what does the following 'exec' example do?

#include <unistd.h>
#include <fcntl.h> // O_CREAT, O_APPEND etc. defined here

int main() {
   close(1); // close standard out
   open("log.txt", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
   puts("Captain's log");
   chdir("/usr/include");
   // execl( executable,  arguments for executable including program name and NULL at the end)

   execl("/bin/ls", /* Remaining items sent to ls*/ "/bin/ls", ".", (char *) NULL); // "ls ."
   perror("exec failed");
   return 0; // Not expected
}


위 코드에서는 어떠한 에러 체크도 하지 않습니다.(close, open, chdir,등등이 전부 정상적으로 동작한다고 가정)

일단 처음에 close(1)을 함으로써 standard out stream을 close해줍니다. 그 다음 open을 통해 log.txt를 열어주면 standard out 대신 log.txt가 1번이 되어 standard out이 log.txt에 저장되게 됩니다. (File descriptor는 낮은 숫자부터 사용하므로)

그 다음 chdir을 통해 디렉토리를  /usr/include로 바꿔주고,

execl을 통해 현재 프로세스의 이미지를 /bin/ls로 바꿔준 후 그 process의 main을 호출합니다.

(shell에서 ls .을 실행한 것과 같음)

마지막으로 perror을 출력하는데 이 실행은 execl이 정상적으로 동작한다면 프로세스 이미지가 ls로 바뀌기 때문에 이 perror은 동작하지 않을 것입니다.



Subtle forkbomb bug


위 코드의 문제점이 무엇일까요??

자세히 살펴보면 execlp에서 echo를 호출하려는 의도였는데 ehco를 호출하고 있습니다. 

이러한 경우 처음에 의도한 대로 10개의 process만 발생하는 것이 아니라 2**10(???((2^10)-1)*2인가??)를 만들어 fork bomb를 만들고 있습니다.  이러한 동작을 방지하려면 exec가 호출된 바로 다음에 exit를 호출해주어야 합니다. 이렇게 하면 exec가 fail해도 fork bomb이 발생하지 않습니다.



What does the child inherit from the parent?

  • 열려있는 파일의 관리. 만약 parent가 나중에 file의 처음 부분으로 돌아가면, child도 똑같이 영향을 받습니다(그 반대의 경우도 마찬가지입니다)
  • Signal Handlers
  • 현재 작업중인 directory
  • 환경 변수

더 자세한 사항은 fork man page를 살펴보세요.

What is different in the child process than the parent process?

Parent process와 child process의 차이점은 우선 process ID입니다. 만약 child process에서 getppid를 호출하면 parent에서 getpid를 통해 호출한 값과 일치할 것입니다. 역시 더 자세한 사항은 fork의 man page를 참조합시다.

How do I wait for my child to finish?

waitpid나 wait을 사용합시다. parent process는 wait이나 waitpid가 return될 때까지 기다릴 것입니다.

What is the fork-exec-wait pattern

일반적인 프로그래밍 패턴은 fork를 호출한 다음 exec를 수행하고 이 동작이 끝날때까지 wait하는 것입니다. 최초의 process가 fork를 하면 child process가 생성되고, 이 child process에서 exec를 사용해 새로운 프로그램을 실행합니다. 반면 parent process에서는 이 child process가 끝나는 것을 기다리기 위해 wait(또는 waitpid)을 사용합니다. 다음에 완성된 예제 코드를 보이도록 하겠습니다.

How do I start a background process that runs at the same time?

wait을 하지 않으면 parent process는 child process를 기다리지 않고 계속 진행합니다. 또한 background process에서 exec를 호출하기전에 열려있는 file decriptor를 close해줌으로써 parent의 input과 output stream과의 연결을 끊을 수 있습니다.
하지만 이러한 child process가 parent process보다 먼저 종료된다면 zombie process가 될 것입니다.


'Angrave System Programming > Processes' 카테고리의 다른 글

Process Control : Wait macros  (0) 2019.01.11
Forking: Fork, Exec, Wait(2)  (0) 2019.01.11
Forking Introduction  (0) 2019.01.10
Process Introduction  (0) 2019.01.10
Kernel, Shells, Terminals  (0) 2019.01.10
Posted by 몰랑&봉봉
,