2010-04-17 18 views
8

Próbuję zaimplementować powłokę linuksową obsługującą orurowanie. Wykonałem już proste polecenia, polecenia działające w tle, przekierowania, ale nie ma jeszcze instalacji.Implementacja rur

Przeczytałem już o tym i widziałem kilka fragmentów kodu, ale wciąż nie byłem w stanie rozwiązać działającego rozwiązania.

Co mam tak daleko:

int fd[2]; 

pipe(fd); 

pid_t pid = fork(); 

if (pid == -1) 
    return -1; 

if (pid == 0) 
{ 
    close(fd[1]); //close write to pipe, in child 
    execlp("cat", "cat", "names.txt", NULL); 
} 

else 
{ 
    close(fd[0]); //close read from pipe, in parent 
    execlp("sort", "sort", NULL); 
} 

Jestem początkujący programista, jak można prawdopodobnie powiedzieć, a kiedy jestem programowania czegoś nie wiem wiele na temat, co jest oczywiście przypadek, I zaczynać od czegoś naprawdę łatwego i konkretnego, a następnie zbudować.

Tak więc, zanim będę w stanie wdrożyć trzy i więcej różnych poleceń w potoku, chciałbym móc obliczyć "ls names.txt | sort" lub coś podobnego, w którym names.txt jest plikiem nazw alfabetycznie niezamówiony.

Zaktualizowany kod, ale nadal nie działa.

Dzięki.

Odpowiedz

9

trzeba wymienić jedną stdout dziecka z piszącym końcem fajki i stdin drugiego dziecka z końcem czytania:

if (pid == 0) 
{ 
    close(fd[1]); //close write to pipe, in child 
    dup2(fd[0], STDIN_FILENO); // Replace stdin with the read end of the pipe 
    close(fd[0]); // Don't need another copy of the pipe read end hanging about 
    execlp("cat", "cat", "names.txt", NULL); 
} 
else 
{ 
    close(fd[0]); //close read from pipe, in parent 
    dup2(fd[1], STDOUT_FILENO); // Replace stdout with the write end of the pipe 
    close(fd[1]); // Don't need another copy of the pipe write end hanging about 
    execlp("sort", "sort", NULL); 
} 
4

Zajrzyj do standardowej biblioteki biblioteki pipe(). Służy do utworzenia potoku. Musisz oczywiście wykonać część pracy, aby proces potomny poprawnie dziedziczył deskryptor pliku.

także zwrócić uwagę na kolejność argumentów dup2():

int dup2(int oldfd, int newfd); 

dup2() sprawia newfd być kopia oldfd, zamykając newfd razie potrzeby

+0

Wiedziałem już, że, po prostu zapomniałem dodać instrukcję potoku do kodu. Co sugerujesz teraz? Dzięki. – nunos

+0

Myślałem, że dup2 (0, fd [0]) kopiował to, co miało przejść do stdout na fd [0], które jest wejściem procesu. Przypuszczam, że tego chcę, prawda? – nunos

+0

@unos: dup2() nie wykonuje kopiowania, kopiuje * deskryptory plików *. Ponieważ fd [0] jest fd jednego końca nowo utworzonego potoku, nie ma sensu go zamykać, jak zrobi to funkcja dup2(). – unwind