Edytujesz „Wywołania systemowe Uniksa”

Z Nonsensopedii, polskiej encyklopedii humoru

Uwaga: Nie jesteś zalogowany. Jeśli wykonasz jakąkolwiek zmianę, Twój adres IP będzie widoczny publicznie. Jeśli zalogujesz się lub utworzysz konto, Twoje zmiany zostaną przypisane do konta, wraz z innymi korzyściami.

Ta edycja może zostać anulowana. Porównaj ukazane poniżej różnice między wersjami, a następnie zapisz zmiany.

Aktualna wersja Twój tekst
Linia 1: Linia 1:
Zanim przejdziemy do części właściwej [[artykuł]]u, warto się zastanowić po co w ogóle został napisany. Kogo właściwie obchodzi coś nazwane tak cudacznie jak ''wywołania systemowe Uniksa''? W normalnych warunkach powinno to być kilku [[Informatyk|piwniczaków]], którzy piszą niskopoziomowe programy na [[Linux]]ie. Jednak z jakiegoś powodu wykładowcy kierunków informatycznych katują [[student]]ów bezużytecznymi syscallami, rozszerzając grupę wtajemniczonych piwniczaków kilkukrotnie.
{{Cytat|Linux jest darmowy, o ile twój czas jest bezwartościowy.|Jamie Zawinski}}

[[Plik:Linux kernel System Call Interface and glibc.svg|thumb|250px|Kompatybilne jednocześnie z POSIX i Linux? W jakim świecie ty żyjesz, że w to wierzysz?]]
Nie zniechęciło cię to jeszcze?
'''Wywołania systemowe Uniksa''' – zbiorowisko luźno powiązanych ze sobą funkcji ukrytych gdzieś w trzewiach biblioteki libc. Wywołana funkcja ''może'' się wykonać i (jeśli ma na to ochotę) zwrócić nic nie mówiące errno. Standardowe wywołania opisuje dokumentacja [[POSIX]], którą można streścić następująco:

{{Cytat2|''Zachowanie jest niezdefiniowane.''}}
'''Wywołania systemowe Uniksa''' – zbiorowisko luźno powiązanych ze sobą funkcji ukrytych gdzieś w trzewiach biblioteki libc. Wywołana funkcja ''może'' się wykonać i (jeśli ma na to ochotę) zwrócić nic nie mówiące errno. Standardowe wywołania opisuje dokumentacja POSIX, którą można streścić następująco:
{{Cytat2|Zachowanie jest niezdefiniowane.}}
Początkującym programistom zalecamy wyrycie sobie tej złotej sentencji na ścianie nad [[monitor]]em i spoglądanie na nią w razie jakichkolwiek wątpliwości.
Początkującym programistom zalecamy wyrycie sobie tej złotej sentencji na ścianie nad [[monitor]]em i spoglądanie na nią w razie jakichkolwiek wątpliwości.

Zanim przejdziemy do części właściwej [[artykuł]]u, warto zastanowić się kogo właściwie obchodzi coś nazwane tak cudacznie jak ''wywołania systemowe Uniksa''? W normalnych warunkach powinno to być kilku [[Informatyk|piwniczaków]], którzy piszą niskopoziomowe programy na [[Linux]]ie. Jednak z jakiegoś niejasnego powodu wykładowcy kierunków informatycznych katują [[student]]ów bezużytecznymi syscallami, rozszerzając grupę wtajemniczonych piwniczaków kilkukrotnie.


== Zarządzanie procesami ==
== Zarządzanie procesami ==
=== <code>fork</code>, czyli robienie dzieci widelcem ===
W celu skuteczniejszego siania chaosu i pszenicy wśród procesora, [[RAM]]u i peryferiów, system jednocześnie uruchamia wiele procesów, które nieustannie konkurują o dostęp do zasobów. Rezultatem jest nieokiełznany bajzel, do kontrolowania którego zostaje zmuszony [[Bóg|Bogu]] ducha winny programista, a za jego błędy cierpi użytkownik. Sam sprawca całego pierdolnika – <del>[[Szatan]]</del> system operacyjny jest święty i ma zawsze rację.
* '''<code>fork</code>''' – zaczynamy z grubej rury, czyli od funkcji, która potrafi stworzyć coś z niczego, zwrócić dwie różne wartości i na dodatek debilnie się nazywać. Jak sama nazwa wskazuje, <code>fork</code> dziabie kernel [[Widelec|widelcem]] gdzieś pomiędzy planistą, a zarządzaniem pamięcią. Wkurzony nie na żarty kernel dla świętego spokoju robi procesowi [[dziecko]] i na odchodne wsadza mu widelec w [[Dupa|wiadome miejsce]].
Zaczynamy z grubej rury, czyli od funkcji, która potrafi stworzyć coś z niczego, zwrócić dwie różne wartości i na dodatek debilnie się nazywać. Jak sama nazwa wskazuje, <code>fork</code> dziabie kernel [[Widelec|widelcem]] gdzieś pomiędzy planistą, a zarządzaniem pamięcią. Wkurzony nie na żarty kernel dla świętego spokoju robi procesowi [[dziecko]] i na odchodne wsadza mu widelec w [[Dupa|wiadome miejsce]].

* '''<code>exec</code>''' – funkcja zazwyczaj wykonywana po <code>fork</code> żeby nieco złagodzić ból po bo bolesnej interakcji z jądrem. Pozwala procesowi przeszczepić sobie wszystkie organy innego programu, zostawiając jedynie PID i parę ''niezdefiniowanych'' interakcji. Jak łatwo się domyślić, funkcja <code>exec</code> wcale nie istnieje, a programista powinien skorzystać z <code>execl</code>, <code>execle</code>, <code>execlp</code>, <code>execv</code>, <code>execve</code> lub <code>execvp</code>. Zrozumienie co robią poszczególne wersje zostawiam jako ćwiczenie dla studentów.

* '''<code>exit</code>''' – kiedy proces ma już dość życia na ziemskim padole łez, decyduje się na krok ostateczny i wykonuje funkcję <code>exit</code>. Za argument można podać 0 (czyli jest dobrze), albo jeden z pierdyliarda kodów błędu, które są kompletnie niezdefiniowane i nie mają żadnego znaczenia. W momencie popełnienia seppuku proces wysyła jeszcze rodzicowi liścik pożegnalny w postaci <code>SIGCHLD</code>. Jest to jeden z nielicznych sygnałów, który nie zabije trafionego procesu, ale za to musi zostać obsłużony ''[[bo tak]]''.

* '''<code>wait</code>''' – jak sama nazwa wskazuje, <code>wait</code> służy do czekania na dzieci aż się zabiją, za wyjątkiem sytuacji, gdy na nie nie czekamy. Przy okazji możemy otrzymać kod, jaki dziecko przekazało do <code>exit</code>, co oczywiście nic nam nie mówi, bo może znaczyć cokolwiek. Jeśli nie zaczekamy na martwe dziecko to zamieni się ono w [[zombie]]. Dodatkowo, jeśli rodzic umrze niewywaitowawszy dzieci, to zombie staną się sierotami i… No generalnie syf się robi, lepiej waitować.

== Sygnały ==
[[Plik:Operation Upshot-Knothole - Badger 001.jpg|thumb|250px|<code>kill(-1, SIGKILL);</code>]]
* '''<code>kill</code>''' – jak mawia stare polskie przysłowie: ''nie machaj tym drągiem baranie na oślep bo jeszcze komuś przyp{{cenzura3}}isz''. Zasada ta nie dotyczy sygnałów w [[Unix|Uniksie]], bo strzelanie sygnałami przypomina nieco operowanie [[Drewniana armata|drewnianą armatą]] po pijaku. Tutaj nie da się ''nie'' machać na oślep, bo nigdy nie wiadomo w co trafisz i jak zareaguje na to dany proces. Równie dobrze armata może ci wybuchnąć w twarz i przedwcześnie zakończyć zabawę.

* '''<code>sigaction</code>''' – coby nieco okiełznać pierdolnik wywoływany przez różnorakie sygnały, można kazać procesowi reagować w określony sposób na niektóre z nich. Sposób bardzo biedny, bo przerywający działanie głównego wątku interruptem i przerzucający kontrolę w pizdu do handlera.

* '''<code>sigsuspend</code>''' – funkcja zawieszająca program aż do otrzymania jednego z sygnałów z podanej maski. Wtedy wykonuje domyślną dyspozycję (zazwyczaj wywalenie procesu) albo odpala handler ustawiony przy pomocy <code>sigaction</code>. Podobno jest lepsze od zwykłego <code>sleep</code>.

* '''<code>sigwait</code>''' – ucywilizowana wersja powyższego. Zamiast cudować z handlerami po prostu zwraca numerek otrzymanego sygnału. Brawo. Nie można tak było od razu?

== Obsługa plików ==
* '''<code>open</code>''' – otwiera plik/socket/[[Dysk twardy|urządzenie blokowe]]/[[Pralka|pralkę]]/[[piwo]]/cokolwiek co może być traktowane jako plik w Uniksie. Żeby było śmieszniej, nie zwraca wskaźnika na jakąś strukturę (jak np. wysokopoziomowy <code>fopen</code>), tylko numerek deskryptora, który nic nie mówi. Całością zajmuje się jądro i programista jest zdany na jego łaskę lub niełaskę. Można też podać jakieś śmieszne flagi, w stylu <code>O_RDONLY</code>, czy <code>O_APPEND</code>, ale efekt końcowy i tak jest losowy.

* '''<code>close</code>''' – tu nawet nie musimy się wysilać, wystarczy że zacytujemy ciocię Wikipedię: '' W dawnych czasach <code>close</code> nie zwracało kodu błędu, więc nikt go nie sprawdzał. Współcześnie zwraca kod błędu, co z punktu widzenia architektury systemu jest kompletnym nieporozumieniem – nikt tak naprawdę nie zdefiniował co konkretnie ma znaczyć błąd przy zamykaniu pliku i co program ma z tym zrobić.''
:Powyższy tekst można śmiało uzupełnić o informację, że ''cały'' POSIX to jedno wielkie nieporozumienie.

* '''<code>read/write</code>''' – jak już se plik otworzymy to wreszcie możemy z niego czytać (lub zapisywać doń) surowe bajty. Pokazujemy funkcji jakiś bufor i modlimy się, żeby się nie przepełnił. Obie te funkcje zwracają całą gamę błędów, od złej flagi, przez przeciekające rury, po interwencję [[Bóg|siły wyższej]].

== Zobacz też ==
* [[Unix]]
* [[powłoka (Linux)]]
* [[Linux]]
* [[X Window System]]

{{Linux}}


=== <code>exec</code>, czyli jak nie przeładowywać funkcji ===
{{stopka}}
Funkcja zazwyczaj wykonywana po <code>fork</code> żeby nieco złagodzić ból po bo bolesnej interakcji z jądrem. Pozwala procesowi przeszczepić sobie wszystkie organy innego programu, zostawiając jedynie PID i parę ''niezdefiniowanych'' interakcji. Jak łatwo się domyślić, funkcja <code>exec</code> wcale nie istnieje, a programista powinien skorzystać z <code>execl</code>, <code>execle</code>, <code>execlp</code>, <code>execv</code>, <code>execve</code> lub <code>execvp</code>. Zrozumienie co robią poszczególne wersje zostawiam jako ćwiczenie dla studentów.
[[Kategoria:Unix]]
[[Kategoria:Programowanie]]
Cc-white.svg Wszystko, co napiszesz na Nonsensopedii, zgadzasz się udostępnić na licencji cc-by-sa-3.0 i poddać moderacji.
NIE UŻYWAJ BEZ POZWOLENIA MATERIAŁÓW OBJĘTYCH PRAWEM AUTORSKIM!
Anuluj Pomoc w edycji (otwiera się w nowym oknie)