제가짠 쉘좀 봐주세요 뭐가 문제일까요..
글쓴이: 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 다음에 안보이는데요
혹시 무엇,무엇인지 알 수 있을까요..
ㅠㅠ 제발 부탁드립니다.
댓글 달기