-
[Develop] Unix Shell 기능 구현Mhwan's Develope/C Languge 2020. 1. 2. 23:57
##기능
- Unix Shell의 각종 기능을 구현
- 순차실행, 후면(background)실행, 입력 재지정, 출력재지정, 입출력 동시 재지정(redirection), 파이프 (pipe)
##간단 설명 및 알고리즘
- 먼저 입력한 명령어를 적절히 파싱
- 일반 실행 : argv에 파싱된 명령어를 넣고 일반적인 실행일 경우 자식프로세스가 execvp를 실행시키는 동안 부모 프로세스는 자식이 끝날때까지 기다림(wait)
12345678910111213141516void executesLine(int isbg, char *argv[]){int status, pid;if ((pid=fork()) == -1)perror("fork failed");else if (pid != 0) {if(isbg==0)pid = wait(&status);else {printf("[1] %d\n", getpid());waitpid(pid, &status, WNOHANG);}} else {execvp(argv[0], argv);}}cs - 후면실행 : 자식이 끝날때까지 부모가 기다리지 않고 종료함, (waitpid 함수의 WNOHANG명령어를 사용)
- 순차실행은 이들을 반복문으로 연속적으로 실행될 수 있게 구현
- 리다이렉션 : dup2함수를 이용, 입력재지정일 경우 dup2(fd, 0)으로, 출력재지정일 경우 dup2(fd, 1)로, 입출력 동시 재지정일 경우 입력 재지정과 출력재지정 dup2를 모두 이어서 실행시켜주고 execvp함수를 통해 명령어를 실행시키면 됨
1234567891011121314151617181920212223242526272829303132333435363738394041void doRedirection(int flag, int is_bg, char *argv[], char* input, char * output){int input_fd, output_fd;int status, pid;if ((pid=fork()) == -1)perror("fork failed");else if (pid != 0) {if(is_bg==0)pid = wait(&status);else {printf("[1] %d\n", getpid());waitpid(pid, &status, WNOHANG);}} else {if (flag == 2) {if((input_fd = open(input, O_RDONLY))==-1){perror(argv[0]);exit(2);}dup2(input_fd, 0);close(input_fd);execvp(argv[0], argv);} else if (flag == 3) {output_fd = open(output, O_CREAT|O_TRUNC|O_WRONLY, 0600);dup2(output_fd, 1);close(output_fd);execvp(argv[0], argv);} else {if (input != NULL && output != NULL) {input_fd = open(input, O_RDONLY);dup2(input_fd, 0);close(input_fd);output_fd = open(output, O_CREAT|O_TRUNC|O_WRONLY, 0600);dup2(output_fd, 1);close(output_fd);execvp(argv[0], argv);}}}}cs - 파이프 : 파이프 수행을 위해 pipe함수에 입출력 모두의 파일 디스크립터인 fd[2]를 넣어서 각 모드를 실행하고, fork를 두번 실행하여 프로세서로 데이터를 전달하도록 구현
12345678910111213141516171819202122232425262728293031323334void doPipe(char* arg1[], char* arg2[]){int fd[2];if(pipe(fd) == -1) {perror("Pipe failed");exit(1);}if(fork() == 0){close(STDOUT_FILENO);dup2(fd[1], 1);close(fd[0]);close(fd[1]);execvp(arg1[0], arg1);perror("parent execvp failed");exit(1);}if(fork() == 0) {close(STDIN_FILENO);dup2(fd[0], 0);close(fd[1]);close(fd[0]);execvp(arg2[0], arg2);perror("child execvp failed");exit(1);}close(fd[0]);close(fd[1]);wait(0);wait(0);}cs ## 링크
Github : https://github.com/mhwan/Myshell
'Mhwan's Develope > C Languge' 카테고리의 다른 글
[Develop] Unix내 파일 및 디렉토리 내의 모든 크기 알아오기 (0) 2020.01.02