Dobrym punktem wyjścia będzie POSIX. Specyfikacja POSIX 2008 jest dostępna online tutaj:
http://pubs.opengroup.org/onlinepubs/9699919799/
To bardziej dostępne (ale czasami mniej rygorystyczne) niż standardowe C i obejmuje znacznie więcej niż tylko standard C, czyli większość standardowych częściach Standardowe biblioteki systemów Unix-like.
Jeśli interesują Cię implementacje, pierwszą rzeczą, na którą należy zwrócić uwagę, jest to, że zachowanie opisane w POSIX jest zwykle rozdzielane (z powodów koniecznościowych i pragmatycznych) między implementacją jądra a implementacją libc przestrzeni użytkownika. Duża liczba funkcji w POSIX (i kilka ze standardu C) będzie jedynie opakowaniem dla "wywołań systemowych", tj. Przejdzie do przestrzeni jądra, aby obsłużyć żądanie. W niektórych implementacjach libc nawet znalezienie tych wrapperów będzie trudne, ponieważ często są one automatycznie generowane przez skrypty kompilacji i/lub ujednolicane w jednym pliku asemblera.
Główną (znaczna ilość kodu non-kernel) podsystemy standardowej biblioteki są na ogół:
- stdio: Na glibc ten jest realizowany przez GNU libio biblioteki, która jest jednolita realizacja C stdio i C++ iostream, zoptymalizowane tak, aby żadne z nich nie musiało zostać spowolnione poprzez bycie opakowaniem dla drugiego. To wielki hack, a kod jest trudny do znalezienia i naśladowania. Inne implementacje (szczególnie BSD, ale także inne biblioteki libx na Linuksie) są znacznie prostsze i czytelniejsze do odczytania. Ostatecznie są one oparte na podstawowych funkcjach IO pliku deskryptora, takich jak
open
, read
itd.
- Wątki POSIX: w przypadku glibc i nowoczesnych uClibc jest to NPTL. Nie jestem zaznajomiony z implementacjami wątków BSD. Inne biblioteki libc albo nie zawierają wątków, albo udostępniają własne implementacje oparte głównie na Linux syscalls.
- Biblioteka matematyczna: ostatecznie prawie wszystkie z nich oparte są na starym kodzie matematyki Sun z początku lat 90., ale bardzo się rozdzieliły. Fdlibm jest dość dobrym przybliżeniem bazowym kodu używanego w nowoczesnych bibliotekach.
- Użytkownik, grupa, nazwa hosta (DNS), itp. Odnośniki: Jest to obsługiwane przez biblioteki libnss w glibc i bezpośrednio w większości innych bibliotek.
- Wyrażenie regularne i glob dopasowanie
- Czas i obsługi
- Locale i konwersji charset
- Malloc
Jeśli chcesz zacząć czytać źródła stref czasowych, polecam nie wychodząc z glibc. Jest bardzo duży i nieporęczny. Jeśli chcesz czytać glibc, pamiętaj, że wiele kodu ukrywa się pod drzewem sysdeps i jest zorganizowane w oparciu o różnorodność systemów, do których ma zastosowanie.
dietlibc jest dość czytelny, ale jeśli czytasz jego źródła, należy pamiętać, że jest to pełna typowych błędów programowania C (na przykład za pomocą int
gdzie size_t
jest potrzebne, a nie sprawdzanie przelewów, itp). Jeśli będziesz o tym pamiętać, może to nie być zły wybór, ponieważ ignorowanie wielu możliwych błędów/niepowodzeń sprawia, że kod jest bardzo prosty.
Powiedziawszy to, do czytania źródła libc, polecam albo jeden z BSD albo musl (disclaimer: jestem głównym autorem mulla, więc jestem tu nieco stronniczy). BSD mają także tę zaletę, że kod jądra jest również niezwykle prosty i czytelny, więc jeśli chcesz przeczytać kod jądra po drugiej stronie wywołania systemowego, możesz to zrobić.
Proszę ponownie otworzyć. Zamknięcie tego jednostronnie było nadużyciem władzy moderatora. Uważam, że to pytanie jest całkowicie uzasadnione, odpowiedzialne w formacie SO, i faktycznie mam odpowiedź, której zablokowano mi przez niefortunną jednostronną decyzję o zamknięciu. –
@R ..: Racja, wydaje się, że pytanie jest teraz otwarte, oznaczając Cię tutaj, aby otrzymać powiadomienie i zobaczyć, że pytanie zostało ponownie otwarte =) – cha0site
@ cha0site: Dzięki! –