정상적인 종료
비정상적인 종료
#include <stdlib.h>
void exit(int status);
void _Exit(int status);
#include <unistd.h>
void _exit(int status);
#include <stdlib.h>
int atexit(void (*func)(void));
/* 성공시 0, 실패시 0이아닌 값이 반환 */
void func1() { printf("print func1\n"); }
void func2() { printf("print func2\n"); }
void func3() { printf("print func3\n"); }
void func4() { printf("print func4\n"); }
int main(int argc, char** argv){
pid_t pid;
atexit(func1); atexit(func2);
atexit(func3); atexit(func4);
pid=fork();
if(pid==0){
printf("CHILD PROCESS : CALLED\n");
printf("CHILD PROCESS : EXIT CALL\n");
exit(0);
}
if(pid < 0){
perror("PARENT ERROR");
exit(1);
}
wait(NULL);
printf("PARENT PROCESS : EXIT CALL\n");
exit(0);
}
[root@localhost unix]# ./a.out
CHILD PROCESS : CALLED
CHILD PROCESS : EXIT CALL
print func4
print func3
print func2
print func1
PARENT PROCESS : EXIT CALL
print func4
print func3
print func2
print func1
#include <sys/wait.h>
pid_t wait(int *status);
/* 성공시 child의 process ID를, 실패시 -1을 반환 */
int status;
pid_t cpid;
cpid = fork(); /* create new process */
if(cpid ==0){
/* child */
/* do something ... */
} else {
/* parent, so wait for child */
cpid = wait(&status);
printf(“The child %d is dead\n”, cpid);
}
------------------------------------------------------------------
pid_t pid;
int status;
pid = wait(NULL) /* ignore status information */
pid = wait(&status); /* status will contain status information */
main() {
pid_t pid;
int status, exit_status;
if((pid=fork()) < 0) fatal("fork failed");
if(pid==0){ /*자식*/
/* 이제 수행을 4초동안 중단시키기 위해 라이브러리 루틴 sleep을 호출 한다 */
sleep(4);
exit(5); /* 0이 아닌값을 가지고 퇴장 */
}
/* 여기까지 수행이 진전된 바 이것은 부모임. 자식을 기다린다. */
if((pid=wait(&status)) == -1){
perror("wait failed");
exit(2);
}
/* 자식이 어떻게 죽었는지 알기 위해 테스트한다 */
if (WIFEXITED(status)){ //WIFEXITED : 정상종료인가 아닌가
exit_status = WEXITSTATUS(status); //status의 뒤 5bit를 추출하는 매크로
printf("Exit status from %d was %d\n", pid,exit_status);
//여기서 exit_status는 5이다.
}
exit(0);
}
Macro | 설명 |
---|---|
WIFEXITED(status) | 정상종료시 0이아닌 값을 출력한다. |
WIFSIGNALED(status) | signal로 인한 종료면 0이아닌 값을 반환하고 WTERMSIG를 이용하여 종료를 일으킨 SIGNAL의 종류를 알 수 있다. |
WIFSTOPPED(status) | child가 중단되면 0이아닌 값을 반환한다. |
WIFCONTINUED(status) | child가 실행중이면 0이아닌 값을 반환한다. |
#include <sys/wait.h>
void pr_exit(int status)
{
if (WIFEXITED(status)) //program의 정상종료를 확인한다.
printf("normal termination, exit status = %d\n",
WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("abnormal termination, signal number = %d%s\n",
WTERMSIG(status),
else if (WIFSTOPPED(status))
printf("child stopped, signal number = %d\n",
WSTOPSIG(status));
}
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *statloc, int options);
/* 성공시 child process ID, 실패시 -1을 반환 */
main(){
pit_t pid;
int status, exit_status;
if((pid=fork()) < 0) fatal("fork failed");
if(pid==0){ /* 자식 */
/* 이제 4초동안 중단시키기 위해 라이브러리 루틴 sleep을 호출한다 */
sleep(4);
exit(5); /* 0이 아닌 값을 가지고 퇴장한다 */
}
/* 여기까지 수행이 진전된 바 이것은 부모임. 따라서 자식이 퇴장했는지 확인한다.
퇴장하지 않았으면, 1초 동안 수면한 후 다시 검사한다. */
while(waitpid(pid, &status, WNOHANG) == 0){
printf("Still waiting... \n");
sleep(1);
}
/* 자식이 어떻게 죽었는지 알기 위해 테스트한다 */
if (WIFEXITED(status)){
exit_status = WEXITSTATUS(status);
printf("Exit status from %d was %d\n", pid,exit_status);
}
exit(0);
}
while(pid=fork()){
count = 0;
/* 3개의 child를 생성한다. */
if(++count==3) break;
}
if (pid == 0){
sleep(5);
printf("I will be back %d\n", getpid());
exit(0); /* 자식은 먼저 죽는다 */
}
else if(pid > 0){
printf("Im parent %d\n", getpid());
printf("Press any key\n");
getchar(); /* 키보드 입력을 기다리는 함수로 child가 죽을 때까지 기다린다. */
}
while(pid=fork()){
if(++count==3) break;
}
if (pid == 0){
printf("I will be back %d\n", getpid());
sleep(500);
exit(0);
}
else if(pid > 0){
printf("Im parent %d\n", getpid());
printf("Press any key\n");
getchar(); /* 먼저 엔터를 치고 부모는 종료한다 */
}
#include <unistd.h>
pid_t getpid(void);
Returns: process ID of calling process
pid_t getppid(void);
Returns: parent process ID of calling process
uid_t getuid(void);
Returns: real user ID of calling process
uid_t geteuid(void);
Returns: effective user ID of calling process
gid_t getgid(void);
Returns: real group ID of calling process
gid_t getegid(void);
Returns: effective group ID of calling process
static int num = 0;
static char namebuf[20];
static char prefix[] = "/tmp/tmp";
char *gentemp(void){
int length;
pid_t pid;
pid = getpid(); /* 프로세스 식별번호를 얻는다. */
/* 표준 문자열처리 루틴들 <string.h> */
strcpy (namebuf, prefix);
length = strlen(namebuf);
/* 파일 이름에 프로세스 식별번호(pid)를 추가한다. */
itoa (pid, &namebuf[length]); /* filename : /tmp/tmp#pid */
strcat (namebuf, ".");
length = strlen (namebuf);
do{
itoa (num++, &namebuf[length]); /* 접미 번호를 추가한다. */
} while (access(namebuf, F_OK) != -1); /* test for existence of file */
return (namebuf); /* filename : /tmp/tmp#pid.#num */
}
#include <unistd.h>
pid_t getpgrp(void);
/* 현재 process의 pgid 반환*/
pid_t getpgid(pid_t pid); /* getpgid(0) == getpgrp() */
/* 성공시 pgid, 실패시 -1 반환 */
#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);
/* 성공시 0, 실패시 -1 반환 */
#include <unistd.h>
pid_t getsid(pid_t pid);
/* 성공시 session leader의 pid를, 실패시 -1을 반환*/
#include <unistd.h>
pid_t setsid(void);
/* 성공시 pgid, 실패시 -1 반환 */
#include <unistd.h>
int chroot(const char *path);
/* 성공시 0, 실패시 -1을 반환 */
int main() {
int pid;
if (chroot("/home/mydir") != 0){ /* ‘/’ == ‘/home/mydir’ */
perror("chroot");
exit(0);
}
if (execl("/bin/bash","bash", NULL) == -1) /* ‘/home/mydir/bin/bash’ */ perror("error");
}
#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
/* 성공시 0, 실패시 -1을 반환 */