linux - Implementing unlimited piping in shell using C -


i'm trying implement c shell allows unlimited unidirectional pipes using character '>'

so can handle ls -a > tail > grep '.zip'

i understand pipes supposed talk between processes, thought came idea use 1 pipe , multiple children.

this have far

#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <string.h> #include <stdlib.h> /*#include <wait.h>*/  char *args[1000][1000];//array of arguments  int args_count = 0;//count of arguments in array  int runcommand(char **arguments, int *fd, int pipehassomedata, int basecase) {    pid_t pid;    int x = 0;    int status;    pid = fork();    if(pid != 0) {        waitpid(pid, &status, 0);        if(basecase) {            if(wifexited(status))             {                  if(wexitstatus(status) == 0)                 {                     /*it worked*/                  } else if(wexitstatus(status) == 255) {                      printf("the program %s not exist \n", arguments[0]);                  } else {                      printf("error: error code: %d", wexitstatus(status));                  }             }             else             {                 printf("there problem not normal");             }            printf("\n \n");        }        return 1;      } else {        if(pipehassomedata == 1) {//  read pipe            dup2(fd[0], 0);//read pipe        }        if(basecase == 0) {// not base case            dup2(fd[1], 1);//write pipe        } else {            close(fd[1]);//close write        }            exit(execvp(arguments[0], arguments));          return 0;      }  }  int execute_commands(char *arguments[1000][1000], int pd[2] = null) {      int current_count = args_count;      int iterator = 0;      int fd[2];      int useapipeincommand = 0;      pipe(fd);  while(iterator <= args_count) {//go through , execute commands          if(current_count == 0) {//base case              return runcommand(arguments[iterator], fd, useapipeincommand, 1);          } else {              runcommand(arguments[iterator], fd, useapipeincommand, 0);              useapipeincommand = 1;          }      iterator++;      current_count--;      }//end while      return 1;  }  int main () {      int = 0;      char  text[1024];             /* input line                 */     char *tok2;       while (1) {                   /* repeat until done ....         */        fflush(stdin);       fflush(stdout);        printf("shell -> ");     /*   display prompt             */           *text = 0;            fgets(text, sizeof text, stdin);             /*   read in command line     */           fflush(stdout);           printf("\n");            char * tok = strtok(text, " \n\t");            if (strcmp(tok, "exit") == 0) {  /* "exit"?     */                return 0;         /*   exit if                */            }           if (strcmp(tok, " ") == 0) {  /* "exit"?     */                continue;         /*   exit if                */            }           tok2 = tok;        memset(args, 0, sizeof(args[0][0]) * 1000 * 1000);//clear arguments array        args_count = 0;            int count = 0;            while(tok2 != null) {               if(strcmp(tok2, ">") != 0) {                   args[args_count][count] = tok2;                   count++;                   tok2 = strtok(null, " \n\t");               } else {//pipe found, argument counter , set count 0           args[args_count][count] = null;           args_count++;                   count = 0;                   tok2 = strtok(null, " \n\t");               }           }           args[args_count][count] = null;       execute_commands(args);      }//end while      return 0;  } 

it running single base case no problem shell freezes when pipe. ideas on issue?

correct answer comments @beau-bouchard , @rici:

pipes have (small) finite buffer; cannot write more little bit pipe without blocking unless other end of pipe being read.

for correct implementation, check out "multiple pipes in c" coding multiple pipe in c

--update:

here final working code having similar issue:

#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <wait.h>  int read = 0;  int write = 1;  char *args[1000][1000];//array of arguments  int args_count = 0;//count of arguments in array  int execute_commands(char *arguments[1000][1000]) {      int pd[2];      int iterator = 0;      int fd[2];      int f_in = 0;  while(iterator <= args_count) {//go through , execute commands        pid_t pid;        int status;        pipe(fd);        pid = fork();        if(pid != 0) {            waitpid(pid, &status, 0);//wait child exit           close(fd[write]);//close writing end                if(wifexited(status))                 {                      if(wexitstatus(status) == 0)                     {                         /*it worked*/                      } else if(wexitstatus(status) == 255) {                          printf("the program %s not exist \n", arguments[iterator][0]);                      } else {                          printf("error: error code: %d", wexitstatus(status));                      }                 }                 else                 {                     printf("there problem not normal %d", status);                 }                  f_in = fd[read];//set pipe in            if(iterator == args_count) {                printf("\n \n");            }            //return 1;          } else {            dup2(f_in, 0);            if(iterator != args_count) {//its not main value                dup2(fd[write], 1);//write pipe            }            close(fd[read]);                exit(execvp(arguments[iterator][0], arguments[iterator]));              return 0;          }      iterator++;      }//end while      return 1;  }  int main () {      int = 0;      char  text[1024];             /* input line                 */     char *tok2;       while (1) {                   /* repeat until done ....         */        fflush(stdin);       fflush(stdout);        printf("shell -> ");     /*   display prompt             */           *text = 0;            fgets(text, sizeof text, stdin);             /*   read in command line     */           fflush(stdout);           printf("\n");            char * tok = strtok(text, " \n\t");            if (strcmp(tok, "exit") == 0) {  /* "exit"?     */                return 0;         /*   exit if                */            }           if (strcmp(tok, " ") == 0) {  /* "exit"?     */                continue;         /*   exit if                */            }           tok2 = tok;        memset(args, 0, sizeof(args[0][0]) * 1000 * 1000);//clear arguments array        args_count = 0;            int count = 0;            while(tok2 != null) {               if(strcmp(tok2, ">") != 0) {                   args[args_count][count] = tok2;                   count++;                   tok2 = strtok(null, " \n\t");               } else {//pipe found, argument counter , set count 0           args[args_count][count] = null;           args_count++;                   count = 0;                   tok2 = strtok(null, " \n\t");               }           }           args[args_count][count] = null;       execute_commands(args);      }//end while      return 0;  } 

Comments

Popular posts from this blog

java - Spring Data JPA: Why findOne(id) executing delete query internally? -

python - Mongodb How to add addtional information when aggregating? -

java - Incorrect order of records in M-M relationship in hibernate -