c - Can not understand the pipe() in my own shell -


this code found own shell. works fine, thing can't understand pipe section of code.

#include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h>  char* cmndtkn[256]; char buffer[256]; char* path=null; char pwd[128];   int main(){  //setting path variable      char *env;     env=getenv("path");      putenv(env);     system("clear");   printf("\t own shell !!!!!!!!!!\n "); printf("_______________________________________\n\n");  while(1){      fflush(stdin);     getcwd(pwd,128);     printf("[mosh~%s]$",pwd);     fgets(buffer,sizeof(buffer),stdin);     buffer[sizeof(buffer)-1] = '\0';      //tokenize input command line        char* tkn = strtok(buffer," \t\n");     int i=0;     int indictr=0;            // loop every part of command         while(tkn!=null)         {              if(strcoll(tkn,"exit")==0 ){                 exit(0);                             }              else if(strcoll(buffer,"cd")==0){             path = buffer;             chdir(path+=3);             }              else if(strcoll(tkn,"|")==0){             indictr=i;             }              cmndtkn[i++] = tkn;             tkn = strtok(null," \t\n");         }cmndtkn[i]='\0';  // execute when command has pipe. when | command found indictr greater 0.     if(indictr>0){          char* leftcmnd[indictr+1];         char* rightcmnd[i-indictr];         int a,b;          for(b=0;b<indictr;b++)             leftcmnd[b]=cmndtkn[b];         leftcmnd[indictr]=null;          for(a=0;a<i-indictr-1;a++)             rightcmnd[a]=cmndtkn[a+indictr+1];         rightcmnd[i-indictr]=null;          if(!fork())         {                fflush(stdout);             int pfds[2];             pipe(pfds);                  if(!fork()){                     close(1);                     dup(pfds[1]);                     close(pfds[0]);                     execvp(leftcmnd[0],leftcmnd);                 }                    else{                     close(0);                     dup(pfds[0]);                     close(pfds[1]);                     execvp(rightcmnd[0],rightcmnd);                 }         }else             wait(null);  //command not include pipe       }else{         if(!fork()){         fflush(stdout);         execvp(cmndtkn[0],cmndtkn);          }else             wait(null);     }  }  } 

what purpose of calls close() parameters of 0 , 1 mean , call dup() do?

on unix, dup() call uses lowest numbered unused file descriptor. so, close(1) before call dup() coerce dup() use file descriptor 1. close(0).

so, aliasing process use write end of pipe stdout (file descriptor 1 used console output), , read end of pipe stdin (file descriptor 0 used console input).

the code may have been more expressed dup2() instead.

dup2(fd[1], 1); /* alias fd[1] 1 */ 

from question how ls | sort works, question not limited why dup() system call being made. question how pipes in unix work, , how shell command pipeline works.

a pipe in unix pair of file descriptors related in writing data on tje writable descriptor allows data read readable descriptor. pipe() call returns pair in array, first array element readable, , second array element writable.

in unix, fork() followed kind of exec() way produce new process (there other library calls, such system() or popen() create processes, call fork() , exec() under hood). fork() produces child process. child process sees return value of 0 call, while parent sees non-zero return value either pid of child process, or -1 indicating error has occurred.

the child process duplicate of parent. means when child modifies variable, modifying copy of variable resides in own process. parent not see modification occur, parent has original copy). however, duplicated pair of file descriptors form pipe can used allow child process parent communicate each other.

so, ls | sort means there 2 processes being spawned, , output written ls being read input sort. 2 processes means 2 calls fork() create 2 child processes. 1 child process exec() ls command, other child process exec() sort command. pipe used between them allow processes talk each other. ls process writes writable end of pipe, sort process reads readable end of pipe.

the ls process coerced writing writable end of pipe dup() call after issuing close(1). sort process coerced reading readable end of pipe dup() call after close(0).

in addition, close() calls close pipe file descriptors used make sure ls process process have open reference writable fd, the sort process process have open reference readable fd. step important because after ls exits, close writable end of fd, , sort process expect see eof result. however, not occur if other process still has writable fd open.


Comments

Popular posts from this blog

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -