Pipe Functionality


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Pipe Functionality
# 1  
Old 09-30-2011
Pipe Functionality

Hi,

I am trying to emulate the '|' functionality through pipe function call. I am passing the o/p of exec in parent as input to the exec in child. The buf is readin the o/p but the exec in child is not working. Can somebody checkout the code and point where am i going wrong or missing something.
Code:
ls | wc -l

Code:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>

int main(){

int piped[2];//pipe descriptors
char buf[16 * 1024];
pid_t child;

if(pipe(piped)<0){
   fprintf(stderr,"pipe creation failed \n");
   exit(-1);
 }
 
 if((child = fork()) < 0){
 fprintf(stderr,"process creation failed \n");
 exit(-1);
 }
 
 else if(child == 0){
        close(piped[1]);//close the write end of child
         close(0);//close stdin
         if((dup2(piped[0],0)) < 0){//duplicate read end with stdin;
        fprintf(stderr,"duplication of pipe desc failed \n");
        exit(-1);
        }
        
              int linesrd = read(piped[0],buf,sizeof(buf));
        
        printf("The noof bytes read are %d \n",linesrd);
       
        if(linesrd < 0)
        fprintf(stderr,"Read error \n");
       
        
        buf[strlen(buf)-1] = '\0';
       
       char *buf1 = buf;
      execlp("wc","wc","-l",buf1,NULL); 
        //exit(1);
        }
        
        else{
        
        close(piped[0]);//close read end of pipe
        close(1);//close stdout
        if(dup2(piped[1],1) < 0){//duplicate write end with stdout
        fprintf(stderr," duplication error \n");
        exit(-1);
        }
        
        int w=execlp("ls","ls",NULL);
        
        close(piped[1]);
        
        if(w<0){
        fprintf(stderr,"Something went wrong \n");
        exit(-1);
        }
        
        wait(NULL);
        
        }
        
        return(0);
        }

output of code:
Code:
ameya@ameya-Dell-System-Inspiron-N4110:~/os_concepts$ The noof bytes read are 247 
wc: a.out
basic_shell
Chapter6.pdf
communication
eof.c
fork-wait-exec
l5.pdf
OS_scheduling
pipe
pipe1.c

Regards,
Ameya



Moderator's Comments:
Mod Comment Video tutorial on how to use code tags in The UNIX and Linux Forums.

Last edited by Franklin52; 10-01-2011 at 05:59 AM.. Reason: Please use code tags for data and code samples, thank you
# 2  
Old 09-30-2011
You made a pretty good try at it, but it's tricky. My comments:

Code:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>

int main(){

int piped[2];//pipe descriptors
char buf[16 * 1024];
pid_t child;

if(pipe(piped)<0){
   fprintf(stderr,"pipe creation failed \n");
   exit(-1);
 }
 
 if((child = fork()) < 0){
 fprintf(stderr,"process creation failed \n");
 exit(-1);
 }
 
 else if(child == 0){
        close(piped[1]);//close the write end of child
         // You don't need to close stdin, dup2() does that.
         close(0);//close stdin
         if((dup2(piped[0],0)) < 0){//duplicate read end with stdin;
        fprintf(stderr,"duplication of pipe desc failed \n");
        exit(-1); // exit only takes positive values.
        }

        // Why are you reading from the pipe?  that's wc's job.
        int linesrd = read(piped[0],buf,sizeof(buf));
        
        printf("The noof bytes read are %d \n",linesrd);
       
        if(linesrd < 0)
        fprintf(stderr,"Read error \n");
       
        // how could strlen() possibly tell you the length of a string that
        // doesn't already have a null terminator??  Just use 'linesrd'.
        buf[strlen(buf)-1] = '\0';

       // Just give execlp buf directly, no need to make another pointer
       // to the exact same memory.
       char *buf1 = buf;

      // Feeding wc another commandline parameter tells it to
      // read from the file NAMED that.  It won't read from stdin.
      execlp("wc","wc","-l",buf1,NULL); 
        //exit(1);
        }
        
        else{        
        close(piped[0]);//close read end of pipe
        // you don't need to close stdout, dup2() does that.
        close(1);//close stdout
        if(dup2(piped[1],1) < 0){//duplicate write end with stdout
        fprintf(stderr," duplication error \n");
        exit(-1);
        }
        
        int w=execlp("ls","ls",NULL);
        // execlp does not create a new process.
        // execlp REPLACES your process.
        // Any code below it only runs when exec fails!
        
        close(piped[1]);
        
        if(w<0){
        fprintf(stderr,"Something went wrong \n");
        exit(-1);
        }
        
        wait(NULL);
        
        }
        
        return(0);
        }

...and corrections:

Code:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>

int main(){
        int piped[2];//pipe descriptors
        pid_t child;

        if(pipe(piped)<0){
                fprintf(stderr,"pipe creation failed \n");
                exit(-1);
        }

        if((child = fork()) < 0){
                 fprintf(stderr,"process creation failed \n");
                exit(-1);
        }
        else if(child == 0){
                close(piped[1]);//close the write end of child
                if((dup2(piped[0],0)) < 0)
                {//duplicate read end with stdin;
                        fprintf(stderr,"duplication of pipe desc failed \n");
                        exit(-1);
                }
                // wc -l will read from fd 0 directly once execlp() replaces
                // this child with it.  This is because it keeps any open files.
                execlp("wc","wc","-l",NULL);
                exit(1); // Yes, you need this in case something goes wrong!
        }
        else{
                close(piped[0]);//close read end of pipe
                if(dup2(piped[1],1) < 0){//duplicate write end with stdout
                        fprintf(stderr," duplication error \n");
                        exit(-1);
                }

                // ls will feed its output directly into fd 1 once execlp() replaces our process with it.
                // This is because exec() keeps the same files open once it's replaced, including pipes, sockets, etc.
                int w=execlp("ls","ls",NULL);
                if(w < 0) perror("Coudln't execlp"); // perror tells you WHAT went wrong
                exit(1);
        }
}

# 3  
Old 09-30-2011
Thanks corona, went wrong conceptually , over-thought i guess.......
# 4  
Old 10-12-2011
Hey Corona ,

Need your help again, related to piping .

eg:
Code:
ls -al|grep -i sam.

I have been asked to implement advanced shell, support pipe features along with others.

i am currently only testing for pipe feature and here is the below function.
Code:
void exec(int argc,char *in[]){
int pipefd[2];
char *argv[20];
pid_t pid,pid2,child,child2;
int j,status,i;
i=0;

/* Creation of pipes for communication */
if(pipe(pipefd) < 0){
   perror("Pipe failure \n");
   exit(-1);
   }
  
        
         if((pid = fork())<0){
         perror("Fork Failure \n");
         exit(-1);
         }
         
         else if(pid == 0){
         printf("In Child1 process args are %s \n",in[i]);          
                    
             printf(" In child1 process args are *%s* * %s \n",argv[0],argv[1]); 
            close(pipefd[0]);//close the read end
            
            if(dup2(pipefd[1],1) < 0){//duplicate write end with stdout
          perror("duplication failed \n");
          exit(-1);    
            }
            
            parse(in[i],argv);
            if((execvp(argv[0],argv)) < 0)
            {perror(" execvp error \n");
            exit(1);
            }
                  //close(pipefd[1]); 
                  child = waitpid(pid,&status,0);
            }
            
            if((pid2 = fork()) < 0){
			  perror(" Fork failed 1 : ");
			  exit(-1);
		  }
		     
		     else if(pid2 == 0){
				 
				         
          close(pipefd[1]);//close the write end of the pipe
          
          if(dup2(pipefd[0],0) < 0){  //duplicate read end with stdin
          perror("duplication failed \n");
          exit(-1);
          }     
          
          //printf(" %s  %s \n",argv1[0],argv1[1]); 
          
          parse(in[i+1],argv); // parse the input to create arg array
          printf("In child2 args are %s * %s %s\n",argv[0],argv[1],argv[2]);
          if((execvp(argv[0],argv)) < 0){
            perror(" execvp child error \n");
            exit(1);
            }
            //close(pipefd[0]);//close after command is completed
           
            }
            else
            {/* the main parent process */
               close(pipefd[0]);
               close(pipefd[1]);
               child2 = waitpid(pid2,&status,0);
		   }
return;
}

As seen above i have forked two children in the parent (i.e shell process) to execute 2 commands.

everything is working am getting output also but a zombie process is left as 2 fork calls create 4 processes and only 2 process are required.

I tried with different variation of wait but somehow its not working.

Output:
Code:
Shell$>-rwxr-xr-x 1 ameya ameya   7465 2011-09-09 02:34 sample
-rwxr-xr-x 1 ameya ameya   7135 2011-09-14 23:57 sample2
-rw-r--r-- 1 ameya ameya    246 2011-09-14 23:57 sample2.c
-rwxr-xr-x 1 ameya ameya   7426 2011-09-15 01:49 sample3
-rw-r--r-- 1 ameya ameya   1294 2011-09-15 01:49 sample3.c
-rwxr-xr-x 1 ameya ameya   7284 2011-09-19 14:42 sample4
-rw-r--r-- 1 ameya ameya    333 2011-09-19 14:42 sample4.c
-rwxr-xr-x 1 ameya ameya   7135 2011-09-27 00:51 sample7
-rw-r--r-- 1 ameya ameya    807 2011-09-09 02:33 sample.c

Code:
Shell$>Currently in child2 process *grep *-i *sam 
 execvp error 
: No such file or directory

Regards,
Ameya


Moderator's Comments:
Mod Comment Video tutorial on how to use code tags in The UNIX and Linux Forums.

Last edited by Franklin52; 10-13-2011 at 03:30 AM.. Reason: Please use code tags, thank you
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

Zip -r Functionality

Hi , I've written the following code to zip the big file $dir_temp ="/home/etc/hst zip -r $dir_temp/file_nm.zip $dir_temp/file_nm The zip file has been created . When I try to UNZIP the file with the following command unzip file_nm.zip The file got unzipped but created in the... (3 Replies)
Discussion started by: smile689
3 Replies

2. Shell Programming and Scripting

How to ignore Pipe in Pipe delimited file?

Hi guys, I need to know how i can ignore Pipe '|' if Pipe is coming as a column in Pipe delimited file for eg: file 1: xx|yy|"xyz|zzz"|zzz|12... using below awk command awk 'BEGIN {FS=OFS="|" } print $3 i would get xyz But i want as : xyz|zzz to consider as whole column... (13 Replies)
Discussion started by: rohit_shinez
13 Replies

3. UNIX for Dummies Questions & Answers

Command Functionality

Hi everyone, today i need that someone help to understand this particular line of command. So you can explain to me step by step, it will be great. ---------- Post updated at 11:53 AM ---------- Previous update was at 11:51 AM ---------- (9 Replies)
Discussion started by: Newer
9 Replies

4. Shell Programming and Scripting

using arrays and also help with array.contains functionality

here is what i have... i=1 while read line do if grep -i-q "create procedure"<<<$line then startline="$line" endline="blahblah" Get procedure name into a variable named procName procName="procedure name is stored" do some... (2 Replies)
Discussion started by: vivek d r
2 Replies

5. Shell Programming and Scripting

Replace pipe with Broken Pipe

Hi All , Is there any way to replace the pipe ( | ) with the broken pipe (0xA6) in unix (1 Reply)
Discussion started by: saj
1 Replies

6. UNIX for Dummies Questions & Answers

using functionality in another ksh

i have a function defined in one ksh i want to use the same functionality in another ksh i am using . ../<ksh name> but it is not picking that functionality what i have to do for the same (2 Replies)
Discussion started by: trichyselva
2 Replies

7. Shell Programming and Scripting

Restartibility Functionality....

Hello, I am trying to write a script that has a option of restarting the script from where it failed. I have to write a script called Batch.sh. This script has to run quite a few sql files as shown below: logcmd.sh -f test1.sql logcmd.sh -f test2.sql logcmd.sh -f test3.sql logcmd.sh -f... (4 Replies)
Discussion started by: rkumar28
4 Replies

8. Shell Programming and Scripting

Sed functionality

I have a few xml files and I want to input say 5 parameters within each file. is it possible to do so with sed? <parameter>A</parameter> <parameter>B</parameter> .... .... And so on. These parameters are meant to go in just inside: <?xml... (2 Replies)
Discussion started by: collern2
2 Replies

9. HP-UX

Functionality difference between HP-UX Release 10.20 and 11.00

Hi All, What is the difference with respect to functionality point of view, between HP-UX Release 10.20 and HP-UX Release 11.00? Does the if condition statement in the shell script behave differently in these two releases? (3 Replies)
Discussion started by: puspendu
3 Replies

10. UNIX for Dummies Questions & Answers

Date functionality

Hi, Could someone help me to get yesterday's date in MMDDYY format. echo `date '+%m%d%y'` is giving me today's date in the above format. Thanks in advance for your help.. Suresh. (1 Reply)
Discussion started by: svannala1
1 Replies
Login or Register to Ask a Question