Thread: Unix pipe simulation

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    2

    Unix pipe simulation

    I have to build a program that simulates the shell pipe |.
    For an instance, if the user calls my program like this:
    % myprogram ls -1 :: sort :: more
    I have to return the same results that the shell would return to ls -1 | sort |more .
    However, everything I try just fails miserably.
    I have tried something like this, using two pipes:

    Code:
    while(loop through the arguments)
    {
        /* suppose that at this point of the code we know the current program to run, with all it's arguments */    
        fork();
        if(child is running)
        {
            if(this is not the first program)
                change child's stdin to currentpipe's read side
            if(this is not the last program)
                change child's stdout to otherpipe's write side
            close all sides of all pipes
            change current pipe to the other pipe
            run exec
        }
        else /*we are on the parent process */
            wait for the child process
        return 0;
    }
    When I execute it with only one program on the arguments, the results are printed ok, but the program doesn't exit. With more than one argument, nothing happens and the program doesn't exit.
    If I remove the wait for the child, the same scenario happens, with the difference that the program exits.
    What am I doing wrong?

  2. #2

  3. #3
    Registered User
    Join Date
    Mar 2008
    Posts
    2
    Sorry, I forgot to mention I must implement this on Linux.
    I have pasted the real code I'm using on http://pastebin.com/m466397e7
    I have no idea why it doesn't work.
    Thanks for the reply =D

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    That's outside my expertise (and ability to test since I currently don't have a linux box).

    BTW, you can post code here. Just use [code] tags when you do.

    gg

  5. #5
    Registered User
    Join Date
    Jan 2008
    Posts
    290
    Maybe this will give you some inspiration.

    Here's how Bash handles command pipes:
    (I stripped out all the error handling crap, rewrote a couple parts, and added some comments to make it a little clearer)
    Code:
    static int execute_pipeline (COMMAND *command,
                                 int asynchronous,
                                 int pipe_in,
                                 int pipe_out,
                                 struct fd_bitmap *fds_to_close)
    {
      int prev, fildes[2], ignore_return, exec_result;
      COMMAND *cmd;
    
      ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0;
    
      prev = pipe_in;
      cmd = command;
    
      // Loops until it reaches a 'normal' command
      //   (a command that isn't a connection)
      while (cmd && cmd->type == cm_connection &&
             cmd->value.Connection && cmd->value.Connection->connector == '|')
      {
        /* Make a pipeline between the two commands. */
        pipe(fildes);
    
        if (ignore_return && cmd->value.Connection->first)
          cmd->value.Connection->first->flags |= CMD_IGNORE_RETURN;
        
        execute_command_internal (cmd->value.Connection->first, // the command to execute
                                  asynchronous,                 // boolean flag
                                  prev,                         // the input pipe
                                  fildes[1],                    // the output pipe
                                  fd_bitmap);                   // error handling crap
    
        if (prev >= 0)
          close (prev);
    
        prev = fildes[0];
        close(fildes[1]);
    
        cmd = cmd->value.Connection->second;
      }
      // end while loop
    
      /* Now execute the rightmost command in the pipeline.  */
      if (ignore_return && cmd)
        cmd->flags |= CMD_IGNORE_RETURN;
      exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close);
    
      if (prev >= 0)
        close (prev);
    
      return (exec_result);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. cont of IPC using PIPE
    By BMathis in forum C Programming
    Replies: 1
    Last Post: 03-15-2009, 05:16 PM
  2. Pipe class.
    By eXeCuTeR in forum Linux Programming
    Replies: 8
    Last Post: 08-21-2008, 03:44 AM
  3. How to program in unix
    By Cpro in forum Linux Programming
    Replies: 21
    Last Post: 02-12-2008, 10:54 AM
  4. Pipe(): Interprocess or Intraprocess comm?
    By @nthony in forum C Programming
    Replies: 2
    Last Post: 03-28-2007, 07:27 PM
  5. About Unix Programming - Making a career desision
    By null in forum C Programming
    Replies: 0
    Last Post: 10-14-2001, 07:37 AM