2016-05-26 9 views
-1

リダイレクト(>)と上級(>+)については、開始方法がわかりません。私は自分のスペースリダイレクト構造体(;\n空白でトークン化されていた)をリンクして、それが ">"かどうかを見て、progAndArgsのリダイレクト構造体と次のノードをoutFileとして保存しようとしています。C - リダイレクト/高度なリダイレクトの実装でのシェルの作成

私はそれを正しくやっていると思いますが、それは非常によく間違っている可能性があります。私が正しくリダイレ​​クト構造体を得れば

parse* p = tokenize_line_semicolons(pinput); 

     myPrint("HERE\n"); 
     // setup redirection struct 
     parse *temp2_p = p; 
     space *spc2; 
     while (temp2_p != NULL) { 
      spc2 = tokenize_space(temp2_p->cmd); 
      space* temp_s = spc2; 
      char* prev = temp_s->spc; 
      if (strcmp(prev,"\n")==0) 
       error(); 
      temp_s = temp_s->next; 
      while (temp_s != NULL) { 
       if (strcmp(temp_s->spc, ">") == 0) { 
        redirection r; 
        r.progAndArgs = prev; 
        if (temp_s->next->spc != NULL) 
         r.outFile = temp_s->next->spc; 
        else 
         error(); 
       } 
       temp_s = temp_s->next; 
      } 
      temp2_p = temp2_p->next; 
     } 

は、しかし、私が使用する方法がわからないんだDUP/dup2の/レコード生成/書き込み/オープン/やって読み>と> +(私はmanページを読んで)。助けてください!

#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <sys/stat.h> 
#include <fcntl.h> 

void myPrint(char *msg) 
{ 
    write(STDOUT_FILENO, msg, strlen(msg)); 
} 

void error() 
{ 
    char error_message[30] = "An error has occurred\n"; 
    write(STDOUT_FILENO, error_message, strlen(error_message)); 
} 



typedef struct parse 
{ 
    char* cmd; 
    struct parse* next; 
} parse; 

typedef struct space 
{ 
    char* spc; 
    struct space* next; 
} space; 
typedef struct dble 
{ 
    space* s; 
    struct dble* next; 
} dble; 

typedef struct redirection 
{ 
    char* progAndArgs; 
    char* outFile; 
} redirection; 



char** p_to_char(space *s) 
{ 
    char** args = (char**)malloc(sizeof(char*)*514); 
    space *temp = s; 
    int i = 0; 

    while (temp != NULL) { 
     args[i] = strdup(temp->spc); 
     // myPrint(args[i]); 
     // myPrint("\n"); 
     temp = temp->next; 
     i++; 
    } 
    return args; 
} 

parse* setparse(char* s) 
{ 
    parse* p = (parse*)malloc(sizeof(parse)); 
    p->cmd = strdup(s); 
    p->next = NULL; 

    return p; 
} 

space* setspace(char* s) 
{ 
    space* sp = (space*)malloc(sizeof(space)); 
    sp->spc = strdup(s); 
    sp->next = NULL; 

    return sp; 
} 

dble* setdble(space* spc) 
{ 
    dble* d = (dble*)malloc(sizeof(dble)); 

    space* temp = spc; 
    while (temp != NULL) { 
     d->s = temp; 
     d->next = (dble*)malloc(sizeof(dble)); 
     d = d->next; 
     temp = temp->next; 
    } 
    return d; 
} 

void show_parse(parse* p) 
{ 
    //myPrint("Show parse\n"); 
    parse* temp = p; 
    while(temp != NULL) { 
     // myPrint(temp->cmd); 
     // myPrint("->"); 
     temp = temp->next; 
    } 
    //myPrint("\n"); 
} 

void show_space(space* sp) 
{ 
    // myPrint("Show space\n"); 
    space* temp = sp; 
    while(temp != NULL) { 
     // myPrint(temp->spc); 
     // myPrint("->"); 
     temp = temp->next; 
    } 
    //myPrint("\n"); 
} 

// TODO - SEE IF DBLE PRINTING RIGHT OR SET UP WRONG 
void show_dble(dble* d) 
{ 
    dble* temp = d; 
    //myPrint("Show dble\n"); 
    while(temp != NULL) { 
     show_space(temp->s); 
     temp = temp->next; 
    } 
    //myPrint("\n"); 
} 

/* tokenized by spaces's - SEPARATE COMMANDS AND PARAMETERS */ 
space* tokenize_space(char* cmd) 
{ 
    char* token_ptr = strdup(cmd); 

    char *token, *token2; 
    token = strtok_r(token_ptr, " ", &token2); 
    space* s = setspace(token); 
    space* fst = s; 

    while (token != NULL) { 
     token = strtok_r(NULL," ", &token2); 
     if (token==NULL){ 
      return fst; 
     } 
     s->next = setspace(token); 
     s = s->next; 
    } 
    return fst; 
} 

/* tokenized by newline and ;'s - SEPARATE COMMANDS WITH PARAMTERS*/ 
parse* tokenize_line_semicolons(char* input) 
{ 
    //myPrint("Starting Tokens!\n"); 

    if (strcmp(input,"\n")) { 
     error(); 
     return NULL; 
    } 
    else { 
     myPrint("HERE\n"); 
    char* token_ptr = input; 

    char *token; 
    token = strtok_r(token_ptr, ";\n", &token_ptr); 
    parse* p = setparse(token); 
    parse* fst = p; 

    while (token != NULL) { 
     token = strtok_r(NULL,";\n", &token_ptr); 
     if (token==NULL){ 
      return fst; 
     } 
     p->next = setparse(token); 
     //tokenize_redirect(p); 
     p = p->next; 
    } 
    return fst; 
    } 
} 

void do_cd(char* param) 
{ 
    int v; 
    // myPrint(param); 
    // myPrint("\n"); 

    if (strcmp(param, "") == 0 || strcmp(param, "~") == 0) { 
     char *directory = getenv("HOME"); 
     v = chdir(directory); 
    } else if (param[0] == '/') { 
     //myPrint("~ /\n"); 
     char* directory = param; 
     v = chdir(directory); 
     //exit(v); 
    } else { 
     char buf[100]; 
     char *directory = getcwd(buf,100); 
     strcat(buf,"/"); 
     strcat(buf,param); 
     //myPrint(directory); 
     v = chdir(directory); 
    } 
    if (v == -1) // chdir error returning 
     error(); 
} 


int run_cmds(char* cmd, char** args, space* s) 
{ 

// myPrint("START run_cmds!!! s->spc: "); 
// myPrint(s->spc); 
// myPrint(", cmd: "); 
// myPrint(cmd); 
// myPrint("\n"); 

    // all cmds return 0 if pass (from exho $?) 
    if (strcmp(s->spc, "exit") == 0) { 
     // myPrint("DOING exit\n"); 
     exit(0); 
    } 
    else if (strcmp(s->spc, "pwd") == 0) { 
     // myPrint("DOING pwd\n"); 
     char* buff = (char*)malloc(sizeof(char)*100); 
     myPrint(getcwd(buff,100)); 
     myPrint("\n"); 
    } else if (strcmp(s->spc, "cd") == 0) { 
     //myPrint("DOING cd\n"); 
     do_cd(s->next->spc); 
    } 
    else { 
     // myPrint("FORK"); 
     // myPrint("\n"); 
     pid_t pid = fork(); 

     if (pid == 0) { 
      // myPrint("CHILD"); 
      // myPrint("\n"); 
      // myPrint(args[0]); 
      // myPrint("\n"); 
      if (execvp(args[0], args) < 0) 
       error(); 
      exit(0); 
     } else { 
      // myPrint("PARENT"); 
      // myPrint("\n"); 
      int status; 
      pid_t ppid = waitpid(pid,&status,WUNTRACED); 
      // myPrint("PARENT 2"); 
      // myPrint("\n"); 
      return ppid; 
     } 
    } 
    return 0; 
} 

//Redirect throws an error if the file already exists or no file specified 

int main(int argc, char *argv[]) 
{ 
    char cmd_buff[100]; 
    char *pinput; 

    // implementing batch mode 
     if (argc > 1) { 
      int len = strlen(argv[1]); 
      if (argv[1][0] == '[' && argv[1][len-1] == ']') { 
       argv[1]++; 
       argv[1][len-2] = '\0'; 
      } 

      FILE *fp = fopen(argv[1],"r"); 
      if (fp == NULL) { 
       error(); 
       exit(1); 
      } 
      char buff[514]; 
      //myPrint("we are about to fgets\n"); 
      while (fgets(buff,514,fp) != NULL) { 
       // myPrint("We are fgetsing\n"); 
       // myPrint(buff); 
       tokenize_line_semicolons(buff); 
      } 
      fclose(fp); 
     } else if (argc >= 3) { 
      error(); 
      exit(1); 
     } 

    while (1) { 
     myPrint("myshell> "); 
     pinput = fgets(cmd_buff, 100, stdin); 

     if (!pinput) { 
      myPrint("pinput\n"); 
      exit(0); 
     } 

     // if 513th char is neither \n or null terminator, its invalid input 
     if (strlen(pinput) > 512) { 
      // myPrint(pinput); 
      // myPrint("\n"); 
      error(); 
      exit(1); 
     } 

     parse* p = tokenize_line_semicolons(pinput); 

     myPrint("HERE\n"); 
     // setup redirection struct 
     parse *temp2_p = p; 
     space *spc2; 
     while (temp2_p != NULL) { 
      spc2 = tokenize_space(temp2_p->cmd); 
      space* temp_s = spc2; 
      char* prev = temp_s->spc; 
      if (strcmp(prev,"\n")) 
       error(); 
      temp_s = temp_s->next; 
      while (temp_s != NULL) { 
       if (strcmp(temp_s->spc, ">") == 0) { 
        redirection r; 
        r.progAndArgs = prev; 
        if (temp_s->next->spc != NULL) 
         r.outFile = temp_s->next->spc; 
        else 
         error(); 
       } 
       temp_s = temp_s->next; 
      } 
      temp2_p = temp2_p->next; 
     } 

     parse* temp_p = p; 
     space *spc; 
     dble *d = (dble*)malloc(sizeof(dble)); 
     dble* tmp_d = d; 

     while (temp_p != NULL) { 
      spc = tokenize_space(temp_p->cmd); 
      d->s = spc; 
      d->next = (dble*)malloc(sizeof(dble)); 
      d = d->next; 
      temp_p = temp_p->next; 
     }  

     show_parse(p); 
     show_dble(tmp_d); 

     char** args = p_to_char(spc); 
     //myPrint("HERE"); 
     while (p != NULL) { 
      run_cmds(p->cmd, args, tmp_d->s); 
      p = p->next; 
      tmp_d = tmp_d->next; 
     } 
    } 
} 
+1

デバッガ.................... –

+0

"解決方法がわかりません" - 上記のコメントを参照してください。 – WhozCraig

答えて

1

引数がnullかどうかをチェックすることなく、引数を使用するsetparse(token)を呼び出します。

+0

ありがとう!それは私の新しいラインsegの不具合を修正した – user1045890

関連する問題