Project2_small shell 개선
- 프로젝트 목적
- ‘&’ (background process) 문제점 해결
- Background process가 종료되면 signal을 받아 정상 종료가 완료되도록 처리
- SIGINT 처리
- Foreground process 종료
- Background process 들 계속 수행
- smallsh 종료되지 않고 prompt 다시 표시
- “|” (pipe) 처리
- command1 | commannd2 → command1의 STDOUT이 command2의 STDIN이 되도록 두 프로세스 연결
- echo 명령어를 통한 환경변수 출력
- $! : 가장 마지막에 실행된 background process pid
- $? :가장 마지막에 종료된 foreground process 의 return value
- $$ : PID of the current shell
- Background process가 종료되면 signal을 받아 정상 종료가 완료되도록 처리

main.c
#include "smallsh.h"
#include <setjmp.h>
//char *prompt = "Command> ";
char pdir[200];
extern sigjmp_buf position;
int main() {
sigsetjmp(position, 1);
struct sigaction sint;
sigemptyset(&sint.sa_mask);
sint.sa_handler = SIG_IGN;
sigaction(SIGINT, &sint, NULL);
getcwd(pdir,200);
while(userin(pdir) != EOF){
// printf("pdir: %s\\n", pdir);
procline();
getcwd(pdir,200);
}
return 0;
}
- sigsetjmp(position,1); 을 통해 sigchild_handler가 동작할 때 점프할 위치를 저장한다.
smallsh.c
void sigchild_handler(int a ){
int status;
pid_t pid = waitpid(-1, &status, WNOHANG);
if(pid > 0)
snprintf(bg_pid,10, "%d", pid);
siglongjmp(position, 1);
}
/..../
int runcommand(char **cline, int where) {
/..../
if (where == BACKGROUND) {
struct sigaction sigchild;
sigemptyset(&sigchild.sa_mask);
sigchild.sa_handler = sigchild_handler;
sigaction(SIGCHLD, &sigchild,NULL);
printf("[Process id] %d\\n", pid);
return 0;
}
if (waitpid(pid, &status, 0) == -1)
return -1;
else {
int temp = WEXITSTATUS(status);
//printf("WEXITSTATUS: %d\\n", temp);
snprintf(fg_status, 10,"%d", temp);
return status;
}
}
- background 프로세스에 자식 프로세스가 종료되면 해당 프로세스를 reap하는 SIGCHLD 핸들러를 등록해준다.
- 자식 프로세스가 종료되면 부모 프로세스에 알림이 간다.
- siglongjmp(position, 1);을 통해 프로그램이 종료되지 않고 main함수가 다시 수행되도록 한다.
- SIGINT 처리

main.c
#include "smallsh.h"
#include <setjmp.h>
//char *prompt = "Command> ";
char pdir[200];
extern sigjmp_buf position;
int main() {
sigsetjmp(position, 1);
struct sigaction sint;
sigemptyset(&sint.sa_mask);
sint.sa_handler = SIG_IGN;
sigaction(SIGINT, &sint, NULL);
getcwd(pdir,200);
while(userin(pdir) != EOF){
// printf("pdir: %s\\n", pdir);
procline();
getcwd(pdir,200);
}
return 0;
}
- SIGINT로 프로세스들을 종료 시킬 때 smallsh 프로세스도 종료되지 않도록 SIGINT를 무시하도록 SIG_IGN를 등록한다.