Thread: Can we use select() to capture output from execl()?

  1. #1
    Watch for flying houses. Nessarose's Avatar
    Join Date
    Sep 2004
    Posts
    46

    Can we use select() to capture output from execl()?

    Hello, I'm writing a server side program that needs to run a program on the UNIX server using execl() or execlp(), and I need to somehow return this output back to the client side. The server handles multiple clients by using the select() function. Right now I have this working by returning the results of execl() to the client by using pipe() and dup(). I was wondering if it would be possible to do this with select() and if so, how?

    Thanks in advance for any 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,659
    > Right now I have this working by returning the results of execl() to the client by using pipe() and dup().
    So the child processes on the server side are writing directly to the file descriptors which are used for sending data back to each client?

    > I was wondering if it would be possible to do this with select() and if so, how?
    select is for testing whether there is anything useful on a set of file descriptors.
    How much sense it makes to use it depends on who's doing the reading and writing in your scenario.
    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
    Watch for flying houses. Nessarose's Avatar
    Join Date
    Sep 2004
    Posts
    46
    So the child processes on the server side are writing directly to the file descriptors which are used for sending data back to each client?

    Yes. This is the snippet of code I have that takes the output of execl() and pipes it to stdout or stderr depending on the situation. The result of the program (error or no) is sent to the client.

    Code:
    /* child process */
    if (fork() == 0) {
            /* fd is for duplicating stdout and
             * fderr is for duplicating stderr 
             */
            close(1);
            dup(fd[1]);
            close(2);
            dup(fderr[1]);
            close(fd[0]);
            close(fd[1]);
            close(fderr[0]);
            close(fderr[1]);
    
            execlp("ps", "ps", NULL);
            _exit(EXIT_SUCCESS);
    } else {
            /* parent process */
            .
            .
            .
            close(fd[1]);
            close(fderr[1]);
    
            /* message was sent to stdout */
            size_read = read(fd[0], client_msg, BUFSIZ);
    
            /* if size_read is <= 0, then message was sent to stderr */
            if (size_read <= 0) {
                size_read = read(fderr[0], client_msg, BUFSIZ);
            }
            write(*current_fd, client_msg, strlen(client_msg));
    }
    I'm just wondering if this is the right way to do it. It works, but I'd like to know if there's a more efficient way of doing it.


    select is for testing whether there is anything useful on a set of file descriptors.
    How much sense it makes to use it depends on who's doing the reading and writing in your scenario.


    How would I use it to determine if stdout and stderr is active? Most of the examples I've seen so far only check if stdin is active. If you could explain it to me, or hyperlink me to a source that explains it, that'd be great.

    Thanks!

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You created fd and fderr using pipe() ?

    So the real answer to my question is "no".
    The child sends data back to the parent, and the parent sends it to the client at the other end of the wire.

    > How would I use it to determine if stdout and stderr is active?
    Select on output streams means that you can send some data without blocking.
    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.

  5. #5
    Watch for flying houses. Nessarose's Avatar
    Join Date
    Sep 2004
    Posts
    46
    Quote Originally Posted by Salem
    You created fd and fderr using pipe() ?
    Yes, was that wrong?

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well if you want the child to send directly to the client (not via the parent), then I'd probably try something like this
    Code:
            close(1); /* current stdout */
            dup(*current_fd); /* now goes to the outbound socket connection */
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A fifo file and select() problem
    By itsdafoetime in forum C Programming
    Replies: 2
    Last Post: 03-08-2009, 02:23 AM
  2. 2d game
    By JordanCason in forum Game Programming
    Replies: 5
    Last Post: 12-08-2007, 10:08 PM
  3. Having trouble making a function do what I want.
    By Shamino in forum C++ Programming
    Replies: 9
    Last Post: 12-07-2007, 11:20 AM
  4. Trying to store system(command) Output
    By punxworm in forum C++ Programming
    Replies: 5
    Last Post: 04-20-2005, 06:46 PM
  5. Output problems with structures
    By Gkitty in forum C Programming
    Replies: 1
    Last Post: 12-16-2002, 05:27 AM