title: C++ processes and pipes
body: <p>I working my way through a C++ and Operating Systems book and I've come upon an assignment that requires creation, writing, and reading from pipes. However my program stalls on reading from the second pipe. My program is to accept input and parse out a space delimited string into tokens and classifying those tokens accordingly. My code is bellow with my problem area marked. Any help is as always very appreciated.</p>
  
  <p>edit: This is supposed to have two children. One for processing the space delimited tokens and the other for determining the type of delimited tokens. As far as debugging goes I only have access to cout as a debugger. So I inserted a cout before the read and after the one before the read appeared but the one after did not.</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;fstream&gt;
  #include &lt;string&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/wait.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  
  using namespace std;
  
  //declaring the pipes
  int pipeOne[2];
  int pipeTwo[2];
  
  struct inputStruct {
  char str[256]; /* one extra spot for \n */
  int  len;      /* length of str         */
  int  flag;     /*  0 for normal input, 1 to indicate “done” */
  };
  
  struct tokenStruct {
  char token[256]; /* tokens can be 255 max */
  int  flag;       /* same as inputStruct   */
  int  tokenType;  /* a code value          */
  };
  
  void dataProcess(){
  
  //new input struct to contain the the input from the parent
  inputStruct input;
  
  //the intial read from the pipe to populate the input stuct
  read( pipeOne[0], (char*)&amp;input, sizeof(inputStruct));
  
  //set the flag
  int flag = input.flag;
  
  while (flag != 1){
  
      int size = 0;
  
      //get the size of the array up until the null character
      while (input.str[size] != '\0'){
          size++;
      }
  
      //Here's the parsing of each token
      for (int i=0; i&lt;size; i++) {
  
          int tokenLength;
  
          tokenStruct token;
  
          //while the char isn't white space or null increment through it
          while (input.str[i] != ' ' &amp;&amp; input.str[i] != '\0') {
  
              //a is the index of the string token 
              int a = 0;
  
              //write the parsed string
              token.token[a] = input.str[i];
  
              a++;
              i++;
  
          }
  
          //write to process 2
          write(pipeTwo[1], (char*)&amp;token, sizeof(tokenStruct));
  
      }
  
      //read again and store the results
      read(pipeOne[0], (char*)&amp;input, sizeof(inputStruct));
      flag = input.flag;
  
  }
  
  tokenStruct token;
  
  token.flag = flag;
  
  //final write to the second child to tell it to commit suicide
  write(pipeTwo[1], (char*)&amp;token, sizeof(tokenStruct));
  
  exit(0);
  }
  
  void tokenClassifer(){
  
  tokenStruct token;
  
  //Problem area is here on ****************************************************
  
  //the initial read
  read(pipeTwo[0], (char*)&amp;token, sizeof(tokenStruct));
  
  while (token.flag != 1){
  
      int size = 0;
  
      //get the size of the array up until the null character
      while (token.token[size] != '\0'){
          size++;
      }
  
      if (size == 1) {
          //check for the one char things first
          switch (token.token[0])
          {
              case '(':
                  token.tokenType = 0;
                  break;
              case ')':
                  token.tokenType = 0;
                  break;
              case ';':
                  token.tokenType = 0;
                  break;
              case '+':
                  token.tokenType = 1;
                  break;
              case '-':
                  token.tokenType = 1;
                  break;
              case '/':
                  token.tokenType = 1;
                  break;
              case '*':
                  token.tokenType = 1;
                  break;
              default:
                  if (isdigit(token.token[0])) {
                      token.tokenType = 2;
                  } else {
                      token.tokenType = 3;
                  }
                  break;
          }
  
      } else {
  
          bool isStr;
  
          int i = 0;
          //check for the more than one character
          while (token.token[i] != '\0'){
  
              //check if it's a string or digits
              if (isdigit(token.token[0])) {
                  isStr=false;
              } else{
                  //set up the bools to show it is a string
                  isStr=true;
                  break;
              }
          }
  
          //if it is a string token type 3
          if (isStr) {
              token.tokenType = 3;
          } else {
              //if not then it's digits and token type 2
              token.tokenType = 2;
          }
  
      }
  
      //print out the token and token type
      cout &lt;&lt; "Token type is: " &lt;&lt; token.tokenType &lt;&lt; "Token value is: " &lt;&lt; token.token &lt;&lt; "\n";
  
      //read the pipe again and start the process all over
      read(pipeTwo[0], (char*)&amp;token, sizeof(tokenStruct));
  }
  
  exit(0);
  }
  
  int main()
  {
  
  //create the pipes for reading and writing between processes
  pipe(pipeOne);
  pipe(pipeTwo);
  
  //fork off both processes
  int value = fork();
  int value2 = fork();
  
  //do the process for the first fork
  if(value == 0){
  
      //fork one
      dataProcess();
  
  } else {
  
      wait(0);
  
  }
  
  //do the process for the second fork
  if (value2 == 0) {
      //fork two
  
      //the token classifer function for the second fork
      tokenClassifer();
  
  } else {
      cout &lt;&lt; "Type some tokens (or just press enter to quit) \n";
      //this is all of the parent functions        
      for (string line; getline(cin, line); )
      {
  
          inputStruct input;
          if (line.empty())
          {
              // if the line is empty, that means the user didn't
              // press anything before hitting the enter key
              input.flag = 1;
              write( pipeOne[1], (char*)&amp;input, sizeof(inputStruct));
              break;
          } else {
  
              //else copy the string into an array
              strcpy(input.str, line.c_str());
  
              //set the flag to zero to show everthing is ok
              input.flag = 0;
          }
  
          //write the stuct to the pipe
          write( pipeOne[1], (char*)&amp;input, sizeof(inputStruct));
  
          cout &lt;&lt; "Type some tokens (or just press enter to quit) \n";
      }
  
      wait(0);
  }
  }
  </code></pre>