Systemy Operacyjne 1 Laboratorium 3 Potoki i łącza nazwane w Linuksie (jeden tydzień) dr inż. Arkadiusz Chrobot

Podobne dokumenty
Instrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)

Instrukcja do laboratorium Systemów Operacyjnych (semestr drugi)

Komunikacja za pomocą potoków. Tomasz Borzyszkowski

Kolejki FIFO (łącza nazwane)

Systemy Operacyjne 1 Laboratorium 2 Procesy i sygnały w Linuksie (jeden tydzień) dr inż. Arkadiusz Chrobot

Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi.

Łącza nienazwane(potoki)

Instrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)

4.2 Sposób korzystania z l acza

Pliki. Funkcje tworzące pliki i operujące na nich opisane są w części 2 pomocy systemowej. Tworzenie i otwieranie plików:

Laboratorium z systemów operacyjnych. System plików - funkcje systemowe. Anna Wojak

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach

Pliki. Operacje na plikach w Pascalu

Wykład PASCAL - Pliki tekstowe

Biblioteka standardowa - operacje wejścia/wyjścia

Jak wiemy, wszystkich danych nie zmieścimy w pamięci. A nawet jeśli zmieścimy, to pozostaną tam tylko do najbliższego wyłączenia zasilania.

Ćwiczenie 4. Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1.

IPC: Kolejki komunikatów

Funkcje zawarte w bibliotece < io.h >

Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Programowanie w językach

Funkcje zawarte w bibliotece < io.h >

Operacje na plikach. Informatyka. Standardowe strumienie wejścia i wyjścia

Część XVII C++ Funkcje. Funkcja bezargumentowa Najprostszym przypadkiem funkcji jest jej wersja bezargumentowa. Spójrzmy na przykład.

Lekcja 10. Uprawnienia. Dołączanie plików przy pomocy funkcji include() Sprawdzanie, czy plik istnieje przy pmocy funkcji file_exists()

Programowanie w językach wysokiego poziomu

Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego

Pliki. Informacje ogólne. Obsługa plików w języku C

Nazwa implementacji: Nauka języka Python pętla for. Autor: Piotr Fiorek

4. Komunikacja pomiędzy procesami przez łącza nienazwane i nazwane

Obsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p.

J. Ułasiewicz Łącza nienazwane, nazwane, select 1

5 Przygotował: mgr inż. Maciej Lasota

Temat zajęć: Obsługa łączy komunikacyjnych

Program wykonujący operację na plikach powinien zachować schemat działania zapewniający poprawną pracę:

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Procesy. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 9 października 2011

Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013

SYSTEMY CZASU RZECZYWISTEGO - VxWorks

System plików warstwa logiczna

Sieci Komputerowe 2 / Ćwiczenia 2

Pliki. Informacje ogólne. Obsługa plików w języku C

Systemy Operacyjne - Operacje na plikach

1 Przygotował: mgr inż. Maciej Lasota

Podstawy programowania w języku C++

Opis protokołu RPC. Grzegorz Maj nr indeksu:

1. Procesy i współbieżność

Języki programowania. Przetwarzanie plików amorficznych Konwencja języka C. Część siódma. Autorzy Tomasz Xięski Roman Simiński

Część 4 życie programu

aodczytywać zniegoza pomoc afunkcjiread, (niebuforowane funkcje wejścia/wyjścia). e sukcesem, to zwróci liczb, erzeczywiściezapisanychbajtów.

Podstawy i języki programowania

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 21 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 24

lekcja 8a Gry komputerowe MasterMind

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Wstęp do Programowania, laboratorium 02

Instrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)

Pytania sprawdzające wiedzę z programowania C++

Programowanie w języku Python. Grażyna Koba

Powłoka I. Popularne implementacje. W stylu sh (powłoki zdefiniowanej w POSIX) W stylu csh. bash (najpopularniejsza) zsh ksh mksh.

Laboratorium 3: Tablice, tablice znaków i funkcje operujące na ciągach znaków. dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

Laboratorium 6: Dynamiczny przydział pamięci. dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

INFORMATYKA Studia Niestacjonarne Elektrotechnika

Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Metody zawarte w klasie File: boolean createnewfile() tworzy nowy, pusty plik, ale tylko jeśli on wcześniej nie istniał. boolean delete() usuwa dany

Instrukcja do laboratorium Systemów Operacyjnych. (semestr drugi)

Działanie systemu operacyjnego

Argumenty wywołania programu, operacje na plikach

Program dopisujący gwiazdkę na końcu pliku tekstowego o nazwie podanej przez uŝytkownika oraz wypisujący zawartość tego pliku.

Statyczne i dynamiczne predykaty

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Klient-Serwer Komunikacja przy pomocy gniazd

Klient poczty elektronicznej - Thunderbird

ISO/ANSI C dostęp do plików ISO/ANSI C. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Znaki globalne w Linuxie

Kolejki komunikatów POSIX

ISO/ANSI C dostęp do plików ISO/ANSI C. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików

SYSTEMY OPERACYJNE I laboratorium 3 (Informatyka stacjonarne 2 rok, semestr zimowy)

Technologie Informacyjne - Linux 2

1 Pierwsze kroki w C++ cz.3 2 Obsługa plików

Spis treści PLIKI BINARNE W JĘZYKU C. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu. Numer ćwiczenia INF23

Wykład II. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

sposób wykonywania operacji zapisu i odczytu dane odczytywane z l acza usuwane (nie można ich odczytać ponownie),

Podstawy Programowania 2 Dwukierunkowa lista liniowa. Plan. Wstęp. Implementacja. Notatki. Notatki. Notatki. Notatki.

4. Pliki Informacje ogólne o dostępie do plików w PHP Sprawdzanie istnienia pliku file_exists()

Strumienie, pliki. Sortowanie. Wyjątki.

Instytut Teleinformatyki

J. Ułasiewicz Łącza nienazwane, nazwane, select 1

Wykład VI. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Iteracyjny serwer TCP i aplikacja UDP

instrukcja użytkownika terminala ARGOX PA-20 SYSTEMY AUTOMATYCZNEJ IDENTYFIKACJI

utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,

SMS SMS telefon. Umożliwia łatwe i szybkie wysyłanie wiadomości SMS...

Wiadomości i umiejętności

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Poniższe funkcje opisane są w 2 i 3 części pomocy systemowej.

Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w

Transkrypt:

Systemy Operacyjne 1 Laboratorium 3 Potoki i łącza nazwane w Linuksie (jeden tydzień) dr inż. Arkadiusz Chrobot 15 października 2016

Wstęp W tej instrukcji zawarte są informacje na temat jednych z podstawowych środków komunikacji między procesami, które dostępne są w systemie Linux. Pierwsza cześć przedstawia koncepcję przesyłania informacji z użyciem strumieni. W drugiej części zawarto opis użycia potoków. Trzecia część poświęcona jest łączom nazwanym, które znane są także jako kolejki fifo. Czwarta część zawiera opis funkcji związanych z obsługą wymienionych łącz. Instrukcja kończy się listą zadań do samodzielnego wykonania na laboratorium. 1. Komunikacja z wykorzystaniem strumieni W systemie Linux istnieje możliwość stworzenia przez proces nowego procesu realizującego wybrane polecenie powłoki oraz łącza komunikacyjnego, nazwanego strumieniem, które będzie łączyło go z procesem rodzicielskim. Umożliwia to funkcja popen(). Łącze utworzone przy jej pomocy jest jednokierunkowe, tzn. proces rodzicielski może je wyłącznie odczytywać lub wyłącznie zapisywać, nie może wykonywać obu tych czynności. Strumień, po zakończeniu korzystania z niego, należy zamykać za pomocą funkcji pclose(). Jest on powiązany ze standardowym wejściem lub wyjściem polecenia realizowanego w ramach procesu potomnego, a więc, w zależności od tego czy jest czytany, czy zapisywany, zastępuje klawiaturę lub ekran. 2. Łącza nienazwane - potoki Innym środkiem komunikacji jednokierunkowej jest łącze nienazwane, czyli inaczej potok (ang. pipe). Służy on do wymiany informacji między dwoma spokrewnionymi procesami, czyli np. między potomkiem i rodzicem, lub dwoma potomkami. Istnieje także mało praktyczna możliwość korzystania z potoku w obrębie jednego procesu. Potok tworzony jest przez system operacyjny na rzecz procesu użytkownika, który wywołuje funkcję pipe(). Dostęp do tego łącza proces użytkownika uzyskuje za pomocą funkcji umożliwiających niskopoziomowe operacje na plikach - read() i write(). Pojemność potoku jest ograniczona, a wielkość tego ograniczenia zależy od konfiguracji systemu. Dla utworzonego potoku można ustawić znacznik (flagę) O_NONBLOCK, który powoduje, że program nie będzie przechodził w stan oczekiwania w określonych sytuacjach, związanych z obsługą potoku (szczegóły w następnym punkcie). Listing 1 przedstawia program, który tworzy dwa procesy (rodzic i potomek), które komunikują się ze sobą przy pomocy potoku. Procesem nadającym informacje, jest potomek, a odbierającym - rodzic. 1

1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<unistd.h> 4 #include<string.h> 5 #include<sys/types.h> 6 #include<sys/wait.h> 7 8 enum names_of_pipe_descriptors {READ, WRITE}; 9 10 11 void do_parent_work(int descriptors[]) 12 { 13 char message[100] = ""; 14 if(close(descriptors[write])<0) 15 perror("parent - close write"); 16 if(read(descriptors[read],message,sizeof(message))<0) 17 perror("read"); 18 printf("odebrana wiadomość: %s\n",message); 19 if(close(descriptors[read])<0) 20 perror("parent - close read"); 21 if(wait(0)<0) 22 perror("wait"); 23 } 24 25 void do_child_work(int descriptors[]) 26 { 27 char *message = "Systemy Operacyjne"; 28 if(close(descriptors[read])<0) 29 perror("child - close read"); 30 if(write(descriptors[write],message,strlen(message))<0) 31 perror("write"); 32 if(close(descriptors[write])<0) 33 perror("child - close write"); 34 exit(0); 35 } 36 37 int main(void) 38 { 39 int pipe_descriptors[2]; 40 if(pipe(pipe_descriptors)<0) 41 perror("pipe"); 42 int pid = fork(); 43 if(pid==-1) 44 perror("fork"); 45 if(pid==0) 46 do_child_work(pipe_descriptors); 47 else 48 do_parent_work(pipe_descriptors); 49 return 0; 50 } Listing 1: Przykład prostej komunikacji za pomocą potoku Aby uprościć identyfikację deskryptorów potoku zdefiniowany został typ wyliczeniowy. Indeks w tablicy deskryptorów identyfikujący deskryptor do odczytu (0) został oznaczony elementem read, a iden- 2

tyfikujący deskryptor do zapisu, elementem write. Proces potomka nadaje do rodzica wiadomość Systemy Operacyjnej. Aby to uczynić najpierw zamyka deskryptor do odczytu, bo nie będzie wykonywał na potoku tej operacji, a następnie, za pomocą funkcji write() zapisuje do potoku, korzystając z deskryptora do zapisu, wspomnianą wiadomość, po czym zamyka również deskryptor do zapisu i kończy swoje działanie. Proces rodzicielski dysponuje buforem na 100 znaków, który po zadeklarowaniu jest inicjowany pustym łańcuchem, a wiec wszystkie jego elementy będą zawierały znak '\0'. Rodzic zamyka najpierw deskryptor potoku do zapisu, następnie przy pomocy funkcji read() i deskryptora do odczytu próbuje z potoku odczytać 100 znaków. Jednakże w potoku będzie mniej znaków i funkcja tylko tyle umieści w buforze message i zakończy swe działanie, nie sygnalizując wyjątku. Rodzic następne wypisze te znaki na ekran, poczeka na zakończenie potomka i również się zakończy. 3. Łącza nazwane - kolejki FIFO Kolejka fifo jest podobna w działaniu do potoku, ale w przeciwieństwie do niego ma nazwę, a więc mogą z niej korzystać procesy niespokrewnione, w podobny sposób, jak mogą korzystać z pliku. Kolejki fifo pojawiły się oficjalnie w systemach uniksowych zgodnych z oryginalną wersją Uniksa o nazwie System III. Pierwotnie tworzono je za pomocą funkcji mknod(), ale obecnie istnieje wygodniejsza w użyciu funkcja mkfifo(). Aby skorzystać z tak utworzonego łącza nazwanego jeden z procesów musi otworzyć je albo wyłącznie do zapisu, albo wyłącznie do odczytu (to samo ograniczenie co w przypadku potoku). Dodatkowo można zastosować flagę O_NONBLOCK. Powoduje to, że proces nie będzie oczekiwał na zakończenie pewnych operacji związanych z obsługą kolejki. Dokładniej objaśnia to tabela 1, której dwa ostatnie wiersze odnoszą się także do potoków. Sytuacja Nie ustawiono O_NONBLOCK Ustawiono O_NONBLOCK Próba otwarcia kolejki tylko do czytania, żaden pro- otworzy kolejkę do pisania. działania funkcji otwierającej Oczekiwanie, aż drugi proces Natychmiastowe zakończenie ces nie otworzył jej do pisania. bez sygnalizowania błędu. Próba otwarcia kolejki tylko do pisania, żaden proces nie otworzył jej do czytania. Próba czytania z kolejki, w której nie ma danych. Próba zapisania do zapełnionej kolejki. Oczekiwanie, aż drugi proces otworzy kolejkę do czytania. Oczekiwanie, aż pojawią się dane. Jeśli żaden proces nie otworzył kolejki do pisania, to funkcja natychmiast zwraca wartość zero. Jeśli w kolejce pojawią się dane, to funkcja zwróci liczbę oczytanych bajtów. Oczekiwanie, aż będzie miejsce do zapisania nowych danych. Natychmiastowe zakończenie działania funkcji otwierającej z sygnalizacją błędu. Funkcja odczytująca natychmiast kończy działanie, zwracając wartość -1. Jeśli kolejka nie jest otwarta do zapisu, to funkcja również natychmiast kończy działanie, ale zwraca wartość 0. Funkcja write() natychmiast kończy działanie zwracając wartość 0. Tabela 1: Zachowanie procesu dla kolejki fifo z ustawioną i nieustawioną flagą O_NONBLOCK. Dodatkowo, zapis i odczyt danych z potoków i kolejek fifo podlega następującym regułom: Jeśli proces żąda przeczytania mniejszej porcji danych niż bieżąco znajduje się w łączu, to otrzyma dokładnie tyle danych, ile zażądał. Reszta danych nie ulega zniszczeniu i może zostać pobrana podczas kolejnej operacji odczytu. Jeśli proces będzie usiłował odczytać więcej danych niż znajduje się bieżąco w łączu, to odczytanych i tak zostanie tylko tyle danych, ile jest w potoku lub kolejce. Jeśli proces próbuje czytać z łącza, które nie zostało przez żaden inny proces otwarte do pisania, to 3

funkcja read() zwróci zero. W przypadku kiedy ustawiony jest znacznik O_NONBLOCK zachowanie funkcji read() jest takie samo. Zapis danych jest operacją niepodzielną, o ile proces zapisuje dane do łącza porcjami mniejszymi od jego pojemności. Jeśli proces próbuje zapisywać do łącza, które nie zostało otwarte przez inny proces do odczytu, to otrzyma sygnał SIGPIPE, którego domyślna obsługa polega na zakończeniu procesu. Po skorzystaniu z kolejki fifo należy ją usunąć, aby nie zajmowała miejsca na dysku. Listingi 2 i 3 zawierają kody źródłowe programów komunikujących się przy pomocy kolejki fifo. 1 #include<stdio.h> 2 #include<unistd.h> 3 #include<fcntl.h> 4 #include<sys/types.h> 5 #include<sys/stat.h> 6 7 void read_from_fifo(int descriptor) 8 { 9 char message[100]=""; 10 if(read(descriptor,message,sizeof(message))<0) 11 perror("read"); 12 printf("odebrana wiadomość: %s\n",message); 13 } 14 15 int main(void) 16 { 17 if(mkfifo("fifo",0600)<0) 18 perror("mkfifo"); 19 int descriptor = open("fifo",o_rdonly); 20 if(descriptor<0) 21 perror("open"); 22 read_from_fifo(descriptor); 23 if(close(descriptor)<0) 24 perror("close"); 25 if(unlink("fifo")<0) 26 perror("unlink"); 27 return 0; 28 } Listing 2: Przykład prostej komunikacji za pomocą kolejki fifo - odbiorca Program odbiorcy tworzy kolejkę, otwiera ją do odczytu, następnie próbuje z niej odczytać 100 znaków, czyli tyle, ile wynosi pojemność jego bufora. Jeśli nie będzie w kolejce informacji, to będzie czekał aż się pojawią. Ostatecznie nadawca umieści w niej mniej niż 100 znaków, ale zostaną one odczytane przez odbiorcę i wyświetlone na ekranie, po czym zamknie on kolejkę i usunie ją z systemu plików. Ostatnią operację powinien wyłącznie on wykonywać, ponieważ jako ostatni będzie korzystał z kolejki. Odbiorca musi być także uruchomiony przed nadawcą, ponieważ to on tworzy kolejkę. Wyjaśnienia wymaga tajemnicza liczba ósemkowa pojawiająca się jako drugi argument wywołania mkfifo(). Jest to wartość opisująca prawa dostępu do kolejki. Kolejne cyfry tej liczby (poza wiodącym zerem) opisują prawa odpowiednio dla: użytkownika, który jest właścicielem (w tym wypadku także twórcą) kolejki, grupy użytkowników, do której należy właściciel oraz dla pozostałych użytkowników zarejestrowanych w systemie. Ponieważ jedna cyfra ósemkowa odpowiada trzem bitom, to każda z tych cyfr zawiera informacje o trzech prawach: rwx, gdzie r oznacza prawo do odczytu, w prawo do zapisu, a x prawo do wykonania. Zatem w zapisie 4

0600 cyfra 6 oznacza prawa do odczytu i zapisu (110 w zapisie binarnym) dla właściciela kolejki, a dwa ostatnie zera oznaczają, że ani grupa, ani pozostali użytkownicy nie mają żadnych praw do tej kolejki. 1 #include<stdio.h> 2 #include<unistd.h> 3 #include<string.h> 4 #include<sys/types.h> 5 #include<sys/stat.h> 6 #include<sys/fcntl.h> 7 8 void write_to_fifo(int descriptor) 9 { 10 char *message = "Systemy Operacyjne"; 11 if(write(descriptor,message,strlen(message))<0) 12 perror("write"); 13 } 14 15 int main(void) 16 { 17 int descriptor = open("fifo",o_wronly); 18 if(descriptor<0) 19 perror("open"); 20 write_to_fifo(descriptor); 21 if(close(descriptor)<0) 22 perror("close"); 23 return 0; 24 } Listing 3: Przykład prostej komunikacji za pomocą kolejki fifo - nadawca Proces nadawca powinien być uruchomiony po odbiorcy. Otwiera on kolejkę do zapisu, a następnie zapisuje w niej wiadomość dla odbiorcy, zamyka tę kolejkę i kończy swoje działanie. 4. Opisy funkcji popen() - funkcja uruchamia polecenie powłoki podane w jej argumentach wywołania oraz tworzy strumień służący do komunikacji między procesem wywołanym a wywołującym, który można obsługiwać standardowymi funkcjami fread() i fwrite(). Szczegóły: man 3 popen fread() - służy do odczytu buforowanego ze strumienia. Szczegóły: man 3 fread fwrite() - służy do buforowanego zapisu do strumienia. Szczegóły: man 3 fwrite pclose() - służy do zamykania strumienia stworzonego przez popen(). Szczegóły: man 3 pclose open() - otwiera plik (również kolejkę fifo) i zwraca liczbę go identyfikującą, nazywaną deskryptorem. Możliwe jest dzięki niej ustalenie trybu otwarcia i ustawienie znaczników. Szczegóły: man 2 open pipe() - służy do tworzenia potoku łączącego dwa spokrewnione procesy. Jako argument wywołania przyjmuje dwuelementową tablicę, w której będą zapisane deskryptory potoku. Deskryptor zerowy jest do odczytu, a pierwszy do zapisu. Zwykle jest ona wywoływana przed fork(), co powoduje, że procesy powstałe w wyniku działania tej ostatniej funkcji odziedziczą tablicę deskryptorów. Każdy z tych procesów zamyka jeden z deskryptorów, np. jeśli komunikacja przebiega według schematu: rodzic potomek, to rodzic zamyka deskryptor do odczytu, a potomek do zapisu. 5

Szczegóły: man 2 pipe read() - czyta określoną liczbę bajtów z deskryptora bez buforowania. Szczegóły: man 2 read write() - zapisuje określoną liczbę bajtów do deskryptora bez buforowania. Szczegóły: man 2 write close() - zamyka deskryptor pliku. Może być użyta z potokiem lub kolejką fifo. Do zamykania strumieni służy fclose() lub pclose(). Szczegóły: man 2 close mkfifo() - tworzy łącze nazwane o podanej nazwie i atrybutach, może być zastąpiona przez mknod(). Szczegóły: man 3 mkfifo fcntl() - służy do manipulacji deskryptorem pliku. Można dzięki niej ustawić flagę O_NONBLOCK dla potoku. Szczegóły: man 2 fcntl unlink() - funkcja ta usuwa z systemu plików nazwę, która może odnosić się do dowiązania lub pliku (ostatni przypadek odpowiada operacji usunięcia pliku). Można ją wykorzystać do automatycznego usuwania łącza nazwanego. Szczegóły: man 2 unlink 5. Zadania Uwaga! Programy należy napisać z podziałem na funkcje z parametrami. Każdy program musi sprawdzać, czy funkcja, z tych, które są opisane wyżej nie sygnalizuje wyjątku podczas wykonania, o ile z jej dokumentacji wynika, że może coś takiego robić. Przed zakończeniem działania każdy program powinien zwolnić zasoby, czyli zamknąć i/lub usunąć strumienie, potoki i kolejki fifo. 1. Napisz program, który wywoła polecenie sort nazwa.c, gdzie nazwa.c jest nazwą pliku z jego kodem źródłowym, a następnie odczyta 50 znaków przez nie zwróconych. 2. Napisz program, który uruchomi polecenie wc i przekaże mu na standardowe wejście dowolny ciąg znaków. 3. Napisz program, który stworzy potok i wykorzysta go do przesyłania danych w obrębie jednego procesu. 4. Napisz program, który stworzy potok i wykorzysta go do komunikacji między dwoma spokrewnionymi procesami. Zadanie wykonaj tak, aby za pomocą argumentów wywołania programu (parametry argc i argv) można było ustalić, czy flaga O_NONBLOCK będzie ustawiona, czy nie. 5. Napisz program, który podzieli się na dwa procesy (rodzic i potomek) komunikujące się przy pomocy potoków. Komunikacja musi być dwukierunkowa. 6. Napisz dwa oddzielne programy (realizując oddzielny kod), które będą się komunikowały przy pomocy kolejki fifo. Wykorzystaj argumenty wywołania tych programów (patrz zadanie 4), aby można było ustalić, czy będą one ustawiały flagę O_NONBLOCK, czy też nie. Po zakończeniu komunikacji jeden z procesów musi usunąć kolejkę. 7. Napisz program, w którym komunikacja między spokrewnionymi procesami będzie odbywała się w jednym kierunku za pomocą łącza nienazwanego, a w drugim za pomocą łącza nazwanego. 8. Stwórz programy do dialogu między dwoma użytkownikami pracującymi w systemie na osobnych terminalach. Do komunikacji użyj kolejki fifo stworzonej za pomocą funkcji mknod(). 9. Napisz program, który wygeneruje cztery procesy. Każdy z tych procesów będzie się komunikował z następnym za pomocą łącza nienazwanego. Pierwszy proces wyśle przez swoje łącze liczby 1, 2, 3 i 4. Każdy kolejny zwiększy każdą z nich o 1, a ostatni z nich wypisze je na ekranie. 6

10. Napisz trzy programy komunikujące się przez kolejkę fifo. Pierwszy program będzie wysyłał kolejne liczby parzyste, drugi kolejne liczby nieparzyste, a trzeci będzie odbierał te liczby i je sumował. Wszystkie procesy powinny wyświetlać wyniki swojej pracy na ekranie. 7