d89cb@efd.lth.se (Christian Brunschen) (07/08/90)
I'm working an a small program that will function as an i/o filter for mail (1) -- fyi, so tat all occurrences of 'mail' can be replaced with 'femail' (No, not my idea -- I'm doing this for a friend :) Anyway, i could use popen(), but that only lets me specify either stdin or stdout replacement -- not both, the way I need it. So I thought of : * creating two pipes * fork()ing * in the child process, redirect stdin to one pipe & stdout to the other * in the cild process, execve() mail(1) * in the parent process, perform i/o and filtering BUT (and here's my question) : how do I actually redirect stdin / stdout to the pipes I created ? I tried stdin = fdopen (MyPipe [1], "r"); but that, naturally, didn't work (illegal lhs of assignment) So, if anyone has any ideas, please tell me; All help will be greatly appreciated! aTdHvAaNnKcSe -- Christian Brunschen -- +--------------------------------+---------------------------------+ | Internet : d89cb@efd.lth.se | IRC : snooker | +------------------------------------------------------------------+ | Apart from the unknowns, everything is obvious." | | - ZORAC, board computer of the Shapieron, in | | James P. Hogan's "Giants' Star" | +------------------------------------------------------------------+
cpcahil@virtech.uucp (Conor P. Cahill) (07/09/90)
In article <1990Jul8.120742.18213@lth.se> d89cb@efd.lth.se (Christian Brunschen) writes: >So I thought of : >* creating two pipes >* fork()ing >* in the child process, redirect stdin to one pipe & stdout to the other You have to be very carefule to avoid a deadlock when using pipes in both directions between two processes. >BUT (and here's my question) : >how do I actually redirect stdin / stdout to the pipes I created ? >stdin = fdopen (MyPipe [1], "r"); This is real close. what you do is: (void) fclose(stdin); /* close stdin */ (void) close(0); /* should be unnecessary */ i = dup(pipe_read_fd); /* i should be 0 */ (void) fdopen(i, "r"); /* stdin should map to pipe 0 */ close(pipe_read_fd); /* dont need anymore */ The reason for doing the dup() & fdopen is to ensure that fd0 gets assigned to stdin since there may be software that does a read(0,...). Note that I did no error checking. You should add the appropriate error checking for each step (other than the close(0) which should fail if stdin was appropriately mapped to 0). -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
leo@ehviea.ine.philips.nl (Leo de Wit) (07/10/90)
In article <1990Jul08.223103.1244@virtech.uucp> cpcahil@virtech.UUCP (Conor P. Cahill) writes: |In article <1990Jul8.120742.18213@lth.se> d89cb@efd.lth.se (Christian Brunschen) writes: [] |>BUT (and here's my question) : |>how do I actually redirect stdin / stdout to the pipes I created ? | |>stdin = fdopen (MyPipe [1], "r"); | |This is real close. what you do is: | | (void) fclose(stdin); /* close stdin */ | (void) close(0); /* should be unnecessary */ | i = dup(pipe_read_fd); /* i should be 0 */ | (void) fdopen(i, "r"); /* stdin should map to pipe 0 */ | close(pipe_read_fd); /* dont need anymore */ | |The reason for doing the dup() & fdopen is to ensure that fd0 gets |assigned to stdin since there may be software that does a read(0,...). | |Note that I did no error checking. You should add the appropriate error |checking for each step (other than the close(0) which should fail if |stdin was appropriately mapped to 0). The dup() should indeed return 0 (or alternatively, use dup2(pipe_read_fd,0)), but I think there is no guarantee that fdopen(i,"r") returns stdin (though 'old-style' stdio implementations will probably do so). How about: (void)dup2(pipe_read,fileno(stdin)); (void)close(pipe_read); (I'm pretty sure there are problems with this as well)? Leo.