powered by
Mi si ol
8 ŚRODOWISKO SYSTEMU UNIX______J
kodu. W szczególności nasza funkcja nie rozpoznaje ani rodzaju ”b” (dostęp binarny) ponieważ w systemach Unix nie ma zastosowania, ani rodzaju który dopuszc* jednocześnie czytanie i pisanie. H
Przy pierwszym wywołaniu funkcji getc licznik znaków danego pliku równa się zero
co wymusza wywołanie funkcji —fillbuf. Jeśli funkcja _fillbuf stwierdzi, że pjji
nie został otwarty do czytania, to natychmiast wraca z sygnałem końca pljk EOF. W przeciwnym przypadku próbuje przydzielić bufor (jeżeli czytanie ma by buforowane).
Gdy bufor jest już ustalony, wówczas funkcja_fillbuf wywołuje funkcję read, ab,
zapełniła ten bufor, po czym nadaje wartości licznikowi oraz wskaźnikom i wrac z pierwszym znakiem znajdującym się w buforze. Następne wywołania funkcji -fillbuf korzystają z przydzielonego już bufora.
#include <stdio.h> #include "syscalls.h”
/* -fillbuf: przydziel i wypełnij bufor wejściowy */ int _fillbuf(FILE *fp)
int bufsize;
if ((fp—>flag & (_READ | _EOF | _ERR)) != _READ) return EOF;
bufsize = (fp—>flag & JJNBUF) ? 1 : BUFSIZ;
if (fp->base == NULL) /* jeszcze nie ma bufora */ if ((fp->base = (char *) malloc(bufsize)) == NULL) return EOF; /* brak miejsca na bufor */
fp—>ptr = fp->base;
fp->cnt = read(fp->fd, fp—>ptr, bufsize);
if (—fp->cnt < 0) { if (fp->cnt == -1) fp—>flag |= - EOF; else
fp—>flag |= _ERR; fp->cnt = 0; return EOF;
return (unsigned char) *fp->ptr++;
0.6 PRZYKŁAD - WYPISYWANIE ZAWARTOŚCI SKOROWIDZÓW jedyne, co jeszcze pozostało, to wyjaśnienie, jak wszystko zaczyna razem wsj cować. Tablica _iob musi być uprzednio zdefiniowana i zainicjowana dla plików stdin, stdout i stderr:
FILE _iob[OPEN_MAX] = { /* stdin, stdout, stderr: */
{ 0, (char +) 0, (char *) 0, _READ, 0 },
{ 0, (char *) 0, (char *) 0, _WRITE, 1 },
{ 0, (char *) 0, (char *) 0, -WRITE | _UNBUF, 2 }
Ze sposobu zainicjowania składowych flag w tablicy struktur wynika, że plik stdin jest przeznaczony do czytania, plik stdout do pisania, a plik stderr do pisania niebu-forowanego.
Ćwiczenie 8.2. Napisz nowe wersje funkcji fopen i _fillbuf, używając pól zamiast jawnych operacji bitowych. Porównaj rozmiar kodu i prędkość działania obu wersji.
Ćwiczenie 8.3. Zaprojektuj i napisz funkcje -flushbuf, fflush i fclose.
Ćwiczenie 8.4. Biblioteka standardowa zawiera funkcję int fseek(FILE *fp, long offset, int origin)
identyczną z funkcją Iseek z wyjątkiem tego, że fp jest wskaźnikiem pliku, a nie deskryptorem pliku, oraz że zwracaną przez funkcję wartością jest stan pliku wyrażony liczbą całkowitą (int), a nie pozycja w pliku. Napisz tę funkcję tak, aby prawidłowo obsługiwała dane buforowane dla innych funkcji bibliotecznych.
Czasem są potrzebne narzędzia współpracujące z systemem plików w inny sposób -Przekazujące informacje o pliku, a nie informacje w nim zawarte. Polecenie systemu n'x o nazwie !s jest przykładem takiego programu narzędziowego: wypisuje nazwy ™ów zawartych w skorowidzu oraz - na żądanie - inne informacje o tych plikach, lak 'eh rozmiary, uprawnienia itp. Polecenie dir w systemie MS-DOS działa podobnie.
Pb *
nieważ skorowidz w systemie Unix jest po prostu plikiem, to w programie ls wyko Przeczytać ten pKk* aby wydobyć z niego nazwy plików. Ale inne informacje I v, * U’ rozmiar’ z konieczności uzyskuje się za pomocą odwołania systemo-
| sle§°’ W innych systemach bywa tak, że nawet nazwy plików skorowidza uzyskuje I ^Jedynie przez odwołanie systemowe; tak jest np. w systemie MS-DOS. Zmierzamy
by dostęp do żądanej informacji był względnie niezależny od systemu, choć-i • nawet jego realizacja była ściśle zależna od systemu.
236
237