제가짠 쉘좀 봐주세요 뭐가 문제일까요..
글쓴이: rlarlagh / 작성시간: 토, 2007/05/19 - 12:16오후
리다이렉션을 짜고 있는데요.. cat<a는 되는데 cat<a>b는 왜 안될까요... 어디가 잘못된건지 힌트좀 주세요ㅠㅠ 리다이렉션 꼭 성공 시키고 싶어요 흑흑 /* basic skeleton for my shell implementation */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include<sys/types.h> #include<unistd.h> #include<sys/wait.h> #include<sys/stat.h> #include<fcntl.h> #define PROMPT "$" #define MAX_LINE 256 #define MAX_ARGV 256 #define FALSE 0 #define TRUE 1 #define STDIN_RE 2 #define STDOUT_RE 3 #define ADD2ARGV(word) \ if (i == MAX_ARGV - 1) { \ argv[MAX_ARGV-1] = NULL; \ return MAX_ARGV; \ } \ else argv[i++] = strdup(word) int redirection(int type, char *file); void clean(char *argv[]); void print(char *argv[], char bg); int parse(char *ln, char *argv[], char *bg); char *getword(char *ln, char *word, char *bg); void exec(char *argv[],char bg); main() { char line[MAX_LINE]; char *argv[MAX_ARGV]; char bg; int redir_in=0; int redir_out=0; int i; while (1) { bg = FALSE; printf("%s ", PROMPT); fgets(line, MAX_LINE, stdin); if (parse(line, argv, &bg) == 0) continue; if (strcmp(argv[0], "exit") == 0) break; exec(argv,bg); clean(argv); } } char *getword(char *ln, char *word, char *bg) { while (*ln != '\0' && isspace(*ln)) ln++; if (*ln == '\0') return NULL; if (*ln == '&') { *bg = TRUE; return NULL; } while (*ln != '\0' && *ln != '&' && !isspace(*ln)) *word++ = *ln++; *word = '\0'; return ln; } int parse(char *ln, char *argv[], char *bg) { int i = 0; int j=0; int k=0; char word[MAX_LINE]; char in[MAX_LINE]; char out[MAX_LINE]; //리다이렉션 문자 찾기 { char* p=strchr(ln,'<'); if(p) { memmove(p+2,p+1,strlen(p)); *p =' '; *(p+1)=' '; } } { char* q=strchr(ln,'>'); if(q) { memmove(q+2,q+1,strlen(q)); *q =' '; *(q+1)=' '; } } while ((ln = getword(ln, word, bg)) != NULL) { ADD2ARGV(word); } argv[i] = NULL; for(j=0; argv[j]!=NULL; j++){ // '<'일경우 if(!strcmp(argv[j],"<")){ if(!argv[j+1]){ printf("error"); return 0; } else{ strcmp(in,argv[j+1]); redirection(STDIN_RE,in); } } } for(k=0; argv[k]!=NULL; j++){ // '>'일경우 if(!strcmp(argv[k],"<")){ if(!argv[k+1]){ printf("error"); return 0; } else{ strcmp(out,argv[j+1]); redirection(STDOUT_RE,out); } } } return i; } void exec(char *argv[],char bg) { int status; pid_t pid; pid=fork(); if(pid>0){ //자식 프로세스가 끝나기를 기다린다. if (wait(&status)!=pid) { printf("wait error");//wait 실패시 exit(-1); } } else if(pid==0){ execvp(argv[0],argv);//명령어 수행 exit(-1) ;//수행 후 자식프로세스 종료 } else{ //(pid>0) printf("fork error");//fork 실패 exit(-1); } }//exec끝 int redirection(int type, char *file){ int fd; int status; pid_t pid; pid=fork(); if(pid>0){ if (wait(&status)!=pid) { printf("wait error"); exit(-1); } } else if(pid==0){ if(type==STDIN_RE) { if((fd=open(file,O_RDONLY))<0)exit(1); if((dup2(fd,0))<0)exit(1); } else if(type==STDOUT_RE) { if((fd=open(file,O_WRONLY|O_CREAT|O_TRUNC,0774))<0)exit(1); if((dup2(fd,1))<0)exit(1); } close(fd); exit(0) ; } } void print(char *argv[], char bg) { int i; for (i = 0; i < MAX_ARGV && argv[i] != NULL; i++) printf("argv[%d] = %s\n", i, argv[i]); if (bg) printf("Background Processing Required\n"); } void clean(char *argv[]) { int i; for (i = 0; i < MAX_ARGV && argv[i] != NULL; i++) free(argv[i]); }
Forums:
저 지금 레포트중이라 보진 못하겠고... 전에 레포트로 낸 셸이 있는데요... 제 기억에는 기능 다 됐던듯..
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#define MAXARG 10
#define MAXBUF 256
#define INFINITE 1
#define INIT_ZERO 0
#define IS_CHILD 0
#define ENTER 10
#define REDIREC_WRITE 1
#define REDIREC_ADD 2
#define REDIREC_READ 3
#define STD_OUT 1
#define STD_IN 0
#define BATCH_ON 1
#define BATCH_OFF 0
void mypause();
void env();
void cd(char*);
void myecho();
void dir();
void clr();
void read_batch();
void error(char*);
void shell_env();
void child_env();
void tockenize(char*);
void select_command();
void read_line();
void tock_pipe(char* point, int);
extern char **environ;
char buf[MAXBUF];
char *arg[MAXARG];
char *tocken;
char *save;
int argn;
char tmpbuf[MAXBUF];
int chk_redirec;
char inputfile[MAXBUF];
char outputfile[MAXBUF];
FILE *read_fp, *write_fp;
int read_fd, write_fd, tmp_fd;
int is_arg_batch = BATCH_OFF;
int main(int argc, char* argv[])
{
if(argc == 2) {
read_batch(argv[1]);
is_arg_batch = BATCH_ON;
}
else if(argc > 2)
error("Usage : myshell batchfile \n Usage : myshell");
shell_env();
while(INFINITE)
{
read_line();
if(buf[0] == ENTER) continue;
tockenize(buf);
if(!strcmp(arg[0], "quit")) break;
select_command();
}
exit(0);
}
void select_command()
{
int pid;
if(!strcmp(arg[0],"pause")) mypause();
else if(!strcmp(arg[0],"environ")) env();
else if(!strcmp(arg[0],"echo")) myecho();
else if(!strcmp(arg[0],"cd")) cd(arg[1]);
else if(!strcmp(arg[0],"dir")) dir();
else if(!strcmp(arg[0],"clr")) clr();
else if(!strcmp(arg[0],"help")) read_batch("./readme");
else if((pid=fork())==IS_CHILD)
{ // child process
child_env();
if(!strcmp(arg[argn-1],"&")) arg[argn-1] = (char*)0;
if((chk_redirec==REDIREC_WRITE)||(chk_redirec==REDIREC_ADD))
{
close(STD_OUT);
dup(write_fd);
}
if(chk_redirec==REDIREC_READ)
{
close(STD_IN);
dup(read_fd);
}
if(execvp(arg[0],arg)==-1) error("unknown instruction");
}
if((pid!=IS_CHILD)&&(!strcmp(arg[argn-1],"&"))) {
printf("parent waiting\n");fflush(stdout);
wait();
}
if((chk_redirec==REDIREC_WRITE)||(chk_redirec==REDIREC_ADD))
{
fclose(write_fp);
close(write_fd);
}
else if(chk_redirec==REDIREC_READ)
{
fclose(read_fp);
close(read_fd);
}
else;
}
void read_line()
{
char* point;
char* tmp;
getcwd(tmpbuf,MAXBUF);
printf("\n%s>",tmpbuf);
fgets(buf,MAXBUF,stdin);
chk_redirec = INIT_ZERO;
while(INFINITE) {
if((point=strstr(buf,">>"))!=NULL)
{
chk_redirec = REDIREC_ADD;
tock_pipe(point,REDIREC_ADD);
if((write_fp=fopen(outputfile,"a"))==NULL)
error("add file fopen error\n");
if((write_fd=open(outputfile,O_WRONLY | O_APPEND))==-1)
error("add file open error\n");
}
else if((point=strchr(buf,'>'))!=NULL)
{
chk_redirec = REDIREC_WRITE;
tock_pipe(point,REDIREC_WRITE);
if((write_fp=fopen(outputfile,"w"))==NULL)
error("write file fopen error\n");
if((write_fd=open(outputfile,O_WRONLY))==-1)
error("write file open error\n");
}
else if((point=strchr(buf,'<'))!=NULL)
{
chk_redirec = REDIREC_READ;
tock_pipe(point,REDIREC_READ);
if((read_fp=fopen(inputfile,"r"))==NULL)
error("read file fopen error\n");
if((read_fd=open(inputfile,O_RDONLY))==-1)
error("read file open error\n");
}
else break;
}
}
void tock_pipe(char* point, int chk_io)
{
char* tmp;
(void*)strtok(point," ");
tmp = strtok(NULL," \n");
if((chk_io==REDIREC_ADD)||(chk_io==REDIREC_WRITE)) {
strcpy(outputfile,tmp);
}
else if(chk_io==REDIREC_READ)
strcpy(inputfile,tmp);
else error("unknown\n");
*point = '\0';
if((tmp=strtok(NULL," \n"))!=NULL)
strcat(buf,tmp);
}
void tockenize(char buf[MAXBUF])
{
static const char delim[] = " \t\n";
argn = INIT_ZERO;
tocken = strtok(buf, delim);
while(tocken) {
arg[argn++] = tocken;
tocken = strtok(NULL, delim);
}
arg[argn] = (char*)0;
}
void clr()
{
printf("%c[2J",27); // ansi - depending
}
void mypause()
{
while(getchar()!=ENTER);
}
void child_env()
{
if(getcwd(tmpbuf,MAXBUF)==NULL) error("shell directory error");
strcat(tmpbuf,"/myshell");
if(setenv("parent",tmpbuf,1)==-1) error("environ write error");
}
void shell_env()
{
if(getcwd(tmpbuf,MAXBUF)==NULL) error("shell directory error");
strcat(tmpbuf,"/myshell");
if(setenv("SHELL",tmpbuf,1)==-1) error("environ write error");
}
#define MAXREADLINE 20
void read_batch(char target[MAXBUF])
{
FILE *fp, *help_to_more_pipe;
char read_line[MAXBUF];
int cnt = INIT_ZERO;
if((fp=fopen(target,"r"))==NULL)
error("readme open error\n");
if((help_to_more_pipe = popen("more","w"))==NULL)
error("more write pipe open error\n");
while(fgets(read_line,MAXBUF,fp)!=NULL) {
if((!strcmp("batchfile",target))&&(is_arg_batch==BATCH_ON))
{
printf("[%4d]\n",cnt+1);
fflush(stdout);
system(read_line);
putchar('\n');
}
else
{
if((chk_redirec==REDIREC_WRITE)||(chk_redirec==REDIREC_ADD))
fputs(read_line, write_fp);
else fputs(read_line, help_to_more_pipe);
}
/* if(++cnt>MAXREADLINE)
{
printf("\n\npress any key\n\n");
(void)getchar();
cnt = INIT_ZERO;
}
*/
}
fclose(fp);
pclose(help_to_more_pipe);
if(!strcmp(target,"batchfile")) exit(0);
}
void error(char mes[MAXBUF])
{
printf("%s\n",mes);
exit(1);
}
void cd(char* target)
{
char name[MAXBUF], name2[MAXBUF];
printf("target = %s\n", target);
if(chdir(target) == -1) {
printf("Change Directory error\n");
//exit(1);
}
getcwd(name,MAXBUF);
printf("%s\n",name);
if(setenv("PWD",name,1)==-1) printf("fail");
}
void dir()
{
DIR *dp;
struct dirent *dirp;
int i = 0;
if((dp = opendir(".")) == NULL) {
perror("opendir failed");
exit(1);
}
while(dirp = readdir(dp)) {
if((chk_redirec==REDIREC_WRITE)||(chk_redirec==REDIREC_ADD))
fprintf(write_fp,"%4d]%s\n",1+i++,dirp->d_name);
else printf("%4d]%s\n",1+i++,dirp->d_name);
}
printf("\n");
closedir(dp);
}
void env()
{
char** cp_env = environ;
int cnt = 0;
while(*cp_env) {
if((chk_redirec==REDIREC_WRITE)||(chk_redirec==REDIREC_ADD))
fprintf(write_fp,"%s\n",*cp_env++);
else printf("%s\n",*cp_env++);
if((++cnt>10)||(chk_redirec!=REDIREC_WRITE)) {
(void)getchar();
cnt = 0;
}
}
}
void myecho()
{
argn = 0;
while(arg[++argn] != NULL) {
if((chk_redirec==REDIREC_WRITE)||(chk_redirec==REDIREC_ADD))
fprintf(write_fp,"%s ",arg[argn]);
else printf("%s ",arg[argn]);
}
putchar('\n');
}
타인을 자기 자신처럼 존경할수 있고, 자기가 하고 싶다고 생각하는 것을 타인에게 할 수 있다면, 그 사람은 참된 사랑을 알고 있는 사람이다. 그리고 세상에는 그 이상 가는 사람은 없다.
부탁합니다.
include 다음에 안보이는데요
혹시 무엇,무엇인지 알 수 있을까요..
ㅠㅠ 제발 부탁드립니다.
댓글 달기