Thread: Redirect stdout using dup

  1. #1
    Registered User
    Join Date
    Dec 2005
    Posts
    167

    Redirect stdout using dup

    Code:
    int main(int argc, char *argv[])
    {
            int f = open("test.txt", O_CREAT|O_RDWR, 0666);
            int out=dup(1);
    
            if(f==-1)
                    perror("open()");
    
            dup2(f, 1);
    
            printf("Hello world\n");
    
            printf("%d\n",close(f));
            close(1);
    
            printf("test\n");
    
            return 0;
    }
    I want to redirect stdout to a file ... and after I print something I want to go back to print to the usual screen output. I can't get back to printing on the screen

    Please help!

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You probably want to restore the original stdout after you've dup'd it to be f.

    --
    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.

  3. #3
    Registered User
    Join Date
    Dec 2005
    Posts
    167
    yap!

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Also, using dup2() is usually redundant. These two are equivalent:

    Code:
    fd = open(...);
    dup2(fd, 1);
    And:

    Code:
    fd = open(...);
    close(1);
    dup(fd);
    On UNIX, the next new file descriptor is always the last one closed, unless nothing was closed, in which case it picks a free one. Thus, close(1) ensures that the following call to dup(fd) will duplicate it to file descriptor 1.

    The first example is one line of code shorter, but the second is generally preferable, because of this:

    If newfd was open, any errors that would have been reported at close()
    time, are lost. A careful programmer will not use dup2 without closing
    newfd first.
    And because you are about to close() anyway, there's no point in calling dup2() since dup() ensures you'll get the correct descriptor. However, in this case, you are not closing the original stdout, but duping it over to some new descriptor, so the problem doesn't show up here. It can show up elsewhere though.

  5. #5
    Registered User
    Join Date
    Dec 2005
    Posts
    167
    Code:
    #include <fcntl.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[]) 
    {
    	int pid, status;	
    	int pid1, pid2;
    
    
    	switch(pid=fork())
    	{
    		case 0:
    		{
    			close(1);dup(0);
    		
    			pid1 = fork();		
    
    			
    			if(pid1==0)
    			{
    
    				execl ("/bin/ls", "ls", "-1", (char *)0);
    				exit(-1);
    			}
    			else
    			{
    				wait(&status);
    			}
    
    			pid2 = fork();
    			
    			if(pid2==0)
    			{
    				execl ("/bin/cat", "cat", (char *)0);
    				exit(-1);
    			}
    			else
    			{
    				wait(&status);
    			}
    
    			break;
    		}
    		default:
    		{
    			wait(&status);
    		}
    	}
    
    	return 0;
    }
    I want this to have the effect of ls -1 | cat so I redirect the stdout to stdin. Where do I go wrong? Please help!

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    You aren't calling pipe() anywhere. Without creating a pipe, how do you expect data to get from one process to another?

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    On UNIX, the next new file descriptor is always the last one closed
    Not true. You get the lowest available file descriptor.
    Code:
    #include <stdio.h>
    #include <unistd.h>
    
    int main(void)
    {
      int sout = dup(1);
      close(1);
      close(2);
      int sin2 = dup(0);
      dup2(sout, 1);
      printf("dup(stdin): &#37;d\n", sin2);
      return 0;
    }
    Prints:
    dup(stdin): 1
    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
    Dec 2005
    Posts
    167
    Code:
    #include <fcntl.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[]) 
    {
    	int pid, status;	
    	int pid1, pid2;
    	int filedes[2];
    
    	pipe(filedes);
    
    	switch(pid=fork())
    	{
    		case 0:
    		{
    			//close(1);dup(0);		
    
    			pid1 = fork();		
    		
    			if(pid1==0)
    			{
    				dup2(filedes[1], 1);
    			//	close(filedes[0]);
    
    				execl ("/bin/ls", "ls", "-lh", (char *)0);
    				exit(-1);
    			}
    			else
    			{
    				wait(&status);
    			}
    
    			pid2 = fork();
    			
    			if(pid2==0)
    			{
    				dup2(filedes[0], 0);
    			//	close(filedes[1]);
    				execl ("/bin/cat", "cat", (char *)0);
    				exit(-1);
    			}
    			else
    			{
    				wait(&status);
    			}
    			break;
    		}
    		default:
    		{
    			wait(&status);
    		}
    	}
    	close(filedes[0]);
    	close(filedes[1]);
    
    	return 0;
    }
    ok... now 2 questions. why doesn't this program exits ? it remains in cat (i belive). And second why is there the need to close the other side of the pipe ?

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    exec displaces the current process.
    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

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by CornedBee View Post
    Not true. You get the lowest available file descriptor.
    Which is just the last one closed, if you only close one at a time The problem was close(1) immediately followed by close(2).

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Problem? I was just demonstrating that my definition is universally true, while yours, despite the word "always", is just a special case (the last descriptor closed is actually the lowest free one).
    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

  12. #12
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by CornedBee View Post
    Problem? I was just demonstrating that my definition is universally true, while yours, despite the word "always", is just a special case (the last descriptor closed is actually the lowest free one).
    Yeah, I was being facetious. At any rate, the close/dup trick is pervasive.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    So it is, but luckily only for the low descriptors stdin, stdout and stderr. Anything above that and it becomes unreliable.
    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

  14. #14
    Registered User
    Join Date
    Mar 2007
    Posts
    142
    > And second why is there the need to close the other side of the pipe ?

    Parent doesn't need those descriptors - two of the children need it and unless you close them,
    the process that reads would wait forever and I think that is why cat blocks in your case. It never
    receives eof or something like that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Redirect stdout
    By GoLuM83 in forum C Programming
    Replies: 6
    Last Post: 12-15-2006, 04:17 PM
  2. redirect stdout to editbox
    By kerm1t in forum Windows Programming
    Replies: 1
    Last Post: 05-11-2005, 10:32 PM
  3. Problems with switch()
    By duvernais28 in forum C Programming
    Replies: 13
    Last Post: 01-28-2005, 10:42 AM
  4. Who to redirect stdout to a file in C
    By edugarcia in forum Linux Programming
    Replies: 3
    Last Post: 10-01-2004, 12:18 AM
  5. redirect stdout to a file?
    By Brian in forum C Programming
    Replies: 5
    Last Post: 01-15-2002, 01:06 PM