Академический Документы
Профессиональный Документы
Культура Документы
Systemy Operacyjne
Sprawozdanie z ćwiczeń laboratoryjnych
Zadanie
Napisać program, który wywołany dla dwóch argumentów zadziała jak wywołanie w terminalu:
w | more
Wywołanie programu:
./potok w more
Rozwiązanie Zadania
W programie na początek zostaje utworzone łącze nienazwane. zostaje to wykonane poprzez
funkcję pipe(). Następnym etapem jest powołanie nowego procesu dla pierwszego argumentu.
W następnym kroku w procesie głównym zostaje powołany drugi proces potomny. W drugim
procesie potomnym podmieniony zostaje deskryptor standardowego wejścia na deskryptor wejścia
łącza. Ponownie oba deskryptory zostają zamknięte i zostaje wywołana funkcja execlp() w celu
podmiany procesu na proces polecenia.
Proces macierzysty po powołaniu obu procesów wywołuje funkcję wait() w celu zakończenia
dopiero po obu procesach potomnych. Następnie kończy swoje działanie wywołując funkcję
exit(0).
Kod Programu
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
close(lacz[0]);
close(lacz[1]);
execlp(argv[1],argv[1],NULL);
}
if(pid)
{
int pid2=fork();
if(pid2==-1)
{
perror("tworzenie procesu 2 nieudane");
exit(1);
}
if(!pid2)
{
dup2(lacz[0],0);
close(lacz[0]);
close(lacz[1]);
execlp(argv[2],argv[2],0);
}
close(lacz[0]);
close(lacz[1]);
wait(NULL);
wait(NULL);
exit(0);
}
}
Przykład Wywołania
Program powyższy obsługuje jedynie proste polecenia bez argumentów. Dla wielu poleceń wynik
jest dokładnie taki sam jak wynik wywołania polecenia pierwszego. Różnica jest widoczna przy
wywołaniu jako drugiego polecenia wc.
Wywołanie programu:
eloar@k1~>./potok ls wc
27 27 377
eloar@k1~>
Wnioski
Łącza nienazwane są przydatne niestety tylko w zakresie procesów jednej aplikacji. Mogą jednak
służyć do szybkiego łączenia wejść i wyjść procesów. Przy ich pomocy można szybko i w łatwy
sposób pobrać do programu wynik wywołania jakiegoś polecenia systemowego.
Niektóre polecenia wymagają jawnego zamknięcia łącza przez proces macierzysty. Na przykład
polecenie more, albo polecenie less. Te dwa polecenia czekają tak długo, aż nie zakończy się ich
standardowe wejście. W przypadku tego programu niezamknięcie tych deskryptorów zakończyłoby
się zakleszczeniem aplikacji. Jeśli jednak usunąć wywołanie funkcji wait() z aplikacji,
zakończyłaby się ona, jednak polecenie oczekujące na koniec swojego wejścia nie mogłoby
poprawnie się zakończyć, a raczej dać poprawnego wyniku. Testy takiego rozwiązania dały wynik
w postaci nie wyświetlania wpisywanych znaków na konsoli po wywołaniu aplikacji, oraz nie
wyświetlanie znaku końca linii. Wszystkie polecenia były jednak poprawnie przyjmowane.