O'Reilly logo

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Linux. Programowanie systemowe

Book Description

Opisany zosta? tu sposób dzia?ania standardowych i zaawansowanych interfejsów zdefiniowanych w Linuksie. Po lekturze napiszesz inteligentniejszy i szybszy kod, który dzia?a we w...

Table of Contents

  1. Linux. Programowanie systemowe
  2. Przedmowa
  3. Wstęp
    1. Przyjęte założenia, dotyczące odbiorców książki
    2. Zawartość książki
    3. Wersje uwzględnione w tej książce
    4. Użyte konwencje
    5. Używanie przykładowych kodów
    6. Podziękowania
  4. 1. Wprowadzenie — podstawowe pojęcia
    1. Programowanie systemowe
      1. Funkcje systemowe
        1. Wywoływanie funkcji systemowych
      2. Biblioteka języka C
      3. Kompilator języka C
    2. API i ABI
      1. API
      2. ABI
    3. Standardy
      1. Historia POSIX oraz SUS
      2. Standardy języka C
      3. Linux i standardy
      4. Książka i standardy
    4. Pojęcia dotyczące programowania w Linuksie
      1. Pliki i system plików
        1. Pliki zwykłe
        2. Katalogi i dowiązania
        3. Dowiązania twarde
        4. Dowiązania symboliczne
        5. Pliki specjalne
        6. Systemy plików i przestrzenie nazw
      2. Procesy
        1. Wątki
        2. Hierarchia procesów
      3. Użytkownicy i grupy
      4. Uprawnienia
      5. Sygnały
      6. Komunikacja międzyprocesowa
      7. Pliki nagłówkowe
      8. Obsługa błędów
    5. Początek programowania systemowego
  5. 2. Plikowe operacje wejścia i wyjścia
    1. Otwieranie plików
      1. Funkcja systemowa open()
        1. Znaczniki w funkcji open()
      2. Właściciele nowych plików
      3. Uprawnienia nowych plików
      4. Funkcja creat()
      5. Wartości zwracane i kody błędów
    2. Czytanie z pliku przy użyciu funkcji read()
      1. Wartości zwracane
      2. Czytanie wszystkich bajtów
      3. Odczyty nieblokujące
      4. Inne wartości błędów
      5. Ograniczenia rozmiaru dla funkcji read()
    3. Pisanie za pomocą funkcji write()
      1. Zapisy częściowe
      2. Tryb dopisywania
      3. Zapisy nieblokujące
      4. Inne kody błędów
      5. Ograniczenia rozmiaru dla funkcji write()
      6. Sposób działania funkcji write()
    4. Zsynchronizowane operacje wejścia i wyjścia
      1. Funkcje fsync() i fdatasync()
        1. Wartości zwracane i kody błędów
      2. Funkcja sync()
      3. Znacznik O_SYNC
      4. Znaczniki O_DSYNC i O_RSYNC
    5. Bezpośrednie operacje wejścia i wyjścia
    6. Zamykanie plików
      1. Kody błędów
    7. Szukanie za pomocą funkcji lseek()
      1. Szukanie poza końcem pliku
      2. Kody błędów
      3. Ograniczenia
    8. Odczyty i zapisy pozycyjne
      1. Kody błędów
    9. Obcinanie plików
    10. Zwielokrotnione operacje wejścia i wyjścia
      1. Funkcja select()
        1. Wartości powrotu oraz kody błędów
        2. Przykład użycia funkcji select()
        3. Przenośny sposób wstrzymania wykonania aplikacji za pomocą funkcji select()
        4. Funkcja pselect()
      2. Funkcja poll()
        1. Wartości powrotu oraz kody błędów
        2. Przykład użycia funkcji poll()
        3. Funkcja ppoll()
      3. Porównanie funkcji poll() i select()
    11. Organizacja wewnętrzna jądra
      1. Wirtualny system plików
      2. Bufor stron
      3. Opóźniony zapis stron
    12. Zakończenie
  6. 3. Buforowane operacje wejścia i wyjścia
    1. Operacje wejścia i wyjścia, buforowane w przestrzeni użytkownika
      1. Rozmiar bloku
    2. Typowe operacje wejścia i wyjścia
      1. Wskaźniki do plików
    3. Otwieranie plików
      1. Tryby
    4. Otwieranie strumienia poprzez deskryptor pliku
    5. Zamykanie strumieni
      1. Zamykanie wszystkich strumieni
    6. Czytanie ze strumienia
      1. Czytanie pojedynczego znaku
        1. Wycofywanie znaku
      2. Czytanie całego wiersza
        1. Czytanie dowolnych łańcuchów
      3. Czytanie danych binarnych
    7. Pisanie do strumienia
      1. Zapisywanie pojedynczego znaku
      2. Zapisywanie łańcucha znaków
      3. Zapisywanie danych binarnych
    8. Przykładowy program używający buforowanych operacji wejścia i wyjścia
    9. Szukanie w strumieniu
      1. Otrzymywanie informacji o aktualnym położeniu w strumieniu
    10. Opróżnianie strumienia
    11. Błędy i koniec pliku
    12. Otrzymywanie skojarzonego deskryptora pliku
    13. Parametry buforowania
    14. Bezpieczeństwo wątków
      1. Nieautomatyczne blokowanie plików
      2. Nieblokowane operacje na strumieniu
    15. Krytyczna analiza biblioteki typowych operacji wejścia i wyjścia
    16. Zakończenie
  7. 4. Zaawansowane operacje plikowe wejścia i wyjścia
    1. Rozproszone operacje wejścia i wyjścia
      1. Funkcje readv() i writev()
        1. Wartości powrotne
        2. Przykład użycia funkcji writev()
        3. Przykład użycia funkcji readv()
        4. Implementacja
    2. Interfejs odpytywania zdarzeń
      1. Tworzenie nowego egzemplarza interfejsu odpytywania zdarzeń
      2. Sterowanie działaniem interfejsu odpytywania zdarzeń
      3. Oczekiwanie na zdarzenie w interfejsie odpytywania zdarzeń
      4. Zdarzenia przełączane zboczem, a zdarzenia przełączane poziomem
    3. Odwzorowywanie plików w pamięci
      1. Funkcja mmap()
        1. Rozmiar strony
        2. Wartości powrotne i kody błędów
        3. Dodatkowe sygnały
      2. Funkcja munmap()
      3. Przykład odwzorowania w pamięci
      4. Zalety używania funkcji mmap()
      5. Wady używania funkcji mmap()
      6. Zmiana rozmiaru odwzorowania
        1. Wartości powrotne i kody błędów
      7. Zmiana uprawnień odwzorowania
        1. Wartości powrotne i kody błędów
      8. Synchronizacja odwzorowanego pliku
        1. Wartości powrotne i kody błędów
      9. Dostarczanie porad dotyczących odwzorowania w pamięci
        1. Wartości powrotne i kody błędów
    4. Porady dla standardowych operacji plikowych wejścia i wyjścia
      1. Funkcja systemowa posix_fadvise()
        1. Wartości powrotne i kody błędów
      2. Funkcja systemowa readahead()
        1. Wartości powrotne i kody błędów
      3. Porada jest tania
    5. Operacje zsynchronizowane, synchroniczne i asynchroniczne
      1. Asynchroniczne operacje wejścia i wyjścia
        1. Asynchroniczne operacje wejścia i wyjścia oparte na wątkach
    6. Zarządcy operacji wejścia i wyjścia oraz wydajność operacji wejścia i wyjścia
      1. Adresowanie dysku
      2. Działanie zarządcy operacji wejścia i wyjścia
      3. Wspomaganie odczytów
        1. Zarządca z terminem nieprzekraczalnym
        2. Zarządca przewidujący
        3. Zarządca ze sprawiedliwym szeregowaniem
        4. Zarządca niesortujący
      4. Wybór i konfiguracja zarządcy operacji wejścia i wyjścia
      5. Optymalizowanie wydajności operacji wejścia i wyjścia
        1. Szeregowanie operacji wejścia i wyjścia w przestrzeni użytkownika
    7. Zakończenie
  8. 5. Zarządzanie procesami
    1. Identyfikator procesu
      1. Przydział identyfikatorów procesów
      2. Hierarchia procesów
      3. Typ pid_t
      4. Otrzymywanie identyfikatora procesu oraz identyfikatora procesu rodzicielskiego
    2. Uruchamianie nowego procesu
      1. Rodzina funkcji exec
        1. Pozostałe elementy grupy funkcji exec
        2. Kody błędów
      2. Funkcja systemowa fork()
        1. Kopiowanie podczas zapisu
        2. Funkcja vfork()
    3. Zakończenie procesu
      1. Inne sposoby na zakończenie procesu
      2. Funkcja atexit()
      3. Funkcja on_exit()
      4. Sygnał SIGCHLD
    4. Oczekiwanie na zakończone procesy potomka
      1. Oczekiwanie na określony proces
      2. Jeszcze wszechstronniejsza funkcja oczekiwania
      3. BSD wkracza do akcji: funkcje wait3() i wait4()
      4. Uruchamianie i oczekiwanie na nowy proces
      5. Procesy zombie
    5. Użytkownicy i grupy
      1. Rzeczywiste, efektywne oraz zapisane identyfikatory użytkownika i grupy
      2. Zmiana rzeczywistego lub zapisanego identyfikatora dla użytkownika lub grupy
      3. Zmiana efektywnego identyfikatora dla użytkownika lub grupy
      4. Zmiana identyfikatora dla użytkownika lub grupy w wersji BSD
      5. Zmiana identyfikatora dla użytkownika lub grupy w wersji HP-UX
      6. Zalecane modyfikacje identyfikatorów użytkownika i grupy
      7. Wsparcie dla zapisanych identyfikatorów użytkownika
      8. Otrzymywanie identyfikatorów użytkownika i grupy
    6. Grupy sesji i procesów
      1. Funkcje systemowe do obsługi sesji
      2. Funkcje systemowe do obsługi grup procesów
      3. Przestarzałe funkcje do obsługi grupy procesów
    7. Demony
    8. Zakończenie
  9. 6. Zaawansowane zarządzanie procesami
    1. Szeregowanie procesów
      1. Notacja O
      2. Przedziały czasowe
      3. Procesy związane z wejściem i wyjściem a procesy związane z procesorem
      4. Szeregowanie z wywłaszczaniem
      5. Wątki
    2. Udostępnianie czasu procesora
      1. Prawidłowe sposoby użycia sched_yield()
      2. Udostępnianie czasu procesora — kiedyś i teraz
    3. Priorytety procesu
      1. nice()
      2. getpriority() i setpriority()
      3. Priorytety wejścia i wyjścia
    4. Wiązanie procesów do konkretnego procesora
      1. sched_getaffinity() i sched_setaffinity()
    5. Systemy czasu rzeczywistego
      1. Systemy ścisłego oraz zwykłego czasu rzeczywistego
      2. Opóźnienie, rozsynchronizowanie oraz parametry graniczne
      3. Wspieranie czasu rzeczywistego przez system Linux
      4. Linuksowe strategie szeregowania i ustalania priorytetów
        1. Strategia FIFO (first in, first out)
        2. Strategia cykliczna
        3. Strategia zwykła
        4. Strategia szeregowania wsadowego
        5. Ustalanie strategii szeregowania dla systemu Linux
      5. Ustawianie parametrów szeregowania
        1. Określanie zakresu poprawnych priorytetów
      6. sched_rr_get_interval()
      7. Środki ostrożności przy pracy z procesami czasu rzeczywistego
      8. Determinizm
        1. Wcześniejsze zapisywanie danych oraz blokowanie pamięci
        2. Wiązanie do procesora a procesy czasu rzeczywistego
    6. Ograniczenia zasobów systemowych
      1. Ograniczenia
        1. Ograniczenia domyślne
      2. Ustawianie i odczytywanie ograniczeń
        1. Kody błędów
  10. 7. Zarządzanie plikami i katalogami
    1. Pliki i ich metadane
      1. Rodzina funkcji stat
      2. Uprawnienia
      3. Prawa własności
      4. Atrybuty rozszerzone
        1. Klucze i wartości
        2. Przestrzenie nazw dla atrybutów rozszerzonych
        3. Operacje dla atrybutów rozszerzonych
    2. Katalogi
      1. Aktualny katalog roboczy
        1. Odczytywanie aktualnego katalogu roboczego
        2. Zmiana aktualnego katalogu roboczego
      2. Tworzenie katalogów
      3. Usuwanie katalogów
      4. Odczytywanie zawartości katalogu
        1. Czytanie ze strumienia katalogu
        2. Zamykanie strumienia katalogu
        3. Funkcje systemowe służące do odczytywania zawartości katalogu
    3. Dowiązania
      1. Dowiązania twarde
      2. Dowiązania symboliczne
      3. Usuwanie elementów z systemu plików
    4. Kopiowanie i przenoszenie plików
      1. Kopiowanie
      2. Przenoszenie
    5. Węzły urządzeń
      1. Specjalne węzły urządzeń
      2. Generator liczb losowych
    6. Komunikacja poza kolejką
    7. Śledzenie zdarzeń związanych z plikami
      1. Inicjalizacja interfejsu inotify
      2. Elementy obserwowane
        1. Dodawanie nowego elementu obserwowanego
        2. Maska elementu obserwowanego
      3. Zdarzenia interfejsu inotify
        1. Odczytywanie zdarzeń inotify
        2. Łączenie zdarzeń przenoszenia
      4. Zaawansowane opcje obserwowania
      5. Usuwanie elementu obserwowanego z interfejsu inotify
      6. Otrzymywanie rozmiaru kolejki zdarzeń
      7. Usuwanie egzemplarza interfejsu inotify
  11. 8. Zarządzanie pamięcią
    1. Przestrzeń adresowa procesu
      1. Strony i stronicowanie
        1. Współdzielenie i kopiowanie podczas zapisu
      2. Regiony pamięci
    2. Przydzielanie pamięci dynamicznej
      1. Przydzielanie pamięci dla tablic
      2. Zmiana wielkości obszaru przydzielonej pamięci
      3. Zwalnianie pamięci dynamicznej
      4. Wyrównanie
        1. Przydzielanie pamięci wyrównanej
        2. Inne zagadnienia związane z wyrównaniem
    3. Zarządzanie segmentem danych
    4. Anonimowe odwzorowania w pamięci
      1. Tworzenie anonimowych odwzorowań w pamięci
      2. Odwzorowanie pliku /dev/zero
    5. Zaawansowane operacje przydziału pamięci
      1. Dokładne dostrajanie przy użyciu funkcji malloc_usable_size() oraz malloc_trim()
    6. Uruchamianie programów, używających systemu przydzielania pamięci
      1. Otrzymywanie danych statystycznych
    7. Przydziały pamięci wykorzystujące stos
      1. Powielanie łańcuchów znakowych na stosie
      2. Tablice o zmiennej długości
    8. Wybór mechanizmu przydzielania pamięci
    9. Operacje na pamięci
      1. Ustawianie wartości bajtów
      2. Porównywanie bajtów
      3. Przenoszenie bajtów
      4. Wyszukiwanie bajtów
      5. Manipulowanie bajtami
    10. Blokowanie pamięci
      1. Blokowanie fragmentu przestrzeni adresowej
      2. Blokowanie całej przestrzeni adresowej
      3. Odblokowywanie pamięci
      4. Ograniczenia blokowania
      5. Czy strona znajduje się w pamięci fizycznej?
    11. Przydział oportunistyczny
      1. Przekroczenie zakresu zatwierdzenia oraz stan braku pamięci (OOM)
  12. 9. Sygnały
    1. Koncepcja sygnałów
      1. Identyfikatory sygnałów
      2. Sygnały wspierane przez system Linux
    2. Podstawowe zarządzanie sygnałami
      1. Oczekiwanie na dowolny sygnał
      2. Przykłady
      3. Uruchomienie i dziedziczenie
      4. Odwzorowanie numerów sygnałów na łańcuchy znakowe
    3. Wysyłanie sygnału
      1. Uprawnienia
      2. Przykłady
      3. Wysyłanie sygnału do samego siebie
      4. Wysyłanie sygnału do całej grupy procesów
    4. Współużywalność
      1. Funkcje, dla których współużywalność jest zagwarantowana
    5. Zbiory sygnałów
      1. Inne funkcje obsługujące zbiory sygnałów
    6. Blokowanie sygnałów
      1. Odzyskiwanie oczekujących sygnałów
      2. Oczekiwanie na zbiór sygnałów
    7. Zaawansowane zarządzanie sygnałami
      1. Struktura siginfo_t
      2. Wspaniały świat pola si_code
    8. Wysyłanie sygnału z wykorzystaniem pola użytkowego
      1. Przykład
    9. Zakończenie
  13. 10. Czas
    1. Struktury danych reprezentujące czas
      1. Reprezentacja pierwotna
      2. Następna wersja — dokładność na poziomie mikrosekund
      3. Kolejna, lepsza wersja — dokładność na poziomie nanosekund
      4. Wyłuskiwanie składników czasu
      5. Typ danych dla czasu procesu
    2. Zegary POSIX
      1. Rozdzielczość źródła czasu
    3. Pobieranie aktualnego czasu
      1. Lepszy interfejs
      2. Interfejs zaawansowany
      3. Pobieranie czasu procesu
    4. Ustawianie aktualnego czasu
      1. Precyzyjne ustawianie czasu
      2. Zaawansowany interfejs ustawiania czasu
    5. Konwersje czasu
    6. Dostrajanie zegara systemowego
    7. Stan uśpienia i oczekiwania
      1. Obsługa stanu uśpienia z dokładnością do mikrosekund
      2. Obsługa stanu uśpienia z dokładnością do nanosekund
      3. Zaawansowane zarządzanie stanem uśpienia
      4. Przenośny sposób wprowadzania w stan uśpienia
      5. Przepełnienia
      6. Alternatywy stanu uśpienia
    8. Liczniki
      1. Proste alarmy
      2. Liczniki interwałowe
      3. Liczniki zaawansowane
        1. Tworzenie licznika
        2. Inicjalizowanie licznika
        3. Odczytywanie czasu wygaśnięcia licznika
        4. Odczytywanie wartości przepełnienia licznika
        5. Usuwanie licznika
  14. A. Rozszerzenia kompilatora GCC dla języka C
    1. GNU C
    2. Funkcje wplatane (inline)
    3. Zapobieganie wplataniu funkcji
    4. Funkcje czyste (pure)
    5. Funkcje stałe
    6. Funkcje, które nie wracają do procedury wywołującej
    7. Funkcje przydzielające pamięć
    8. Wymuszanie sprawdzania wartości powrotnej dla procedur wywołujących
    9. Oznaczanie funkcji niezalecanych
    10. Oznaczanie funkcji używanych
    11. Oznaczanie funkcji lub parametrów nieużywanych
    12. Pakowanie struktury
    13. Zwiększanie wartości wyrównania dla zmiennej
    14. Umieszczanie zmiennych globalnych w rejestrach
    15. Optymalizacja gałęzi kodu
    16. Uzyskiwanie typu dla wyrażenia
    17. Uzyskiwanie wielkości wyrównania dla danego typu
    18. Pozycja elementu w strukturze
    19. Uzyskiwanie powrotnego adresu funkcji
    20. Zakresy funkcji case
    21. Arytmetyka wskaźników do funkcji oraz wskaźników void
    22. Więcej przenośności i elegancji za jednym razem
  15. B. Bibliografia
    1. Programowanie w języku C
    2. Programowanie w Linuksie
    3. Jądro Linuksa
    4. Projektowanie systemu operacyjnego
  16. C. O autorze
  17. Indeks
  18. Kolofon
  19. Copyright