Interfejsy Programowe Systemów Operacyjnych

Wielkość: px
Rozpocząć pokaz od strony:

Download "Interfejsy Programowe Systemów Operacyjnych"

Transkrypt

1 Interfejsy Programowe Systemów Operacyjnych Jacek Dziedzic FTiMS, PG 2007, 2008 v1.01

2 POSIX Zaczynamy od interfejsu programowego, który nie jest przypisany do konkretnego systemu operacyjnego. POSIX jest standardem (IEEE 1003, ISO/IEC 9945), który opisuje jakie cechy powinien spełniać system operacyjny, który będzie nosił miano "zgodnego z POSIX". Nazwa pochodzi od Portable Operating System Interface. Próba zdefiniowania jednego interfejsu programowego (API), który obowiązywałby w systemach uniksowych. Pierwsze wydanie: Ostatnia wersja:

3 POSIX Początkowo standard nie był dostępny za darmo, a IEEE życzyło sobie niemało za kopię stanardu. Pod koniec lat '80 spotkało się to ze sprzeciwem aktywistów walczących dla sprawy darmowości standardów, w konsekwencji powstał konkurencyjny standard Single Unix Specification. Od 1998 grupa robocza Austin Group koordynuje prace nad wspólnym standardem POSIX i Single Unix Specification v3. 3

4 POSIX Darmowy dostęp do POSIX/Single Unix Specification: wystarczy się zarejestrować. Uwaga: chociaż dalej mówimy właściwie o Single Unix Specification, będziemy wspólny standard określać nazwą POSIX, nie SUS. 4

5 POSIX Ważniejsze SO spełniające normy POSIX: BSD/OS, Mac OS X, MINIX, Solaris, Windows NT, Windows XP pro + SP1, Windows Server 2003, Windows Vista, Windows (np. NT, 9x) + Cygwin. FreeBSD, Linux, BeOS. Kolor żółty oznacza zgodność niekompletną. 5

6 Dużo. Co definiuje POSIX? Zachowanie systemu plików (hierarchię, prawa dostępu, legalność nazw, strukturę systemu plików, odciski czasowe plików). Zachowanie procesów, w tym współbieżnych (nadawanie numerów procesom, planowanie procesów, semantyka spójności, bezpieczeństwo ze względu na wątki, semafory, wątki, gniazda). Sygnały. System kolejkowania. 6

7 Co definiuje POSIX? Zestaw znaków (kodowanie, także sprawy narodowe locale). Środowisko (jak działają zmienne środowiskowe, jakie są pewne standardowe zmienne). Wyrażenia regularne (regex). Strumienie we/wy (stdin, stdout,...). Obsługę terminala. Bibliotekę C. Zachowanie funkcji matematycznych (głównie w przypadku błędów, nieskończoności, nie-liczb). 7

8 Co definiuje POSIX? Standardową powłokę (opartą na ksh), ze szczegółami. Typową składnię (opcje) programów użytkowych. Szereg programów użytkowych omówimy kilkanaście najważniejszych. Kilkanaście innych omówiliśmy już na AiASO.... dużo innych drobiazgów. 8

9 Programy użytkowe (utilities) Operacje na systemie plików: cd, pwd, ls. cp, mv, rm, touch. mkdir, rmdir. chmod, chgrp, chown. find. diff, cmp, patch, od. split. ln. df, du. Na żółto zaznaczono programy omawiane na AiASO. 9

10 Programy użytkowe (utilities) touch Tworzy plik, jeśli nie istniał. Ustawia, zależnie od opcji, czas dostępu do pliku (access time, atime) lub czas modyfikacji pliku (modification time, mtime) na bieżący lub zadany. chgrp Zmienia grupę użytkowników związaną z plikiem. chown Zmienia właściciela pliku. 10

11 Programy użytkowe (utilities) diff plik1 plik2 Porównuje pliki tekstowe, wypisując minimalną listę zmian, które trzeba wykonać aby zawartość plik1 zamienić na plik2. Format opisujący zmiany jest podobny do poleceń w edytorze ed, które pozwoliłyby zamienić plik1 na plik2. Jeśli pliki są identyczne, nie wypisuje nic. Do porównywania plików binarnych służy program cmp, diff wypisze co najwyżej "Binary files differ". Listę zmian produkowaną przez diff pozwala zorientować się w różnicach między plikami, może być też przetwarzana przez program patch, aby zamienić plik1 na plik2. Operuje na całych liniach. 11

12 Programy użytkowe (utilities) diff plik1 plik2 Służy także do porównywania katalogów. Ważniejsze opcje: -c dodaje trzy linie kontekstu przy każdej zmianie. -r rekurencyjnie przegląda katalogi, jeśli porównujemy katalogi. patch -i wynik_diff plik1 Korzystając z wyników diff, wnosi poprawki do plik1, tak że jego zawartość staje się zawartością plik2 (który był argumentem diff). 12

13 Programy użytkowe (utilities) cmp plik1 plik2 Porównuje pliki. Jeśli pliki są identyczne, nie wypisuje nic. W przypadku różnic wypisuje numer pierwszego różnego bajtu i numer linii (numerowane od 1). plik1 plik2 differ: byte 13163, line 941 Ważniejsze opcje: -l wypisuje wszystkie różnice, podając w każdej linii trzy liczby: number bajtu i jego wartości (ósemkowo!) w plik1 i w plik

14 od plik1 Programy użytkowe (utilities) Wypisuje zawartość pliku w zadanym formacie. Pozwala na wypisywanie fragmentu pliku. Format: liczby całkowite, znaki, liczby zmiennoprzecinkowe, ósemkowe, szesnastkowe, etc. Ważniejsze opcje: -t x1 format szesnastkowy, pojedyncze bajty: cat Ala Ala ma kota i psa od -t x1 Ala c d b 6f a a

15 Programy użytkowe (utilities) split plik1 prefiks Dzieli plik na porcje, zapisując je do nowych plików. Domyślny rozmiar porcji to 1000 linii. Porcje zapisywane są do plików prefiksaa, prefiksab, prefiksac,..., prefiksba, prefiksbb,... Ważniejsze opcje: -b n ustawia rozmiar porcji na n bajtów. -b nk ustawia rozmiar porcji na n kibibajtów. -b nm ustawia rozmiar porcji na n mibibajtów. 15

16 Programy użytkowe (utilities) df du Wypisuje informacje o wolnym miejscu w systemach plików. Ważniejsze opcje: -k wyniki w kibibajtach, nie w blokach 512-bajtowych. Wypisuje informacje o miejscu w systemie plików zajętym przez pliki i katalogi w katalogu bieżącym (lub zadanym). Ważniejsze opcje: -k wyniki w kibibajtach, nie w blokach 512-bajtowych. 16

17 Programy użytkowe (utilities) Obróbka plików tekstowych: ed, vi. cat, head, tail, nl, sort, uniq, wc, more. paste. Na żółto zaznaczono programy omawiane na AiASO. 17

18 Programy użytkowe (utilities) ed vi Historyczny edytor plików tekstowych, pracujący w trybie linii. Prekursor vi, pierwsze wykorzystanie wyrażeń regularnych. Inspiracja dla sed i grep. Interaktywnie raczej nie wykorzystywany (chyba, że dla sportu), główne zastosowanie w skryptach. Edytor pracujący w trybie pełnoekranowym. 18

19 nl plik Programy użytkowe (utilities) Numeruje linie w pliku. Wypisuje kolejne linie pliku, poprzedzając je ich kolejnymi numerami. Format numeracji (wiodące zera, szerokość, wyrównanie) można zmienić za pomocą opcji. uniq plik Wypisuje kolejne linie pliku, usuwając z wydruku duplikaty. Duplikaty wyszukiwane są tylko przez porównanie z sąsiednimi liniami. Na ogół stosuje się na pliku już posortowanym, poprzednie ograniczenie nie gra wówczas roli. 19

20 sort plik Programy użytkowe (utilities) (Głównie) sortuje linie pliku, wypisując wynik. Domyślny klucz sortowania: alfabetycznie, po linii. Ważniejsze opcje: -k n sortowanie po n-tej kolumnie -n sortowanie numeryczne (tj. 33 będzie przed 300, mimo że alfabetycznie nie jest). Uwaga: ten tryb nie rozpoznaje liczb w notacji naukowej, tj. ustawi 2E+04 przed 2. Prawidłowe rozpoznawanie liczb w notacji naukowej zapewnia opcja -g, która jednak nie jest częścią POSIX. paste plik1 plik2 Skleja pliki kolumnami. 20

21 Programy użytkowe (utilities) Przetwarzanie łańcuchów, wyszukiwanie wzorców: dirname, basename. tr, sed, grep, cut. Na żółto zaznaczono programy omawiane na AiASO. 21

22 dirname arg Programy użytkowe (utilities) Zwraca nazwę katalogu, w którym znajduje się plik lub katalog arg. dirname ~janek/pliki/list.txt /home/janek/pliki basename arg Operacja odwrotna wycina nazwę katalogu, pozostawiając nazwę pliku. dirname ~janek/pliki/list.txt list.txt 22

23 cut -c lista plik Programy użytkowe (utilities) Wybiera znaki zadane w lista z każdej linii pliku, wypisując wynik. echo "Ala ma kota" cut -c 5 m echo "Ala ma kota" cut -c 5-8 ma k cut -f lista [-d sep] plik Wybiera pola zadane w lista z każdej linii pliku, wypisując wynik. Pola rozdziela znak separatora sep, domyślnie tabulator. echo "Ala ma kota" cut -f 3 kota 23

24 Programy użytkowe (utilities) Zarządzanie procesami: fg, bg, nice, renice, kill. ps, jobs. at. (top nie jest użytkiem POSIX). 24

25 Programy użytkowe (utilities) jobs Wypisuje zadania uruchomione w bieżącej sesji. jobs [1] Running tar -jcf suma.tar * & [2] Running find / -name "*.txt" & [3] Done sleep 100 & [4] Stopped echo "kot" & Ważniejsze opcje: -l wypisuje dodatkowe informacje (głównie PID) 25

26 Programy użytkowe (utilities) fg [id] Przenosi zadanie na pierwszy plan. Bez argumentów przenosi ostatnie zadanie. Z argumentem id (numerem zadania na liście wypisywanej przez jobs, nie PID) przenosi zadane zadanie. bg [id] j.w., ale przenosi zadanie na drugi plan (praca w tle). 26

27 kill PID Programy użytkowe (utilities) Kończy proces o numerze PID, wysyłając do niego sygnał SIGTERM. Ważniejsze opcje: -s sygnał wysyła zadany sygnał, zamiast sygnału SIGTERM. Argument sygnał może być zadany jako liczba albo nazwa sygnału (bez przedrostka "SIG"). Dopuszczalne sygnały i ich numery: 1 SIGHUP 2 SIGINT 3 SIGQUIT 6 SIGABRT 9 SIGKILL 14 SIGALRM 15 SIGTERM 27

28 nice program Programy użytkowe (utilities) Uruchamia program z gorszym priorytetem. Konkretnie, powiększa wartość "nice" procesu, która jest dodawana do jego priorytetu. Pozwala na uruchamianie programów w taki sposób, żeby nie zakłócały zbytnio normalnej pracy (np. długo działających w tle programów). Wartość jest powiększana o pewną stałą (np. 10), może też być zadana przez użytkownika za pomocą opcji -n. Dopuszczalne są wartości ujemne jeśli chcemy polepszyć priorytet zadania. Polepszanie priorytetu może wykonać tylko root. 28

29 Programy użytkowe (utilities) renice -n value pid Działa jak nice, ale ustawia wartość "nice" procesowi już wystartowanemu (o numerze pid) na value. Polepszać priorytet może zazwyczaj tylko root, nawet jeśli chcemy tylko cofnąć uprzednie pogorszenie. Niektóre implementacje renice oczekują wartości value bez parametru -n (wtedy są niezgodne z POSIX). Inne postaci polecenia pozwalają na zmianę priorytetów grup procesów, wszystkich procesów pewnego użytkownika albo grupy użytkowników. 29

30 Programy użytkowe (utilities) ps Wypisuje informacje o procesach. Szczegóły: man ps, powinno było być omówione na PWiR. Ważniejsze opcje: -f komplet informacji -A informacja o wszystkich procesach, nie o tych wystartowanych na bieżącym termiinalu przez bieżącego użytkownika. Może wymagać uprawnień. 30

31 at -f plik kiedy Programy użytkowe (utilities) Wykonuje polecenia zawarte w plik w późniejszym czasie, zadanym przez kiedy. at -f skrypt now + 1 hour at -f skrypt 3pm tomorrow at -f skrypt midnight at -f skrypt now + 1 month Może wymagać przywilejów (użytkownik występuje w /usr/lib/cron/at.allow i nie występuje w /usr/lib/cron/at.deny). 31

32 Programy użytkowe (utilities) Narzędzia programistów: c99, fort77, awk, nm, make. c99 i fort77 to kompilatory języków programowania (odpowiednio: C99 i FORTRANu 77), to nie miejsce żeby je omawiać. awk to interpreter "języka programowania", omawialiśmy go na AiASO. Na żółto zaznaczono programy omawiane na AiASO. 32

33 Programy użytkowe (utilities) nm wypisuje symbole w plikach wykonywalnych, plikach wynikowych (*.o) lub ich kolekcjach (bibliotekach, *.a). Składnia: nm plik. Plik wynikowy, z którego pochodzi symbol. Wartość symbolu. Typ symbolu (najczęściej spotykane): T w sekcji kodu (na ogół funkcja). U niezdefiniowany (w tym pliku). W symbol słaby. R w sekcji danych do odczytu. D w sekcji danych zainicjowanych. B w sekcji danych niezainicjowanych (BSS). małe litery symbole lokalne. wielkie globalne (zewnętrzne). 33

34 Programy użytkowe (utilities) Przykład działania nm na prostym programie w C (po skompilowaniu, oczywiście). Po co nam nm? Przydaje się, gdy podczas kompilacji programu dostajemy błędy fazy linkowania np. niezdefiniowane symbole. Możemy wówczas poszukiwać jakiej biblioteki lub jakiego pliku wynikowego zapomnieliśmy włączyć, przeszukując symbole w bibliotekach. 34

35 Programy użytkowe (utilities) Interesujące opcje nm: -C odmaglowuje (demangle) nazwy. -l pokazuje numery linii w plikach źródłowych, z których symbole pochodzą (konieczne -g przy kompilacji). Przykład: Kompilowane źródło Wydruk nm bez -C (nazwy przemaglowane). Wydruk nm -C (nazwy odmaglowane). Wydruk nm -Cl (nr linii, odmaglowanie). 35

36 Programy użytkowe (utilities) make: inteligentna pomoc w rekompilacji programów. Ręczne kompilowanie programów jest nietrudne i OK, dopóki mamy niewiele plików źródłowych. Gdy plików zbierze się wiecej... Nieporęczne polecenie kompilacji. Nie warto przekompilowywać wszystkich plików, jeśli właśnie zmieniliśmy jeden. Ale skąd wiadomo, co trzeba przekompilować po wprowadzeniu naszej zmiany? Czasem nie tylko ten jeden, zmieniany plik. 36

37 Programy użytkowe (utilities) Z pomocą przychodzi make sposób na poinstruowanie kompilatora jak należy przekompilować projekt. Przykład: mamy cztery pliki p1.cpp, p2.cpp, p3.c i main.cpp, które chcemy, by były skompilowane do p1.o, p2.o, p3.o, main.o, które następnie chcemy połączyć i dodając bibliotekę libbibl.a i otrzymać program wynikowy prog.out. "Ręcznie" postępowalibyśmy następująco: g++ -c p1.cpp p2.cpp main.cpp gcc -c p3.c g++ p1.o p2.o p3.o main.o -lbibl -o prog.out Zobaczmy, jak możemy opisać nasz projekt w języku make. Opis ten zapisujemy w pliku o nazwie Makefile lub makefile. wówczas wystarczy wydać polecenie make, żeby stworzyć program wynikowy, przekompilowując co potrzeba. 37

38 Programy użytkowe (utilities) W naszym przypadku Makefile mógłby wyglądać następująco: Linia komentarza. Linie postaci "a : b" mówią "aby utworzyć a potrzebne jest b, oto przepis jak na podstawie b utworzyć a". Aby utworzyć prog.out potrzebne są p1.o, p2.o, p3.o, main.o, a przepis jest linię niżej. Aby utworzyć p1.o potrzebne jest p1.cpp, a przepis jest linię niżej. UWAGA: Linie zawierające "przepis" muszą zaczynać się od tabulatora (mcedit podświetla go na czerwono) inaczej make nie zrozumie naszych intencji. 38

39 Programy użytkowe (utilities) W naszym przypadku Makefile mógłby wyglądać następująco: Przepis na "all" mówi co trzeba zrobić, aby utworzyć cały projekt. W naszym przypadku wystarczy powiedzieć, że "aby otrzymać all, potrzeba prog.out". Zwyczajowo dodaje się przepis na "clean", który mówi co zrobić, żeby wyczyścić projekt. make uruchomione bez parametrów wymusza przetwarzanie przepisów po kolei, co często jest równoważne "make all", czyli stara się utworzyć cały projekt. 39

40 Programy użytkowe (utilities) Krótsza wersja, korzystająca z reguł wnioskowania (inference rules). Reguły wnioskowania mówią jak otrzymać wszystkie pliki jednego typu z plików drugiego typu, np. "Aby otrzymać potrzebne pliki *.o z plików *.cpp, zastosuj następujący przepis". Reguła wnioskowania "jak z *.cpp dostać *.o" Reguła wnioskowania "jak z *.c dostać *.o" Specjalne makra: $< plik przetwarzany przez regułę wnioskowania ("źródłowy"). $@ plik będący wynikiem przetwarzania przez regułę wnioskowania. 40

41 Programy użytkowe (utilities) Wygodniej jest korzystać ze zmiennych. Teraz, gdy nasz program rozbuduje się o nowy plik, dopisujemy go do dwóch pierwszych linijek i po sprawie. Gdy chcemy przy kompilacji uwzględnić dodatkowe opcje (np. -g) możemy dopisać je do trzeciej linii. Podobnie łatwo radzimy ṡobie ze zmianą nazwy programu. Ważna zaleta make przekompilowane będą tylko te pliki, które trzeba make decyduje o tym na podstawie porównania czasów modyfikacji plików źródłowego i wynikowego. 41

42 POSIX/SUSv3: Operacje plikowe 42

43 Otwarcie pliku int open(const char* pathname, int flags); albo int open(const char* pathname, int flags, mode_t mode); NB: Język C nie pozwala na przeciążanie funkcji (ale pozwala na zmienną liczbę parametrów (variadic functions) więc de facto wygląda to tak: int open(const char* pathname, int flags,...); Stowarzysza deskryptor pliku (file descriptor) z fizycznym plikiem (file), zadanym w parametrze pathname. Otrzymany deskryptor jest zwracany przez funkcję open. Deskryptor pliku: liczba, która identyfikuje plik w późniejszych operacjach we/wy. 43

44 Otwarcie pliku int open(const char* pathname, int flags); "Pod poszewką" najczęściej wygląda to tak, że tworzony jest wpis w globalnej (systemowej) tablicy plików otwartych i odnośnik do niego w tablicy plików procesu w konsekwencji zmiana nazwy pliku po jego otwarciu nie rzutuje na operacje na nim cały czas odwołujemy się do niego za pomocą deskryptora, nie nazwy. Wskaźnik pozycji pliku zostaje przesunięty na początek pliku. flags tryb otwarcia pliku. Alternatywa bitowa kilkunastu możliwych wartości. 44

45 Otwarcie pliku flags musi zawierać dokładnie jedną z: O_RDONLY jeśli otwieramy plik tylko do odczytu, O_WRONLY jeśli otwieramy plik tylko do zapisu, O_RDWR jeśli otwieramy plik do odczytu i do zapisu. Przy otwieraniu kolejek FIFO nie wolno podać O_RDWR. Pozostałe flagi (ważniejsze): O_APPEND przy każdym zapisie plik będzie przewijany na koniec (nawet jeśli w międzyczasie do pliku pisał inny proces, z wyjątkiem plików montowanych pod NFS te mogą ulec zniszczeniu). O_CREAT plik zostanie utworzony, jeśli nie istniał. 45

46 Otwarcie pliku O_CREAT plik zostanie utworzony, jeśli nie istniał. O_DSYNC wymusza synchronizowane we/wy na pliku, tj. pisanie do pliku blokuje proces do momentu, w którym dane fizycznie znajdą się na dysku. O_EXCL w połączeniu z O_CREAT wymusza niepowodzenie otwarcia (i tworzenia) pliku, w przypadku gdy plik już istnieje. Sprawdzenie to jest atomowe, tj. zabezpiecza przed sytuacją, w której inny proces, w międzyczasie tworzy wspomniany plik. O_EXCL bez O_CREAT nie ma sensu. Atomowość jest popsuta w plikach montowanych pod NFS. 46

47 Otwarcie pliku O_TRUNC obcina plik do długości 0, w przypadku zakończonego powodzeniem otwarcia do zapisu (lub zapisui-odczytu). W zasadzie stosuje się tylko do plików zwykłych (nie kolejek, terminali, innych plików specjalnych). W razie niepowodzenia open() zwraca wartość -1 gwarantując, że żaden plik nie został utworzony ani zmodyfikowany. Ustawiana jest globalna zmienna errno. Dodatkowy argument mode pozwala na zadanie atrybutów, z którymi plik zostanie utworzony (w przypadku O_CREAT), z dokładnością do wartości umask dla procesu (która zostanie bitowo odjęta od mode). W nieobecności O_CREAT wartość mode jest ignorowana. Przy O_CREAT musi ona zostać podana. Atrybuty odnoszą się do przyszłych dostępów do pliku, tj. jest możliwe np. otwarcie do pisania pliku i zadanie w mode r-xr-xr-x. 47

48 Otwarcie pliku int creat(const char* pathname, mode_t mode); jest skrótem na... open(pathname, O_WRONLY O_TRUNC O_CREAT, mode); czyli pozwala stworzyć (ew. przyciąć, gdy już istnieje) plik gotowy do zapisu.... ale stosowanie creat() jest niepolecane istnieje tylko z przyczyn historycznych, dla zachowania kompatybilności wstecz. 48

49 Odczyt z pliku ssize_t read(int fildes, void* buf, size_t nbyte); Próbuje wczytać nbyte bajtów z pliku o deskryptorze fildes, pod adres buf. size_t to typ całkowity, bez znaku, stosowany w C i C++ do indeksowania tablic. Na ogół jest to typedef na unsigned int albo unsigned long int, ale nie należy na tym polegać. ssize_t to odmiana size_t ze znakiem (po to, by móc zwrócić -1 w wypadku niepowodzenia). Nie korzysta z int, żeby umożliwić dostęp do dużych plików, bez psucia starych programów. Zwraca: liczbę odczytanych bajtów, albo -1 w wypadku niepowodzenia (wówczas ustawia errno). 49

50 Odczyt z pliku Ważne: read() może odczytać mniej bajtów, niż żądamy i zwrócić odpowiednio mniejszą wartość. Nie można więc ślepo zakładać, że udało się odczytać nbytes bajtów! Typowe sytuacje, w których odczytano mniej bajtów, niż żądaliśmy: Odczyt z terminala użytkownik nie wpisał na czas tyle znaków, ile chcieliśmy. Koniec pliku po prostu nie ma więcej bajtów. Odczyty z kolejek, potoków, po sieci nie dotarło tyle bajtów, ile byśmy chcieli. Odczyt z urządzeń, które czytają rekordami (taśmy). Wystąpił sygnał przy odczycie z pliku, po odczytaniu co najmniej jednego bajtu (jeśli wcześniej, zwraca -1). 50

51 Odczyt z pliku Wskaźnik pozycji w pliku przesuwa się o tyle bajtów, ile udało się odczytać (dla plików, które w ogóle dysponują wskaźnikiem pozycji, np. terminale go nie mają). Co się dzieje ze wskaźnikiem w przypadku niepowodzenia w zasadzie nie wiadomo. Dopuszczalne jest żądanie odczytu 0 bajtów zwracana jest wówczas wartość 0, bez podejmowania żadnej akcji, poza skontrolowaniem poprawności żądania (np. poprawności parametru fildes, praw dostępu do pliku, etc.). Gdy wskaźnik jest na końcu pliku przy wywołaniu read(), zwracane jest 0 bajtów. 51

52 Odczyt z pliku Odczyty z fragmentów pliku, które nigdy nie były zapisane zwracają bajty zerowe (przykładowy scenariusz: lseek() poza koniec pliku, write() plik powiększa się, potem lseek() w "dziurę" między starym końcem pliku, a właśnie zapisanymi danymi i read() zwrócone zostaną zera, a nie śmieci). Jeśli odczytano jakiekolwiek bajty, czas dostępu do pliku zostanie uaktualniony (przy NFS nie zawsze, z oszczędności). Gwarancja atomowości (ważne!) (spójność sekwencyjna): na odczyt danych z pliku nie mają wpływu inne, współbieżne odczyty z tego samego pliku. w przypadku współbieżnego odczytu i zapisu do pliku, operacja odczytu zwróci bajty sprzed zapisu lub takie jak po zapisie, ale nie mieszankę jednej i drugiej wersji (co mogłoby mieć miejsce, gdyby nie było spójności sekwencyjnej). 52

53 Zapis do pliku ssize_t write(int fildes, const void* buf, size_t nbyte); Próbuje zapisać nbyte bajtów do pliku o deskryptorze fildes, spod adresu buf. Również może zwrócić mniejszą liczbę bajtów, niż chcieliśmy zapisać. Typowe sytuacje, kiedy to następuje: brak miejsca na medium, przekroczona quota, przekroczony limit rozmiaru pliku (ulimit -s) procesu, zgłoszenie sygnału po zapisaniu co najmniej 1 bajtu.... ale gdy nie udało się zapisać żadnego bajtu zwraca -1 (np. chcemy zapisać 300 bajtów, ale na dysku jest miejsce tylko na 20 write() zapisze 20 bajtów, zwróci 20. Kolejny write() z nbyte>0 nie powiedzie się, zwracając -1). 53

54 Zapis do pliku Składnia i zachowanie podobne do read(), poza drobnymi różnicami: Naturalnie, plik zostanie wydłużony w przypadku zapisów poza bieżący koniec pliku. W przypadku O_APPEND zapis zawsze ma miejsce na końcu pliku. Gwarancja silnej spójności każdy read(), który rozpoczął się po zakończeniu operacji write(), a który czyta bajty właśnie zapisane, zawsze zwróci nowe (świeżo zapisane) bajty, nawet jeśli fizycznie nie trafiły one na dysk. To ważne! Spójność sekwencyjna współbieżnych zapisów skutkiem wykonania dwóch (lub więcej) współbieżnych operacji zapisu będzie zapis danych z jednej z nich (niekoniecznie ostatniej!), ale nie mieszanka danych z różnych zapisów. 54

55 Odczyt, zapis uwagi Oczywiście w wypadku dwóch zapisów następujących po sobie, do pliku trafiają wyniki późniejszego write(). Gwarancje spójności są nieco inne (słabsze) dla kolejek i potoków, nie będziemy wnikać w szczegóły. Również dla terminali nie ma gwarancji atomowości (także przy odczytach) w konsekwencji procesy mogą kraść sobie znaki z klawiatury (odczyt) i mieszać wypisywane na ekran dane (zapis). Każde read() i write() kosztuje wywołanie funkcji systemowej warto więc operować większymi porcjami (co najmniej kilkanaście KB), by zwiększyć wydajność. Co więcej bardzo drobne zapisy (krótsze niż st_blksize zwracane przez stat będą szczególnie niewydajne). 55

56 Synchronizacja (wymiecenie buforów) int fsync(int fildes); Wymusza opróżnienie (wymiecenie, flush) buforów związanych z deskryptorem fildes. Oczekujemy, że po wywołaniu fsync() dane zapisane do pliku związanego z fildes trafią fizycznie na dysk (czy inne medium). Potrzebne, jeśli dalsze działanie programu polega na fizycznej obecności danych na medium (transakcyjne bazy danych, kontrolowany restart systemu, etc.). Trudne do zrealizowania jeśli dysk obsługuje writecaching na niskim poziomie, fsync() nie potrafi zagwarantować, że dane "rzeczywiście rzeczywiście" trafią na dysk. Również zwraca -1 w przypadku niepowodzenia. 56

57 Przesuwanie wskaźnika off_t lseek(int fildes, off_t offset, int whence); whence stała symboliczna, mówiąca skąd mierzymy żądane przesunięcie (SEEK_SET, SEEK_CUR, SEEK_END). offset o ile bajtów względem whence przesuwamy. Zwraca bieżącą pozycję w pliku, mierzoną od początku, bądź (off_t)-1 w przypadku niepowodzenia. Wolno przesuwać się poza koniec pliku (dopełnienie zerami przy zapisie). Samo przesunięcie nie dopełnia pliku. Przesunięcie nie jest stricte operacją we/wy modyfikuje tylko tablice systemowe. Dla specyficznych urządzeń (plików specjalnych) nie jest wykluczone, że ujemne przesunięcia są legalne (!) wówczas tylko sprawdzenie errno pozwala odróżnić poprawny wynik -1 od -1 sygnalizującego błąd. Nie wszystkie pliki pozwalają na przesuwanie wskaźnika (potoki, terminale, katalogi) wówczas zachowanie jest nieokreślone. off_t typedef na "jakiś typ całkowity". 57

58 int close(int fildes); Zamknięcie pliku Zamyka plik o deskryptorze fildes, zwracając deskryptor do puli wolnych deskryptorów. W razie niepowodzenia (sygnał, błąd we/wy, błędne fildes) zwraca -1. Jeśli był to ostatni deskryptor odwołujący się do jakiegoś pliku, jest on usuwany z ogólnosystemowej tablicy otwartych plików. Może się wiązać z faktycznym usunięciem pliku (jeśli było ono odwlekane na skutek tego, że plik był otwarty). Apel do programistów (za man 2 close): Not checking the return value of close() is a common but nevertheless serious programming error. It is quite possible that errors on a previous write() operation are first reported at the final close(). Not checking the return value when closing the file may lead to silent loss of data. This can especially be observed with NFS and with disk quota. 58

59 Inne, mniej istotne, operacje plikowe dup(), dup2() duplikowanie deskryptorów odnoszących się do tego samego pliku (przydatne przy przekierowywaniu). fcntl() zmiana pewnych własności już otwartego pliku (zakładanie i zdejmowanie blokad (locks), zmiana niektórych flag względem tych podanych przy otwarciu, kontrola reakcji na sygnały, żądań powiadamiania o zmianach dotyczących pliku lub katalogu, duplikowanie deskryptorów, i in.). ioctl() różne żądania dotyczące plików specjalnych jakie, to zależy od sterownika, który obsługuje ten typ pliku specjalnego np. kontrola terminala (rozmiar okna, czy echo, etc.). Przeglądanie zawartości katalogu: opendir(), readdir(), closedir(), rewinddir(), seekdir(), scandir(), telldir(). 59

60 Inne, mniej istotne, operacje plikowe chmod(), chown() zmiana praw dostępu, właściciela i grupy pliku. int truncate(const char *path, off_t length); Ustawia długość pliku na zadaną jeśli jest mniejsza, niż bieżąca, plik zostaje przycięty. Jeśli jest większa, plik zostaje wydłużony przez dopisanie zer. Wskaźnik pozycji pliku nie przesuwa się (nawet jeśli miałby wskazywać poza koniec pliku). Musimy mieć prawa zapisu do pliku. Zwraca -1 w przypadku niepowodzenia. W razie przekroczenia limitu rozmiaru pliku (ulimit -f) zgłasza sygnał. ftruncate() wersja, która bierze deskryptor zamiast nazwy wówczas plik musi być otwarty (do zapisu). 60

61 Inne, mniej istotne, operacje plikowe chdir(), getcwd(), getcwd(). mkdir(), rmdir(). rename(), link(), symlink(), unlink(), readlink(), remove(). int stat(const char* restrict path, struct stat* restrict buf); wydobywa pewne informacje o pliku zadanym w path, zapisując je pod adres buf, wskazujący na strukturę stat. Jeśli path jest symlinkiem, podąża za odwołaniem. Nie potrzeba praw do pliku, ale 'x' dla wszystkich katalogów po drodze. restrict nowe słowo kluczowe w C99, za pomocą którego gwarantujemy kompilatorowi, że dane miejsce w pamięci nie zostanie zmodyfikowane także za pomocą innego wskaźnika (trochę co innego niż const). Raczej nieistotne z punktu widzenia POSIX, ale pomaga kompilatorowi na pewne optymalizacje i założenia. Tu na przykład gwarantuje, że buf i path są rozłączne (niby oczywiste, ale perwersyjni programiści się zdarzają). W C++ (jeszcze) nie istnieje, ale większość kompilatorów cichcem je ignoruje. 61

62 Inne, mniej istotne, operacje plikowe int stat(const char* restrict path, struct stat* restrict buf); Struktura stat jest zdefiniowana w sys/stat.h: struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ }; mode_t st_mode; /* protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for filesystem I/O */ blkcnt_t st_blocks; /* number of blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last status change */ st_blocks może być mniejsze niż (st_size/512) dla plików rzadkich (sparse files). 62

63 POSIX/SUSv3: Komunikacja międzyprocesowa 63

64 POSIX: Komunikacja międzyprocesowa Semafory. Gniazda. Wątki (omówione na AiASO i PWiR). Kolejki wiadomości. Pamięć współdzielona (shared memory). Sygnały. Potoki (pipes). 64

65 POSIX: Komunikacja międzyprocesowa Semafory. Sposób na kontrolowanie i ograniczanie dostępu do zasobów współdzielonych, np. współdzielonego przez procesy obszaru pamięci. Klasyczna definicja: Operacje P( ) i V( ). P( ) czekaj, aż zasób będzie wolny. Gdy się zwolni, zaznacz, że zajęty i przejmij kontrolę nad zasobem. V( ) zwolnij zasób, zaznacz że wolny. Odpowiedniki kolejowe: P( ) czekaj, aż tory wolne, zaznacz semaforem, że jedziesz. V( ) przejechałeś, zaznacz że tory wolne. Krytycznie ważne: operacje te muszą być atomowe. Oczekiwanie na zasób w P( ) powinno unikać busy-waiting. 65

66 POSIX: Komunikacja międzyprocesowa Semafory. W POSIX semafory nie tylko binarne, a przechowujące wartość całkowitą (czyli mogą opisywać dostęp do kilku sztuk zasobów) operacja V( ) zwiększa licznik, P( ) zmniejsza licznik jeśli >0. W POSIX realizowane przez operacje: sem_init(), sem_destroy() tworzenie i usuwanie semafora. sem_wait() czeka na semaforze na zasób, przejmując nad nim kontrolę, gdy staje się dostępny (operacja P( )). sem_post() zwalnia zasób (operacja V( )). sem_getvalue() podgląda licznik semafora. sem_trywait() nieblokująca wersja sem_wait() jeśli zasób jest do wzięcia, przejmuje go jak sem_wait(). Jeśli nie, od razu wraca z błędem EAGAIN. 66

67 POSIX: Komunikacja międzyprocesowa Gniazda. Wspomnieliśmy już na laborce, więc główne informacje tylko pokrótce. Sposób na komunikację między dwoma procesami bądź na lokalnej maszynie, bądź zdalnie. Typy gniazd (dyktują rodzaj komunikacji): SOCK_STREAM strumień komunikacyjny: dupleksowane przesyłanie danych, z gwarancją niezawodności. Porcje danych dowolne (jak rozmowa telefoniczna). SOCK_DGRAM przesyłanie datagramów rekordów o ustalonej długości, bez gwarancji niezawodności: datagramy mogą się wyprzedzać, nie dochodzić, dochodzić zduplikowane (jak listy w Poczcie Polskiej). Dupleksowana. SOCK_RAW pozwalają na bezpośredni dostęp do protokołu, który gniazdo implementuje. SOCK_SEQPACKET komunikacja datagramowa, ale z gwarancją niezawodności. Dupleksowana, datagramy mają z góry ustalony rozmiar maksymalny. Zaimplementowana tylko dla komunikacji lokalnej. SOCK_RDM komunikacja datagramowa, niezawodna ale bez gwarancji kolejności. 67

68 POSIX: Komunikacja międzyprocesowa Gniazda. Typowy schemat komunikacji (dla SOCK_STREAM): SERWER: KLIENT: socket(); // tworzy gniazdo socket(); // tworzy gniazdo bind(); // związuje nazwę listen(); // nasłuchuje accept(); // przyjmuje połączenie connect(); // nawiązuje połączenie Wymiana danych za pomocą send() i recv() analogiczna jak pisanie i czytanie do/z pliku + dodatkowe flagi, jeśli chcemy dokładniejszej kontroli nad przesyłaniem (np. można podglądać daną do odebrania, bez odebrania). Wymiana możliwa również za pomocą klasycznych write() i read() możemy traktować gniazdo jak plik. close() zamyka gniazdo. 68

69 POSIX: Komunikacja międzyprocesowa Gniazda. W linuksie gniazda widoczne są w systemie plików, jako pliki specjalne. Klient i serwer powinni być z góry umówieni na nazwę gniazda klient szuka gniazda po nazwie. W komunikacji datagramowej nie ma negocjowania połączenia (nie korzystamy z listen() i accept()), a komunikacja odbywa się za pomocą sendto(), sendmsg(), recvfrom(), recvmsg(). 69

70 POSIX: Komunikacja międzyprocesowa Gniazda. W linuksie gniazda widoczne są w systemie plików, jako pliki specjalne. Klient i serwer powinni być z góry umówieni na nazwę gniazda klient szuka gniazda po nazwie. W komunikacji datagramowej nie ma negocjowania połączenia (nie korzystamy z listen() i accept()), a komunikacja odbywa się za pomocą sendto(), sendmsg(), recvfrom(), recvmsg(). 70

71 POSIX: Komunikacja międzyprocesowa Wątki. W teorii szeroko omawialiśmy na AiASO; nie będziemy się powtarzać. W praktyce były ćwiczone na PWiR, więc na laboratorium nie będziemy się nimi zajmować. Wątki posiksowe: pthreads (libpthread). POSIX definiuje tylko interfejs wątków, pozostawiając implementację. W linuksie trzy poważne implementacje: LinuxThreads to ta starsza implementacja, nie w 100% zgodna z POSIX. Pierwsza poważna implementująca wątki jądra. NGPT New Generation POSIX Threads to ta w systemie m:n, która się nie przyjęła, porzucona w NPTL Native POSIX Thread Library obecnie dominująca, w systemie 1:1. Zapewnia lepszą wydajność przy dużej liczbie wątków, prawie 100% zgodność z POSIX. 71

72 POSIX: Komunikacja międzyprocesowa Kolejki wiadomości (message queues). Sposób na wymianę wiadomości pomiędzy procesami jeden proces wkłada wiadomości do kolejki, inny proces wyciąga wiadomości z kolejki. W jednym z dwóch standardów wiadomości można wydobywać selektywnie, niekoniecznie w kolejności FIFO. procesnadawca procesodbiorca kolejka wiadomości typ wiadomość 1 typ wiadomość 2 72

73 POSIX: Komunikacja międzyprocesowa Kolejki wiadomości (message queues). Wiadomości mają konkretne rozmiary oraz typy. Typ wiadomości pełni rolę analogiczną to pola tag, które występowało w wiadomościach MPI pozwala ono na selekcję wiadomości bez konieczności ich odbioru. klient1- nadawca serwerodbiorca klient2- nadawca selekcja wiadomości kolejka wiadomości #1 wiadomość 1 #1 wiadomość 2 #2 wiadomość 3 73

74 POSIX: Komunikacja międzyprocesowa Kolejki wiadomości (message queues). Dwa zestawy API dla kolejek wiadomości: System V message queues starsze, bardziej popularne w starych systemach: msgget(), msgsnd(), msgrcv(), msgctl(). POSIX message queues nowsze, w Linuksie w pełni zaimplementowane od jądra mq_open(), mq_close(). mq_send(), mq_receive(). mq_timedsend(), mq_timedreceive(). mq_unlink(), mq_getattr(), mq_setattr(). Posiksowe kolejki wiadomości nie korzystają z typu, natomiast wiadomości mają priorytety. Z kolejki wyjmowana jest najstarsza z wiadomości o najwyższym priorytecie (czyli najważniejszy jest priorytet). 74

75 POSIX: Komunikacja międzyprocesowa Kolejki wiadomości (message queues). Otwarcie kolejki wiadomości: mqd_t mq_open(const char* name, int oflag,...); Otwiera istniejącą, bądź tworzy nową kolejkę wiadomości, zwracając deskryptor (uchwyt), którego następnie używamy do identyfikacji kolejki. name nazwa koleki. POSIX nie precyzuje czy kolejki są widoczne w systemie plików i czy są dostępne dla funkcji, które operują na systemie plików, natomiast name zawsze podlega tym samym zasadom, co nazwy ścieżek (ograniczenia długości i legalnych znaków). Na ogół nazwa zaczyna się od /. W Linuksie można w /dev/mqueue zamontować wirtualny system plików, w którym widać wiadomości (szczegóły: man mq_overview), jednak POSIX tego nie precyzuje implementacje mogą tak robić, ale nie muszą. 75

76 POSIX: Komunikacja międzyprocesowa Kolejki wiadomości (message queues). Otwarcie kolejki wiadomości: mqd_t mq_open(const char* name, int oflag,...); oflag przede wszystkim standardowe flagi: O_RDONLY, O_WRONLY, O_RDWR. Jeśli w danym procesie otworzymy kolejkę tylko do zapisu, możemy tylko wysyłać wiadomości, podobnie w trybie tylko do odczytu. Wolno nam jednak otworzyć tę samą kolejkę wielokrotnie, również w różnych trybach, w tym samym procesie (jak w i różnych procesach). Z pozostałych flag ważniejsza tylko O_CREAT. Zamknięcie kolejki wiadomości: int mq_close(mqd_t mqdes); 76

77 POSIX: Komunikacja międzyprocesowa Kolejki wiadomości (message queues). Otwarcie kolejki wiadomości: mqd_t mq_open(const char* name, int oflag,...); Kolejne parametry (symbolizowane przez elipsę... ) są potrzebne, gdy tworzymy nową kolejkę (podając O_CREAT). Pierwszy z nich opisuje prawa dostępu do kolejki, drugi jej atrybuty. Na atrybuty kolejki (zebrane w struct mq_attr) składają się: Flaga blokowania (O_NONBLOCK) opisuje czy dostęp do kolejki jest blokujący, czy nieblokujący. Maksymalna liczba wiadomości w kolejce. Maksymalny rozmiar wiadomości. Liczba wiadomości w kolejce w danej chwili (przy tworzeniu ten nas nie interesuje). 77

78 POSIX: Komunikacja międzyprocesowa Kolejki wiadomości (message queues). Wysłanie wiadomości do kolejki: int mq_send(mqd_t mqdes, const char* bufor, size_t długość, unsigned priorytet); Jak zapis do pliku do kolejki o deskryptorze mqdes, wkłada wiadomość spod adresu bufor, o długości długość. Różnica względem zapisu do pliku priorytet. Gdy kolejka pełna blokuje wysyłającego, aż zwolni się miejsce, chyba że O_NONBLOCK (wtedy zwraca błąd EAGAIN i kończy się). W przypadku, gdy kilka wątków konkuruje o dostęp do tej samej pełnej kolejki, mamy gwarancję że pierwszy wybudzi się ten, o najwyższym priorytecie. Błąd, jeśli długość > maksymalnego rozmiaru wiadomości. 78

79 POSIX: Komunikacja międzyprocesowa Kolejki wiadomości (message queues). Odebranie wiadomości z kolejki: int mq_receive(mqd_t mqdes, char* bufor, size_t długość, unsigned* priorytet); Jak odczyt z pliku, tylko argument priorytet. Tym razem priorytet przekazujemy przez wskaźnik funkcja wypełnia to pole priorytetem odebranej wiadomości jeśli nas on nie interesuje, przekazujemy NULL. Zawsze wyjmowana jest wiadomość o najwyższym priorytecie (a spośród nich najstarsza). Bufor musi mieścić co najmniej długość bajtów, a długość nie może być mniejsza niż rozmiar wiadomości wyspecyfikowany przy tworzeniu kolejki. 79

80 POSIX: Komunikacja międzyprocesowa Kolejki wiadomości (message queues). Odebranie wiadomości z kolejki: int mq_receive(mqd_t mqdes, char* bufor, size_t długość, unsigned* priorytet); Podobnie jak zapis przy pełnej kolejce, próba odczytu z pustej kolejki blokuje proces dopóty, dopóki w kolejce nie pojawi się wiadomość, chyba że jesteśmy w trybie O_NONBLOCK. Jak przy zapisie, tak i tu w przypadku gdy jest kilka wątków, które konkurują o odbiór wiadomości, pierwszy obudzi się ten o najwyższym priorytecie. 80

81 POSIX: Komunikacja międzyprocesowa Kolejki wiadomości (message queues). Jeśli chcemy uniknąć zablokowania procesu na zbyt długo przy wysłaniu lub odbiorze wiadomości, a nie chcemy O_NONBLOCK, możemy posłużyć się mq_timedsend() i mq_timedreceive(). Obie te funkcje kończą się, jeśli w trakcie oczekiwania na zwolnienie się miejsca w kolejce (send) albo pojawienie się wiadomości w kolejce (receive) zegar przekroczy zadany czas, bądź czas ten będzie już przekroczony w momencie rozpoczęcia oczekiwania. UWAGA: kontrola czasu ma miejsce tylko w w/w wypadkach, tj. gdy kolejka jest pełna (send) albo pusta (receive) jeśli jest miejsce na nadanie wiadomości (send) albo jest wiadomość do odebrania (receive) zadane timeouty nie są brane pod uwagę! 81

82 POSIX: Komunikacja międzyprocesowa Kolejki wiadomości (message queues). Usunięcie kolejki wiadomości: int mq_unlink(const char* name); Jeśli inny proces korzysta z kolejki, usunięcie będzie odwleczone do momentu zamknięcia wszystkich uchwytów (deskryptorów), które odnoszą się do kolejki. Niuans: mq_unlink() nie(koniecznie) blokuje, tj. jest możliwe że funkcja zakończy się zanim kolejka zostanie faktycznie usunięta w okresie pomiędzy tymi dwoma zdarzeniemi mq_open() na tej kolejce może zakończyć się błędem. Operacje na atrybutach kolejki: mq_getattr(), mq_setattr(). UWAGA: Jedynym atrybutem, który można zmienić jest pole flag... Maksymalnego rozmiaru wiadomości ani maksymalnej liczby wiadomości w kolejce po utworzeniu kolejki nie sposób zmienić! 82

83 POSIX: Komunikacja międzyprocesowa Pamięć współdzielona (shared memory). Prosty i wydajny mechanizm komunikacji między procesami. Zasada działania: Tworzymy albo otwieramy obiekt pamięci współdzielonej za pomocą shm_open(), podobnie jak plik dostajemy uchwyt jak do pliku. Ustalamy rozmiar obiektu pamięci współdzielonej za pomocą ftruncate(), jak dla pliku. Mapujemy plik reprezentujący pamięć współdzieloną za pomocą mmap(), dostając wskaźnik na region pamięci, do którego od teraz mamy dostęp (jaki to zależy od flag otwarcia). Jeśli powtórzymy w/w operacje w dwóch procesach, mamy w obydwu dostęp do tego samego regionu pamięci. 83

84 POSIX: Komunikacja międzyprocesowa Pamięć współdzielona (shared memory). Regiony pamięci współdzielonej mogą być widoczne w systemie plików, ale nie muszą zależy od implementacji. Ponieważ od momentu shm_open() posługujemy się uchwytem, nic nie stoi na przeszkodzie, by były to jakieś wewnętrzne struktury systemowe, które nie przekładają się na byty w systemie plików. Oczywiście operacje plikowe (ftruncate(), close(),...) operujące na uchwytach będą działać na uchwytach odnoszących się do pamięci współdzielonej, jeśli tylko mają sens (np. zachowanie lseek() jest niezdefiniowane). Niuanse: nazwa powinna zaczynać się od /, podlega tym samym ograniczeniom co nazwy zwykłych plików. Nie ma trybu O_WRONLY. Jak dla plików, zawartość jest zerowana jeśli czytamy miejsca wcześniej niezapisane. 84

85 POSIX: Komunikacja międzyprocesowa Potoki (pipes). To właśnie ten mechanizm pozwala na wiązanie wyjścia jednego procesu z wejściem innego (ls grep cpp sort). Potok tworzymy za pomocą: int pipe(int fildes[2]); Funkcja tworzy potok, w elementach tablicy zwraca dwa deskryptory plików, odnoszące się do dwóch końców potoku komunikacyjnego. Dane pisane do fildes[1] mogą być odczytane z fildes[0], w porządku FIFO, za pomocą normalnych operacji plikowych. Potok jest jednokierunkowy, tj. nie jest powiedziane, co dzieje się przy próbie dostępu "pod prąd" (zapisu do fildes[0] albo odczytu z fildes[1]). Zwraca 0 w przypadku powodzenia. 85

86 POSIX: Komunikacja międzyprocesowa Potoki (pipes). Przykład, za manualem: pipe() fork() int fildes[2]; const int BSIZE = 100; char buf[bsize]; ssize_t nbytes; int status; close() write() read() if(-1==pipe(fildes))... /* błąd (brak wolnych plików) */ switch (fork()) { case -1: /* błąd w fork() */ break; case 0: /* Potomek - niech czyta z potoku */ close(fildes[1]); /* Zamyka niepotrzebny koniec 'odczytowy'*/ nbytes = read(fildes[0], buf, BSIZE); /* Czyta, jak z pliku */ /* Kolejne odczyty napotkają na EOF */ close(fildes[0]); /* Koniec pracy z potokiem, zamknij */ exit(exit_success); default: /* Rodzic - niech pisze do potoku */ close(fildes[1]); /* Zamyka niepotrzebny koniec 'zapisowy'*/ write(fildes[1], "Hello world\n", 12); /* Pisz cos do potoku */ close(fildes[1]); /* Koniec pracy z potokiem, zamknij */ exit(exit_success); } 86

87 POSIX: Komunikacja międzyprocesowa Potoki (pipes). Funkcja popen() pozwala na wywołanie innego programu (albo polecenia powłoki) i przekierowanie wyników do potoku: FILE* popen(const char* command, const char* mode); Polecenie command jest wywoływane tak, jakby proces wykonał fork() a potem (na potomku) execl(). Zwraca: wskaźnik na strumień (FILE) reprezentujący potok albo NULL (błąd). Mechanizmu strumieni (alternatywny do open()/close()/read()/write() mechanizm, to ten operujący fopen()/fclose()/fread()/fwrite()) nie omawialiśmy. mode=="r": dostajemy 'odczytowy' koniec potoku odczyty z potoku to odczyty ze standardowego wyjścia command. mode=="w": dostajemy 'zapisowy' koniec potoku zapisy do potoku to zapisy na standardowe wejście command. Zamykać trzeba za pomocą pclose(), nie fclose(), poza tą różnicą zachowuje się jak zwykły strumień. 87

88 POSIX: Komunikacja międzyprocesowa Sygnały (signals). Mechanizm asynchronicznego powiadamiania procesu o pewnych zdarzeniach. Asynchroniczność polega na tym, że proces może zostać przerwany w dowolnym nieatomowym miejscu i zmuszony do reakcji na sygnał. Sygnał przerwanie programowe. Sygnały mogą być zgłaszane przez programy albo przez jądro SO. Przykładowe sytuacje, w których zgłaszane są sygnały: User nacisnął ^C SO wysyła do procesu sygnał SIGINT. User nacisnął ^Z SO wysyła do procesu sygnał SIGTSTP. Wykonano polecenie kill na jakimś procesie skutkuje to wysłaniem mu sygnału SIGTERM. Proces wykonał dzielenie przez zero, na skutek czego wystąpił wyjątek sprzętowy, reakcją SO na niego jest wysłanie sygnału SIGFPE do procesu, który dzielił. Podobnie przy próbie dostępu do nieswojej pamięci (SIGSEGV) czy błędzie szyny (SIGBUS) w obydwu przypadkach sygnał wysyła SO. 88

89 POSIX: Komunikacja międzyprocesowa Sygnały (signals). Proces może zgłaszać sygnały samemu, synchronicznie, za pomocą raise(). Można również zgłaszać sygnały innym procesom, za pomocą kill(pid_t pid, int sig). Proces może sobie zażyczyć, by niektóre sygnały do niego docierały (zamaskować sygnały). Niektórych sygnałów (SIGKILL, SIGSTOP) zablokować nie można. Zablokowanie niektórych sygnałów (SIGBUS, SIGSEGV, SIGILL, SIGFPE) skutkuje niezdefiniowanym zachowaniem w przypadku ich późniejszego zgłoszenia w innym kontekście niż celowe zgłoszenie za pomocą raise(). 89

90 POSIX: Komunikacja międzyprocesowa (Reakcja na) sygnały (signals). Jak wygląda reakcja na sygnał możemy zdefiniować za pomocą funkcji signal() bierze ona dwa parametry numer sygnału na który chcemy reagować i wskaźnik na funkcję, która będzie wywoływana w razie wystąpienia sygnału. Można również wybrać dwa inne zachowania: SIG_IGN ignoruj dany sygnał i SIG_DFL wywołaj domyślną procedurę obsługi. Domyślne procedury obsługi wykonują, zależnie od sygnału, jedną z czynności: wstrzymanie procesu, zakończenie procesu, zakończenie procesu poprzedzone zapisem core-dump, zignorowanie sygnału. Na ogół jeśli proces nie sprecyzował reakcji na dany sygnał, a ten zostanie zgłoszony, proces zostaje zakończony. 90

91 POSIX: Komunikacja międzyprocesowa (Predefiniowane) sygnały (signals) Za Wikipedią: SIGABRT - process aborted SIGALRM - signal raised by alarm SIGBUS - bus error SIGCHLD - child process terminated, stopped (*or continued) SIGCONT - continue if stopped SIGFPE - floating point exception SIGHUP - hangup SIGILL - illegal instruction SIGINT - interrupt SIGKILL - kill SIGPIPE - write to pipe with no one reading SIGQUIT - quit SIGSEGV - segmentation violation SIGSTOP - stop executing temporarily SIGTERM - termination SIGTSTP - terminal stop signal SIGTTIN - background process attempting to read ("in") SIGTTOU - background process attempting to write ("out")... 91

92 POSIX: Komunikacja międzyprocesowa (C i C++ a) sygnały (signals). Procedura obsługi sygnału (signal handler) zarejestrowana za pomocą signal() podlega pewnym ograniczeniom, ponieważ może być, w zasadzie, wywołana z dowolnego kontekstu: nie wszystkie funkcje wolno wołać z procedury obsługi, nie ma w niej generalnie dostępu do zmiennych statycznych. W C++ funkcja obsługi sygnału musi być POF (plain-old-function), tj. nie może korzystać z tych elementów C++, które są nadzbiorem C. W praktyce pozwalamy sobie na korzystanie z drobnych udogodnień (for(int i...) zamiast int i; for(i...)) C++ bez problemu. Z zaawansowanych mechanizmów C++ korzystać nie wolno np. throw zakończy się katastrofą. Szereg innych problemów (co z zasięgiem zmiennych?). 92

93 Oficjalny plan przemiotu: Co dalej? 1h: API Application Programming Interface. Win32 API i Native API. Windows i komunikaty. 2h: Wyświetlanie tekstu. Graphic Device Interface. Struktura GDI. 1h: Kontekst urządzenia. Podstawy grafiki w środowisku Windows. 2h: Klawiatura. Komunikaty i zestawy znaków. Mysz. Obszar roboczy myszy. 1h: Zegar. Kontrolki. Menu i okna dialogowe. 1h: Koncepcja MDI. 1h: Wielozadaniowość i wielowątkowość w systemie Windows. 2h: System plików w systemie LINUX/UNIX. 1h: Interfejs terminala. 2h: Procesy. Komunikacja między procesami. Sygnały. 1h: Interfejs gniazdowy w systemie LINUX. 93

94 Windows API 94

95 "Hello world!" przy wykorzystaniu WinAPI funkcja okna aplikacji główna funkcja programu, odpowiednik main(). 95

96 WinMain() int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow); Entry point programów pod Windows. Zwraca int ("dziwna" konwencja, gdzie 0 oznacza błąd). WINAPI to #define na stdcall i jest wskazówką dla kompilatora dot. konwencji wywołania funkcji, dla nas kompletnie nieistotne. HINSTANCE to typ opisujący uchwyty do instancji (kopii, wywołania) programu. hinstance uchwyt do bieżącej instancji. hprevinstance obecnie zawsze równy NULL, w Win16 służył do identyfikacji czy jesteśmy pierwszą, czy kolejną instancją programu, teraz jest to bardziej skomplikowane. lpcmdline linia poleceń (bez nazwy programu) jako jeden łańcuch. LPSTR to alias na char*. ncmdshow sposób wyświetlania okna (zminimalizowane, zmaksymalizowane, normalne, aktywne czy nie,...). 96

97 Zadania WinMain(): zainicjować aplikację, zarejestrować klasę okna, utworzyć główne okno aplikacji, wejść w pętlę przyjmowania i obsługi wiadomości. WinMain() W razie niepowodzenia (tj. gdy aplikacja nie dotarła do pętli wiadomości), powinniśmy zwrócić 0. W razie powodzenia (odebranie wiadomości WM_QUIT) zwracamy kod powrotu zawarty we wiadomości. 97

98 Tworzenie okna aplikacji Klasa okna opisuje wszystkie "takie same" okna. Klasa nie w znaczeniu C++ (class). struct WNDCLASS { UINT style; WNDPROC lpfnwndproc; int cbclsextra; int cbwndextra; HINSTANCE hinstance; HICON hicon; HCURSOR hcursor; HBRUSH hbrbackground; LPCTSTR lpszmenuname; LPCTSTR lpszclassname; }; 98

99 Tworzenie okna aplikacji W pierwszej kolejności musimy zarejestrować klasę okna. Rejestrowanie klasy okna: wiąże procedurę obsługi okna (WNDPROC lpfnwndproc) i pozostałe atrybuty klasy okna z nazwą tej klasy (LPCTSTR lpszclassname) od tego momentu posługujemy się nazwą klasy okna (np. przy tworzeniu). Gdy klasa jest zarejestrowana, możemy tworzyć okna przedstawicieli tej klasy. Do tworzenia okna służy funkcja API CreateWindow() (albo bardziej rozbudowana CreateWindowEx()). CreateWindow(wc.lpszClassName,TEXT("Hello world!"), nazwa klasy okna styl okna rozmiary okna WS_OVERLAPPEDWINDOW WS_VISIBLE,0,0, 200,100,0,0,hInst,0); uchwyt do okna-rodzica instancja, która jest właścicielem okna (od 2000 ignorowany) tekst z belki położenie narożnika 99

100 Tworzenie okna aplikacji Tu definiujemy klasę okna, rejestrujemy ją i tworzymy okno. 100

101 Obsługa wiadomości (komunikatów) W pętli (obsługi) komunikatów (message loop) pozostaje WinMain() do końca programu. Komunikaty (messages, notifications) są reakcją systemu na działania użytkownika (wciśnięty klawisz, kliknięcie myszy, przesunięcie okna, tknięcie suwaka, zamknięcie okna, i wiele, wiele więcej) i inne zdarzenia (np. odpalenie zegara) (events). To właśnie z komunikatami (np. WM_PAINT) związywaliśmy na OJP konkretne funkcje programu, gdy korzystaliśmy z MFC przy tworzeniu aplikacji w VC++. Windows umieszcza wszystkie komunikaty w kolejce (message queue), naszym zadaniem jest je wydobywać i przekazywać do obsługi. 101

102 Obsługa komunikatów Utrzymywana jest oddzielna kolejka komunikatów dla każdego programu (a dokładnie dla wątku). Typowy sposób postępowania: wydobycie pierwszego komunikatu z kolejki (GetMessage()), wywołanie TranslateMessage() aby dokonać tłumaczenia komunikatów dotyczących klawiszy wirtualnych (chodzi m.in. o to, by wiadomość typu "wciśnięto klawisz" została przetłumaczona na wiadomość "nadszedł znak" dzięki temu nie musimy sprawdzać np. stanu Shift i Caps Lock by odgadnąć, czy znak to "X" czy "x"). Podobnie chcemy, żeby skróty alt-litera tłumaczyły się na wybór z menu. TranslateMessage() wyjmuje "surowy komunikat z kolejki i wkłada (na początek) komunikat przetworzony. w razie konieczności podjęcie jakichś akcji (tu nie podejmujemy), "oddanie" komunikatu systemowi, by go wyekspediował (DispatchMessage()) do funkcji okna, która zajmuje się reagowaniem na komunikaty. kolejny komunikat

103 Funkcja okna funkcja okna reaguje na wybrane komunikaty... a dla niektórych woła domyślną procedurę obsługi 103

104 Funkcja okna W konsekwencji mimo, że formalnie nasz program cały czas "kręci się" w pętli komunikatów to z naszego punktu widzenia działanie programu wygląda tak, że co chwilę (po każdym komunikacie) wołana jest funkcja okna, która podejmuje odpowiednie działania (reaguje na te komunikaty, które uzna za stosowne, dla pozostałych woła DefWindowProc()). Gdy na OJP tworzyliśmy aplikację korzystającą z MFC, to wszystko było ukryte we wnętrznościach klasy dialogu i klasy aplikacji, które tworzyło dla nas środowisko. Skonstruowana przez MFC funkcja okna po prostu wywoływała powiązane uprzednio z komunikatami funkcje metody klasy dialogu, np. obsługa komunikatu WM_PAINT skutkowała wywołaniem metody OnPaint() klasy dialogu. W ten sposób MFC kreowało "w miarę obiektowe" opakowanie dla sterowanego zdarzeniami (event-driven) programu. 104

105 Gdzie kryje się WinAPI? Mało kto decyduje się dziś na programowanie w Windows przy użyciu "surowego" WinAPI, korzystamy raczej z obiektowych osłon (wrappers), takich jak: MFC poznaliśmy nieco na OJP. Chowa wywołania WinAPI wewnątrz klas typu CWnd, CButton, CEdit... ATL (Active Template Library) "lekka" alternatywa dla MFC, nadająca się bardziej do tworzenia aplikacji internetowych, OWL (Object Windows Library) konkurencyjne rozwiązanie Borlanda (Borland C do 5.02; koniec lat '90, porzucone) VCL konkurencyjne rozwiązanie Borlanda, napisane w Object Pascalu (język stosowany w Delphi) stosowane w Delphi, Borland C++ Builder. CLX wariacja na temat VCL, w założeniu międzyplatformowa (Builder, Delphi, Kylix); porzucona na rzecz VCL. Windows Forms część.net, sukcesor C++/CLI. inne nakładki, głównie na GUI, także międzyplatformowe (Qt, wxwidgets,...) pod Windows generalnie korzystają z WinAPI. 105

106 Jak w Visual Studio 2005? W Visual Studio 2005 mamy do wyboru kilka modeli aplikacji, bazujących, odpowiednio, na: ATL, CLR (Windows Forms), MFC, Win32 generuje projekt wykorzystujący "surowe" WinAPI. 106

107 Dygresja: Pozabijanie procesów bez fork() exec kill -SIGKILL <pid> 107

108 Ważniejsze komunikaty WM_DESTROY jest wysyłany do okna, które jest niszczone, już po usunięciu go z ekranu. To jedyny komunikat, który bezwzględnie musimy obsłużyć. Typowa reakcja polega na wywołaniu PostQuitMessage(), co skutkuje wstawieniem do kolejki komunikatów komunikatu WM_QUIT. WM_QUIT komunikat ten jest generowany przy zamykaniu aplikacji. Tak naprawdę nigdy nie trafia do procedury okna, bowiem jest to jedyny komunikat, dla którego GetMessage() zwraca 0, co kończy pętlę obsługi wiadomości. 108

109 Ważniejsze komunikaty WM_CLOSE sygnalizuje, że okno powinno ulec zamknięciu. Domyślna funkcja obsługi woła DestroyWindow(), które to: niszczy zegary związane z oknem, niszczy menu związane z oknem, odcina okno od Schowka, czyści kolejkę komunikatów okna, wysyła do okna WM_DESTROY i WM_NCDESTROY. Jeśli chcemy, możemy sami reagować na ten komunikat spytać czy użytkownik na pewno chce zamknąć aplikację albo celowo zignorować ten komunikat nie da się wówczas zamknąć okna w normalny sposób. WM_TIMER sygnalizuje, że tyknął jeden z zegarów przypisanych do okna. Na OJP to właśnie z tym komunikatem związywaliśmy metodę OnTimer(), która reagowała na zegar. 109

110 Ważniejsze komunikaty WM_PAINT sygnalizuje, że wnętrze okna wymaga odrysowania, np. na skutek tego, że będąc wcześniej zasłonięte teraz się odsłoniło, bądź zmieniło rozmiary. Tego komunikatu nie powinniśmy sami wysyłać jeśli chcemy wymusić odrysowanie okna, korzystamy z funkcji UpdateWindow() albo RedrawWindow(). To z WM_PAINT stowarzyszaliśmy metodę OnPaint() gdy korzystaliśmy z MFC. WM_NCPAINT podobnie jak WM_PAINT, ale dotyczy obszaru "nieklienckiego", tj. obrysu okna (belki, ramki, menu, suwaków). W typowych zastosowaniach zadowala nas domyślna procedura obsługi, ale jeśli chcemy tworzyć "fikuśne" okna, możemy tu dokonywać odrysowywania potrzebnych elementów. WM_ERASEBKGND sygnalizuje, że trzeba odrysować tło okna (np. po zmianie rozmiaru). Domyślna procedura obsługi dobrze sobie z tym radzi. 110

111 Ważniejsze komunikaty WM_GETTEXT, WM_SETTEXT proszą odpowiednio o odczytanie i ustawienie tekstu związanego z oknem. Dla okna dialogowego tekst zawarty jest w belce. Dla przycisków (kontrolki to też okna!) jest to napis na przycisku. Dla editboksów chodzi o tekst będący zawartością editboksa. Wysyłając do kontrolki te wiadomości możemy odczytać i zmienić ich zawartość. WM_GETICON, WM_SETICON pozwalają, odpowiednio, pobrać uchwyt do ikon związanych z oknem (małej i dużej) i ustawić ikony. WM_SIZE informuje, że nastąpiła zmiana rozmiarów okna. Przechwycenie pozwala reagować na te zmiany, np. ograniczając je (przyciąganie okien do innych okien, blokada zmian rozmiaru, utrzymywanie proporcji szer-wys). WM_MOVE podobnie, dla przesunięć okna. 111

112 Przykładowy ciąg komunikatów WM_GETMINMAXINFO WM_NCCREATE WM_NCCALCSIZE WM_CREATE WM_SHOWWINDOW WM_WINDOWPOSCHANGING WM_WINDOWPOSCHANGING WM_ACTIVATEAPP WM_NCACTIVATE WM_GETTEXT WM_ACTIVATE WM_SETFOCUS WM_NCPAINT WM_GETTEXT WM_ERASEBKGND WM_WINDOWPOSCHANGED WM_SIZE WM_MOVE WM_GETICON WM_GETICON WM_GETICON WM_PAINT WM_NCHITTEST WM_SETCURSOR WM_NCMOUSEMOVE WM_NCHITTEST WM_SETCURSOR WM_NCMOUSEMOVE WM_NCHITTEST WM_SETCURSOR WM_NCMOUSEMOVE WM_NCHITTEST WM_SETCURSOR WM_NCMOUSEMOVE WM_NCHITTEST WM_SETCURSOR WM_NCMOUSEMOVE WM_NCHITTEST WM_SETCURSOR WM_NCMOUSEMOVE WM_NCHITTEST WM_SETCURSOR WM_NCLBUTTONDOWN WM_CAPTURECHANGED WM_SYSCOMMAND WM_CLOSE WM_WINDOWPOSCHANGING WM_WINDOWPOSCHANGED WM_NCACTIVATE WM_ACTIVATE WM_ACTIVATEAPP WM_KILLFOCUS WM_DESTROY WM_NCDESTROY To kolejne komunikaty, które dostaje funkcja okna naszego trywialnego programu pierwsza kolumna: inicjacja, druga kolumna: praca, trzecia: po kliknięciu na [ X ]. 112

113 Komunikaty myszy WM_?BUTTONDOWN, WM_?BUTTONUP sygnalizują, odpowiednio, naciśnięcie i puszczenie przycisku myszy.?== L : lewy przycisk,?== R : prawy przycisk,?== M : środkowy przycisk. WM_?BUTTONDBLCLK podwójne kliknięcie. Nie każde okno dostaje komunikaty o podwójnym kliknięciu, trzeba sobie tego zażyczyć przy tworzeniu okna (styl CS_DBLCLKS). Sekwencja komunikatów reprezentująca podwójne kliknięcie jest wówczas następująca: BUTTONDOWN, BUTTONUP, BUTTONDBLCLK, BUTTONUP. Parametry komunikatów (lparam, wparam) zawierają współrzędne kursora myszy, stan klawiszy ctrl i shift oraz stan naciśnięcia klawiszy myszki (czyli można np. wykryć kliknięcie lewego przycisku przy wciśniętym prawym i shift). 113

114 Komunikaty myszy WM_MOUSEMOVE sygnalizuje, że nastąpił ruch myszy nad obszarem klienckim naszego okna. Każda zmiana współrzędnych kursora myszy generuje komunikat, ale jeśli okno nie nadąża z przetwarzaniem komunikatów, system usuwa je z kolejki. W konsekwencji liczba zarejestrowanych przez nas komunikatów zależy od tego, jak szybko je obsługujemy. Im szybciej się wykonuje procedura obsługi komunikatu WM_MOUSEMOVE, tym precyzyjniej śledzimy ruch myszy (dostając więcej komunikatów). WM_MOUSEWHEEL pokręcono kółkiem myszy. Podobnie, jak dla komunikatów związanych z przyciskami, możemy sprawdzić stan ctrl, shift i przycisków myszy. WM_MOUSEACTIVATE okno zostało aktywowane kliknięciem myszki. Na ogół ta wiadomość jest dla nas oczywista i nie reagujemy na nią, ale możemy to zrobić (np. jeśli nie godzimy się na aktywowanie). 114

115 Komunikaty myszy WM_NC* odpowiedniki poprzednich komunikatów dla obszaru nieklienckiego. Pozwalają reagować na kliknięcia i przesuwanie myszą nad belką tytułową, obramowaniem okna, menu i suwakami. 115

116 Zaawansowane operacje związane z myszą Przechwytywanie (capture) Normalnie komunikaty myszy trafiają do okna, w którym znajduje się punkt istotny (hot-spot) kursora w danej chwili. Czasem chcemy zmienić to zachowanie, np. gdy chcemy scentralizować reakcje na mysz w nadrzędnym oknie, które, zamiast potomków ma reagować na komunikaty, gdy zależy nam na przejęciu komunikatu o puszczeniu klawisza myszy po tym, jak użytkownik "wywleka" (drag) coś z naszego okna wówczas komunikat o puszczeniu klawisza normalnie nie dotarłby do naszego okna, ponieważ hot-spot kursora znajduje się poza oknem. Więcej informacji: WM_CAPTURECHANGED, ReleaseCapture(), GetCapture(). Hover/leave. Dwa dodatkowe komunikaty: WM_MOUSEHOVER i WM_MOUSELEAVE są przekazywane do okna, tylko jeśli sobie tego zażyczymy (TrackMouseEvent()). Mówią one o tym, że kursor myszki przebywał (co najmniej) przez pewien zadany czas w pewnym zadanym prostokącie (hover) i że go opuścił (leave). 116

117 Zaawansowane operacje związane z myszą Clipping. Zdarza się, że chcemy ograniczyć ruchy myszki do pewnego obszaru, np. gdy w programie graficznym użytkownik rysuje krzywą za pomocą myszki, nie chcemy by podczas rysowania kursor mógł opuścić okno programu. Za pomocą funkcji ClipCursor() możemy zażądać ograniczenia położenia kursora do zadanego prostokąta. Przeciągnij-i-upuść (drag-and-drop). Dosyć skomplikowane. Łatwo za to można obsłużyć przeciąganie plików do okna naszej aplikacji. Wystarczy: raz wywołać DragAcceptFiles(), żeby zgłosić, że chcemy być odbiorcą przeciąganych plików. reagować na komunikat WM_DROPFILES. Informacje o przeciągniętych plikach możemy wydobyć korzystając z funkcji DragQueryFile(). obsługę komunikatu zakończyć wywołując DragFinish(). 117

118 Obsługa klawiatury scan-code systemowa kolejka komunikatów sterownik klawiatury Klawiatura generuje scan-code (numer klawisza, numery te różnią się w zależności od modelu klawiatury) przy każdym naciśnięciu i zwolnieniu klawisza. Scan-codes są również generowane przy przytrzymaniu klawisza. Sterownik interpretuje scan-code, oblicza na jego podstawie virtualkey code niezależny od modelu klawiatury numer klawisza. Tworzony jest komunikat zawierający informacje o wciśniętym lub zwolnionym klawiszu i umieszczany w systemowej kolejce komunikatów. 118

119 Obsługa klawiatury scan-code sterownik klawiatury systemowa kolejka komunikatów kolejka komunikatów aplikacji (dokładnie: wątku) Gdy przychodzi czas na obsługę komunikatu klawiatury, system wyjmuje go z systemowej kolejki komunikatów, sprawdza, które okno ma w danej chwili focus i wysyła komunikat do kolejki komunikatów pierwszoplanowego wątku, który to okno utworzył. Po ich odbiorze (GetMessage()) z kolejki na ogół chcemy dokonać tłumaczenia komunikatów WM_KEYDOWN i WM_KEYUP na komunikaty wyższego poziomu (zamieniać virtual-key code na znak) i korzystamy z TranslateMessage(). 119

120 Komunikaty związane z klawiaturą WM_KEYDOWN, WM_KEYUP oznaczają, odpowiednio, że naciśnięto i zwolniono klawisz. Na ogół występują parami, ale długie przytrzymanie klawisza skutkuje wysłaniem serii komunikatów WM_KEYDOWN, po których następuje tylko jeden WM_KEYUP. (konkretnie, wiadomość WM_KEYDOWN przechowuje licznik powtórzeń, który kończy się na 15 potem generowane są kolejne komunikaty WM_KEYDOWN). Oba komunikaty odnoszą się do klawiszy niesystemowych, tj. bez przytrzymanego alt. O naciśnięciu i zwolnieniu klawisza systemowego informują komunikaty WM_SYSKEYDOWN i WM_SYSKEYUP. Klawisze systemowe: te z przytrzymanym alt (oraz F10). Domyślna procedura obsługi reaguje odpowiednio na (alt-)tab i (alt-)enter. Obsługa WM_SYSKEYDOWN i WM_KEYDOWN często implementuje reakcję na skróty klawiaturowe tłumacząc je na WM_SYSCOMMAND i WM_COMMAND. Normalnie dobrze radzi sobie z tym DefWindowProc(). 120

121 Komunikaty związane z klawiaturą WM_CHAR komunikat klawiatury wysokiego poziomu, generowany przez TranslateMessage(). Oznacza, że okno otrzymało znak z klawiatury. Jeśli korzystamy z TranslateMessage() i TranslateAccelerator() (obsługuje klawisze skrótów), będziemy dostawać ewentualne dodatkowe komunikaty pomiędzy WM_KEYDOWN i WM_KEYUP: WM_CHAR po naciśnięciu klawiszy niesterujących. WM_COMMAND i WM_SYSCOMMAND po naciśnięciu skrótów klawiaturowych. Klawisze sterujące: Ctrl, Shift, F1-F12, Enter, ESC,,,,, Home, End, Ins, Del, PgUp, PgDn, Tab i kilka innych... nie generują wiadomości WM_CHAR. WM_DEADCHAR generowany dla klawiszy niemych (np. w sekwencji `a tłumaczonej na ą klawiszem niemym jest ` ). 121

122 Komunikaty focusu WM_SETFOCUS dostaje go okno, które właśnie zdobyło focus. Najczęściej nie zależy nam na jego obsłudze, ale przydaje się na przykład, gdy w reakcji na zdobycie focusu chcemy zacząć wyświetlać kursor (tekstowy). WM_KILLFOCUS dostaje go okno, które zaraz utraci focus. Parametr wiadomości niesie informację o uchwycie okna, które focus dostaje. Reagujemy na ten komunikat gdy musimy pozbyć się kursora (tekstowego). GetFocus() pozwala wątkowi zorientować się, które z okien (własnych, bądź nie) ma w tej chwili focus. SetFocus() pozwala zmienić focus. 122

123 Komunikat WM_ACTIVATE WM_ACTIVATE trafia zarówno do okna, które właśnie staje się aktywne, jak i do okna, które przestaje być aktywne (na skutek aktywacji innego okna). Sytuacje te rozróżniamy na podstawie parametrów wiadomości. Okno aktywne to, które ma podświetloną belkę i jest przesunięte na wierzch. Aktywacja następuje na skutek: kliknięcia myszką na okno (także zminimalizowane do paska), alt-tab, alt-esc, wybrania okna z listy zadań, programowo: SetActiveWindow(). Aktywność jest blisko związana z focusem, ale to nie to samo. Focus ma okno aktywne lub jedno z jego okien potomnych (np. kontrolka). Domyślna procedura obsługi WM_ACTIVATE daje focus oknu. 123

124 Grafika GDI 124

125 Grafika z wykorzystaniem GDI GDI (Graphics Device Interface) interfejs umożliwiający tworzenie obiektów graficznych i rysowanie ich na urządzeniach wyjściowych (monitory, drukarki, plotery). Korzystaliśmy zeń pośrednio, w opakowaniu klas MFC (CDC, CPaintDC, CPoint, CRect,...). Prosty sposób na tworzenie (prostej) grafiki w Windows. Nie nadaje się do animacji (innej niż bardzo prosta) nie pozwala na synchronizację wyświetlania z pionowym odświeżaniem ekranu, w konsekwencji obraz migocze (flicker)). Nie wspiera 3D. Do poważnej grafiki: OpenGL, DirectX. Windows XP: sukcesor, GDI+. Windows Vista: Zupełnie nowe rozwiązanie: DWM (Desktop Window Manager), utrata akceleracji sprzętowej dla GDI. 125

126 GDI: kontekst urządzenia Koncepcja kontekstu urządzenia (device context, DC), który pośredniczy w dostępie do urządzenia graficznego, pozwalając ujednolicić operacje graficzne. Dzięki temu możemy rysować na różnych urządzeniach wykorzystując jedno API. Kontekst urządzenia jest strukturą, która zawiera informacje o urządzeniu (rozdzielczości, tryby, możliwości odwzorowania kolorów) i zestaw obiektów graficznych w danej chwili "wybranych" dla urządzenia: pióro (pen) do rysowania linii i obrysów, pędzel (brush) do rysowania wypełnień, bitmapę (bitmap), paletę (pallette) opisującą dostępne kolory, region wykorzystywany głównie do obcinania (clipping) odrysowywanych obszarów, ścieżka (path) opisuje kształty, czcionkę (font). 126

127 GDI: kontekst urządzenia Kontekst urządzenia jest obiektem o typie nieprzejrzystym (opaque object), tzn. nie mamy wglądu w to jak wygląda struktura danych składająca się na kontekst urządzenia. Operujemy tylko uchwytami do kontekstu urządzenia. Za pomocą odpowiednich funkcji API możemy zdobyć (get) uchwyt do kontekstu urządzenia, który potem przekazujemy funkcjom graficznym, a następnie zwalniamy (release) lub, w przypadku drukarki, usuwamy (delete). HDC typ reprezentujący kontekst urządzenia. Cztery typy kontekstów urządzenia: Display związany z ekranem, Printer związany z drukarką, Memory reprezentujący wirtualny ekran w pamięci, Information umożliwiający (tylko) wydobycie danych o urządzeniu, które reprezentuje. 127

128 GDI: Kontekst urządzenia Zdobywanie kontekstu urządzenia: Dla kontekstów ekranowych: GetDC(), GetDCEx(). Jako argument podajemy uchwyt do okna, dostajemy uchwyt do kontekstu urządzenia związanego z oknem. Podając NULL dostajemy uchwyt całego ekranu. Dla kontekstów drukarki (i nie tylko): CreateDC(). Dla kontekstów w pamięci: CreateCompatibleDC(). Dla kontekstów informacyjnych: CreateIC(). 128

129 GDI: z czy bez WM_PAINT? Praktycznie wszystkie operacje graficzne wykonujemy w reakcji na komunikat WM_PAINT. Komunikat ten będzie generowany zawsze, kiedy system uzna że okno wymaga odrysowania (odsłonięcie przez inne okno, powrót ze stanu minimalizacji, zmiana rozmiarów, przewijanie, etc.) albo kiedy my tego zażądamy (UpdateWindow(), RedrawWindow()). System domyśla się które fragmenty okna wymagają odrysowania, a które są "świeże" (cf. clipping region), przycinając operacje graficzne tak, że rysowanie odbywa się tylko dla tych fragmentów okna, dla których jest wymagane. Zdarzają się sytuacje, gdy potrzeba rysować poza WM_PAINT, ale to rzadkość. Możliwość ta przydaje się, gdy potrzeba natychmiastowej reakcji na działania użytkownika, w trakcie obsługi komunikatu, np. przy zaznaczaniu tekstu myszą. Wówczas sami dokonujemy rysowania podczas obsługi danego komunikatu (np. WM_MOUSEMOVE). Na ogół należy wtedy zadbać o przywrócenie oknu stanu poprzedniego oraz o poprawne zachowanie w razie wystąpienia WM_PAINT w trakcie rysowania (bądź jego zablokowanie, cf. LockWindowUpdate()). 129

130 GDI: BeginPaint() Gdy rysujemy w reakcji na komunikat WM_PAINT, musimy zasygnalizować systemowi początek i koniec operacji graficznych, ujmując je (zbiorczo) między wywołaniami funkcji BeginPaint() i EndPaint(). HDC BeginPaint(HWND hwnd, LPPAINTSTRUCT lppaint); Przekazujemy uchwyt do okna, po którym będziemy rysować i adres struktury typu PAINTSTRUCT, w której system przechowa informacje dotyczące rysowania (dla nas mało istotne). Dostajemy kontekst urządzenia związany z wyspecyfikowanym oknem. BeginPaint() przygotowuje system do tego, że będziemy rysować w obszarze okna m.in. ukryty zostaje kursor tekstowy a tło okna zostaje zmazane pędzlem tła. Nie wolno wołać BeginPaint() w kontekście innym niż reakcja na WM_PAINT. 130

131 GDI: EndPaint() Po zakończeniu rysowania wołamy funkcję EndPaint(). Kursor tekstowy (o ile był) zostaje odtworzony. BOOL EndPaint(HWND hwnd, CONST PAINTSTRUCT* lppaint); Przekazujemy te same parametry, co dla BeginPaint(). Nie zwraca nic sensownego. Każde wywołanie BeginPaint() musi mieć odpowiadające mu wywołanie EndPaint(). Typowy scenariusz wygląda zatem tak: PAINTSTRUCT info; HDC kontekst = BeginPaint(uchwyt_okna,&info); if(null==kontekst) // błąd else //... tu rysujemy EndPaint(uchwyt_okna,&info); 131

132 GDI: wybór narzędzi malarskich Zanim zaczniemy rysować, wypada wybrać narzędzia, za pomocą których tego dokonamy, i tak: pióro tworzymy za pomocą HPEN CreatePen(int fnpenstyle, int nwidth, COLORREF crcolor); Drugi argument definiuje grubość linii, w jednostkach logicznych. Podanie 0 skutkuje rysowaniem linii o grubości zawsze równej jednemu pikselowi. Trzeci argument definiuje kolor pióra. Pierwszy opisuje styl. Pióra "przerywane" działają tylko dla grubości 0 lub 1. Aby otrzymać wartość koloru typu COLORREF, na ogół korzystamy z makra RGB, które bierze trzy argumenty składowe R, G, B koloru, z zakresu Bardziej skomplikowane pióra możemy utworzyć za pomocą ExtCreatePen(). Funkcja zwraca uchwyt do świeżo stworzonego pióra lub NULL, w razie niepowodzenia. 132

133 GDI: wybór narzędzi malarskich Zanim zaczniemy rysować, wypada wybrać narzędzia, za pomocą których tego dokonamy, i tak: pędzel o jednolitym kolorze tworzymy za pomocą HBRUSH CreateSolidBrush(COLORREF crcolor); pędzel malujący wzorem: HBRUSH CreateHatchBrush(int fnstyle, COLORREF crcolor); Pierwszy argument określa rodzaj wzoru. pędzel malujący bitmapą: HBRUSH CreatePatternBrush(HBITMAP hbmp); Wszystkie trzy funkcje zwracają uchwyt do świeżo stworzonego pędzla lub NULL, w razie niepowodzenia. 133

134 GDI: wybór narzędzi malarskich Możemy też korzystać z predefiniowanych pędzli i piór, zamiast tworzyć nowe. W tym celu posługujemy się funkcją GetStockObject(): HGDIOBJ GetStockObject(int fnobject); Argument fnobject jest stałą symboliczną, mówiącą jaki obiekt chcemy otrzymać, do wyboru mamy m.in.: BLACK_PEN, WHITE_PEN, NULL_PEN BLACK_BRUSH, DKGRAY_BRUSH, GRAY_BRUSH, LTGRAY_BRUSH, WHITE_BRUSH, NULL_BRUSH Wynik działania funkcji (w przypadku powodzenia) rzutujemy na HPEN lub HBRUSH. 134

135 GDI: wybór narzędzi malarskich Samo utworzenie pióra i pędzla to jeszcze nie wszystko. W następnej kolejności musimy je wybrać (select) dla danego kontekstu urządzenia. Dokonujemy tego za pomocą funkcji: HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj); Funkcja wybiera obiekt hgdiobj (tu: pióro lub pędzel) dla kontekstu urządzenia hdc. Uwaga: Funkcja zwraca poprzedni obiekt tego samego rodzaju, który był wybrany w kontekście urządzenia. Na nas spoczywa obowiązek przywrócenia tego obiektu (również za pomocą SelectObject()) po zakończeniu rysowania. Uwaga-2: Wszystkie obiekty utworzone za pomocą funkcji Create*() należy, gdy nie są już potrzebne, usunąć za pomocą DeleteObject(), inaczej z każdym tworzeniem będziemy tracić zasoby. Obiektów predefiniowanych (GetStockObject()) nie usuwamy. 135

136 GDI: współrzędne logiczne Funkcje graficzne GDI mogą pracować w różnych układach współrzędnych logicznych w domyślnym układzie (MM_TEXT) jednostką jest jeden piksel, a współrzędna (0, 0) odpowiada lewemu górnemu narożnikowi kontekstu urządzenia. Wada/zaleta domyślnego układu: zmiana rozdzielczości ekranu pociąga za sobą zmianę rozmiaru rysowanych kształtów, bo sama jednostka (piksel) zmienia rozmiar. Układ współrzędnych logicznych możemy zmienić za pomocą funkcji int SetMapMode(HDC hdc, int fnmapmode); hdc kontekst urządzenia, dla którego przeprowadzamy zmianę. fnmapmode nowy układ współrzędnych (sposób mapowania jednostek logicznych na fizyczne). 136

137 GDI: współrzędne logiczne Dopuszczalne wartości fnmapmode: MM_LOMETRIC, MM_HIMETRIC jednostka logiczna odpowiada 0.1 lub (odpowiednio) 0.01 mm. MM_LOENGLISH, MM_HIENGLISH jednostka logiczna odpowiada 0.01" lub (odpowiednio) 0.001". MM_TWIPS jednostka logiczna odpowiada 1/1440" (1 twip). MM_ISOTROPIC jednostki zdefiniowane przez użytkownika (cf. SetWindowExtEx(), SetViewportExtEx()), z gwarantowaną izotropowością (jednostka na osi X równa tej na osi Y). MM_ANISOTROPIC jak wyżej, ale bez izotropowości (jednostka na osi X może być inna od tej na osi Y). MM_TEXT domyślny układ, w którym jedna jednostka = 1 piksel. Oś Y jest zorientowana na różne sposoby, w zależności od trybu y mapowania: (0,0) y MM_TEXT x (0,0) MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH 137 x? (zdefiniowane przez użytkownika) MM_ISOTROPIC, MM_ANISOTROPIC

138 GDI: współrzędne logiczne Inne funkcje związane z mapowaniem współrzędnych: GetMapMode() pozwala sprawdzić wybrane współrzędne logiczne. SetWindowOrgEx(), SetWindowExtEx(), SetViewportOrgEx(), SetViewportExtEx() kontrolują jak współrzędne używane podczas rysowania mapują się na współrzędne w oknie (np. pozwolą przesunąć punkt (0, 0) na środek okna). GDI umożliwia również automatyczne transformowanie układów współrzędnych to, co rysujemy w prostokątnym układzie współrzędnych można poddać transformacjom: skalowania, translacji, obrotu, ścięcia, odbicia... zanim trafi do okna. 138

139 GDI: rysowanie podstawowych kształtów Prostokąt: BOOL Rectangle(HDC hdc, int nleftrect, int ntoprect, int nrightrect, int nbottomrect); Prostokąt zaokrąglony: BOOL RoundRect(HDC hdc, int nleftrect, int ntoprect, int nrightrect, int nbottomrect, int nwidth, int nheight); Elipsa: BOOL Ellipse(HDC hdc, int nleftrect, int ntoprect, int nrightrect, int nbottomrect); Wycinek elipsy: Pie(); Łuk elipsy: Arc(); Odcinek elipsy (łuk elipsy + cięciwa): Chord(); 139

140 GDI: rysowanie podstawowych kształtów Obramowanie prostokąta: FrameRect(). Wnętrze prostokąta (zadanym pędzlem): FillRect(). Dowolny wielokąt: Polygon(). Zbiór dowolnych wielokątów: PolyPolygon(). Linia prosta: najpierw przesuwamy pióro za pomocą MoveToEx(), następnie rysujemy linię do zadanego położenia: LineTo(). Linia łamana (linia odcinkami prosta): PolyLine(). Zbiór linii łamanych PolyPolyLine(). 140

141 GDI: rysowanie podstawowych kształtów Piksel: COLORREF SetPixel(HDC hdc, int X, int Y, COLORREF crcolor); (kolor jest aproksymowany, faktycznie użyty kolor jest zwracany). Piksel, bez zwracania koloru (zapewnia lepszą wydajność): BOOL SetPixelV(HDC hdc, int X, int Y, COLORREF crcolor); Wypełnianie bieżącym pędzlem kształtu prostokątnego: BOOL PatBlt(HDC hdc, int x, int y, int szer, int wys, DWORD dwrop); dwrop operacja rastrowa, która zostanie wykonana: PATCOPY nakłada pędzel, PATINVERT wykonuje XOR obszaru z pędzlem, DSTINVERT ignoruje pędzel i odwraca kolory obszaru, BLACKNESS ignoruje pędzel i maluje na czarno, WHITENESS ignoruje pędzel i maluje na biało. 141

142 GDI: rysowanie podstawowych kształtów Wypełnianie bieżącym pędzlem dowolnego kształtu (FloodFill): BOOL ExtFloodFill(HDC hdc, int x, int y, Wypełnia obszar, poczynając od punktu (x, y). COLORREF crcolor, UINT fufilltype); Dla fufilltype==floodfillborder wypełnia obszar ograniczony obramowaniem koloru crcolor. Dla fufilltype==floodfillsurface wypełnia obszar o kolorze crcolor (wówczas obramowanie może być wielokolorowe). 142

143 GDI: rozmiary okna BOOL GetWindowRect(HWND hwnd, LPRECT lprect); Zwraca prostokąt okna (we współrzędnych ekranowych, punkt (0, 0) jest w lewym górnym rogu ekranu). BOOL GetClientRect(HWND hwnd, LPRECT lprect); Zwraca prostokąt obszaru klienckiego okna (w pikselach, punkt (0, 0) jest w lewym górnym rogu okna). BOOL ClientToScreen(HWND hwnd, LPPOINT lppoint); Przelicza współrzędne punktu z okna na współrzędne ekranowe. Przeliczone współrzędne dostajemy pod adresem wskazywanym przez lppoint (tam też przekazujemy współrzędne do konwersji). typedef struct {LONG x; LONG y;} POINT LPPOINT wskaźnik na POINT. 143

144 GDI: obszar niekliencki Możemy również rysować po obszarze nieklienckim okna (belka, obramowanie, paski przewijania) należy robić to w reakcji na komunikat WM_NCPAINT (jeśli nie zadowala nas domyślna procedura obsługi). Aby dostać się do obszaru nieklienckiego, potrzebujemy kontekstu urządzenia całego okna, możemy go zdobyć korzystając z funkcji HDC GetWindowDC(HWND hwnd); Nie korzystamy z BeginPaint() i EndPaint(). Po zakończeniu rysowania musimy zwolnić zdobyty kontekst za pomocą ReleaseDC(). Podając NULL w miejsce hwnd zdobywamy kontekst całego ekranu (na pierwszym monitorze). Dla pozostałych monitorów: GetDC(). Dobrze sprawdzić rozmiary belki i obrysu, jeśli chcemy po nich rysować: GetSystemMetrics(). 144

145 GDI: tekst Tekst jest wyświetlany przy użyciu czcionki wybranej w danej chwili dla kontekstu urządzenia (SelectObject()). Wybieramy albo czcionkę gotową (GetStockObject()), albo tworzymy własną (CreateFontIndirect()). Również kolor tekstu i kolor tła są cechą kontekstu urządzenia. Podstawowa funkcja, za pomocą której możemy wyświetlić tekst to BOOL TextOut(HDC hdc, int x, int y, LPCTSTR tekst, int n); Funkcja wyświetla tekst na współrzędnych (x, y) (cf. wyrównanie). Tekst przekazywany jest przez wskaźnik tekst. Wyświetlanych jest n znaków. Łańcuch nie musi być zakończony \0 (po to podajemy długość). Windows 95/98/Me tekst jest ograniczony do 8192 znaków. 145

146 GDI: tekst kolory Wypisywany tekst czyści tło, chyba że postanowimy inaczej: int SetBkMode(HDC hdc, int ibkmode); ibkmode==transparent bez czyszczenia tła. ibkmode==opaque z czyszczeniem tła. Funkcja zwraca poprzednio wybrany tryb (lub 0 w razie niepowodzenia). Uwaga: ustawiony tryb ma wpływ na czyszczenie tła także w innych operacjach (malowaniu pędzlami "deseniowymi" i piórami, które nie są ciągłe). Zmiana koloru tła tekstu (i wspomnianych wyżej operacji): COLORREF SetBkColor(HDC hdc, COLORREF crcolor); Zmiana koloru tekstu: COLORREF SetTextColor(HDC hdc, COLORREF crcolor); Obydwie funkcje zwracają poprzednio wybrany kolor. 146

147 GDI: tekst wyrównanie Możemy zażyczyć sobie wyrównywania tekstu, służy do tego: UINT SetTextAlign(HDC hdc, UINT fmode); fmode określa jak będzie wyrównywany tekst, jest (sensowną) sumą bitową poniższych flag: Wyrównanie w poziomie: TA_LEFT do lewej. TA_RIGHT do prawej. TA_CENTER wyśrodkowany. Wyrównanie w pionie: TA_BASELINE bazowa linia pisma wyrównana do y. TA_TOP górna krawędź tekstu wyrównana do y. TA_BOTTOM dolna krawędź tekstu wyrównana do y. Inne kierunki tekstu: TA_RTLREADING tekst pisany od prawej do lewej. VTA_BASELINE, VTA_CENTER odpowiedniki TA_BASELINE i TA_CENTER dla tekstu pionowego. 147

148 GDI: tekst wyrównanie... flagi do SetTextAlign(), kontynuacja. Flagi opisujące co dzieje się ze wskaźnikiem bieżącej pozycji tekstu po wypisaniu tekstu: TA_NOUPDATECP nic. TA_UPDATECP wskaźnik jest przesuwany, a wartości x i y przekazane do funkcji TextOut() są ignorowane zamiast tego tekst zawsze jest wyświetlany na bieżącej pozycji. 148

149 GDI: tekst zaawansowane funkcje Mamy też do dyspozycji bardziej zaawansowane funkcje służące do wyświetlania tekstu: DrawTextEx() rozpoznaje znaki tabulacji, pozwala traktować '&' jako normalny znak (domyślnie służy do podkreślania liter), umożliwia automatyczne dzielenie wierszy, umożliwia zadanie prostokąta, w którym ma mieścić się tekst, jeśli na spodzie prostokąta wypada niepełna linia tekstu, można wymusić jej zniknięcie, umożliwia wyświetlanie "..." na końcu tekstu, jeśli ten nie mieści się wewnątrz prostokąta, j.w., ale w środku tekstu lub w zadanych miejscach, umożliwia zadanie tabulatorów. 149

150 GDI: tekst zaawansowane funkcje Mamy też do dyspozycji bardziej zaawansowane funkcje służące do wyświetlania tekstu: ExtTextOut() pozwala przycinać tekst do prostokąta, pozwala na kontrolę rozstrzału (kerningu) znaków, pozwala na pisanie od prawej do lewej, pozwala na drukowanie cyfr zdefiniowanych przez locale (zamiast cyfr arabskich). TabbedTextOut() jak TextOut(), ale pozwala na zdefiniowanie tabulatorów. 150

151 GDI: tekst wybór czcionki Najprostszy sposób, to wybrać jedną z dostępnych z "magazynu", za pomocą GetStockObject(). Do wyboru mamy następujące stałe symboliczne reprezentujące czcionki: ANSI_FIXED_FONT font ANSI o stałej szerokości znaków, ANSI_VAR_FONT font ANSI o zmiennej (proporcjonalnej) szerokości znaków, DEVICE_DEFAULT_FONT czcionka domyślna dla danego urządzenia (nie ma w Win 9x), DEFAULT_GUI_FONT domyślna czcionka dla interfejsu użytkownika (ta, która jest używana do wyświetlania menu) MS Sans Serif. OEM_FIXED_FONT czcionka o stałej szerokości znaków dostar-czona przez producenta urządzenia (OEM), SYSTEM_FONT (teoretycznie) czcionka systemowa (Win 9x, NT: MS Sans Serif, 2000/XP: Tahoma) stosowanie niezalecane. SYSTEM_FIXED_FONT przestarzały; zachowany tylko dla celów kompatybilności z Windows 2.x (!). 151

152 GDI: tekst tworzenie czcionki Drugi, dający większe pole manewru, sposób to utworzenie czcionki za pomocą HFONT CreateFontIndirect(CONST LOGFONT* lplf);... gdzie lplf jest wskaźnikiem na strukturę LOGFONT, która zawiera informacje o czcionce logicznej, którą chcemy utworzyć. W Windows od 2000 wzwyż mamy też do dyspozycji funkcję CreateFontIndirectEx(), która daje większe możliwości. 152

153 GDI: tekst tworzenie czcionki typedef struct { LONG lfheight; LONG lfwidth; LONG lfescapement; LONG lforientation; LONG lfweight; BYTE lfitalic; BYTE lfunderline; BYTE lfstrikeout; BYTE lfcharset; BYTE lfoutprecision; BYTE lfclipprecision; BYTE lfquality; BYTE lfpitchandfamily; TCHAR lffacename[lf_facesize]; } LOGFONT; 153

154 GDI: tekst struktura LOGFONT lfheight żądana wysokość znaków w czcionce, wyrażona w jednostkach logicznych (nie w pikselach ani punktach!). Wysokość jest mierzona razem z uwzględnieniem wewnętrznych odstępów pionowych w znakach. Jeśli chcemy zignorować wewnętrzne odstępy i wyspecyfikować wysokość samego znaku (tzw. wysokość em, czyli odległość między górną a dolną krawędzią dużego 'M'), podajemy wielkość ujemną. Zero oznacza wartość domyślną. lfwidth żądana średnia szerokość znaków w czcionce. Zero domyślna. lfescapement kąt, pod którym "pnie się" tekst, w 0.1. lforientation kąt, o który znaki obrócone są względem kierunku wyznaczonego przez lfescapement. lfweight grubość czcionki, w skali Czcionka normalna ma grubość 400, bold oznacza wartość domyślną. 154

155 GDI: tekst struktura LOGFONT lfitalic TRUE oznacza kursywę. lfunderline TRUE oznacza podkreślenie. lfstrikeout TRUE oznacza przekreślenie. lfcharset zestaw znaków. Ważniejsze to: ANSI_CHARSET, DEFAULT_CHARSET, EASTEUROPE_CHARSET, SYMBOL_CHARSET. lfoutprecision specyfikuje szczegóły dopasowania czcionek (np. czy preferujemy czcionki TrueType, PostScript czy rastrowe), generalnie zdajemy się na OUT_DEFAULT_PRECIS. lfclipprecision opisuje co dzieje się ze znakami, które częściowo wystają poza region, do którego przykrajany jest tekst. W praktyce używa się tylko CLIP_DEFAULT_PRECIS. 155

156 GDI: tekst struktura LOGFONT lfquality informuje, czy przy dopasowaniu czcionki bardziej zależy nam na jakości czcionki, czy na dokładnym dopasowaniu dostępnych czcionek do czcionki żądanej, kontroluje antialiasing. Ważniejsze wartości: DEFAULT_QUALITY nie zależy nam szczególnie na jakości. DRAFT_QUALITY kompletnie nie zależy nam na jakości. Wówczas np. czcionki rastrowe mogą być skalowane, co daje nam do dyspozycji więcej możliwych rozmiarów czcionek i lepsze dopasowanie rozmiaru. CLEARTYPE_QUALITY włącza antialiasing ClearType w Windows XP i późniejszych (jeśli dostępny). 156

157 GDI: tekst struktura LOGFONT lfpitchandfamily typ czcionki. Suma bitowa jednej z wartości spośród FIXED_PITCH, VARIABLE_PITCH, DEFAULT_PITCH, i jednej spośród FF_ROMAN szeryfowe czcionki proporcjonalne (np. MS Serif), FF_SWISS bezszeryfowe czcionki proporcjonalne (np. MS Sans Serif). FF_SCRIPT czcionki przypominające pismo odręczne (np. Cursive). FF_MODERN czcionki o stałej szerokości znaków, zarówno szeryfowe, jak i nie (np. Courier New). FF_DECORATIVE czcionki dekoracyjne (np. Old English). FF_DONTCARE czcionka domyślna. 157

158 GDI: tekst struktura LOGFONT lffacename nazwa czcionki w postaci łańcucha (nie może być dłuższa niż 32 znaki, razem z kończącym \0), np. "Arial CE". Podanie NULL skutkuje wybraniem pierwszej czcionki, która spełnia warunki zadane przez lfoutprecision, lfpitchandfamily i lfquality. Nazwy czcionek dostępnych w systemie wraz z ich parametrami możemy zdobyć wywołując funkcję EnumFontFamiliesEx(), co jest procesem dość złożonym (mechanizm callback). Łatwo natomiast możemy sprawdzić ile miejsca (w jednostkach logicznych) zajmuje jakiś łańcuch wypisany wybraną w danej chwili w kontekście urządzenia czcionką korzystamy z funkcji GetTextExtentPoint32(). 158

159 Kontrolki 159

160 Kontrolki Każda kontrolka jest oddzielnym oknem, oznaczonym jako potomne względem okna, w którym kontrolka się znajduje. Kontrolki dodajemy albo korzystając z pliku z zasobami, albo tworzymy programowo, jak inne okna, za pomocą CreateWindowEx(), jako nazwę klasy okna podając jedną z predefiniowanych nazw (np. "BUTTON", "COMBOBOX", "EDIT"). Przy tworzeniu okna kontrolki do opcji stylu dodajemy WS_CHILD. Komunikować się z kontrolkami możemy wysyłając im komunikaty (SendMessage()), np. WM_SETTEXT, albo bezpośrednio, albo korzystając z makr (np. ComboBox_GetMinVisible()), które nieco to upraszczają. Również za pomocą komunikatów (WM_COMMAND, WM_NOTIFY) kontrolki dają znać oknu-rodzicowi o zdarzeniach. Jeśli korzystamy z gotowych kontrolek, ich obsługą będzie się zajmowało okno-rodzic. 160

161 Kontrolki: przyciski Przycisków jest kilka rodzajów: push button (typowy przycisk); (obok tekstu może zawierać bitmapę lub ikonę), dwustanowy check box, trójstanowy check box, (trzeci stan: nieokreślony (indeterminate)) radio button, group box; (nietypowy: nie akceptuje kliknięć ani focusu, ale formalnie to też przycisk), split button (Vista), (kliknięcie w strzałkę rozwija menu) command link (Vista), (właściwie zwykły przycisk, poza tym że domyślnie nie wyróżnia się z tła i wyświetla dodatkowy tekst). Oficjalna polska terminologia: push button przycisk. check box pole wyboru, kratka. radio button przycisk radiowy, przycisk opcji, przełącznik. group box pole grupy. 161

162 Kontrolki: przyciski Kontrolę nad wyglądem przycisku zapewniają nam style przycisku, które podajemy podczas tworzenia okna-przycisku. Ważniejsze style: Typy przycisków: BS_PUSHBUTTON "zwykły" przycisk (push button). BS_RADIOBUTTON przycisk typu radio button. BS_CHECKBOX przycisk typu check box. BS_3STATE przycisk typu trójstanowy check box. BS_GROUPBOX "przycisk" typu group box. BS_SPLITBUTTON przycisk typu split button. BS_COMMANDLINK przycisk typu command link. BS_DEFPUSHBUTTON, BS_DEFSPLITBUTTON, BS_DEFCOMMANDLINK wersje "domyślne" przycisków. Reagują kliknięciem na Enter, nawet gdy nie mają focusu, mogą też wizualnie wyglądać na wyróżnione. 162

163 Style przycisków, c.d.: Kontrolki: przyciski Automatyczne przyciski check box i radio button. Począwszy od Windows 95 kontrolki te oferują "inteligentne" wersje. Check boksy same zmieniają stan po kliknięciu, przyciski radio button same zmieniają stan po kliknięciu i wyłączają przyciski z tej samej grupy. BS_AUTOCHECKBOX "inteligentny" przycisk check box. BS_AUTORADIOBUTTON "inteligentny" przycisk radio button. BS_AUTO3STATE "inteligentny" przycisk trójstanowy check box. Pozycjonowanie tekstu: BS_TOP, BS_VCENTER, BS_BOTTOM (w pionie). BS_LEFT, BS_CENTER, BS_RIGHT (w poziomie). BS_LEFTTEXT (przenosi tekst na lewą stronę w przyciskach check box i radio button). 163

164 Style przycisków, c.d.: Pozostałe (ważniejsze): Kontrolki: przyciski BS_BITMAP przycisk zawiera bitmapę, BS_ICON przycisk zawiera ikonę, BS_TEXT przycisk zawiera tekst. BS_MULTILINE tekst zawija się do kolejnych wierszy, jeśli się nie mieści. BS_NOTIFY przycisk powiadamia okno-rodzica o zdobyciu (WM_SETFOCUS) lub utracie (WM_KILLFOCUS) focusu. BS_FLAT, BS_PUSHLIKE. BS_OWNERDRAW specyfikuje, że przycisk sam będzie się odrysowywał. Okno-rodzic będzie otrzymywać komunikat WM_DRAWITEM w razie konieczności odrysowania przycisku. 164

165 Kontrolki: przyciski Tekst zawarty w przycisku funkcjonuje jak belka tytułowa okna, tj. można zadać go przy tworzeniu okna, zmieniać korzystając z komunikatu WM_SETTEXT i sprawdzać korzystając z WM_GETTEXT. Tekst "drobny" przycisku typu command link można zmienić korzystając z wiadomości BCM_SETNOTE. Rozmiary przycisku jak rozmiary okna. Przycisk sygnalizuje kliknięcie wysyłając do okna-rodzica komunikat WM_COMMAND, z kodem BN_CLICKED (zawartym w parametrach komunikatu). Kliknięcie w przycisk daje mu focus (z wyjątkiem group box). Przycisk split button zachowuje się jak zwykły push button, dopóki nie klikniemy na strzałkę. Więcej informacji: BCN_DROPDOWN (kliknięcie na strzałkę), BCM_SETSPLITINFO (kontrola strzałki). 165

166 Kontrolki: przyciski check box, radio button Kliknięcie w check box skutkuje wysłaniem WM_COMMAND (z powiadomieniem BN_CLICKED) do okna-rodzica. W przypadku check boksów nieautomatycznych, na rodzicu spoczywa odpowiedzialność za zmianę stanu check boksa. Check boksy automatyczne same zmieniają stan (rodzic może zignorować komunikat). Zmiana stanu check boksa (automatyczna lub programowa) sama skutkuje jego odrysowaniem. Stan check boksa sprawdzamy za pomocą IsDlgButtonChecked(). Dla radio buttons: analogicznie. Jeśli ustawimy atrybut WS_GROUP dla każdego pierwszego przycisku radio button z grupy i uczynimy go automatycznym, stan pozostałych przycisków w grupie będzie się czyścił automatycznie. Grupa jest rozpoznawana na podstawie WS_GROUP, kontrolka group box pełni wyłącznie rolę estetyczną. Stan radio button sprawdzamy za pomocą IsDlgButtonChecked(). 166

167 Kontrolki: przyciski check box, radio button Stan każdego przycisku (dla group box ma to ograniczony sens) możemy sprawdzić wysyłając do niego komunikat BM_GETCHECK albo BM_GETSTATE, a ustawić wysyłając komunikat BM_SETCHECK albo BM_SETSTATE. Na stan przycisku składają się: check state: (zaznaczony, odznaczony (dotyczy check box i radio button) i dodatkowo nieokreślony (dla trójstanowego)). focus state: (ma focus, bądź nie). push state: (jest właśnie wciskany, bądź nie). Inne wiadomości wysyłane do przycisków: BM_SETSTYLE (ale nie wolno zmieniać typu), BM_SETIMAGE, BM_GETIMAGE. 167

168 Kontrolki: przyciski Powiadomienia (wiadomości WM_COMMAND lub WM_NOTIFY z parametrem z poniższej listy), które przyciski mogą wysyłać do okna-rodzica: BN_CLICKED, BN_SETFOCUS, BN_KILLFOCUS już wspomnieliśmy. BN_DOUBLECLICKED, BN_PUSHED, BN_UNPUSHED, BN_DISABLE, BN_PAINT (dla przycisków odrysowywanych ręcznie), BCN_HOTITEMCHANGE (Win XP i nowsze; kursor myszy znalazł się nad przyciskiem lub opuścił obszar przycisku). Przycisk musi mieć styl WS_NOTIFY, jeśli chcemy dostawać w/w szczegółowe powiadomienia. 168

169 Kontrolki: przyciski varia Domyślna procedura obsługi okna-przycisku (nie rodzica!), który jest typu radio button lub check box reaguje na WM_CHAR zmieniając stan przycisku, jeśli wciśnięto + (włącza), = (włącza) lub (wyłącza). Dla WM_KEYDOWN reakcją na spację jest wciśnięcie przycisku. 169

170 Timer 170

171 Timer Mieliśmy z nim do czynienia na OJP. UINT_PTR SetTimer(HWND hwnd, UINT_PTR nidevent, UINT uelapse, TIMERPROC lptimerfunc); Ustawia zegar o identyfikatorze nidevent, tykający co uelapse ms. Okno musi należeć do wątku, który woła SetTimer(). Podanie uchwytu okna w hwnd i lptimerfunc==null skutkuje tym, że z każdym tyknięciem zegara do okna będzie wysyłany komunikat WM_TIMER. Możemy sprawdzić, który zegar tyknął badając parametry komunikatu. Jeśli podamy lptimerfunc, który jest wskaźnikiem na funkcję o konkretnej sygnaturze, to ta funkcja będzie wołana z każdym tyknięciem zegara. Uwaga: Wówczas wołania (*lptimerfunc) dokonuje domyślna procedura obsługi komunikatu WM_TIMER. W konsekwencji nawet wtedy pętla komunikatów musi funkcjonować, jeśli chcemy reagować na zegar. 171

172 Timer UINT_PTR SetTimer(HWND hwnd, UINT_PTR nidevent, UINT uelapse, TIMERPROC lptimerfunc); Zwraca nie-zero w razie powodzenia. Zbiory identyfikatorów różnych okien są niezależne od siebie, tj. dwa okna mogą mieć różne od siebie zegary, o identycznych identyfikatorach. Kolejne wywołania SetTimer() dla tego samego identyfikatora nadpisują poprzedni zegar nowym. Usuwamy zegar za pomocą: BOOL KillTimer(HWND hwnd, UINT_PTR nidevent); Usuwa zegar o identyfikatorze nidevent związany z oknem hwnd. Zwraca nie-zero w razie powodzenia. Komunikaty WM_TIMER, które już są w kolejce wiadomości nie zostaną usunięte. 172

173 Menu 173

174 Menu Na ogół tworzymy je w pliku zasobów (resource file) (.rc), korzystając ze specjalnej składni, bądź rysujemy w środowisku graficznym, które tworzy plik.rc za nas. Pliki zasobów (.rc) jest kompilowany przez kompilator zasobów (resource compiler) do pliku.res, który dołączany jest do kodu wynikowego podczas łączenia (linkowania). W środowisku VS krok kompilacji zasobów wykonywany jest automatycznie, wystarczy dodać jeden zasób (Project / Add Resource / Menu). 174

175 Menu Przykładowy plik, myresource.rc: & oznacza podkreślenie (i tworzy skrót automatycznie). Każdy element menu ma swój identyfikator. 175

176 Menu Identyfikatory mapowane są na liczby w pliku myresource.h. Plik, myresource.h odpowiadający pokazanemu wcześniej plikowi zasobów: Również samo menu ma swój identyfikator. Wspomniany plik.h włączamy (#include) zarówno w pliku.rc, jak i w pliku.cpp, w którym tworzymy i obsługujemy okno, bo... Identyfikator menu będzie potrzebny przy tworzeniu okna. Identyfikatory elementów menu będą potrzebne przy reakcji na klikanie w menu przez użytkownika. 176

177 Menu: dodawanie Musimy jeszcze wyspecyfikować stworzone przez nas menu podczas tworzenia klasy okna: IDR_MENU1 identyfikator menu. Menu: reakcja na Wybieranie przez użytkownika elementów menu skutkuje wysyłaniem WM_COMMAND do funkcji obsługi okna. Na podstawie parametrów wnioskujemy o tym, który element został wybrany (zwykle robimy switch(...) po identyfikatorach). 177

178 Menu: modyfikacja Wygaszenie (gray-out) i ponowne przywrócenie elementu menu możemy zrealizować za pomocą BOOL EnableMenuItem(HMENU hmenu, UINT uid, UINT uenable); hmenu uchwyt do menu, na którym operujemy. uid identyfikator elementu menu, lub jego numer (zależy od uenable). uenable kombinacja dwóch stałych symbolicznych, jednej z {MF_BYCOMMAND, MF_BYPOSITION}, jednej z {MF_ENABLED, MF_GRAYED}. MF_BYCOMMAND: uid jest interpretowane jako identyfikator menu, MF_BYPOSITION: uid jest interpretowane jako numer elementu. 178

179 Menu: modyfikacja Większą kontrolę nad elementami menu zapewnia funkcja SetMenuItemInfo(). Pozwala ona kontrolować: zaznaczenie elementów menu, zaznaczenie elementów menu, przenoszenie elementów menu do nowych linii i kolumn, dodawanie linii-separatorów do menu, zmianę tekstu elementu, podświetlanie elementu, elementy menu odrysowywane programowo ("owner-draw"). Łatwe zaznaczanie elementów menu : CheckMenuItem(). Związanie bitmap z elementami menu: SetMenuItemBitmaps(). 179

180 Menu: modyfikacja Kolejne funkcje pozwalające na dynamiczną modyfikację struktury lub wyglądu menu: LoadMenu() wczytuje menu z zasobów, SetMenu() wiąże wczytane menu z oknem, CreateMenu() tworzy puste menu, CreatePopupMenu() tworzy puste podmenu, AppendMenu() dodaje na końcu element lub podmenu do menu, InsertMenu() wstawia element lub podmenu do menu, DeleteMenu() usuwa element menu, DestroyMenu() niszczy całe menu, DrawMenuBar() odrysowuje pasek menu 180

181 "Powszechne" okna dialogowe (common dialogs) 181

182 "Powszechne" dialogi (common dialog boxes)... wyboru pliku ("Open", "Save As").... wyboru koloru ("Color").... wyszukania ("Find").... zamiany ("Replace").... wyboru czcionki ("Font"). 182

183 "Powszechne" dialogi (common dialog boxes)... wydruku ("Print").... właściwości strony ("Page Setup"). Więcej informacji (online help): 183

Programy użytkowe (utilities)

Programy użytkowe (utilities) nm wypisuje symbole w plikach wykonywalnych, plikach wynikowych (*.o) lub ich kolekcjach (bibliotekach, *.a). Składnia: nm plik. Plik wynikowy, z którego pochodzi symbol. Wartość symbolu. Typ symbolu (najczęściej

Bardziej szczegółowo

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

Pliki. Funkcje tworzące pliki i operujące na nich opisane są w części 2 pomocy systemowej. Tworzenie i otwieranie plików: Pliki W celu wykonania jakiejkolwiek operacji na istniejącym pliku, plik ten musi zostać otwarty, natomiast jeśli plik jeszcze nie istnieje, to musi zostać utworzony. Plik może zostać otwarty w trybie:

Bardziej szczegółowo

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

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach Laboratorium Systemów Operacyjnych Ćwiczenie 4. Operacje na plikach Wykonanie operacji wymaga wskazania pliku, na którym operacja ma zostać wykonana. Plik w systemie LINUX identyfikowany jest przez nazwę,

Bardziej szczegółowo

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

Obsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011 Obsługa plików Systemy Operacyjne 2 laboratorium Mateusz Hołenko 25 września 2011 Plan zajęć 1 Pliki w systemie Linux i-węzły deskryptory plików 2 Operacje na plikach otwieranie i zamykanie zapis i odczyt

Bardziej szczegółowo

Kolejki FIFO (łącza nazwane)

Kolejki FIFO (łącza nazwane) Kolejki FIFO (łącza nazwane) Systemy Operacyjne 2 laboratorium Mateusz Hołenko 6 listopada 2011 Plan zajęć 1 Łącza w systemie Linux kolejki FIFO vs. potoki specyfika łączy nazwanych schemat komunikacji

Bardziej szczegółowo

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

Laboratorium z systemów operacyjnych. System plików - funkcje systemowe. Anna Wojak Laboratorium z systemów operacyjnych System plików - funkcje systemowe Anna Wojak 1 Zagadnienia do samodzielnego przygotowania: podstawowe polecenia linux, podstawy programowania w jezyku C, deskryptor

Bardziej szczegółowo

Komunikacja za pomocą potoków. Tomasz Borzyszkowski

Komunikacja za pomocą potoków. Tomasz Borzyszkowski Komunikacja za pomocą potoków Tomasz Borzyszkowski Wstęp Sygnały, omówione wcześniej, są użyteczne w sytuacjach błędnych lub innych wyjątkowych stanach programu, jednak nie nadają się do przekazywania

Bardziej szczegółowo

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

Powłoka I. Popularne implementacje. W stylu sh (powłoki zdefiniowanej w POSIX) W stylu csh. bash (najpopularniejsza) zsh ksh mksh. Powłoka I Popularne implementacje W stylu sh (powłoki zdefiniowanej w POSIX) bash (najpopularniejsza) zsh ksh mksh W stylu csh csh tcsh 12 października 2018 1 / 16 Powłoka II Zachęta Komunikuje się z użytkownikiem

Bardziej szczegółowo

Instrukcja do laboratorium Systemów Operacyjnych (semestr drugi)

Instrukcja do laboratorium Systemów Operacyjnych (semestr drugi) Instrukcja do laboratorium Systemów Operacyjnych (semestr drugi) wiczenie trzecie Temat: Potoki i ł cza nazwane w Linuksie. Opracowanie: mgr in ż. Arkadiusz Chrobot Wprowadzenie 1. Komunikacja z wykorzystaniem

Bardziej szczegółowo

Bash - wprowadzenie. Bash - wprowadzenie 1/39

Bash - wprowadzenie. Bash - wprowadzenie 1/39 Bash - wprowadzenie Bash - wprowadzenie 1/39 Bash - wprowadzenie 2/39 Czym jest bash? Rysunek : Zadanie powłoki to ukrycie wywołań systemowych Bash - wprowadzenie 3/39 Czym jest bash? Przykład polecenia:

Bardziej szczegółowo

Systemy Operacyjne ZAAWANSOWANE OPERACJE WEJŚCIA-WYJŚCIA DLA PLIKÓW

Systemy Operacyjne ZAAWANSOWANE OPERACJE WEJŚCIA-WYJŚCIA DLA PLIKÓW Systemy Operacyjne ZAAWANSOWANE OPERACJE WEJŚCIA-WYJŚCIA DLA PLIKÓW Zajęcia 2 - Podstawowe operacje wejścia-wyjścia dla plików 1 Pozyskiwanie i wyświetlanie metadanych pliku 2 Wejście/wyjście asynchroniczne

Bardziej szczegółowo

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

Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi. Przykład: $ ls more Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi. Tworzenie łącza #include int pipe(int filedes[2]); Przykład: int

Bardziej szczegółowo

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

Lekcja 10. Uprawnienia. Dołączanie plików przy pomocy funkcji include() Sprawdzanie, czy plik istnieje przy pmocy funkcji file_exists() Paweł Gmys PHP strona 1 Lekcja 10 Uprawnienia Aby skrypt PHP mógł odwołać się do pliku, musi mieć odpowiednie uprawnienia. Szczegóły są zależne od serwera. Najczęściej chyba skrypt ma uprawnienia takie,

Bardziej szczegółowo

Klient-Serwer Komunikacja przy pomocy gniazd

Klient-Serwer Komunikacja przy pomocy gniazd II Klient-Serwer Komunikacja przy pomocy gniazd Gniazda pozwalają na efektywną wymianę danych pomiędzy procesami w systemie rozproszonym. Proces klienta Proces serwera gniazdko gniazdko protokół transportu

Bardziej szczegółowo

1 Przygotował: mgr inż. Maciej Lasota

1 Przygotował: mgr inż. Maciej Lasota Laboratorium nr 1 1/7 Język C Instrukcja laboratoryjna Temat: Programowanie w powłoce bash (shell scripting) 1 Przygotował: mgr inż. Maciej Lasota 1) Wprowadzenie do programowania w powłoce Skrypt powłoki

Bardziej szczegółowo

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

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1 Podstawy programowania. Wykład Funkcje Krzysztof Banaś Podstawy programowania 1 Programowanie proceduralne Pojęcie procedury (funkcji) programowanie proceduralne realizacja określonego zadania specyfikacja

Bardziej szczegółowo

IPC: Kolejki komunikatów

IPC: Kolejki komunikatów IPC: Kolejki komunikatów Systemy Operacyjne 2 laboratorium Mateusz Hołenko 7 listopada 2011 Plan zajęć 1 Mechanizmy IPC kolejki komunikatów pamięć współdzielona semafory 2 Kolejki komunikatów kolejka komunikat

Bardziej szczegółowo

INFORMATYKA Studia Niestacjonarne Elektrotechnika

INFORMATYKA Studia Niestacjonarne Elektrotechnika INFORMATYKA Studia Niestacjonarne Elektrotechnika Wydział Elektrotechniki i Informatyki dr inż. Michał Łanczont Wydział Elektrotechniki i Informatyki p. E419 tel. 81-538-42-93 m.lanczont@pollub.pl http://lanczont.pollub.pl

Bardziej szczegółowo

Iteracyjny serwer TCP i aplikacja UDP

Iteracyjny serwer TCP i aplikacja UDP Iteracyjny serwer TCP i aplikacja UDP Iteracyjny serwer TCP Funkcje wywoływane przez serwer TCP socket() - bind() - listen() - accept() - read() / write() - close() socket() Creates an endpoint for communication

Bardziej szczegółowo

Obsługa plików Procesy

Obsługa plików Procesy Obsługa plików Procesy Systemy Operacyjne 2 laboratorium Mateusz Hołenko 15 października 2011 Plan zajęć 1 Obsługa plików 1 Pliki w systemie Linux i-węzły deskryptory plików 2 Operacje na plikach 3 Operacje

Bardziej szczegółowo

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

Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p. Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni Wykład 6 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Plan prezentacji Wskaźnik do pliku Dostęp do pliku: zapis, odczyt,

Bardziej szczegółowo

Linux: System Plików

Linux: System Plików Linux: System Plików Systemy Operacyjne Mateusz Hołenko 3 marca 2013 Plan zajęć Wszystko jest plikiem Obsługa systemu plików Prawa dostępu Wyszukiwanie Mateusz Hołenko Linux: System Plików [2/24] Wszystko

Bardziej szczegółowo

2. System uprawnień w linuxie

2. System uprawnień w linuxie 2. System uprawnień w linuxie Uprawnienia do plików: -rw-r--r-x 1 pawelza students 0 Lis 17 08:21 plik Mamy tutaj trzy grupy uprawnień: -rw - dla właściciela (owner, oznaczany też "user" reprezentowany

Bardziej szczegółowo

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

SYSTEMY OPERACYJNE I laboratorium 3 (Informatyka stacjonarne 2 rok, semestr zimowy) Procesy i shell. Polecenia ps, sleep, exit, jobs, bg, fg, top, kill, bash, tcsh, which, type, whereis, touch. Metaznak & i >>. Dowiązania miękkie i twarde. Proces jest programem, który jest wykonywany

Bardziej szczegółowo

SYSTEMY OPERACYJNE I SIECI KOMPUTEROWE

SYSTEMY OPERACYJNE I SIECI KOMPUTEROWE Klasyczne polecenia: ls [opcje][katalog][pliki] opcje podstawowe -a wyświetla również pliki ukryte -b znaki niedrukowane jako liczby ósemkowe -c sortuje dane zgodnie z datą zmiany -k podaje wielkość pliku

Bardziej szczegółowo

W pierwszej kolumnie wyświetlany jest identyfikator procesu (pid)

W pierwszej kolumnie wyświetlany jest identyfikator procesu (pid) Ćwiczenie 2 Cel ćwiczenia: Poznanie mechanizmów wejścia/wyjścia, zapoznanie się ze sposobami wyświetlania plików tekstowych i wyszukiwania informacji, podstawowe operacje na plikach tekstowych, zmienne

Bardziej szczegółowo

System plików warstwa logiczna

System plików warstwa logiczna Dariusz Wawrzyniak Pojęcie u Plik jest abstrakcyjnym obrazem informacji gromadzonej i udostępnianej przez system komputerowy. Plik jest podstawową jednostką logiczną magazynowania informacji w systemie

Bardziej szczegółowo

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

Pliki. Informacje ogólne. Obsługa plików w języku C Pliki Informacje ogólne Plik jest pewnym zbiorem danych, zapisanym w systemie plików na nośniku danych (np. dysku twardym, pendrive, płycie DVD itp.). Może posiadać określone atrybuty, a odwołanie do niego

Bardziej szczegółowo

Znaki globalne w Linuxie

Znaki globalne w Linuxie Znaki globalne w Linuxie * reprezentuje jeden lub wiele znaków (wild-card character)? reprezentuje dokładnie jeden znak (wild-card character) [abcde] reprezentuje dokładnie jeden znak z wymienionych [a-e]

Bardziej szczegółowo

Kurs systemu Unix wykład wstępny. Kurs systemu Unix 1

Kurs systemu Unix wykład wstępny. Kurs systemu Unix 1 Kurs systemu Unix wykład wstępny Kurs systemu Unix 1 Cele wykladu Zdobycie podstawowej wiedzy o systemie i jego narzędziach. Poznanie unixowych języków skryptowych (bash, awk,...). Nauka programowania

Bardziej szczegółowo

5. Model komunikujących się procesów, komunikaty

5. Model komunikujących się procesów, komunikaty Jędrzej Ułasiewicz str. 1 5. Model komunikujących się procesów, komunikaty Obecnie stosuje się następujące modele przetwarzania: Model procesów i komunikatów Model procesów komunikujących się poprzez pamięć

Bardziej szczegółowo

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

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p. Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy Wykład 12 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Plan prezentacji (1) Obsługa łańcuchów znakowych getchar(), putchar()

Bardziej szczegółowo

4.2 Sposób korzystania z l acza

4.2 Sposób korzystania z l acza 4.2 Sposób korzystania z l acza 31 Opis programu: Program procesu potomnego (linie 16 19) jest taki sam, jak w przyk ladzie na listingu 3. W procesie macierzystym nastepuje z kolei przekierowanie standardowego

Bardziej szczegółowo

Programowanie na poziomie sprzętu. Programowanie w Windows API

Programowanie na poziomie sprzętu. Programowanie w Windows API Programowanie w Windows API Windows API Windows Application Programming Interface (API) to zestaw funkcji systemu operacyjnego Windows, które umożliwiają aplikacjom korzystanie z wszystkich usług systemu.

Bardziej szczegółowo

Podstawy programowania skrót z wykładów:

Podstawy programowania skrót z wykładów: Podstawy programowania skrót z wykładów: // komentarz jednowierszowy. /* */ komentarz wielowierszowy. # include dyrektywa preprocesora, załączająca biblioteki (pliki nagłówkowe). using namespace

Bardziej szczegółowo

Funkcje zawarte w bibliotece < io.h >

Funkcje zawarte w bibliotece < io.h > PLIKOWE OPERACJE WEJŚCIA - WYJŚCIA Język C/C++ nie ma wbudowanych żadnych instrukcji umożliwiających wykonywanie operacji wejścia-wyjścia! Służą do tego funkcje biblioteczne. Funkcje zawarte w bibliotece

Bardziej szczegółowo

Temat zajęć: Obsługa systemu plików.

Temat zajęć: Obsługa systemu plików. Temat zajęć: Obsługa systemu plików. Czas realizacji zajęć: 90 min. Zakres materiału, jaki zostanie zrealizowany podczas zajęć: I. Operacje na plikach zwykłych. Tworzenie i otwieranie plików, deskryptory

Bardziej szczegółowo

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02 METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE Wykład 02 NAJPROSTSZY PROGRAM /* (Prawie) najprostszy przykład programu w C */ /*==================*/ /* Między tymi znaczkami można pisać, co się

Bardziej szczegółowo

Niektóre katalogi są standardowymi katalogami zarezerwowanymi do użytku przez system. Znaczenie wybranych katalogów systemowych jest następujące:

Niektóre katalogi są standardowymi katalogami zarezerwowanymi do użytku przez system. Znaczenie wybranych katalogów systemowych jest następujące: Podstawy systemu Linux Linux jest systemem operacyjnym dla komputerów PC, opracowany na początku lat dziewięćdziesiątych przez Linusa Torvaldsa. Podobnie jak Unix jest on systemem wielozadaniowym - umożliwia

Bardziej szczegółowo

PRACOWNIA INFORMATYCZNA BASH - PODSTAWOWE INFORMACJE

PRACOWNIA INFORMATYCZNA BASH - PODSTAWOWE INFORMACJE PRACOWNIA INFORMATYCZNA BASH - PODSTAWOWE INFORMACJE Magda Mielczarek Pracownia Informatyczna 2015/2016 1 Podstawowe definicje Linux system operacyjny, które oferuje kompletne środowisko programistyczne

Bardziej szczegółowo

Funkcje zawarte w bibliotece < io.h >

Funkcje zawarte w bibliotece < io.h > PLIKOWE OPERACJE WEJŚCIA - WYJŚCIA Język C/C++ nie ma wbudowanych żadnych instrukcji umożliwiających wykonywanie operacji wejścia-wyjścia! Służą do tego funkcje biblioteczne. Funkcje zawarte w bibliotece

Bardziej szczegółowo

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6 JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM Wykład 6 1 SPECYFIKATOR static Specyfikator static: Specyfikator ten powoduje, że zmienna lokalna definiowana w obrębie danej funkcji nie jest niszczona

Bardziej szczegółowo

Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania

Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania Przemysław Kobylański Wprowadzenie Każdy program w C musi zawierać przynajmniej funkcję o nazwie main(): Aby możliwe

Bardziej szczegółowo

Biblioteka standardowa - operacje wejścia/wyjścia

Biblioteka standardowa - operacje wejścia/wyjścia Biblioteka standardowa - operacje wejścia/wyjścia Przemysław Gawroński D-10, p. 234 Wykład 6 15 stycznia 2019 (Wykład 6) Biblioteka standardowa - operacje wejścia/wyjścia 15 stycznia 2019 1 / 14 Outline

Bardziej szczegółowo

BASH - LINIA POLECEŃ. Bioinformatyka 2018/2019

BASH - LINIA POLECEŃ. Bioinformatyka 2018/2019 BASH - LINIA POLECEŃ Bioinformatyka 2018/2019 PODSTAWOWE DEFINICJE Linux system operacyjny, które oferuje kompletne środowisko programistyczne Powłoka interfejs wiersza poleceń zapewniający komunikację

Bardziej szczegółowo

Opis protokołu RPC. Grzegorz Maj nr indeksu:

Opis protokołu RPC. Grzegorz Maj nr indeksu: Opis protokołu RPC Grzegorz Maj nr indeksu: 236095 1 Streszczenie Niniejszy dokument opisuje specyfikację protokołu RQP (Remote Queues Protocol). W jego skład wchodzą: opis celów protokołu; opis założeń

Bardziej szczegółowo

Aplikacja Sieciowa wątki po stronie klienta

Aplikacja Sieciowa wątki po stronie klienta Aplikacja Sieciowa wątki po stronie klienta Na ostatnich zajęciach zajmowaliśmy się komunikacją pomiędzy klientem a serwerem. Wynikiem naszej pracy był program klienta, który za pomocą serwera mógł się

Bardziej szczegółowo

Działanie systemu operacyjnego

Działanie systemu operacyjnego Działanie systemu operacyjnego Budowa systemu komputerowego I NIC Jednostka centralna Sterownik dysku Sterownik drukarki Sterownik sieci Szyna systemowa (magistrala danych) Sterownik pamięci operacyjnej

Bardziej szczegółowo

Pliki. Operacje na plikach w Pascalu

Pliki. Operacje na plikach w Pascalu Pliki. Operacje na plikach w Pascalu ścieżka zapisu, pliki elementowe, tekstowe, operacja plikowa, etapy, assign, zmienna plikowa, skojarzenie, tryby otwarcia, reset, rewrite, append, read, write, buforowanie

Bardziej szczegółowo

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie. Część XXII C++ w Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie. Ćwiczenie 1 1. Utwórz nowy projekt w Dev C++ i zapisz go na

Bardziej szczegółowo

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

Instrukcja do laboratorium Systemów Operacyjnych. (semestr drugi) Instrukcja do laboratorium Systemów Operacyjnych (semestr drugi) Ćwiczenie drugie (jedne zajęcia) Temat: Procesy i sygnały w Linuksie. Opracowanie: mgr in ż. Arkadiusz Chrobot Wprowadzenie 1. Budowa procesu

Bardziej szczegółowo

Przekierowanie wejścia wyjścia:

Przekierowanie wejścia wyjścia: Przekierowanie wejścia wyjścia: program ma trzy podstawowe strumienie wejścia-wyjścia - standardowe wejście - standardowe wyjście - standardowe wyjście diagnostyczne przekierowanie standardowego wyjścia

Bardziej szczegółowo

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

Systemy Operacyjne 1 Laboratorium 3 Potoki i łącza nazwane w Linuksie (jeden tydzień) dr inż. Arkadiusz Chrobot 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

Bardziej szczegółowo

1 Podstawy c++ w pigułce.

1 Podstawy c++ w pigułce. 1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,

Bardziej szczegółowo

Przetwarzanie tekstu 2. Operacje na plikach tekstowych w systemie Linux

Przetwarzanie tekstu 2. Operacje na plikach tekstowych w systemie Linux Przetwarzanie tekstu 2 Operacje na plikach tekstowych w systemie Linux filtry programy przetwarzajace pliki (w szczególności tekstowe) w taki sposób, że odczytuja dane (plik wejściowy) ze standardowego

Bardziej szczegółowo

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

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main. Część XVI C++ Funkcje Jeśli nasz program rozrósł się już do kilkudziesięciu linijek, warto pomyśleć o jego podziale na mniejsze części. Poznajmy więc funkcje. Szybko się przekonamy, że funkcja to bardzo

Bardziej szczegółowo

Podstawy i języki programowania

Podstawy i języki programowania Podstawy i języki programowania Laboratorium 8 - wprowadzenie do obsługi plików tekstowych i wyjątków mgr inż. Krzysztof Szwarc krzysztof@szwarc.net.pl Sosnowiec, 11 grudnia 2017 1 / 34 mgr inż. Krzysztof

Bardziej szczegółowo

Sieci komputerowe. Wykład 7: Transport: protokół TCP. Marcin Bieńkowski. Instytut Informatyki Uniwersytet Wrocławski

Sieci komputerowe. Wykład 7: Transport: protokół TCP. Marcin Bieńkowski. Instytut Informatyki Uniwersytet Wrocławski Sieci komputerowe Wykład 7: Transport: protokół TCP Marcin Bieńkowski Instytut Informatyki Uniwersytet Wrocławski Sieci komputerowe (II UWr) Wykład 7 1 / 23 W poprzednim odcinku Niezawodny transport Algorytmy

Bardziej szczegółowo

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

Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013 Laboratorium Podstaw Informatyki Strona 1 Laboratorium Podstaw Informatyki Kierunek Elektrotechnika Obsługa plików Kraków 2013 Laboratorium Podstaw Informatyki Strona 2 Obsługa plików Zanim będziemy mogli

Bardziej szczegółowo

Systemy operacyjne. Instrukcja laboratoryjna. Ćwiczenie 1: Polecenia systemu UNIX/LINUX. Opracował: dr inż. Piotr Szpryngier

Systemy operacyjne. Instrukcja laboratoryjna. Ćwiczenie 1: Polecenia systemu UNIX/LINUX. Opracował: dr inż. Piotr Szpryngier Systemy operacyjne Instrukcja laboratoryjna Ćwiczenie 1: Polecenia systemu UNIX/LINUX Opracował: dr inż. Piotr Szpryngier Olsztyn 2009 1 Wprowadzenie. Cel zajęć praktycznych. Wymagania stawiane studentom

Bardziej szczegółowo

Uruchamianie programów w systemie Linux, potoki, strumienie, procesy, alias

Uruchamianie programów w systemie Linux, potoki, strumienie, procesy, alias 7 październik 2008 Uruchomienie, monitorowanie procesu, potoki, aliasy S laj d 1 Uruchamianie programów w systemie Linux, potoki, strumienie, procesy, alias 7 październik 2008 Uruchomienie, monitorowanie

Bardziej szczegółowo

Linux: Procesy. Systemy Operacyjne. Mateusz Hołenko. 26 marca 2013

Linux: Procesy. Systemy Operacyjne. Mateusz Hołenko. 26 marca 2013 Linux: Procesy Systemy Operacyjne Mateusz Hołenko 26 marca 2013 Plan zajęć Co to jest sygnał? Polecenia systemowe Sygnały Zadania Mateusz Hołenko Linux: Procesy [2/18] Co to jest proces? Co to jest proces?

Bardziej szczegółowo

Systemy Operacyjne I: Procesy

Systemy Operacyjne I: Procesy Politechnika Poznańska 4 kwietnia 2013 Materiały Prezentacja oraz inne materiały zostały przygotowane na podstawie: Użytkowanie systemu operacyjnego UNIX - dr D.Wawrzyniak Systemy operacyjne - skrypt -

Bardziej szczegółowo

Instytut Teleinformatyki

Instytut Teleinformatyki Instytut Teleinformatyki Wydział Inżynierii Elektrycznej i Komputerowej Politechnika Krakowska programowanie usług sieciowych Dziedzina Unix laboratorium: 06 Kraków, 2014 06. Programowanie Usług Sieciowych

Bardziej szczegółowo

Zadanie 2: transakcyjny protokół SKJ (2015)

Zadanie 2: transakcyjny protokół SKJ (2015) Zadanie 2: transakcyjny protokół SKJ (2015) 1 Wstęp Zadanie polega na zaprojektowaniu niezawodnego protokołu transakcyjnego bazującego na protokole UDP. Protokół ten ma być realizowany przez klasy implementujące

Bardziej szczegółowo

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

1. Procesy i współbieżność 1. Procesy i współbieżność Opracował: Sławomir Samolej Politechnika Rzeszowska, Katedra Informatyki i Automatyki, Rzeszów, 2013. 1.1. Wprowadzenie Proces to przestrzeń adresowa i pojedynczy wątek sterujący,

Bardziej szczegółowo

Mechanizmy pracy równoległej. Jarosław Kuchta

Mechanizmy pracy równoległej. Jarosław Kuchta Mechanizmy pracy równoległej Jarosław Kuchta Zagadnienia Algorytmy wzajemnego wykluczania algorytm Dekkera Mechanizmy niskopoziomowe przerwania mechanizmy ochrony pamięci instrukcje specjalne Mechanizmy

Bardziej szczegółowo

Technologie Informacyjne - Linux 2

Technologie Informacyjne - Linux 2 Technologie Informacyjne - 2 Instytut Matematyki Uniwersytet Gdański Powłoka - polecenia pośredniczace Polecenie grep wypisuje z pliku lub strumienia wejściowego te wiersze, które sa zgodne z podanym wyrażeniem.

Bardziej szczegółowo

/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h>

/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h> Szablon programu: /* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include /* opcjonalne: deklaracja typów o rozmiarze jednego i dwóch

Bardziej szczegółowo

4. Procesy pojęcia podstawowe

4. Procesy pojęcia podstawowe 4. Procesy pojęcia podstawowe 4.1 Czym jest proces? Proces jest czymś innym niż program. Program jest zapisem algorytmu wraz ze strukturami danych na których algorytm ten operuje. Algorytm zapisany bywa

Bardziej szczegółowo

Systemy operacyjne. System operacyjny Linux - wstęp. Anna Wojak

Systemy operacyjne. System operacyjny Linux - wstęp. Anna Wojak Systemy operacyjne System operacyjny Linux - wstęp Anna Wojak 1 1 Wstęp Linux jest systemem z rodziny Unix. Pierwsza wersja systemu została opracowana w 1969 roku przez K.Thompsona i D.Ritchie Jest to

Bardziej szczegółowo

Uniwersytet w Białymstoku Wydział Ekonomiczno-Informatyczny w Wilnie SYLLABUS na rok akademicki 2009/2010

Uniwersytet w Białymstoku Wydział Ekonomiczno-Informatyczny w Wilnie SYLLABUS na rok akademicki 2009/2010 Tryb studiów Studia stacjonarne Kierunek studiów Informatyka Poziom studiów Pierwszego stopnia Rok studiów/semestr 2(rok)/(sem) Specjalność Bez specjalności Kod katedry/zakładu w systemie USOS 10000000

Bardziej szczegółowo

Działanie systemu operacyjnego

Działanie systemu operacyjnego Budowa systemu komputerowego Działanie systemu operacyjnego Jednostka centralna dysku Szyna systemowa (magistrala danych) drukarki pamięci operacyjnej I NIC sieci Pamięć operacyjna Przerwania Przerwania

Bardziej szczegółowo

ang. file) Pojęcie pliku (ang( Typy plików Atrybuty pliku Fragmentacja wewnętrzna w systemie plików Struktura pliku

ang. file) Pojęcie pliku (ang( Typy plików Atrybuty pliku Fragmentacja wewnętrzna w systemie plików Struktura pliku System plików 1. Pojęcie pliku 2. Typy i struktury plików 3. etody dostępu do plików 4. Katalogi 5. Budowa systemu plików Pojęcie pliku (ang( ang. file)! Plik jest abstrakcyjnym obrazem informacji gromadzonej

Bardziej szczegółowo

Algorytm. a programowanie -

Algorytm. a programowanie - Algorytm a programowanie - Program komputerowy: Program komputerowy można rozumieć jako: kod źródłowy - program komputerowy zapisany w pewnym języku programowania, zestaw poszczególnych instrukcji, plik

Bardziej szczegółowo

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

4. Pliki Informacje ogólne o dostępie do plików w PHP Sprawdzanie istnienia pliku file_exists() 4. Pliki 4.1. Informacje ogólne o dostępie do plików w PHP Jak praktycznie każdy język programowania, PHP zapewnia dostęp do systemu plików znajdujących się na komputerze, na którym uruchamiany jest skrypt,

Bardziej szczegółowo

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Tablice (jedno i wielowymiarowe), łańcuchy znaków Tablice (jedno i wielowymiarowe), łańcuchy znaków wer. 8 z drobnymi modyfikacjami! Wojciech Myszka Katedra Mechaniki i Inżynierii Materiałowej 2017-04-07 09:35:32 +0200 Zmienne Przypomnienie/podsumowanie

Bardziej szczegółowo

Trochę o plikach wsadowych (Windows)

Trochę o plikach wsadowych (Windows) Trochę o plikach wsadowych (Windows) Zmienne środowiskowe Zmienną środowiskową można ustawić na stałe w systemie (Panel sterowania->system- >Zaawansowane ustawienia systemu->zmienne środowiskowe) lub też

Bardziej szczegółowo

Przydziały (limity) pojemności dyskowej

Przydziały (limity) pojemności dyskowej Przydziały (limity) pojemności dyskowej W dużych sieciach lokalnych bądź w przypadku, gdy z danego komputera korzysta kilku różnych użytkowników, administrator może zechcieć mieć kontrolę nad przydziałem

Bardziej szczegółowo

System operacyjny UNIX system plików. mgr Michał Popławski, WFAiIS

System operacyjny UNIX system plików. mgr Michał Popławski, WFAiIS System operacyjny UNIX system plików System plików systemu UNIX (s5fs) System plików ma strukturę drzewa. Na samym szczycie znajduje się korzeń (root), symbolicznie przedstawiany jako /. Z punktu widzenia

Bardziej szczegółowo

Narzędzia informatyczne w językoznawstwie

Narzędzia informatyczne w językoznawstwie Narzędzia informatyczne w językoznawstwie Wiersz poleceń - Potoki i pliki wsadowe Marcin Junczys-Dowmunt junczys@amu.edu.pl Zakład Logiki Stosowanej http://www.logic.amu.edu.pl 22. października 2008 Marcin

Bardziej szczegółowo

Łącza nienazwane(potoki)

Łącza nienazwane(potoki) 8. Łącza nienazwane(potoki) Łącze (potok, ang. pipe) jest to urządzenie komunikacyjne pozwalające na przesyłanie informacji w jedną stronę. Jeden proces wysyła dane do łącza za pomocą funkcji write, zaś

Bardziej szczegółowo

Programowanie w języku C++ z użyciem Windows API

Programowanie w języku C++ z użyciem Windows API Programowanie w języku C++ z użyciem Windows API Autor: Mateusz Ferenc Data opracowania: 30 maja 2012 r. Windows API jest jedną z bibliotek programistycznych przeznaczonych do pisania programów na platformę

Bardziej szczegółowo

1 Podstawy c++ w pigułce.

1 Podstawy c++ w pigułce. 1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,

Bardziej szczegółowo

System operacyjny UNIX Ćwiczenie 1. Podstawowe polecenia systemu Unix

System operacyjny UNIX Ćwiczenie 1. Podstawowe polecenia systemu Unix Wydział Mechatroniki i Budowy Maszyn Specjalność: Automatyka i Robotyka Rok II Semestr IV 1. Logowanie w systemie Unix. System operacyjny UNIX Ćwiczenie 1. Podstawowe polecenia systemu Unix Do zalogowania

Bardziej szczegółowo

4. Procesy pojęcia podstawowe

4. Procesy pojęcia podstawowe 4. Procesy pojęcia podstawowe 4.1 Czym jest proces? Proces jest czymś innym niż program. Program jest zapisem algorytmu wraz ze strukturami danych na których algorytm ten operuje. Algorytm zapisany bywa

Bardziej szczegółowo

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

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

Bardziej szczegółowo

BASH - WPROWADZENIE Bioinformatyka 4

BASH - WPROWADZENIE Bioinformatyka 4 BASH - WPROWADZENIE Bioinformatyka 4 DLACZEGO BASH? Praca na klastrach obliczeniowych Brak GUI Środowisko programistyczne Szybkie przetwarzanie danych Pisanie własnych skryptów W praktyce przetwarzanie

Bardziej szczegółowo

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4 Dr inż. Dariusz JĘDRZEJCZYK Wskaźniki Dynamiczna alokacja pamięci Przykłady 11/3/2016 AGH, Katedra Informatyki Stosowanej i Modelowania 2 Wskaźnik to

Bardziej szczegółowo

Skrypty powłoki Skrypty Najcz ciej u ywane polecenia w skryptach:

Skrypty powłoki Skrypty Najcz ciej u ywane polecenia w skryptach: Skrypty powłoki Skrypty są zwykłymi plikami tekstowymi, w których są zapisane polecenia zrozumiałe dla powłoki. Zadaniem powłoki jest przetłumaczenie ich na polecenia systemu. Aby przygotować skrypt, należy:

Bardziej szczegółowo

Wstęp do informatyki. stęp do informatyki Polecenia (cz.2)

Wstęp do informatyki. stęp do informatyki Polecenia (cz.2) Wstęp do informatyki stęp do informatyki Polecenia (cz.2) Lista procesów top Pokaż listę procesów polecenie interaktywne Procesy Uruchamianie w tle. shell nie czeka na zakończenie procesu, można wydawać

Bardziej szczegółowo

Lab 9 Podstawy Programowania

Lab 9 Podstawy Programowania Lab 9 Podstawy Programowania (Kaja.Gutowska@cs.put.poznan.pl) Wszystkie kody/fragmenty kodów dostępne w osobnym pliku.txt. Materiały pomocnicze: Wskaźnik to specjalny rodzaj zmiennej, w której zapisany

Bardziej szczegółowo

Struktury. Przykład W8_1

Struktury. Przykład W8_1 Struktury Struktury pozwalają na grupowanie zmiennych różnych typów pod wspólną nazwą. To istotnie ułatwia organizacje danych, które okazują się w jednym miejscu kodu programu. To jest bardzo ważne dla

Bardziej szczegółowo

Sieci i systemy operacyjne I Ćwiczenie 1. Podstawowe polecenia systemu Unix

Sieci i systemy operacyjne I Ćwiczenie 1. Podstawowe polecenia systemu Unix Wydział Zarządzania i Modelowania Komputerowego Specjalność: Informatyka Stosowana Rok III Semestr V 1. Logowanie w systemie Unix. Sieci i systemy operacyjne I Ćwiczenie 1. Podstawowe polecenia systemu

Bardziej szczegółowo

Temat zajęć: Filtry, strumienie standardowe oraz przetwarzanie potokowe. stderr

Temat zajęć: Filtry, strumienie standardowe oraz przetwarzanie potokowe. stderr Temat zajęć: Filtry, strumienie standardowe oraz przetwarzanie potokowe Czas realizacji zajęć: 180 min. Zakres materiału, jaki zostanie zrealizowany podczas zajęć: Strumienie standardowe i ich przekierowywanie,

Bardziej szczegółowo

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

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 Plik to uporządkowany ciąg danych Dostęp do danych w pliku jest sekwencyjny, tj. istnieje pojęcie elementu aktualnego (tzw. wskaźnika pliku). Możliwy dostęp do danych w pliku jest tylko tam, gdzie wskazuje

Bardziej szczegółowo

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

Pliki. Informacje ogólne. Obsługa plików w języku C Pliki Informacje ogólne Plik jest pewnym zbiorem danych, zapisanym w systemie plików na nośniku danych. Może posiadać określone atrybuty, a odwołanie do niego odbywa się poprzez nazwę. Każdy plik ma skończoną

Bardziej szczegółowo

1. Znajdź za pomocą programu locate wszystkie pliki które zawierają w nazwie słowo netscape locate netscape

1. Znajdź za pomocą programu locate wszystkie pliki które zawierają w nazwie słowo netscape locate netscape FIND http://www.cs.put.poznan.pl/akobusinska/downloads/find.pdf 1. Znajdź za pomocą programu locate wszystkie pliki które zawierają w nazwie słowo netscape locate netscape 2. Ogranicz wynik polecenia 1

Bardziej szczegółowo

2 Przygotował: mgr inż. Maciej Lasota

2 Przygotował: mgr inż. Maciej Lasota Laboratorium nr 2 1/7 Język C Instrukcja laboratoryjna Temat: Wprowadzenie do języka C 2 Przygotował: mgr inż. Maciej Lasota 1) Wprowadzenie do języka C. Język C jest językiem programowania ogólnego zastosowania

Bardziej szczegółowo

Języki C i C++ Wykład: 2. Wstęp Instrukcje sterujące. dr Artur Bartoszewski - Języki C i C++, sem. 1I- WYKŁAD

Języki C i C++ Wykład: 2. Wstęp Instrukcje sterujące. dr Artur Bartoszewski - Języki C i C++, sem. 1I- WYKŁAD Języki C i C++ Wykład: 2 Wstęp Instrukcje sterujące 1 dr Artur Bartoszewski - Języki C i C++, sem. 1I- WYKŁAD programowania w C++ Instrukcje sterujące 2 Pętla for for ( instrukcja_ini ; wyrazenie_warunkowe

Bardziej szczegółowo