UNIT 09 프로세스 제어 로봇 SW 교육원 3기.

Slides:



Advertisements
Similar presentations
Signal Handling ( 금 ) 한 민 규
Advertisements

12장 프로세스.
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 11장 프로세스간 통신 인공지능실험실 석사 2학기 이희재
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
Linux/UNIX Programming APUE (Process Control)
8장 프로세스.
컴퓨터 프로그래밍 기초 [Final] 기말고사
9 파이프.
인공지능실험실 석사 2학기 김승겸 TCP/IP Socket Programming… 제 10장 멀티태스킹 기반의 서버구현 인공지능실험실 석사 2학기 김승겸
Signal & Inter-Process Communication
Linux System Programming
Department of Computer Engineering
Department of Computer Science and Engineering
데이터 파일 C 데이터 파일과 스트림(Stream) 텍스트 파일 처리
6 프로세스 생성과 실행.
6 프로세스 생성과 실행.
제15장 파일 입출력 문자열을 출력하는 여러가지 방법 (15-2쪽) 문자열만 처리하는 입출력 함수
Department of Computer Engineering
양방향 파이프의 활용 양방향 통신 파이프는 기본적으로 단방향이므로 양방향 통신을 위해서는 파이프를 2개 생성한다.
12장 파이프.
fork로 생성한 자식 프로세스에서 exec 함수군을 호출
07. 디바이스 드라이버의 초기화와 종료 김진홍
CHAPTER 02 OpenCV 개요 PART 01 영상 처리 개요 및 OpenCV 소개.
Root Filesystem Porting
12장 프로세스.
Signal & Inter-Process Communication
Term Project Team Member
Department of Computer Engineering
프로세스 생성[1] 프로그램 실행 : system(3) #include <stdlib.h>
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
Root Filesystem Porting
DK-128 ADC 실습 아이티즌 기술연구소
8 메모리 매핑.
파일 기술자 파일 기술자 현재 열려있는 파일을 구분하는 정수값 저수준 파일 입출력에서 열린 파일을 참조하는데 사용
4장 파일.
메시지 큐[5] – test1.c 메시지 제어: msgctl(2) #include <sys/msg.h>
Sungkyunkwan University OS Project Dongkun Shin
파일 접근권한 제어 stat 구조체의 st_mode 항목에 파일의 종류와 접근권한 정보저장 st_mode 값의 구조.
5 프로세스 정보.
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
Signal & Inter-Process Communication
리눅스 시스템 & 커널 기초 P.46 – P.53 이름: nsh009 학번: 112 1/20.
Device Driver 임베디드 시스템 I.
24장. 파일 입출력.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express Slide 1 (of 22)
19. 함수 포인터와 void 포인터.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
School of Electronics and Information. Kyung Hee University.
데이터베이스실험실 석사 2학기 조정희 TCP/IP Socket Programming… 제 18장 윈도우 기반 쓰레드 사용하기 데이터베이스실험실 석사 2학기 조정희
Department of Computer Engineering
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
Signal & Inter-Process Communication
Department of Computer Engineering
Kernel, Ramdisk, JFFS2 Porting
( Windows Service Application Debugging )
시스템 인터페이스 Lab#5 쉡 실습.
7주차: Functions and Arrays
3. 모듈 (5장. 모듈).
구조체(struct)와 공용체(union)
실습과제 (변수와 자료형, ) 1. 다음 작업 (가), (나), (다)를 수행하는 프로그램 작성
9 파이프.
06. 디바이스의 등록과 해제 김진홍
Signal & Inter-Process Communication
1. 지역변수와 전역변수 2. auto, register 3. static,extern 4. 도움말 사용법
Reversing 발표자 : 박현우.
개정판 누구나 즐기는 C언어 콘서트 제13장 동적 메모리 출처: pixabay.
7 생성자 함수.
Signal & Inter-Process Communication
2019 2학기 9장 배열과 포인터 1. 주소, 주소연산자(&) 2. 포인터, 역참조연산자(*) 3. 배열과 포인터.
Presentation transcript:

UNIT 09 프로세스 제어 로봇 SW 교육원 3기

init 프로세스 init 프로세스 프로세스 ID : 1 시스템 부팅 절차 마지막에 커널에 의해 실행됨 커널 부팅 이후 UNIX 시스템을 뛰우는 역할을 함 시스템 의존적 초기화 파일들 /etc/rc* 파일들, /etc/inittab과, /etc/init.d의 파일들을 읽고 시스템을 특정한 상태(이를테면 다중 사용자 상태)로 설정함 종료되지 않음 일반 사용자 프로세스로써 고아가 된 자식 프로세스의 부모 프로세스 역할을 함 /sbin/init $ ls -l /sbin/init -rwxr-xr-x 1 root root 31328 Oct 13 2013 /sbin/init

프로세스 ID 프로세스 ID 커널에 의해 관리되는 고유한 프로세스 ID 음이 아닌 정수 값 대부분의 UNIX System들은 방금 종료된 프로세스의 ID가 새로 만든 프 로세스에 배정되는 일을 방지하기 위해 프로세스 ID의 재사용을 지연하 는 알고리즘들을 구현하고 있음

실습 1: 프로세스 ID #include<unistd.h> pid_t getpid(void); Returns : process ID of calling process pid_t getppid(void); Returns : parent process ID of calling process #include<stdio.h> #include<unistd.h> int main(void) { printf("getpid:%d\n", getpid()); printf("getppid:%d\n", getppid()); return 0; }

프로세스와 관련된 ID 프로세스는 여러 가지 ID와 관련되어 있음 일반적인 프로그램을 실행 실제(real) 사용자/그룹 ID 로그인 시 패스워드 파일에서 읽어 오는 ID 로그인 세션 동안에는 바뀌지 않음 유효(effective) 사용자/그룹 ID, 추가 그룹 ID 파일에 대한 접근 권한을 결정함 저장된 set-user-ID(saved SUID), 저장된 group-user-ID(saved SGID) exec( ) 함수 수행 시 저장된 유효 사용자/그룹 ID 일반적인 프로그램을 실행 유효 사용자/그룹 ID = 실제 사용자/그룹 ID set-user-ID(SUID), set-group-ID(SGID)비트가 설정된 파일을 실행 유효 사용자/그룹 ID = 실행 파일의 소유 사용자/그룹 ID

실습 2: 프로세스와 관련된 ID 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 #include<stdio.h> #include<unistd.h> int main(void) { printf("getuid:%d\n", getuid()); printf("geteuid:%d\n", geteuid()); printf("getgid:%d\n", getgid()); printf("getegid:%d\n", getegid()); return 0; }

fork 함수 기존 프로세스(부모 프로세스)가 새 프로세스(자식 프로세스)를 생성 한번 호출, 두번 반환 #include<unistd.h> pid_t fork(void); Returns : 0 in child, process ID of child in parent, -1 on error 기존 프로세스(부모 프로세스)가 새 프로세스(자식 프로세스)를 생성 한번 호출, 두번 반환 자식 프로세스는 부모 프로세스의 복사본 자식, 부모 프로세스 모두 fork호출 이후의 명령들을 계속 실행함 부모의 자료구역, 힙, 스택의 복사본을 갖음 COW(Copy-On-Write) 기법을 사용함 텍스트 구역은 공유함

실습 3: fork 함수(1/2) #include<stdio.h> #include<stdlib.h> #include<unistd.h> int glob = 6; char buf[] = "a write to stdout\n"; int main(int argc, char *argv[]) { int var; pid_t pid; var = 88; if(write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1){ fprintf(stderr, "write error\n"); exit(1); } printf("before fork\n"); //fflush(stdout); if((pid = fork()) < 0){ fprintf(stderr, "fork error\n"); }else if(pid == 0){ glob++; var++; }else{ sleep(2); printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var); exit(0);

실습 3: fork 함수(2/2) $ ./forkEx1 a write to stdout before fork pid = 18052, glob = 7, var = 89 pid = 18051, glob = 6, var = 88 $ $ ./ forkEx1 > temp.out $ cat temp.out pid = 18054, glob = 7, var = 89 pid = 18053, glob = 6, var = 88

fork 함수 : 파일 공유 부모의 열린 파일 서술자들이 모두 자식에게 복사됨 해당 파일 서술자에 대해 dup함수가 호출된 것과 같은 효과 모든 열린 파일 서술자에 대해 동일한 파일 테이블 항목을 공유 동일한 파일 오프셋을 공유함 부모 프로세스 테이블 항목 fd 0: fd 1: fd 2: fd 플래그들 파일 포인터 파일 상태 플래그들 현재 파일 오프셋 V노드 포인터 파일 테이블 v노드 정보 i노드 정보 현재 파일 크기 v노드 테이블 자식 프로세스 테이블 항목

실습 4: fork 함수(파일의 공유)(1/3) #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<fcntl.h> #include<string.h> #define PERM 0644 #define MAXBUF 256 char msg[MAXBUF]; int main(int argc, char *argv[]) { char *szFile = "data"; int fd; long offset; pid_t pid; if((fd = open(szFile, O_RDWR | O_CREAT, PERM)) == -1){ fprintf(stderr, "open error\n"); exit(1); } if((pid = fork()) < 0){ fprintf(stderr, "fork error\n");

실습 4: fork 함수(파일의 공유)(2/3) else if(pid == 0){ /* 자식 프로세스 */ printf("%d:I'm child\n", getpid()); sleep(2); sprintf(msg, "pid:%d write\n", getpid()); if(write(fd, msg, strlen(msg)) != strlen(msg)){ fprintf(stderr, "write error\n"); exit(1); } offset = lseek(fd, 0, SEEK_CUR); printf("%d:offset:%ld\n", getpid(), offset); }else{ /* 부모 프로세스 */ printf("%d:I'm parent\n", getpid()); close(fd); exit(0);

실습 4: fork 함수(파일의 공유)(3/3) $ ./forkEx2 2706:I'm parent 2706:offset:15 2707:I'm child $ 2707:offset:30 [Enter] $ $ cat data pid:2706 write pid:2707 write

fork 함수 fork 시스템 콜에 의해 자식에게 상속되는 속성 열린 파일들(파일 디스크립터 테이블) 열린 파일 서술자들에 대한 exec시 닫기(close-on-exec) 플래그 실제 사용자/그룹 ID, 유효 사용자/그룹 ID SUID플래그와 SGID플래그 현재 작업 디렉토리 파일 모드 생성 마스크 환경 목록 신호 마스크와 신호 처리 설정들 추가 그룹 ID들, 부착된 공유 메모리 영역들, 메모리 매핑 들 자원 한계들, 프로세스 그룹 ID, 세션 ID, 제어터미널, 루트 디렉토리

fork 함수 자식 프로세스와 부모 프로세스의 차이 fork 함수가 실패하는 경우 fork의 반환 값 프로세스의 ID, 부모 프로세스의 ID 부모가 잠근 파일 자물쇠들은 자식에게 상속되지 않음 아직 발동되지 않은 정보(alarm)들은 자식에서 모두 해제됨 자식의 유보 중인 신호 집합은 비워짐(빈 집합이 됨) fork 함수가 실패하는 경우 시스템에 너무 많은 프로세스들이 있을 때 사용자 ID당 프로세스의 최대 개수인 CHILD_MAX값을 넘었을 때

vfork 함수 프로세스 생성이후 즉시 exec를 실행하는 경우에 특화된 버전 부모의 프로세스공간을 자식에게 복사하지 않음 #include<unistd.h> pid_t vfork(void); Returns : 0 in child, process ID of child in parent, -1 on error 프로세스 생성이후 즉시 exec를 실행하는 경우에 특화된 버전 부모의 프로세스공간을 자식에게 복사하지 않음 vfork 이후 즉시 exec(또는 exit)가 호출할 테고, 따라서 부모의 주소공간을 참조하는 일은 없을 것을 가정하기 때문임 자식 프로세스와 부모 프로세스가 같은 주소공간에서 실행됨 자식 프로세스가 먼저 실행되는것을 보장함 자식이 exec나 exit를 호출하기 전까지 부모 프로세스의 실행은 유보됨

vfork 함수 #include<stdio.h> #include<stdlib.h> #include<unistd.h> int glob = 6; /* 초기화된 자료 구역에 있는 외부 변수 */ int main(void) { int var; /* 스택에 저장되는 자동 변수 */ pid_t pid; var = 88; printf("before vfork\n"); //fflush(stdout); if((pid = vfork()) < 0){ fprintf(stderr, "fork error\n"); exit(1); }else if(pid == 0){ /* 자식 프로세스 */ glob++; /* 변수들을 수정한다 */ var++; _exit(0); /* 자식이 종료됨 */ } /* 부모는 여기에서부터 실행을 재개한다 */ printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var); exit(0); $ ./vfork before vfork pid = 18077, glob = 7, var = 89 $

exit 함수들 프로세스가 종료되는 상황(8가지) 프로세스의 종료 정상적인 종료(5) 비정상적인 종료(3) main 의 반환(return) exit 호출 _exit 또는 _Exit 호출 마지막 스레드를 시작한 스레드 시동 루틴의 반환(return) 마지막 스레드의 pthread_exit 호출 비정상적인 종료(3) abort 호출(SIGABRT) signal 수신 마지막 스레드의 실행 취소 프로세스의 종료 프로세스가 어떻게 종료되든 결국에는 커널 안의 동일한 코드가 수행됨 열린 서술자들을 모두 닫음 프로세스가 사용한 메모리 해제 기타 마무리 작업

exit 함수들 종료 상태(exit status) 종지 상태(termination status) 정상적인 종료인 exit 함수들(exit, _exit, _Exit)의 호출 시 인자 값 종지 상태(termination status) 최종적으로 _exit가 호출될 때 커널이 프로세스의 종료상태를 종지상태로 변환 비정상적인 종료의 경우 커널이 종지상태를 결정함 프로세스가 종료되면 커널은 SIGCHLD 신호를 부모 프로세스에게 보냄 ※ SIGCHLD 신호에 대한 기본 동작은 '무시'

exit 함수들 고아 프로세스 좀비(zombie) 프로세스 자식보다 부모 프로세스가 먼저 종료 됐을 때 일반적으로 한 프로세스가 종료되면 커널은 모든 활성 프로세스를 훑으면서 종료된 프로세스의 자식 프로세스들이 남아 있는지 찾음, 만일 자식이 남아 있으면 그 자식 프로세스들의 부모 프로세스 ID를 1로 설정함 (init 프로세스) 반드시 하나의 부모 프로세스를 갖게 됨 좀비(zombie) 프로세스 자식 프로세스가 종료되면 종지상태 등 자식 프로세스가 종료된 상태를 확인하기 위한 일부분의 자료를 남겨둠 자식의 프로세스 ID, 프로세스의 종지 상태, 프로세스가 사용한 CPU 시간 등

실습 5: 고아 프로세스 #include<stdio.h> #include<unistd.h> #include<stdlib.h> int main(int argc, char *argv[]) { pid_t pid; if((pid = fork()) < 0){ fprintf(stderr, "fork error\n"); exit(1); }else if(pid == 0){ printf("I'am Child Porcess : %d\n", getpid()); sleep(2); printf("My parent process : %d\n", getppid()); }else{ printf("I'am Parent Porcess : %d\n", getpid()); } return 1; $ ./orphan I'am Parent Porcess : 2817 $ I'am Child Porcess : 2818 My parent process : 1 [Enter] $

실습 6: 좀비 프로세스(1/2) #include<stdio.h> #include<unistd.h> #include<stdlib.h> int main(int argc, char *argv[]) { pid_t pid; if((pid = fork()) < 0){ fprintf(stderr, "fork error\n"); exit(1); }else if(pid == 0){ printf("I'am Child Porcess : %d\n", getpid()); printf("Child Porcess end : %d\n", getpid()); }else{ printf("I'am Parent Porcess : %d\n", getpid()); sleep(10); } return 1;

실습 6: 좀비 프로세스(2/2) $ ./zombie & [1] 2877 $ I'am Parent Porcess : 2877 I'am Child Porcess : 2878 Child Porcess end : 2878 [Enter] $ ps PID TTY TIME CMD 2842 pts/1 00:00:00 bash 2877 pts/1 00:00:00 zombie 2878 pts/1 00:00:00 zombie <defunct> 2879 pts/1 00:00:00 ps $ [1]+ Exit 1 ./zombie $ ./zombie I'am Parent Porcess : 2880 I'am Child Porcess : 2881 Child Porcess end : 2881 $ $ ps u USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND pi 2615 0.0 1.0 6272 4704 pts/0 Ss 18:48 0:02 -bash pi 2850 0.2 0.9 5688 4028 pts/2 Ss 20:46 0:00 /bin/bash pi 2880 0.0 0.2 1548 932 pts/1 S+ 20:50 0:00 ./zombie pi 2881 0.0 0.0 0 0 pts/1 Z+ 20:50 0:00 [zombie] <defunct> pi 2882 0.0 0.4 4464 2116 pts/2 R+ 20:50 0:00 ps u $

wait 함수와 waitpid 함수 부모가 자식 프로세스의 종료를 기다리게 함 자식 프로세스의 종지 상태를 회수함 #include<sys/wait.h> pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc, int options); Both return : process ID if OK, 0(see later), or -1 on error 부모가 자식 프로세스의 종료를 기다리게 함 자식 프로세스의 종지 상태를 회수함 반환 값 : 종료된 프로세스의 ID 종지상태를 알 필요가 없을 경우 statloc인수 NULL

wait 함수와 waitpid 함수 wait함수와 waitpid함수 중 하나를 부모에서 호출할 때 호출이 반환되는 방식은 상황에 따라 다름 부모의 자식 프로세스들이 모두 아직 실행 중이면 호출이 반환되지 않음 (부모의 실행이 차단됨) 한 자식이 프로세스가 종료되어 해당 종지 상태의 회수를 기다리고 있는 상황이라면 호출이 즉시 반환됨 자식 프로세스가 하나도 없으면 즉시 오류가 반환됨 두 함수의 차이점 wait함수는 하나의 자식 프로세스가 종료될 때까지 차단되나 waitpid함수는 인자(WNOHANG)를 설정하면 차단을 방지할 수 있음 wait함수는 임의의 자식 프로세스를 기다리지만 waitpid함수는 특정한 자식 프로세스를 지정할 수 있음

wait 함수와 waitpid 함수 waitpid는 wait에 비해 좀더 유연한 기능을 갖음 pid 인자 값에 따른 기능 임의의 자식 프로세스를 기다림 프로세스 ID가 pid인 한 자식 프로세스를 기다림 프로세스 그룹 ID가 호출한 프로세스의 것과 동일한 임의의 자식 프로세스를 기다림 프로세스 그룹 ID가 pid의 절대값과 같은 임의의 자식 프로세스를 기다림

wait 함수와 waitpid 함수 종지 상태 (statloc 정수 포인터) 상태 값내에 저장되는 내용 종료상태(정상적인 종료의 경우) 신호의 번호(비정상적인 종료의 경우) 코어파일 생성여부 종지 상태를 확인하기 위한 매크로 정의 (POSIX.1) 헤더파일 <sys/wait.h> 네 게의 매크로 중 하나만 참(상호 배타적임) WIFEXITED(status) WIFSIGNALED(status) WIFSTOPPED(status) WIFCONTINUED(status)

wait 함수와 waitpid 함수 WIFEXITED(status) WIFSIGNALED(status) 자식 프로세스가 정상적으로 종료되었으면 참 WEXITSTATUS(status)를 이용해 자식의 종료 상태를 알아낼 수 있음 자식이 exit, _exit, _Exit로 넘겨준 인수의 하위 8비트 WIFSIGNALED(status) 자식 프로세스가 신호를 받았으나 그것을 처리하지 않아서 비정상적으로 종료되었으면 참 WTERMSIG(status)를 이용해서 종료를 유발한 신호의 번호를 알 수 있음 코어파일 생성여부 확인 매크로 WCOREDUMP(status) WIFSTOPPED(status) 자식 프로세스가 현재 중지 중이면 참 WSTOPSIG(status)를 이용해 중지를 유발한 신호의 번호를 알수 있음 WIFCONTINUED(status) 자식 프로세스가 작업 제어 중지 이후 실행이 재개되었으면 참

실습 7: 종지상태(1/2) #include <sys/wait.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> void pr_exit(int status) { if(WIFEXITED(status)) printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); else if(WIFSIGNALED(status)) printf("abnormal termination, signal number = %d%s\n", WTERMSIG(status), #ifdef WCOREDUMP WCOREDUMP(status) ? "(core file generated)" : ""); #else ""); #endif else if(WIFSTOPPED(status)) printf("child stopped, signal number = %d\n", WSTOPSIG(status)); else if(WIFCONTINUED(status)) printf("child continued\n"); }

실습 7: 종지상태(2/2) int main(void) { pid_t pid; int status; if((pid = fork()) < 0){ fprintf(stderr, "fork error\n"); exit(1); }else if(pid == 0) exit(7); //정상 종료 if(wait(&status) != pid){ fprintf(stderr,"wait error\n"); } pr_exit(status); abort(); //비정상 종료 fprintf(stderr, "wait error\n"); if((pid = fork()) < 0){ fprintf(stderr, "fork error\n"); exit(1); }else if(pid == 0) status /= 0; // 비정상 종료 if(wait(&status) != pid){ fprintf(stderr, "wait error\n"); } pr_exit(status); exit(0); $ ./termstatus normal termination, exit status = 7 abnormal termination, signal number = 6 abnormal termination, signal number = 8 $

실습 8: waitpid(1/2) #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<wait.h> int main(int argc, char *argv[]) { pid_t pid, ret_pid; int status; if((pid = fork()) < 0){ fprintf(stderr, "fork error\n"); exit(1); }else if(pid == 0){ printf("Child Porcess is started : %d\n", getpid()); sleep(5); printf("Child Porcess is finished : %d\n", getpid()); exit(7); } else{ printf("Parent Porcess is started : %d\n", getpid()); while((ret_pid = waitpid(-1, &status, WNOHANG)) == 0){ printf(" waitpid WNOHANG\n"); sleep(1); } printf(" waitpid return %d\n", ret_pid); printf(" child exit status:%d\n", WEXITSTATUS(status)); printf("Parent Porcess is finished : %d\n", getpid()); return 1;

실습 8: waitpid (2/2) $ ./waitpid Parent Porcess is started : 2937 waitpid WNOHANG Child Porcess is started : 2938 Child Porcess is finished : 2938 waitpid return 2938 child exit status:7 Parent Porcess is finished : 2937 $

exec류 함수들 새 프로그램을 시동 새 프로그램으로 완전히 대체되어 main함수에서 실행이 다시 시작됨 #include<unistd.h> int execl(const char *pathname, const char *arg0, … /* (char *)0 */ ); int execv(const char *pathname, const *const argv[]); int execle(const char *pathname, const char *arg0, … /* (char *)0 , char *const envp[] */ ); int execve(const char *pathname, char *const argv[], char *const envp[]); int execlp(const char *filename, const char *arg0, … /* (char *)0 */ ); int execvp(const char *filename, char *const argv[]); All six return : -1 on error, no return on success 새 프로그램을 시동 새 프로그램으로 완전히 대체되어 main함수에서 실행이 다시 시작됨 실행파일로부터 이미지(텍스트, 데이터, 힙, 스택구역)를 로딩하여 현재 프로세스를 새 이미지로 대체

exec류 함수들 exec를 호출한 프로세스의 새 프로그램으로 상속되는 특성들 프로세스ID와 부모 프로세스ID 현재 작업 디렉토리 파일 모드 생성 마스크 추가 그룹 ID 프로세스 그룹 ID 세션 ID 제어 터미널 경보(alarm) 발동까지 남은 시간 루트 디렉토리 파일 자물쇠 프로세스 신호 마스크 아직 처리되지 않은 신호들 자원의 한계들 tms_utime, tms_stime, tms_cutime, tms_cstime 값들

exec류 함수들 열린 파일들이 어떻게 처리되는 가는 각 서술자의 FD_CLOEXEC (exec 호출시 닫기 close_on_exec) 플래그에 따라 결정됨 새 프로그램 파일의 SUID, SGID 비트의 설정 여부에 따라 유효 사용자 ID와 유효 그룹 ID는 변할 수 있음 시스템 호출 execve, 나머지는 라이브러리 함수

실습 9: exec 함수(1/4) #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/wait.h> char *env_init[] = {"USER=unknown", "PATH=/tmp", NULL}; int main(void) { pid_t pid; if((pid = fork()) < 0){ fprintf(stderr, "fork error\n"); exit(1); } else if(pid == 0){ /* 경로이름 설정, 환경을 지정 */ if(execle("./echoall", "echoall", "myarg1", "ARG2", (char *)0, env_init) < 0){ fprintf(stderr, "execle error\n"); } if(waitpid(pid, NULL, 0) < 0){ fprintf(stderr, "wait error\n"); if((pid = fork()) < 0) { }else if(pid == 0){ if(execlp("./echoall", "echoall", "only 1 arg", (char *)0) < 0){ fprintf(stderr, "execlp error\n"); exit(0);

실습 9: exec 함수(2/4) // echoall 프로그램 #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]) { int i; char **ptr; extern char **environ; /* 명령줄 인수들을 모두 출력한다. */ for(i = 0 ; i < argc ; i++) printf("argv[%d]: %s\n", i, argv[i]); for(ptr = environ; *ptr != 0 ; ptr++) printf("%s\n", *ptr); exit(0); }

실습 9: exec 함수(3/4) $ ./exec argv[0]: echoall argv[1]: myarg1 argv[2]: ARG2 USER=unknown PATH=/tmp argv[1]: only 1 arg SHELL=/bin/bash TERM=screen SSH_CLIENT=192.168.1.8 55201 22 SSH_TTY=/dev/pts/0 USER=pi LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36: TERMCAP=SC|screen|VT 100/ANSI X3.64 virtual terminal:\ :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:bs:bt=\E[Z:\ :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:ct=\E[3g:\ :do=^J:nd=\E[C:pt:rc=\E8:rs=\Ec:sc=\E7:st=\EH:up=\EM:\ :le=^H:bl=^G:cr=^M:it#8:ho=\E[H:nw=\EE:ta=^I:is=\E)0:\ :li#60:co#120:am:xn:xv:LP:sr=\EM:al=\E[L:AL=\E[%dL:\ :cs=\E[%i%d;%dr:dl=\E[M:DL=\E[%dM:dc=\E[P:DC=\E[%dP:\ :im=\E[4h:ei=\E[4l:mi:IC=\E[%d@:ks=\E[?1h\E=:\ :ke=\E[?1l\E>:vi=\E[?25l:ve=\E[34h\E[?25h:vs=\E[34l:\ :ti=\E[?1049h:te=\E[?1049l:us=\E[4m:ue=\E[24m:so=\E[3m:\ :se=\E[23m:mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:ms:\ :Co#8:pa#64:AF=\E[3%dm:AB=\E[4%dm:op=\E[39;49m:AX:\

실습 9: exec 함수(4/4) :vb=\Eg:G0:as=\E(0:ae=\E(B:\ :ac=\140\140aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++,,hhII00:\ :po=\E[5i:pf=\E[4i:Km=\E[M:k0=\E[10~:k1=\EOP:k2=\EOQ:\ :k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:k7=\E[18~:\ :k8=\E[19~:k9=\E[20~:k;=\E[21~:F1=\E[23~:F2=\E[24~:\ :F3=\E[1;2P:F4=\E[1;2Q:F5=\E[1;2R:F6=\E[1;2S:\ :F7=\E[15;2~:F8=\E[17;2~:F9=\E[18;2~:FA=\E[19;2~:kb=:\ :K2=\EOE:kB=\E[Z:kF=\E[1;2B:kR=\E[1;2A:*4=\E[3;2~:\ :*7=\E[1;2F:#2=\E[1;2H:#3=\E[2;2~:#4=\E[1;2D:%c=\E[6;2~:\ :%e=\E[5;2~:%i=\E[1;2C:kh=\E[1~:@1=\E[1~:kH=\E[4~:\ :@7=\E[4~:kN=\E[6~:kP=\E[5~:kI=\E[2~:kD=\E[3~:ku=\EOA:\ :kd=\EOB:kr=\EOC:kl=\EOD:km: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games MAIL=/var/mail/pi STY=2841.pts-0.raspberrypi-robotcode77 PWD=/home/pi/12 LANG=en_GB.UTF-8 HOME=/home/pi SHLVL=2 LOGNAME=pi WINDOW=0 SSH_CONNECTION=192.168.1.8 55201 192.168.1.10 22 _=./exec $