Created
April 14, 2019 14:08
-
-
Save ipodipad/70ca0e6d1d477d55939a911cb29b3472 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <sys/time.h> | |
#include <signal.h> | |
#include "smsh.h" | |
static char curBuf[MAXLENGTH], commBuf[20][MAXLENGTH], connect[MAXARGS]; | |
int line = 0; | |
void BufFull() | |
{ | |
int i; | |
for(i = 1; i < 20; i++) | |
strcpy(commBuf[i - 1], commBuf[i]); | |
line = 19; | |
} | |
int GetCommand() | |
{ | |
int c, count, i; | |
printf("[smsh] "); | |
count = 0; | |
while(1) | |
{ | |
if((c = getchar()) == EOF) | |
return (EOF); | |
if(count < MAXLENGTH) | |
{ | |
if(line == 20) | |
BufFull(); | |
commBuf[line][count++] = c; | |
} | |
if(c == '\n' && count < MAXLENGTH) | |
{ | |
if(count == 1) | |
return 0; | |
commBuf[line++][count - 1] = '\0'; | |
strcpy(curBuf, commBuf[line - 1]); | |
return count; | |
} | |
if(c == '\n') | |
{ | |
printf("too long\n"); | |
count = 0; | |
printf("[smsh] "); | |
} | |
} | |
} | |
/* 백그라운드 모드 */ | |
int isBack() | |
{ | |
int i; | |
for(i = 0; curBuf[i] != '\0'; i++) | |
{ | |
if(curBuf[i] == '&') | |
{ | |
curBuf[i] = '\0'; | |
return 1; | |
} | |
} | |
return 0; | |
} | |
int Parse(char ret[], char *vec[], char parsign[]) | |
{ | |
int ln, count; | |
char *token; | |
count = 0; | |
ln = 0; | |
token = strtok(ret, parsign); | |
while(token != '\0' && ln < MAXARGS) | |
{ | |
count++; | |
vec[ln] = token; | |
token = strtok('\0', parsign); | |
ln++; | |
} | |
vec[ln] = '\0'; | |
count--; | |
return count; | |
} | |
int SinglePipe(char *Vec[]) | |
{ | |
int p[2], status; | |
char *execVec[MAXARGS]; | |
switch(fork()) | |
{ | |
case -1 : fprintf(stderr, "fork error!"); | |
break; | |
case 0 : if(pipe(p) < 0) | |
{ | |
fprintf(stderr, "pipe error!"); | |
return -1; | |
} | |
switch(fork()) | |
{ | |
case -1 : fprintf(stderr, "fork error!"); | |
break; | |
case 0 : close(1); | |
dup(p[1]); | |
close(p[0]); | |
close(p[1]); | |
Parse(Vec[0], execVec, " "); | |
execvp(execVec[0], execVec); | |
default : close(0); | |
dup(p[0]); | |
close(p[0]); | |
close(p[1]); | |
Parse(Vec[1], execVec, " "); | |
execvp(execVec[0], execVec); | |
} | |
default : wait(&status); | |
break; | |
} | |
} | |
int PipeExec(char *Vec[], int count, int execIndex) | |
{ | |
int p[MAXPIPE][2]; | |
char *execVec[MAXARGS]; | |
pid_t pid[MAXPIPE + 1]; | |
if(pipe(p[count - 1]) < 0) | |
{ | |
fprintf(stderr, "pipe error!"); | |
return -1; | |
} | |
count--; | |
switch(fork()) | |
{ | |
case -1 : fprintf(stderr, "fork error!"); | |
return -1; | |
case 0 : close(1); | |
dup(p[count][1]); | |
close(p[count][0]); | |
close(p[count][1]); | |
if(count > 0) | |
PipeExec(Vec, count, execIndex + 1); | |
Parse(Vec[count], execVec, " "); | |
execvp(execVec[0], execVec); | |
break; | |
default : close(0); | |
dup(p[count][0]); | |
close(p[count][0]); | |
close(p[count][1]); | |
if(execIndex == 1) | |
{ | |
Parse(Vec[count + 1], execVec, " "); | |
execvp(execVec[0], execVec); | |
} | |
break; | |
} | |
return 0; | |
} | |
int IsHistory(char *Vec[]) | |
{ | |
if(strcmp(Vec[0], "history") == 0) | |
return 1; | |
else if(strncmp(Vec[0], "!", 1) == 0) | |
return 2; | |
else | |
return 0; | |
} | |
int History(char Vec[], int flag) | |
{ | |
char numStr[3]; | |
int i, exeNum; | |
if(flag == 1) | |
{ | |
printf("== history list ==\n"); | |
for(i = 0; i < 20; i++) | |
{ | |
if(commBuf[i][0] == '\0') | |
break; | |
printf("[%2d] %s\n", i, commBuf[i]); | |
} | |
printf("== history list end ==\n"); | |
} | |
else | |
{ | |
for(i = 1; i < 3; i++) | |
{ | |
numStr[i - 1] = Vec[i]; | |
} | |
if(numStr[0] == '!') | |
exeNum = line - 2; | |
else | |
exeNum = atoi(numStr); | |
if(line == 20 && strcmp(commBuf[19], "\0") != 0) | |
{ | |
exeNum--; | |
} | |
strcpy(curBuf, commBuf[exeNum]); | |
strcpy(commBuf[line - 1], curBuf); | |
printf("%s\n", curBuf); | |
RunCommand(); | |
} | |
} | |
int IsDirection(char *Vec[]) | |
{ | |
int i; | |
for(i = 0; strstr(Vec[i], "\0") != '\0'; i++) | |
{ | |
if(strstr(Vec[i], ">>") != '\0') | |
return 1; | |
else if(strstr(Vec[i], ">!") != '\0') | |
return 2; | |
else if(strstr(Vec[i], ">") != '\0') | |
return 3; | |
else if(strstr(Vec[i], "<") != '\0') | |
return 4; | |
} | |
return 0; | |
} | |
int Direction(char *Vec[], int flag) | |
{ | |
int fd, nbyte, i; | |
char buf[1024]; | |
char temp[MAXLENGTH]; | |
char *vector[MAXLENGTH]; | |
memset(temp, '\0', sizeof(temp)); | |
for(i = 0; i < MAXARGS; i++) | |
{ | |
if(strncmp(Vec[i], ">", 1) == 0 || strncmp(Vec[i], "<", 1) == 0) | |
break; | |
strcat(temp, Vec[i]); | |
strcat(temp, " "); | |
} | |
Parse(temp, vector, " "); | |
switch(flag) | |
{ | |
case 1 : fd = open(Vec[i + 1], O_WRONLY | O_CREAT | O_APPEND, 0644); | |
switch(fork()) | |
{ | |
case -1 : fprintf(stderr, "fork error!"); | |
break; | |
case 0 : close(1); | |
dup(fd); | |
execvp(vector[0], vector); | |
default : wait(0); | |
} | |
close(fd); | |
break; | |
case 2 : fd = open(Vec[i + 1], O_WRONLY | O_CREAT | O_TRUNC, 0644); | |
switch(fork()) | |
{ | |
case -1 : fprintf(stderr, "fork error!"); | |
break; | |
case 0 : close(1); | |
dup(fd); | |
execvp(vector[0], vector); | |
default : wait(0); | |
} | |
close(fd); | |
break; | |
case 3 : fd = open(Vec[i + 1], O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0644); | |
switch(fork()) | |
{ | |
case -1 : fprintf(stderr, "fork error!"); | |
break; | |
case 0 : close(1); | |
dup(fd); | |
execvp(vector[0], vector); | |
default : wait(0); | |
} | |
close(fd); | |
break; | |
case 4 : fd = open(Vec[i + 1], O_RDONLY); | |
switch(fork()) | |
{ | |
case -1 : fprintf(stderr, "fork error!"); | |
break; | |
case 0 : close(0); | |
dup(fd); | |
execvp(vector[0], vector); | |
default : wait(0); | |
} | |
close(fd); | |
break; | |
} | |
} | |
int IsChdir(char *Vec[]) | |
{ | |
if(strncmp(Vec[0], "cd ..", 5) == 0) | |
return 1; | |
if(strncmp(Vec[0], "cd", 2) == 0) | |
return 2; | |
return 0; | |
} | |
void ChDir(char *Vec[], int flag) | |
{ | |
if(flag == 1) | |
{ | |
chdir(".."); | |
} | |
else | |
{ | |
chdir(Vec[1]); | |
} | |
} | |
int RunCommand() | |
{ | |
int i, j, status, pipeCount, hisflag, drflag, cdflag; | |
char *vector[MAXARGS]; | |
char *execVec[MAXARGS]; | |
char *pipeVec[MAXARGS]; | |
int pip[MAXPIPE][2]; | |
pid_t pid, pipepid[MAXPIPE]; | |
fd_set rset[MAXPIPE], wset[MAXPIPE]; | |
if(isBack()) | |
{ | |
if((pid = fork()) < 0) | |
fprintf(stderr, "fork error!"); | |
else if(pid == 0) | |
{ | |
printf("[Background] Process ID : %d\n", getpid()); | |
RunCommand(); | |
printf("[Background] Process ID : %d --> Done\n", getpid()); | |
exit(0); | |
} | |
else | |
return 0; | |
} | |
else | |
{ | |
if(Parse(curBuf, vector, ";") > 0) | |
{ | |
for(i = 0; i < MAXARGS; i++) | |
{ | |
if(vector[i] == '\0') | |
break; | |
strcpy(curBuf, vector[i]); | |
RunCommand(); | |
} | |
} | |
else if((pipeCount = Parse(curBuf, pipeVec, "|")) > 0) | |
{ | |
int status; | |
pid_t pid; | |
if(pipeCount == 1) | |
SinglePipe(pipeVec); | |
else | |
{ | |
if((pid = fork()) < 0) | |
fprintf(stderr, "fork error!"); | |
else if(pid == 0) | |
PipeExec(pipeVec, pipeCount, 1); | |
else | |
waitpid(pid, &status, 0); | |
} | |
} | |
else | |
{ | |
Parse(pipeVec[0], execVec, " "); | |
if(strncmp(execVec[0], "\0", 1) == 0) | |
return 0; | |
if((hisflag = IsHistory(execVec)) > 0) | |
History(execVec[0], hisflag); | |
else if((drflag = IsDirection(execVec)) > 0) | |
{ | |
Direction(execVec, drflag); | |
return 0; | |
} | |
else if((cdflag = IsChdir(execVec)) > 0) | |
{ | |
ChDir(execVec, cdflag); | |
} | |
else | |
{ | |
if((pid = fork()) < 0) | |
fprintf(stderr, "fork error!"); | |
else if(pid == 0) | |
{ | |
execvp(execVec[0], execVec); | |
} | |
else | |
{ | |
if(waitpid(pid, &status, 0) == -1) | |
return -1; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment