Thread: Handling I/O redirections in my shell.

  1. #1
    Registered User
    Join Date
    Apr 2006
    Location
    Beirut, Lebanon
    Posts
    20

    Handling I/O redirections in my shell.

    Hi all.
    This is my first post here, and i need urgent help with a programming assignment.
    I am working on an assignment which requires me to build a simple shell. My shell must handle simple commands with arguements and ones with piping and I/O redirection.
    The problem is i have no idea how to implement this redirection.
    To further explain, my program reads the user's input such as: "ls -1 > text.txt" and does what a normal shell does. The problem is redirecting one's output as an input and the reverse. I have to execute two of the commands by forking two children and execve-ing. Then i need to do the redirection thing.
    I have no idea were to start. I suppose it has to do with piping? I'm not sure.

    Thanks alot for your help!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    The system calls you need to research are
    pipe()
    dup()
    close()
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Apr 2006
    Location
    Beirut, Lebanon
    Posts
    20
    ok, i did a little reasearch and came up with a solution.
    - For redirecting the input of a process to a file, such as: ls < text.txt
    I do dup (fd[0], 0). And then i run ls in child 1 and fork a new child that reads the text.txt and sends it to ls as input.

    - For redirecting the input of a process to another program, such as: ls > wc
    I do dup (fd[0], 0) in child 1and dup (fd[1], 1) in the second child.

    - For redirecting the output of a process to a file, such as: ls > text.txt
    I use do dup (fd[1], 1). And then i run ls in child 1 and fork a new child that reads the output from ls with read() and writes it in a file.

    Is that it? Am i totally lost?
    Other than that, i know how to use pipe and close.
    Thanks.
    Last edited by sbho; 04-11-2007 at 01:45 PM.

  4. #4
    Registered User
    Join Date
    Apr 2006
    Location
    Beirut, Lebanon
    Posts
    20
    Oh and just one thing.
    I am working with signals, so i've defined my own signal handler, but can't type cast it to SignalHandler in the signal method (second parameter). I have included signal.h but it doesn't work. it still says undefined.
    Why is that?
    thanks.

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    SignalHandler? Sounds very much unlike anything likely to be in the POSIX standard.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    According to the signal manpage, the following is the proper prototype for a handler:

    Code:
    typedef void (*sighandler_t)(int);
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    And no cast should be necessary - if you have to cast, your handler's prototype is incorrect.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Registered User
    Join Date
    Apr 2006
    Location
    Beirut, Lebanon
    Posts
    20
    This is from the tutorial:
    Code:
    #include <ctype.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h>
    
    char *prog;     /* program name -- always in argv[0] */
    char temp_filename[20];     /* template for a temporary file */
    
    /** Function to act as an interrupt handler. */
    int handle_ctl_c()
    {
        fprintf(stderr, "%s: handle_ctl_c: caught interrupt signal.\n",prog);
        fprintf(stderr, "%s: handle_ctl_c: remove temporary file %s\n",prog, temp_filename);
        unlink(temp_filename);
        exit(0);
    }
    
    int main(int argc, char *argv[])
    {
        FILE *file_p;     /* file pointer for temporary file */
        prog = argv[0];     /* program name for diagnostic output */
    
        /* create temporary file */
        sprintf(temp_filename, "tmp%d", getpid());
        file_p = fopen(temp_filename, "w");
        fprintf(file_p, "Temporary file generated by process %d.\n",getpid());
        fclose(file_p);
        fprintf(stderr, "%s: created temporary file %s\n",prog, temp_filename);
    
        /** Ignore interrupt signal (SIGINT) for 5 seconds. */
        signal(SIGINT, SIG_IGN);
        fprintf(stderr, "%s: SIGINT is now ignored.\n", prog);
        fprintf(stderr, "%s: ctl-c is now ineffective.\n", prog);
        sleep(5);
    
        /** handle_ctl_c will be called when a SIGINT is received. */
        signal(SIGINT, (SignalHandler) handle_ctl_c);
        fprintf(stderr, "%s: handle_ctl_c is now the SIGINT signal handler.\n",prog);
        sleep(5);
    
        /** SIGINT will now interrupt the program. */
        signal(SIGINT, SIG_DFL);
        fprintf(stderr, "%s: SIGINT now has the default handler.\n", prog);
        sleep(5);
    
        /** remove the temporary file created earlier. */
        fprintf(stderr, "%s: remove temporary file %s\n",prog, temp_filename);
        unlink(temp_filename);
        exit(0);
    }

  9. #9
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    The handle_ctl_c function should take an int as a parameter, which will be the signal which was recieved (SIGINT in this case).

    Edit: It should also have a void return type, not int.
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by XSquared View Post
    The handle_ctl_c function should take an int as a parameter, which will be the signal which was recieved (SIGINT in this case).
    Any function with no declared parameters is implicitly variadic, and can be cast silently to any function pointer type. If you do not need the integer parameter (it specified the signal number), there's no need to declare it. This is all within the bounds of normal C usage.

    Had it been declared as int handler(void), this would not be the case. Remember that no declared parameters is not the same thing as a void parameter list.

  11. #11
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    Yeah, my brain is stuck in C++ mode at the moment. The warning/error should go away if the return type is declared as void for the function instead of int, I believe.
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  12. #12
    Registered User
    Join Date
    Apr 2006
    Location
    Beirut, Lebanon
    Posts
    20
    Well i changed it to void, but i still get:
    warning: assignment makes integer from pointer without a cast.
    I'm confused. iI'm totally new to this signals thing and it's driving me nutts.

  13. #13
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by XSquared View Post
    According to the signal manpage, the following is the proper prototype for a handler:

    Code:
    typedef void (*sighandler_t)(int);
    So if the type is sighandler_t (as it CLEARLY states here), why are you using SignalHandler? Are you expecting the compiler to somehow guess what you mean?

  14. #14
    Registered User
    Join Date
    Apr 2006
    Location
    Beirut, Lebanon
    Posts
    20
    Dunno!

    I am using sighandler_t, but i'm getting: undeclared (first use in this function).
    Isn't that type supposed to be in signal.h?
    WTF is goin' on??

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by man signal
    The use of sighandler_t is a GNU extension. Various versions of libc
    predefine this type; libc4 and libc5 define SignalHandler, glibc
    defines sig_t and, when _GNU_SOURCE is defined, also sighandler_t.
    That's where "SignalHandler" comes from. Bottom line: don't cast at all. Unless you really need to store the old handler, don't use this type explicitly at all.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. event handling is serialized in MS Visual Studio C++ 2005 ??
    By mynickmynick in forum Windows Programming
    Replies: 3
    Last Post: 08-07-2008, 04:47 AM
  2. why page based I/O can improve performance?
    By George2 in forum C Programming
    Replies: 1
    Last Post: 06-12-2006, 07:42 AM
  3. File I/O both ASCII and binary handling in C++
    By random in forum C++ Programming
    Replies: 6
    Last Post: 08-16-2005, 04:53 AM
  4. What shell is more powerful?
    By xddxogm3 in forum Tech Board
    Replies: 10
    Last Post: 07-24-2004, 10:47 PM
  5. Overlapped I/O and Completion Port :: Winsock
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 10-30-2002, 05:14 PM