C Board  

Go Back   C Board > Platform Specific Boards > Linux Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 04-02-2008, 05:51 AM   #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!
spank is offline   Reply With Quote
Old 04-02-2008, 06:14 AM   #2
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
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.
matsp is offline   Reply With Quote
Old 04-02-2008, 06:34 AM   #3
Registered User
 
Join Date: Dec 2005
Posts: 167
yap!
spank is offline   Reply With Quote
Old 04-02-2008, 09:52 AM   #4
Staff software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 6,014
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:

Quote:
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.
brewbuck is offline   Reply With Quote
Old 04-02-2008, 10:43 AM   #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!
spank is offline   Reply With Quote
Old 04-02-2008, 10:46 AM   #6
Staff software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 6,014
You aren't calling pipe() anywhere. Without creating a pipe, how do you expect data to get from one process to another?
brewbuck is offline   Reply With Quote
Old 04-02-2008, 11:11 AM   #7
Cat without Hat
 
CornedBee's Avatar
 
Join Date: Apr 2003
Posts: 8,579
Quote:
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): %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
CornedBee is offline   Reply With Quote
Old 04-02-2008, 11:14 AM   #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 ?
spank is offline   Reply With Quote
Old 04-02-2008, 11:16 AM   #9
Cat without Hat
 
CornedBee's Avatar
 
Join Date: Apr 2003
Posts: 8,579
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
CornedBee is offline   Reply With Quote
Old 04-02-2008, 11:26 AM   #10
Staff software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 6,014
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).
brewbuck is offline   Reply With Quote
Old 04-02-2008, 11:30 AM   #11
Cat without Hat
 
CornedBee's Avatar
 
Join Date: Apr 2003
Posts: 8,579
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
CornedBee is offline   Reply With Quote
Old 04-02-2008, 11:32 AM   #12
Staff software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 6,014
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.
brewbuck is offline   Reply With Quote
Old 04-02-2008, 11:35 AM   #13
Cat without Hat
 
CornedBee's Avatar
 
Join Date: Apr 2003
Posts: 8,579
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
CornedBee is offline   Reply With Quote
Old 04-03-2008, 05:16 PM   #14
Registered User
 
Join Date: Mar 2007
Posts: 76
> 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.
idelovski is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

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


All times are GMT -6. The time now is 12:02 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22