Note that there are some explanatory texts on larger screens.

plurals
  1. PO*Almost* Perfect C Shell Piping
    primarykey
    data
    text
    <p>I am writing a small linux shell in C and am so very close to being done. I take in a command from the user and store it in <strong>args</strong>, delimited by spaces. In the following example, let's say that args contains the following:</p> <p><code>args[] = {"ls", "-l", "|", "wc"};</code></p> <p>My function takes in <strong>args</strong> and also takes in how many <strong>pipes</strong> there are. I've commented my code as much as possible. Here it is:</p> <pre><code>int do_command(char **args, int pipes) { // The number of commands to run const int commands = pipes + 1; int i = 0; int pipefds[2*pipes]; for(i = 0; i &lt; pipes; i++){ if(pipe(pipefds + i*2) &lt; 0) { perror("Couldn't Pipe"); exit(EXIT_FAILURE); } } int pid; int status; int j = 0; int k = 0; int s = 1; int place; int commandStarts[10]; commandStarts[0] = 0; // This loop sets all of the pipes to NULL // And creates an array of where the next // Command starts while (args[k] != NULL){ if(!strcmp(args[k], "|")){ args[k] = NULL; // printf("args[%d] is now NULL", k); commandStarts[s] = k+1; s++; } k++; } for (i = 0; i &lt; commands; ++i) { // place is where in args the program should // start running when it gets to the execution // command place = commandStarts[i]; pid = fork(); if(pid == 0) { //if not last command if(i &lt; pipes){ if(dup2(pipefds[j + 1], 1) &lt; 0){ perror("dup2"); exit(EXIT_FAILURE); } } //if not first command&amp;&amp; j!= 2*pipes if(j != 0 ){ if(dup2(pipefds[j-2], 0) &lt; 0){ perror("dup2"); exit(EXIT_FAILURE); } } int q; for(q = 0; q &lt; 2*pipes; q++){ close(pipefds[q]); } // The commands are executed here, // but it must be doing it a bit wrong if( execvp(args[place], args) &lt; 0 ){ perror(*args); exit(EXIT_FAILURE); } } else if(pid &lt; 0){ perror("error"); exit(EXIT_FAILURE); } j+=2; } for(i = 0; i &lt; 2 * pipes; i++){ close(pipefds[i]); } for(i = 0; i &lt; pipes + 1; i++){ wait(&amp;status); } } </code></pre> <p>My problem is that while the program is <em>kind of</em> executing correctly, it is behaving strangely and I was hoping you could help me out.</p> <p>For example hen I run <strong>ls | wc</strong>, the output is that of <strong>ls | wc</strong>, but then it also prints the output of a simple <strong>ls</strong> right below it, even though it should just be the <strong>wc</strong> of the output.</p> <p>As another example, when I try <strong>ls -l | wc</strong>, the first number of <strong>wc</strong> shows up, but then the output of <strong>ls -l</strong> shows up below it, even though it should just be the <strong>wc</strong> of the output.</p> <p>Thanks in advance! :)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload