Thread: undup2?

  1. #1
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    undup2?

    If I redirect stdout into a pipe with dup2, how can I get it back again?

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    
    int main () {
            FILE *pin, *pout;
            int pp[2], i, chr;
            pipe(pp); 
            pout = fdopen(pp[0], "r");
            pin = fdopen(pp[1], "w");
            close(pp[0]);
            dup2(pp[1],1);
            puts("hello");
            printf("test");
            fclose(pin); //   ?? 
            close(pp[1]);   //  ??
            while((chr=fgetc(pout)) != EOF) printf("%c",chr);
            close(pp[0]);
            fclose(pout);       // everything closed
            puts("hello");
            fflush(NULL);     // and flushed
    }
    (there is no output)

    I recognize that "It is not very useful for a single process to use a pipe to talk to itself", however, I'm trying to get the logic of c redirection. In other contexts (eg. shell scripting) redirecting stdin and stdout is always simple and straightforward -- if you exec 3>$1 you can later exec 1>&3. But in this example, stdout never comes back, even if the file descriptor it was redirected into gets closed, etc.

    Also strange to me is that stderr seems to be included (puts).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    puts doesn't write to stderr, it writes to stdout.

    I don't think I have any good answers for you -- you can try assigning stdout to a FILE* before you dup2, and switching back to that, but I have a sinking suspicion that won't work very well.

    Edit: Of course that's a stupid suggestion, since they'll share a file pointer and will travel (duplicate, whatever) together. I'll be interested to see a solution should you or someone come up with one.
    Last edited by tabstop; 09-22-2008 at 10:50 AM.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by tabstop View Post
    I don't think I have any good answers for you -- you can try assigning stdout to a FILE* before you dup2, and switching back to that, but I have a sinking suspicion that won't work very well.
    No doubt. I am willing to abandon such fruitless researchs immediately. There are some strange things like this (about c) that i guess reflect the fact that no one would really want to do this that way anyway.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I'm pretty sure you can do something like this:
    Code:
    newdes = dup(STDIN);
    dup2(STDIN, pipefd);
    ... stuff that reads the pipe. 
    dup2(STDIN, newdes); 
    close(newdes);
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I tried

    Code:
    dbout=dup(1);    // at beginning
    dup2(1,dbout);  // later
    hoping this would reinstate stdout normally but to no avail, probably because whatever happened to it (attached to closed pipe) also happened to dbout.

    Inspired by http://cboard.cprogramming.com/showthread.php?t=107253 I was screwing around with this & pipe & fork all weekend and the ratio of things "I'm pretty sure you can do" to things "actually not really" was rather poor, I think there is a string of my posts in here about such stuff.

    Basically, I bet you can't write a set of forked processes that successfully pipes "ls" to "grep" to another "grep" (or sort, or sed, or whatever). It doesn't matter, because system("ls | grep e | grep c") works (ie. bash has to do it itself). But it certainly sounds easy, and I thought I came up with a lot of code that looks nice.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Tags for this Thread