LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 09-20-2008, 06:10 PM   #1
syfung
LQ Newbie
 
Registered: Sep 2008
Posts: 1

Rep: Reputation: 0
Question in process redirection


I am trying to write a program to run ls ../ | grep sg | sort
with execvp and pipe in linux
The program does what I want it to do but the sequence is wrong.
The shell always prompt before the result.
How can I print the result before the shell prompt?
Here is my code:
Code:
#include <stdio.h>
#include <unistd.h>
int main(){
        char cmd[255];
        int fd[2];
        int fd2[2];
        int i;
        pid_t id;
        pipe(fd);
        pipe(fd2);
        for(i = 1; i < 4; i++){
                id = fork();
                if(id==0){
                        switch (i){
                                case(1): close(fd[0]);
                                    close(fd2[0]);
                                    close(fd2[1]);
                                    dup2(fd[1],STDOUT_FILENO);
                                    char * args1[] = { "ls", "../", NULL};
                                    execvp(args1[0],args1);
                                    break;
                                case(2): close(fd2[0]);
                                    dup2(fd2[1],STDOUT_FILENO);
                                    close(fd[1]);
                                    dup2(fd[0],STDIN_FILENO);
                                    char *args2[] = {"grep","sg",NULL};
                                    execvp(args2[0],args2);
                                    break;
                                case(3): close(fd[0]);
                                    close(fd[1]);
                                    close(fd2[1]);
                                    dup2(fd2[0],STDIN_FILENO);
                                    char *args3[] = {"sort",NULL};
                                    execvp(args3[0],args3);
                                }
                }else{
                        waitpid(id);
                }
        }
        return 0;
}
 
Old 09-20-2008, 07:56 PM   #2
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Change your else statement to something like this:
Code:
        pid_t id, pgid; /*(change at top)*/

/*...*/

                 else{
                        /*put all in a new process group*/
                        if (i == 1) pgid = id;
                        setpgid(id, pgid);
                }
Right before all execvp statements, put this:
Code:
                                    /*stop the process to wait for the others*/
                                    raise(SIGSTOP);
Lastly, place this statement after the for loop:
Code:
        int status, error;

        /*wait for all to stop (ignoring interrupts)*/
        while ( ((error = waitpid(-pgid, &status, WUNTRACED)) < 0 && errno == EINTR) ||
                (error == 0 && (WIFSTOPPED(status) || WIFEXITED(status))) )
        if (error == 0 && --i <= 1) break;

        /*continue the process group*/
        killpg(pgid, SIGCONT);

        /*wait for all processes to exit*/
        while (waitpid(-pgid, NULL, 0x00) == 0 || errno == EINTR);
What this will do is cause all child processes to stop right before execvp to ensure that all are ready before any execvp. Once the parent determines all are stopped with waitpid, it continues them all with SIGCONT. I didn't actually try this with your code, but it's an adaptation of a pattern I normally use. It isn't perfect, but it's a start.
ta0kira

PS The last waitpid line probably does what you're looking for, but the rest should also be in there.

PPS You might also consider signal(SIGPIPE, SIG_IGN); in case a child exits and causes a pipe signal in the parent: this will keep the parent from terminating with stopped children.

P3S You also need to take into account fork being negative.

Last edited by ta0kira; 09-20-2008 at 08:58 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Newbie on forking child process and I/O redirection neo_in_matrix Programming 4 09-16-2005 04:05 AM
Apache redirection question... WeNdeL Linux - Software 2 04-01-2004 11:48 AM
Redirection question... Zeracles *BSD 0 02-21-2004 12:11 PM
redirection the process stdout do1do Linux - Security 3 11-24-2003 12:39 AM
redirection process stdout do1do Linux - General 2 11-23-2003 10:06 PM


All times are GMT -5. The time now is 07:23 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration