System Programming Lab Week 4: Shell
Schedule for your own shell 1 st shell 기본기능 fork / exec Background Processing/ Sequential Execution ls, find, grep 2 nd Environment variables/ Shell variables built-in command cd, exit, set, unset, alias, unalias, umask
Schedule for your own shell 3 rd Signal Trap history 4 th pipe / redirection
Shell 쉘의시작 Text mode : 시스템에로그인하면쉘상태로진입 GUI mode : xterm 이나 hanterm 등의터미널실행으로쉘진입 쉘의역할 명령을해석하고실행 쉘의종류 bash, csh, ksh, sh, tcsh, zsh 리눅스배포본 = Kernel + Shell + Application
fork() 새로운프로세스생성 생성된프로세스 : 자식프로세스 (child process) fork() 를호출한프로세스 : 부모프로세스 (parent process) fork() 가이루어지는시점에서두프로세스가동시에작업수행 함수정의
fork() Example I #include <stdio.h> #include <string.h> #include <sys/types.h> #define MAX_COUNT 200 #define BUF_SIZE 100 int main(void){ pid_t pid; int i; char buf[buf_size]; fork(); pid = getpid(); for (i = 1; i <= MAX_COUNT; i++) { sprintf(buf, "This line is from pid %d, value = %d\n", pid, i); write(1, buf, strlen(buf)); }return; }
fork() Example I
fork() Example II #include <stdio.h> #include <sys/types.h> #define MAX_COUNT 200 void ChildProcess(void); /* child process prototype */ void ParentProcess(void); /* parent process prototype */ int main(void) { pid_t pid; } pid = fork(); if (pid == 0) ChildProcess(); else ParentProcess(); return;
fork() Example II void ChildProcess(void) { int i; } for (i = 1; i <= MAX_COUNT; i++){ printf("this line is from child, value = %d\n", i); sleep(1); printf(" *** Child process is done ***\n"); void ParentProcess(void){ int i; check the process tree using pstree command running this example } for (i = 1; i <= MAX_COUNT; i++){ printf("this line is from parent, value = %d\n", i); sleep(1); } printf("*** Parent is done ***\n");
fork() Example II
fork() Example II
fork() Example II
exec() family 실행파일을수행 exec 계열의함수가사용된뒤의코드는메모리에서삭제 exec 함수에인자로들어간실행파일의코드가메모리에올라감 fork() 를항상수반 exec 수행후다른코드는의미가없어짐 fork() 를이용해 child process 가 exec 를수행 exec 뒤의코드는 parent process 가수행
exec() family exec family execl : 실행파일수행 execle : 실행파일에환경변수를인자로넘겨줌 execlp : 현재디렉토리의실행파일수행 execv : 인자를배열에저장해서실행파일수행 execve : 환경변수를인자로넘겨줌. 인자는배열에저장 execvp : 현재디렉토리의실행파일수행, 인자는배열에저장 section 8.10 exec functions 실제 exec 함수군의 prototype 정의 ( 다른 PPT 에나와있음 )
exec() family Int execl(const char *pathname, const char *arg0, /* (char *)0 */); 실행파일수행 Int execle(const char *pathname, const char *arg0, /* (char *)0, char *const envp[] */); 실행파일에환경변수를인자로넘겨줌 Int execlp(const char *pathname, const char *arg0,, /* (char *)0 */); 현재디렉토리의실행파일수행 Int execv(const char *pathname, *const argv[]); 인자를배열에저장해서실행파일수행 execve(const char *pathname, *const argv[], /* (char *)0, char *const envp[] */); 환경변수를인자로넘겨줌. 인자는배열에저장 execvp(const char *pathname, *const argc[]); 현재디렉토리의실행파일수행, 인자는배열에저장
exec() Example I #include <unistd.h> Int main(void){ puts( exec before\n ); execl( /bin/ls, ls, -l, NULL); puts( exec after..blahblah ); return; }
exec() Example II #include <unistd.h> Int main(void){ if(fork()==0){ execl( /bin/ls, ls, -l, NULL); } else{ wait(null); puts( Child Finished\n ); } }
Basic functions of Shell 명령어를받아서이를자식프로세스에서생성 예 ) 두번째주강의자료 fork & exec example
Background Processing background / foreground 명령끝에 & 문자를넣어실행 e.g) gcc shell.c & 작업번호와프로세스 ID 를출력하고 background 로돌아가고, 쉘프롬프트출력. 작업번호는 background 명령에순서대로부여. 사용자입력이필요한명령은 background 로보낼수없음 jobs 명령을이용하여 background process 를확인할수있음. fg/bg 명령을사용하여 background/foreground 상태에서실행가능. kill 명령으로 background 작업멈춤
- 20 - setpgid() #include <unistd.h> int setpgid(pid_t pid, pid_t pgid); 프로세스는 setpgid 함수를이용하여프로세스의그룹을바꿀수있음. pid 번호를가진프로세스의그룹 ID 를 pgid 그룹으로변경 pid 가 0 이면호출하는프로세스 ID 를사용 pgid 가 0 이면 pid 에해당하는프로세스가그룹리더 리턴값 : 0 success 1 fail
Five-State Process Model Dispatch New Admit Ready TimeOut Running Release Exit Event Occurs Event Wait Blocked New A process that has just been created but has not yet been admitted to the pool of executable processes by the operating system. Typically, a new process has not yet been loaded into main memory, although its process control block has been created
Five-State Process Model Dispatch New Admit Ready TimeOut Running Release Exit Event Occurs Event Wait Blocked Ready A process that is prepared to execute when given the opportunity
Five-State Process Model Dispatch New Admit Ready TimeOut Running Release Exit Event Occurs Event Wait Blocked Running The Process that is currently being executed. For this chapter, we will assume a computer with a single processor, so at most one process at a time can be in this state
Five-State Process Model Dispatch New Admit Ready TimeOut Running Release Exit Event Occurs Event Wait Blocked Blocked A process that is cannot execute until some event occurs, such as the completion of an I/O operation
Five-State Process Model Dispatch New Admit Ready TimeOut Running Release Exit Event Occurs Event Wait Blocked Exit A process that has been released from the pool of executable processes by the O/S, eithe because it halted or because it aborted for some reason
Scheduling First-Come-First-Served Non-preemptive Ai Bi Ci Di Ei A B C D E
Scheduling A Round Robin Preemptive B C D E Ai Bi Ci Di Ei A 3 B 6 C 2 D 1 E 5
Interrupt Interrupt A mechanism that peripheral devices inform an asynchronous event to Linux Due to some sort of event that is external to and independent of the currently running process Ex) Completion of I/O operation
Exception Exception Inform an synchronous software event to Linux Divided by zero Invalid machine code Overflow Page fault Segmentation fault Protection fault
Trap Trap Relates to an error or exception condition generated within the currently running process Ex) illegal file access attempt IDT ( Interrupt Description Table ) Common trap handler for 80*86 divide_error() debug() nmi(). segment_not_present(). page_fault (). 0x0 Device interrupt handler Timer_interrupt Hd_interrupt. 0x20 System_call vector System_call() 0x80
Signal handling 시그널 (signal) 의개념 시그널 소프트웨어인터럽트 (interrupt) 프로세스들사이에서비동기적사건의발생을젂달 시그널이름 서로다른사건을구별하기위하여여려종류의시그널을제공 모든시그널은 SIG 로시작하는이름을갖는다 시그널에대한작업 시그널의발생, 젂달, 처리
signal handling 시그널의종류 <sys/signal.h> 에정의 e.g) #define SIGHUP 1 #define SIGINT 2
signal handling 시그널의발생 (generation) 터미널에서특수키를누르는경우 하드웨어의오류 0 으로나눆경우, 잘못된메모리를참조하는경우등 kill 함수의호출 특정프로세스나프로세스그룹에서원하는시그널을발생 / 젂달한다 대상프로세스에대한권한이있어야한다. kill 명령의실행 내부적으로 kill 함수를호출한다 소프트웨어적조건 네트워크에서의데이터오류 (SIGURG), 파이프작업에서의오류 (SIGPIPE), 알람의종료 (SIGALRM) 등
signal handling 시그널의젂달 (delivery) 발생된시그널이수싞되어정해진방법대로처리되는것 지연 (pending) : 발생된시그널이젂달되지못한상태 시그널의블록 (block) 블록이해제되거나무시하도록변경될때까지지연된상태로남는다. 시그널마스크 (signal mask) : 블록될시그널집합
signal handling 시그널의처리 (disposition, action) 시그널을무시한다 (ignore) SIGKILL 과 SIGSTOP 시그널을제외한모든시그널을무시할수있다. 하드웨어오류에의해발생한시그널에대해서는주의해야한다. 시그널을처리한다 (catch) 시그널이발생하면미리등록된함수 (handler) 가수행된다 SIGKILL 과 SIGSTOP 시그널에는처리할함수를등록할수없다. 기본처리방법에따른다. (default) 특별한처리방법을선택하지않은경우 대부분시그널의기본처리방법은프로세스를종료시키는것이다.
signal handling 시그널처리방법의선택 typedef void(*sighandler_t)(int signo); sighandler_t signal(int signum, sighandler_t handler); 지정한시그널에대한세가지처리방법중하나를선택한다. signo 인자 : 시그널번호
signal handling handler 인자 SIG_IGN : 지정한시그널을무시한다. SIG_DFL : 기본처리방법에따라처리한다. 사용자정의함수 (signal handler) : 시그널이발생하면호출될함수의주소 리턴값 : 지정한시그널에대한이젂까지의처리방법
Signal handling When you press. Ctrl + z SIGSTOP is sent to the process. 프로세스는 blocked 상태에머물게됨. Ctrl + c SIGINT is sent to the process. 프로세스는 Terminate
Signal handling Example #include errhdr.h static void sig_usr(int); int main(void) { if(signal(sigusr1,sig_usr)==sig_err) err_sys( can t catch SIGUSR1 ); if(signal(sigusr2,sig_usr)==sig_err) err_sys( can t catch SIGUSR2 ); for(;;) pause(); } static void sig_usr(int signo) { if(signo==sigusr1) printf( received SIGUSR1\n ); else if(signo==sigusr2) printf( received SIGUSR2\n ); else err_dump( received signal %d\n,signo); }
순차실행 입력된명령어를순차적으로실행 입력서식 command1; command2; command3 e.g)mkdir test ; pwd ; ls -l
Assignment #3 Requirements shell 실행으로쉘시작 커맨드프롬프트는 사용자이름 @ 현재위치 $ ex)root@splab $ 제작한 ls, find, grep 수행가능 Shell에서 exec으로수행하도록 하나의프로젝트로묶어서사용하도록 background 수행가능 순차실행가능 Ctrl+C(SIGINT) 시그널처리 프로그램종료되지않음 커맨드실행주에는 SIGINT 가능하게처리
Makefile Tips 프로젝트디렉토리구조 Makefile 에서다른디렉토리의 Makefile 호출 kwsh/makefile 의경우 make C kwls 를사용하면해당디렉토리의 makefile 을호출
Makefile Tips Makefile