2014-03-07 57 views
0

所以我試圖用管道捕獲一個文件並將其塞入到一個名爲newfile.txt的文件當前cat命令使用execvp工作,但是它輸出到命令顯示器上。然後當程序進入sed命令時程序進入無限循環。sed命令使用管道導致無限循環

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 

#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 

char *myargv2[]={"sed", "-e" "s/color/colour/g", NULL}; 
char *myargv1[]={"cat", "colorfile.txt", NULL}; 

main() 
{ 
    int f_des[2]; 
    int fd[2]; 
    int pipe(int filedes[2]); 
    int file = open("newfile.txt",O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 

    if (file < 0) 
     return 1; 

    // create a pipe 
    // Open a pipe and report error if it fails 
    if (pipe(f_des)==-1) 
    { 
     perror("Pipe"); 
     exit(2); 
    } 

    //fork the process 
    // Use switch for fork, because parent doesn't need child's pid. 
    switch (fork()) 
    { 
    case -1: // Error 
     perror("Fork"); 
     exit(2); 

    case 0: // Child 
     printf("HERE1\n"); 
     //child will call dup2 to hook standard output to one end of the pipe. Then, execute the cat command using execvp 
     dup2(fd[1], fileno(stdout)); 
     execvp(myargv1[0], myargv1); 
     close(fd[1]); 
     close(fd[0]); 
     perror(myargv1[0]); 
     close(fd[1]); 
     close(fd[0]); 
     printf("HERE12\n"); 

     exit(3); 

    default: // Parent 
    { 
     printf("HERE13\n"); 
     //parent will call dup2 to hook standard input to the other end of the pipe. Then, execute the sed command using execvp 
     dup2(fd[0], fileno(stdin)); 
     execvp(myargv2[0], myargv2); 
     perror(myargv2[0]); 
     close(fd[1]); 
     close(fd[0]); 
     printf("HERE14\n"); 

     //parent will also call dup2 to hook standard output to the file called newfile.txt 
     if(dup2(file,0 < 0)) 
      return 1; 
    } 

    exit(4); 
    } 

    return 0; 
} 

顯然我在這裏掙扎。任何人都可以指出我做錯了什麼和/或指向我有關如何做到這一點的良好信息來源?

謝謝!

+1

你最好先從網上開始易於使用的linux編程。如果你從第十章開始學習,那麼你的每一個疑問都會清楚,我認爲這個程序出現在第十四章。請檢查一次,這對你很有幫助。 – asifaftab87

回答

0

一個主要問題是,您無法決定是否使用f_desfd作爲管道文件描述符。您有:

int f_des[2]; 
int fd[2]; 
int pipe(int filedes[2]); 
… 
if (pipe(f_des) == -1) 
{ 
    perror("Pipe"); 
    exit(2); 
} 

pipe()的聲明不是一個好主意;這就是系統標題所做的。但嚴重的問題是您在f_des中創建管道,之後使用fd

另一個問題是,您不能準確關閉管道文件描述符。你也有相當多的多餘的代碼。此代碼工作正常:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <fcntl.h> 

static char *myargv2[]={"sed", "-e" "s/color/colour/g", NULL}; 
static char *myargv1[]={"cat", "colorfile.txt", NULL}; 

int main(void) 
{ 
    int fd[2]; 
    int pipe(int filedes[2]); 
    int file = open("newfile.txt",O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 

    if (file < 0) 
     return 1; 

    if (pipe(fd)==-1) 
    { 
     perror("Pipe"); 
     exit(2); 
    } 

    switch (fork()) 
    { 
    case -1: // Error 
     perror("Fork"); 
     exit(2); 

    case 0: // Child 
     printf("HERE1\n"); 
     dup2(fd[1], fileno(stdout)); 
     close(fd[0]); // Important (in general) 
     close(fd[1]); // Important (in general) 
     execvp(myargv1[0], myargv1); 
     perror(myargv1[0]); 
     printf("HERE12\n"); 
     exit(3); 

    default: // Parent 
     printf("HERE13\n"); 
     dup2(fd[0], fileno(stdin)); 
     close(fd[0]); // Crucial 
     close(fd[1]); // Important (in general) 
     execvp(myargv2[0], myargv2); 
     perror(myargv2[0]); 
     exit(4); 
    } 

    return 0; 
} 

一條簡單的拇指法則是:

  • 如果dup()或管道標準輸入或標準輸出的dup2()一端,你應該同時關閉原管文件描述符。含有

給定的輸入文件colorfile.txt

this is the color of danger 
coloration is not important 
end of file is. 

程序的輸出是:

HERE13 
HERE1 
this is the colour of danger 
colouration is not important 
end of file is. 

有趣的是,如果該程序的輸出被管道輸送到另一個程序,調試信息ISN」打印。這是默認緩衝的結果。