lab05-3

Run Settings
LanguageC
Language Version
Run Command
#include <errno.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <fcntl.h> #define MAX_INPUT_SIZE 4096 #define MAX_TOKEN_SIZE 64 #define MAX_NUM_TOKENS 64 #define TOKEN_CNT 64 typedef enum {false, true} bool; // 문자열을 공백 단위로 tokenizing해 char *배열로 return하는 함수 // same as parse_line func. char **tokenize(char *line_p) { char **tokens = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *)); char *now_token = (char *)malloc(MAX_TOKEN_SIZE * sizeof(char)); int token_idx = 0; // tokens에서의 idx (현재 몇번째 token인가) int char_idx = 0; // tokens[token_idx]에서의 idx for (int i =0; i < strlen(line_p); i++) { // line 순회 char ch = line_p[i]; if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\0') { // 공백문자일 경우 tokenize if (char_idx != 0) { now_token[char_idx] = '\0'; // 현재 token 마지막 null문자 추가 tokens[token_idx] = (char*)malloc(MAX_TOKEN_SIZE*sizeof(char)); // 다음 token 동적 할당 if (!strcmp("pps", now_token) || !strcmp("ttop", now_token)) { // 상대 경로로 변경 strcpy(tokens[token_idx], "./"); strcat(tokens[token_idx++], now_token); // 현재 tokens[token_idx]에 복사 } else { strcpy(tokens[token_idx++], now_token); // 현재 tokens[token_idx]에 복사 } char_idx = 0; } } else { now_token[char_idx++] = ch; } } free(now_token); tokens[token_idx] = NULL; return tokens; } // 파이프 처리하는 함수 void do_pipe(char **tokens, int pipe_idx[TOKEN_CNT], int pipe_cnt) { int pipes[TOKEN_CNT][2] = {0, }; // 파이프 목록 int pid; int status; /***** 1번째 명령어 실행 *****/ pipe(pipes[0]); // 파이프 생성 if ((pid = fork()) < 0) { fprintf(stderr, "fork() error\n"); exit(1); } else if (pid == 0) { close(STDOUT_FILENO); // stdout close dup2(pipes[0][1], STDOUT_FILENO); // 0번째 pipe stdout에 복사 close(pipes[0][1]); // pipe close execvp(tokens[pipe_idx[0]], &tokens[pipe_idx[0]]); // exec fprintf(stderr, "execvp() error\n"); } close(pipes[0][1]); // pipe close wait(&status); // exec 종료까지 대기 if (WIFSIGNALED(status) || WIFSTOPPED(status)) { exit(1); } /***** 마지막 명령어 제외 모두 실행 *****/ for (int i = 0; i < pipe_cnt - 1; i++) { pipe(pipes[i+1]); // 파이프 생성 if ((pid = fork()) < 0) { fprintf(stderr, "fork() error\n"); exit(1); } else if (pid == 0) { close(STDIN_FILENO); // stdin close close(STDOUT_FILENO); // stdout close dup2(pipes[i][0], STDIN_FILENO); // pipe stdin에 복사 dup2(pipes[i+1][1], STDOUT_FILENO); // pipe stdout에 복사 close(pipes[i][0]); // pipe close close(pipes[i+1][1]); // pipe close execvp(tokens[pipe_idx[i+1]], &tokens[pipe_idx[i+1]]); // exec fprintf(stderr, "execvp() error\n"); } close(pipes[i+1][1]); // pipe close wait(&status); // exec 종료까지 대기 if (WIFSIGNALED(status) || WIFSTOPPED(status)) exit(1); } /***** 마지막 명령어 실행 *****/ if ((pid = fork()) < 0) { fprintf(stderr, "fork() error\n"); exit(1); } else if (pid == 0) { close(STDIN_FILENO); // stdin close dup2(pipes[pipe_cnt-1][0], STDIN_FILENO); // pipe stdin에 복사 close(pipes[pipe_cnt-1][0]); // pipe close close(pipes[pipe_cnt-1][1]); // pipe close execvp(tokens[pipe_idx[pipe_cnt]], &tokens[pipe_idx[pipe_cnt]]); // exec } wait(&status); // exec 종료까지 대기 if (WIFSIGNALED(status) || WIFSTOPPED(status)) { exit(1); } return; } // 명령어 exec하는 함수 void run_commands(char **tokens) { bool has_pipe = false; int pipe_cnt = 0; int start_idx = 0; int len = 0; int pipe_idx[TOKEN_CNT] = {0, }; for (int i = 0; tokens[i] != NULL; i++, len++) { // 파이프 있을 경우 token NULL로 변경 if (!strcmp(tokens[i], "|")) { tokens[i] = NULL; pipe_idx[++pipe_cnt] = i+1; // pipdIdx에 pipe로 구분되는 token들 시작 index 저장 has_pipe = true; } } if (has_pipe) { do_pipe(tokens, pipe_idx, pipe_cnt); } else { // 파이프 없을 경우 if (execvp(tokens[0], tokens) < 0) { if (errno == 2) { fprintf(stderr, "%s: command not found\n", tokens[0]); exit(1); } else { fprintf(stderr, "execvp error! errno: %d\n", errno); exit(1); } } int status; wait(&status); if (WIFSIGNALED(status) || WIFSTOPPED(status)) { exit(1); } } exit(0); } void *getCurrentDir(void){ char *currWorkDir, *token; char buffer[MAX_INPUT_SIZE + 1]; char *directory; size_t length; currWorkDir = getcwd(buffer, MAX_INPUT_SIZE + 1 ); token = strrchr(currWorkDir, '/'); if( currWorkDir == NULL ){ printf("Error"); /* You decide here */ exit(1); } if (token == NULL) { printf("Error"); /* You decide here */ exit(1); } length = strlen(token); directory = malloc(length); memcpy(directory, token+1, length); return directory; } //This is the main function of the program. int main(int argc, char* argv[]) { char line_p[MAX_INPUT_SIZE]; char **tokens; int i; FILE* fp; char *dir = getCurrentDir(); if (argc == 2) { // batch mode인 경우 if ((access(argv[1], F_OK)) < 0) { fprintf(stderr, "File doesn't exists.\n"); return -1; } if ((fp = fopen(argv[1],"r")) < 0) { fprintf(stderr, "fopen error for %s\n", argv[1]); return -1; } } while (1) { // 무한 반복 /* 입력 시작 */ bzero(line_p, sizeof(line_p)); if (argc == 2) { // batch mode인 경우 if (fgets(line_p, sizeof(line_p), fp) == NULL) { // file 모두 읽었을 경우 break; } line_p[strlen(line_p) - 1] = '\0'; } else { // interactive mode인 경우 printf("gosh@%s> ", dir); scanf("%[^\n]", line_p); getchar(); free(dir); } /* 입력 완료 */ line_p[strlen(line_p)] = '\n'; // 개행 문자 추가 tokens = tokenize(line_p); // tokenizing if (!tokens[0]) { // 입력 x 처리 continue; } int pid; if ((pid = fork()) < 0) { // 자식 process 생성 fprintf(stderr, "vfork error!\n"); exit(1); } else if (pid == 0) { // 자식 프로세스인 경우 run_commands(tokens); } else { // 본 프로세스인 경우 int status; waitpid(pid, &status, 0); if (WIFSIGNALED(status) || WIFSTOPPED(status) || WEXITSTATUS(status) == 1) { // 에러 발생 처리 fprintf(stderr, "SSUShell : Incorrect command\n"); } for (i=0;tokens[i]!=NULL;i++) { // 동적 할당 해제 free(tokens[i]); } free(tokens); } } return 0; }
#include <errno.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <fcntl.h> #define MAX_INPUT_SIZE 1024 #define MAX_TOKEN_SIZE 64 #define MAX_NUM_TOKENS 64 #define TOKEN_CNT 64 #include "else.h" typedef enum {false, true} bool; // 문자열을 공백 단위로 tokenizing해 char *배열로 return하는 함수 char **tokenize(char *line_p) { char **tokens = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *)); char *now_token = (char *)malloc(MAX_TOKEN_SIZE * sizeof(char)); int token_idx = 0; // tokens에서의 idx (현재 몇번째 token인가) int char_idx = 0; // tokens[token_idx]에서의 idx for (int i =0; i < strlen(line_p); i++) { // line 순회 char ch = line_p[i]; if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\0') { // 공백문자일 경우 tokenize if (char_idx != 0) { now_token[char_idx] = '\0'; // 현재 token 마지막 null문자 추가 tokens[token_idx] = (char*)malloc(MAX_TOKEN_SIZE*sizeof(char)); // 다음 token 동적 할당 if (!strcmp("pps", now_token) || !strcmp("ttop", now_token)) { // 상대 경로로 변경 strcpy(tokens[token_idx], "./"); strcat(tokens[token_idx++], now_token); // 현재 tokens[token_idx]에 복사 } else { strcpy(tokens[token_idx++], now_token); // 현재 tokens[token_idx]에 복사 } char_idx = 0; } } else { now_token[char_idx++] = ch; } } free(now_token); tokens[token_idx] = NULL; return tokens; } // 파이프 처리하는 함수 void do_pipe(char **tokens, int pipe_idx[TOKEN_CNT], int pipe_cnt) { int pipes[TOKEN_CNT][2] = {0, }; // 파이프 목록 int pid; int status; /***** 1번째 명령어 실행 *****/ pipe(pipes[0]); // 파이프 생성 if ((pid = fork()) < 0) { fprintf(stderr, "fork() error\n"); exit(1); } else if (pid == 0) { close(STDOUT_FILENO); // stdout close dup2(pipes[0][1], STDOUT_FILENO); // 0번째 pipe stdout에 복사 close(pipes[0][1]); // pipe close execvp(tokens[pipe_idx[0]], &tokens[pipe_idx[0]]); // exec fprintf(stderr, "execvp() error\n"); } close(pipes[0][1]); // pipe close wait(&status); // exec 종료까지 대기 if (WIFSIGNALED(status) || WIFSTOPPED(status)) { exit(1); } /***** 마지막 명령어 제외 모두 실행 *****/ for (int i = 0; i < pipe_cnt - 1; i++) { pipe(pipes[i+1]); // 파이프 생성 if ((pid = fork()) < 0) { fprintf(stderr, "fork() error\n"); exit(1); } else if (pid == 0) { close(STDIN_FILENO); // stdin close close(STDOUT_FILENO); // stdout close dup2(pipes[i][0], STDIN_FILENO); // pipe stdin에 복사 dup2(pipes[i+1][1], STDOUT_FILENO); // pipe stdout에 복사 close(pipes[i][0]); // pipe close close(pipes[i+1][1]); // pipe close execvp(tokens[pipe_idx[i+1]], &tokens[pipe_idx[i+1]]); // exec fprintf(stderr, "execvp() error\n"); } close(pipes[i+1][1]); // pipe close wait(&status); // exec 종료까지 대기 if (WIFSIGNALED(status) || WIFSTOPPED(status)) exit(1); } /***** 마지막 명령어 실행 *****/ if ((pid = fork()) < 0) { fprintf(stderr, "fork() error\n"); exit(1); } else if (pid == 0) { close(STDIN_FILENO); // stdin close dup2(pipes[pipe_cnt-1][0], STDIN_FILENO); // pipe stdin에 복사 close(pipes[pipe_cnt-1][0]); // pipe close close(pipes[pipe_cnt-1][1]); // pipe close execvp(tokens[pipe_idx[pipe_cnt]], &tokens[pipe_idx[pipe_cnt]]); // exec } wait(&status); // exec 종료까지 대기 if (WIFSIGNALED(status) || WIFSTOPPED(status)) { exit(1); } return; } // 명령어 exec하는 함수 void run_commands(char **tokens) { bool has_pipe = false; int pipe_cnt = 0; int start_idx = 0; int len = 0; int pipe_idx[TOKEN_CNT] = {0, }; for (int i = 0; tokens[i] != NULL; i++, len++) { // 파이프 있을 경우 token NULL로 변경 if (!strcmp(tokens[i], "|")) { tokens[i] = NULL; pipe_idx[++pipe_cnt] = i+1; // pipdIdx에 pipe로 구분되는 token들 시작 index 저장 has_pipe = true; } } if (has_pipe) { do_pipe(tokens, pipe_idx, pipe_cnt); } else { // 파이프 없을 경우 if (execvp(tokens[0], tokens) < 0) { if (errno == 2) { fprintf(stderr, "%s: command not found\n", tokens[0]); exit(1); } else { fprintf(stderr, "execvp error! errno: %d\n", errno); exit(1); } } int status; wait(&status); if (WIFSIGNALED(status) || WIFSTOPPED(status)) { exit(1); } } exit(0); } int main(int argc, char* argv[]) { char *line; char **args; int status; char line_p[MAX_INPUT_SIZE]; char **tokens; int i; FILE* fp; if (argc == 2) { // batch mode인 경우 if ((access(argv[1], F_OK)) < 0) { fprintf(stderr, "File doesn't exists.\n"); return -1; } if ((fp = fopen(argv[1],"r")) < 0) { fprintf(stderr, "fopen error for %s\n", argv[1]); return -1; } } while (1) { // 무한 반복 /* 입력 시작 */ bzero(line_p, sizeof(line_p)); if (argc == 2) { // batch mode인 경우 if (fgets(line_p, sizeof(line_p), fp) == NULL) { // file 모두 읽었을 경우 break; } line_p[strlen(line_p) - 1] = '\0'; } else { // interactive mode인 경우 char *dir = getCurrentDir(); printf("gosh@%s> ", dir); scanf("%[^\n]", line_p); getchar(); } /* 입력 완료 */ line_p[strlen(line_p)] = '\n'; // 개행 문자 추가 tokens = tokenize(line_p); // tokenizing if (!tokens[0]) { // 입력 x 처리 continue; } int pid; if ((pid = fork()) < 0) { // 자식 process 생성 fprintf(stderr, "vfork error!\n"); exit(1); } else if (pid == 0) { // 자식 프로세스인 경우 run_commands(tokens); } else { // 본 프로세스인 경우 int status; waitpid(pid, &status, 0); if (WIFSIGNALED(status) || WIFSTOPPED(status) || WEXITSTATUS(status) == 1) { // 에러 발생 처리 fprintf(stderr, "SSUShell : Incorrect command\n"); } for (i=0;tokens[i]!=NULL;i++) { // 동적 할당 해제 free(tokens[i]); } free(tokens); } line = read_line(); args = parse_line(line); status = dispatch_command(args); free(line); free(args); } return 0; }
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> #include <sys/types.h> #define PATH_MAX 4096 #include "else.h" void error(const char *msg) { perror(msg); exit(EXIT_FAILURE); } void cisshPipe(char **command1, char **command2) { int fd[2]; pid_t childPid; if (pipe(fd) != 0) error("failed to create pipe"); if ((childPid = fork()) == -1) error("failed to fork"); if (childPid == 0) { dup2(fd[1], 1); close(fd[0]); close(fd[1]); execvp(command1[0], command1); error("failed to exec command 1"); } else { dup2(fd[0], 0); close(fd[0]); close(fd[1]); execvp(command2[0], command2); error("failed to exec command 2"); } } //reading the user input. char *read_line(){ char *line = NULL; ssize_t bufsize = 0; getline(&line, &bufsize, stdin); return line; } //parsing the user input. char **parse_line(char *line){ int bufsize = 64, position = 0; char **tokens = malloc(bufsize * sizeof(char*)); char *token; token = strtok(line, " \t\r\n\a"); while (token != NULL) { tokens[position] = token; position++; if (position >= bufsize) { bufsize += 64; tokens = realloc(tokens, bufsize * sizeof(char*)); } token = strtok(NULL, " \t\r\n\a"); } tokens[position] = NULL; return tokens; } //This function is responsible for executing commands. int execute_line(char **args){ int status; pid_t pid; pid = fork(); if (pid == 0) { if (execvp(args[0], args) == -1) { perror("go/sh"); } exit(EXIT_FAILURE); } else if (pid < 0) { perror("go/sh"); } else { do { waitpid(pid, &status, WUNTRACED); } while (!WIFEXITED(status) && !WIFSIGNALED(status)); } return 1; } //This function is responsible for changing the directory. int cd(char **args){ if (args[1] == NULL) { fprintf(stderr, "go/sh: expected argument to \"cd\"\n"); } else { if (chdir(args[1]) != 0) { perror("go/sh"); } } return 1; } //This function is responsible for displaying help information. int help(char **args){ printf("go/sh - Simple UNIX Shell\n\n"); printf("The following are built-in commands supported by go/sh\n"); printf("cd\t\tChange the working directory\n"); printf("help\t\tDisplay this help information\n"); printf("exit\t\tExit go/sh\n"); return 1; } //This function is responsible for exiting go/sh. int go_sh_exit(char **args){ return 0; } //This function is responsible for dispatching the commands. int dispatch_command(char **args){ char *builtin_str[] = { "cd", "help", "exit" "sort" "error" }; int (*builtin_func[]) (char **) = { &cd, &help, &go_sh_exit, cisshPipe, error }; int i; if (args[0] == NULL) { return 1; } for (i = 0; i < 5; i++) { if (strcmp(args[0], builtin_str[i]) == 0) { return (*builtin_func[i])(args); } } return execute_line(args); } void *getCurrentDir(void){ char *currWorkDir, *token; char buffer[PATH_MAX + 1]; char *directory; size_t length; currWorkDir = getcwd(buffer, PATH_MAX + 1 ); token = strrchr(currWorkDir, '/'); if( currWorkDir == NULL ){ printf("Error"); /* You decide here */ exit(1); } if (token == NULL) { printf("Error"); /* You decide here */ exit(1); } length = strlen(token); directory = malloc(length); memcpy(directory, token+1, length); return directory; }
#ifndef ELSE_H #define ELSE_H #include "else.h" char *read_line(); char **parse_line(char *line); int execute_line(char **args); int cd(char **args); int help(char **args); int go_sh_exit(char **args); int dispatch_command(char **args); void *getCurrentDir(void); #endif
pipe : pipe.o else.o gcc -o pipe pipe.o else.o pipe.o : pipe.c gcc -c -o pipe.o pipe.c else.o : else.c gcc -c -o else.o else.c clean : rm *.o pipe shell : shell.o else.o gcc -o shell shell.o else.o shell.o : shell.c gcc -c -o shell.o shell.c else.o : else.c gcc -c -o else.o else.c clean : rm *.o shell
#include <errno.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <fcntl.h> #define MAX_INPUT_SIZE 1024 #define MAX_TOKEN_SIZE 64 #define MAX_NUM_TOKENS 64 #define TOKEN_CNT 64 #include "else.h" typedef enum {false, true} bool; char **tokenize(char *line_p) { char **tokens = (char **)malloc(MAX_NUM_TOKENS * sizeof(char *)); char *now_token = (char *)malloc(MAX_TOKEN_SIZE * sizeof(char)); int token_idx = 0; int char_idx = 0; for (int i =0; i < strlen(line_p); i++) { char ch = line_p[i]; if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\0') { if (char_idx != 0) { now_token[char_idx] = '\0'; tokens[token_idx] = (char*)malloc(MAX_TOKEN_SIZE*sizeof(char)); if (!strcmp("pps", now_token) || !strcmp("ttop", now_token)) { strcpy(tokens[token_idx], "./"); strcat(tokens[token_idx++], now_token); } else { strcpy(tokens[token_idx++], now_token); } char_idx = 0; } } else { now_token[char_idx++] = ch; } } free(now_token); tokens[token_idx] = NULL; return tokens; } //pipe void do_pipe(char **tokens, int pipe_idx[TOKEN_CNT], int pipe_cnt) { int pipes[TOKEN_CNT][2] = {0, }; // pipes int pid; int status; /***** first command *****/ pipe(pipes[0]); // pipe if ((pid = fork()) < 0) { fprintf(stderr, "fork() error\n"); exit(1); } else if (pid == 0) { close(STDOUT_FILENO); // stdout close dup2(pipes[0][1], STDOUT_FILENO); // cp pipe[0] to stdout close(pipes[0][1]); // pipe close execvp(tokens[pipe_idx[0]], &tokens[pipe_idx[0]]); // exec fprintf(stderr, "execvp() error\n"); } close(pipes[0][1]); // pipe close wait(&status); // wit for exec term if (WIFSIGNALED(status) || WIFSTOPPED(status)) { exit(1); } /***** execute commands except last command *****/ for (int i = 0; i < pipe_cnt - 1; i++) { pipe(pipes[i+1]); // pipe if ((pid = fork()) < 0) { fprintf(stderr, "fork() error\n"); exit(1); } else if (pid == 0) { close(STDIN_FILENO); // stdin close close(STDOUT_FILENO); // stdout close dup2(pipes[i][0], STDIN_FILENO); // cp to pipe stdin dup2(pipes[i+1][1], STDOUT_FILENO); // cp to pipe stdout close(pipes[i][0]); // pipe close close(pipes[i+1][1]); // pipe close execvp(tokens[pipe_idx[i+1]], &tokens[pipe_idx[i+1]]); // exec fprintf(stderr, "execvp() error\n"); } close(pipes[i+1][1]); // pipe close wait(&status); // wait exec terminate if (WIFSIGNALED(status) || WIFSTOPPED(status)) exit(1); } /***** excute last command *****/ if ((pid = fork()) < 0) { fprintf(stderr, "fork() error\n"); exit(1); } else if (pid == 0) { close(STDIN_FILENO); // stdin close dup2(pipes[pipe_cnt-1][0], STDIN_FILENO); // cp to pipe stdin close(pipes[pipe_cnt-1][0]); // pipe close close(pipes[pipe_cnt-1][1]); // pipe close execvp(tokens[pipe_idx[pipe_cnt]], &tokens[pipe_idx[pipe_cnt]]); // exec } wait(&status); // wait exec terminate if (WIFSIGNALED(status) || WIFSTOPPED(status)) { exit(1); } return; } // function for exec command void run_commands(char **tokens) { bool has_pipe = false; int pipe_cnt = 0; int start_idx = 0; int len = 0; int pipe_idx[TOKEN_CNT] = {0, }; for (int i = 0; tokens[i] != NULL; i++, len++) { // change token NULL when command exist if (!strcmp(tokens[i], "|")) { tokens[i] = NULL; pipe_idx[++pipe_cnt] = i+1; has_pipe = true; } else if (!strcmp(tokens[i], "<")) { int fd = open(tokens[i+1], O_RDONLY); if (fd < 0) { fprintf(stderr, "Failed to open file '%s'\n", tokens[i+1]); exit(1); } dup2(fd, STDIN_FILENO); close(fd); tokens[i] = NULL; i++; } else if (!strcmp(tokens[i], ">")) { int fd = open(tokens[i+1], O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd < 0) { fprintf(stderr, "Failed to open file '%s'\n", tokens[i+1]); exit(1); } dup2(fd, STDOUT_FILENO); close(fd); tokens[i] = NULL; i++; } else if (!strcmp(tokens[i], "sort")) { // execute sort command execvp("sort", &tokens[i]); fprintf(stderr, "Failed to execute sort command\n"); exit(1); } } if (has_pipe) { do_pipe(tokens, pipe_idx, pipe_cnt); } else { // no pipe if (execvp(tokens[0], tokens) < 0) { if (errno == 2) { fprintf(stderr, "%s: command not found\n", tokens[0]); exit(1); } else { fprintf(stderr, "execvp error! errno: %d\n", errno); exit(1); } } int status; wait(&status); if (WIFSIGNALED(status) || WIFSTOPPED(status)) { exit(1); } } exit(0); } int main(int argc, char* argv[]) { char *line; char **args; int status; char line_p[MAX_INPUT_SIZE]; char **tokens; int i; FILE* fp; if (argc == 2) { // batch mode if ((access(argv[1], F_OK)) < 0) { fprintf(stderr, "File doesn't exists.\n"); return -1; } if ((fp = fopen(argv[1],"r")) < 0) { fprintf(stderr, "fopen error for %s\n", argv[1]); return -1; } } while (1) { // infinite loop /* input */ bzero(line_p, sizeof(line_p)); if (argc == 2) { // batch mode if (fgets(line_p, sizeof(line_p), fp) == NULL) { // read all file break; } line_p[strlen(line_p) - 1] = '\0'; } else { // interactive mode char *dir = getCurrentDir(); printf("gosh@%s> ", dir); scanf("%[^\n]", line_p); getchar(); } /* input done */ line_p[strlen(line_p)] = '\n'; tokens = tokenize(line_p); // tokenizing if (!tokens[0]) { continue; } int pid; if ((pid = fork()) < 0) { // child process fprintf(stderr, "vfork error!\n"); exit(1); } else if (pid == 0) { // if child procedd run_commands(tokens); } else { // if parent process int status; waitpid(pid, &status, 0); if (WIFSIGNALED(status) || WIFSTOPPED(status) || WEXITSTATUS(status) == 1) { //error fprintf(stderr, "SSUShell : Incorrect command\n"); } for (i=0;tokens[i]!=NULL;i++) { // free alloc free(tokens[i]); } free(tokens); } line = read_line(); args = parse_line(line); status = dispatch_command(args); free(line); free(args); } return 0; }
Editor Settings
Theme
Key bindings
Full width
Lines