簡體   English   中英

C - 單殼管道實施不斷在終端中被絞死

[英]C - Single shell piping implementation keeps getting hanged in terminal

我一直在嘗試在shell程序中實現管道結構,如果我執行簡單命令,例如“hello | rev”,它就可以工作

但是,當我嘗試“head -c 1000000 / dev / urandom | wc -c”時,它會掛起(忽略引號)

我的實施是:

             int fd[2];
             pipe(fd);
            // IN CHILD 
           // Piping for the first command
              if (isPiped && (e == list_begin(&p->commands))) 
               {

                  close(fd[0]);
                  dup2(fd[1], 1);
                  close(fd[1]);

               }

               // Last command in the pipe
               else if (isPiped && (list_next(e) ==   list_tail(&p->commands))) 
               {

                  close(fd[1]);
                  dup2(fd[0], 0);
                  close(fd[0]);

               }

      // IN PARENT
     if (isPiped && (e == list_begin(&p->commands))) 
           {
             close(fd[1]);
           }

           else if (isPiped && (list_next(e) == list_tail(&p->commands))) 
           {
              close(fd[0]);
           }

我已經被教會在使用完之后總是關閉文件描述符,我認為這就是我正在做的事情 - 但是我在某個地方有文件描述符泄漏,我無法弄清楚在哪里。 我一直試圖做很多關閉和重復fd的組合,但無濟於事。

為了進一步提出一個完整的問題,這是主要的相關代碼:

我這樣做的方法是使用一個列表結構,將每個命令/作業添加到列表中。 變量“e”是列表的元素。

int main(int ac, char *argv[]) {

int numPipes = list_size(&commands) - 1;
bool isPiped = false;
if (numPipes > 0)
   isPiped = true;

int fd[2];
pipe(fd);

pid_t pid = fork();
// In child
if (pid == 0) 
{
    if (isPiped && (e == list_begin(&p->commands))) 
    {       
      close(fd[0]);
      dup2(fd[1], 1);
      close(fd[1]);              
    }

   // Last command in the pipe
   else if (isPiped && (list_next(e) == list_tail(&p->commands))) 
   {            
    close(fd[1]);
    dup2(fd[0], 0);
    close(fd[0]);             
   }
// command is a struct. I have it set up so that the terminal can read in what the user inputs
execvp(command->argv[0], command->arg);

 }
// In parent
 if (isPiped && (e == list_begin(&p->commands))) 
 {
  close(fd[1]);
 }

 else if (isPiped && (list_next(e) == list_tail(&p->commands))) 
 {
   close(fd[0]);
 }
 int status;
 waitpid(-1, &status, WUNTRACED);
}

這就是我的管道算法。 其余的僅用於其他內置作業,例如前景,后台,終止命令和io重定向。 非常感謝!

父進程應在啟動兩個子進程后關閉管道的兩端。 如果它沒有關閉管道的寫入端,那么從管道讀取的子節點將永遠不會獲得EOF,因此它永遠不會終止。 如果它沒有關閉管道的讀取端,但正在讀取的子節點在讀取所有輸入之前終止,則正在寫入的子節點將永遠不會出現錯誤並將阻塞,等待父節點在父節點時讀取無意閱讀。

所以,父母只需要:

close(fd[0]);
close(fd[1]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM