title: C Unix Pipes Example
body: <p>Trying to implement a shell, mainly piping. I've written this test case which I expect to simply pipe ls to wc...it definitely doesn't work as expected. It prints ls to the terminal then prints memory exhausted.
  I'm very lost in how to fix this and get it to work. find_path works in all of my tests.</p>
  
  <p>Edit - I have to use execv for the project, its a class thing, but I've tried it with execvp just in case and it does the exact same thing. Also this is just an example, a test to see why it does not work, I call fork twice once for both commands and waitpid because I have nothing else to do.</p>
  
  <pre><code>#include &lt;unistd.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/stat.h&gt;
  #include &lt;stdio.h&gt;
  int find_path(char* execname, char** dst)
  {        
          char *path = getenv("PATH");
          path = strdup(path);
          char *pos;
          path = strtok_r(path, ":", &amp;pos);
          char *originalpath  = path;
          do
          {
                  char* test = (char*)calloc(strlen(path) + strlen(execname) + 2, sizeof(char));
                  test = strcpy(test, path);
                  int testlen = strlen(test);
                  (*(test+testlen)) = '/';
                  strcpy(test + testlen + 1,execname);
                  struct stat buf;
                  int result = stat(test, &amp;buf);
                  if (result == 0)
                  {
                          *dst = test;
                          free (originalpath);
                          return 1;
                  }
                  else
                  {
                          free(test);
                  }
  
          } while ((path = strtok_r(NULL, ":", &amp;pos)) != NULL);
          free(originalpath);
          return 0;
  }
  
  int main()
  {
      char *cmd1 = "ls";
      char *cmd2 = "wc";
      int filedes[2];
      pipe(filedes);
      char** argv = (char**)calloc(1, sizeof(char*)); 
      argv[0] = (char*)malloc(sizeof(char*));
      argv[0] = NULL;
  
      pid_t pid = fork();
      if (pid == 0)
      {
          char *path;
                  find_path(cmd1, &amp;path);
          dup2(filedes[1],stdout);
  
          execv(path,argv); 
      }
      pid = fork();
      if (pid == 0)
      {
          dup2(filedes[0], stdin);
          char *path;
          find_path(cmd2, &amp;path);
          execv(path, argv);
  
      }
      else
          waitpid(pid);
  
  }
  </code></pre>