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 pliku, śieżka dostępu do pliku, i-węzeł, zmianna errno, plik nagłówkowy f cntl.h, kody błędów. 1 System plików - funkcje systemowe Linux Wstęp Na laboratorium przyjrzymy się podstawowym operacjom dostarczanym przez system umożliwiajcym obsugę plików z wnętrza programów. Do tych operacji można zaliczyć open - otwiera plik, albo tworzy pusty plik, create - tworzy pusty plik, close - zamyka wcześniej otwarty plik, read - pobiera informacje z pliku, write - umieszcza informację w pliku, lseek - przechodzi do określonego bajtu w pliku, unlink - usuwa plik, dup - tworzy kopię deskryptora i nadaje jej pierwszy wolny numer z tablicy otwartych plików, dup2 - tworzy kopię deskryptora, umożliwia okrelenie jej identyfikatora przez użytkownika. 2 opis funkcji open() int open(const char *pathname, int flags, int mode) wynik - deskryptor pliku(>=0), lub -1 w przypadku błędu, pathname - ścieżka dostępu do pliku, flags - określa sposób otwierania pliku, mode - używane z flagą O_CREAT, flagi: O_RDONLY - otwarcie w trybie tylko do odczytu, O_WRONLY - otwarcie w trybie tylko do zapisu, O_RDWR otwarcie w trybie do odczytu i do zapisu, O_CREAT - utworzenie pliku, jeśli plik jeszcze nie istnieje, O_TRUNC - obcięcie pliku, jeśli plik istnieje i otwierany jest w trybie O_WRONLY lub O_RDWR, 2
creat() O_EXCL - powoduje zgłoszenie błędu jeśli plik już istnieje i otwierany jest z flagą O_CREAT, O_APPEND - operacje pisania odbywają się na końcu pliku. int creat(char *pathname, int mode). wynik - deskryptor pliku(>=0), lub -1 w przypadku błędu podobnie jak open(), wywołanie creat(pathname,mode) jest równoważne wywołaniu open(pathname, O_CREAT O_WRONLY O_TRUNC, mode) możliwe kody błędów close() EFAULT - nazwa pathname wskazuje poza dostępną przestrzeń adresową, EACCES - żądany dostęp do pliku nie jest dozwolony, ENFILE - osiągnięto limit otwartych plików w systemie, EMFILE - proces już otworzył dozwoloną maksymalną liczbę plików, EROFS - żądane jest otwarcia w trybie zapisu pliku będącego plikiem tylko do odczytu, EEXIST - plik o podanej nazwie już istnieje, a użyto flag O_CREAT i O_EXCL. int close(int filedes) funkcja close() zwalnia deskryptor pliku, moe byc on powtórnie przydzielony. Jeśli deskryptor jest ostatnim, który odnosi sie do danej pozycji w tablicy plików, wówczas pozycja ta jest również zwalniana. Zdejmowane sa wszelkie blokady założone przez proces na pliku, wynik - 0 w przypadku sukcesu lub -1 w przypadku błędu, filedes - deskryptor zamykanego pliku, read() EBADF - wartość f iledesd nie jest prawidłowym deskryptorem otwartego pliku int read( int filedes, void *buf, size_t count) liczba zwracana przez read - ilość rzeczywicie przeczytanych bajtów, -1 w przypadku wystpienia błędu, buf - adres bufora znajdujcego się w segmencie danych procesu, do którego zostaną przekazane dane odczytane z pliku w wyniku wywołania funkcji read, count - ilość bajtów do odczytania, EISDIR - filedes odnosi się do katalogu, 3
write() EBADF - filedes nie jest prawidłowym deskryptorem pliku, lub nie jest otwarty dla odczytu, EINVAL - f iledes wskazuje na obiekt nieodpowiedni do odczytu, EFAULT - buf wskazuje poza dostępną przestrzeń adresową, EINTR - wywołanie zostało przerwane sygnałem przed odczytaniem danych, EAGAIN - przy użyciu O_NONBLOCK wybrano nieblokujące I/O, a nie ma akurat danych dostępnych do odczytania natychmiast, EIO - błąd I/O. int write( int filedes, void *buf, size_t count) liczba zwracana przez write - ilość rzeczywicie zapisanych bajtów. -1 w przypadku wystpienia błędu buf - adres bufora znajdujcego się w segmencie danych procesu, z którego zostaną pobrane dane zapisane przez funkcję write count - ilość bajtów do zapisania lseek() EFAULT - adres buf jest poza dostępną przestrzenią adresową EINVAL - deskryptor f iledes wskazuje na obiekt nieodpowiedni do zapisu, EBADF - deskryptor f iledes nie jest prawidłowym deskryptorem pliku, lub nie jest otwarty dla odczytu, EAGAIN - wybrano nieblokujący I/O (przy użyciu O_NONBLOCK) a do potoku lub gniazda o deskryptorze f iledes nie można natychmiast zapisać danych, item EINTR - wywołanie zostało przerwane sygnałem przed zapisaniem danych, ENOSPC - urządzenie, zawierające plik o deskryptorze f iledes nie ma miejsca na dane, EPIPE - filedes jest podłączony do potoku, lub gniazda, którego drugi koniec jest zamknięty. long lseek( inf filedes, off_t offset, int start_flags) liczba zwracana przez lseek - nowa pozycja w pliku, liczona w bajtach względem początku pliku -1 w przypadku wystpienia błędu. offset - liczba bajtów, o jak należy przesunąć wskaźnik start_f lags - parametr określajcy pozycję względem której jest przesuwany wskaźnik: SEEK_SET - początek pliku, SEEK_END - koniec pliku, SEEK_CUR - bieżąca pozycja, 4
EBADF - deskryptor f iledes nie jest prawidłowym deskryptorem pliku, ESPIPE - filedes jest związany z potokiem, gniazdem, lub FIFO, EINVAL - parametr start f lags ma nieprawidłową wartością. unlink() int unlink(const char *pathname) w przypadku poprawnego usunięcia pliku funkcja zwraca 0, -1 w przypadku wystąpienia błędu, pathname - wskaźnik do napisu zawierajcego nazwę ścieżki pliku, który ma być usunięty (nazwa bezwzględna lub względna), dup() EFAULT - nazwa pathname wskazuje poza dostępną przestrzeń adresową, EACCES - żądany dostęp do pliku nie jest dozwolony, int dup( int oldfiledes ) funcja zwraca nowy deskryptor, -1 w przypadku wystąpienia błędu, oldf iledes - deskryptor zamykanego pliku, możliwe kody błędu: dup2() EBADF - oldf iledes nie jest deskryptorem otwartego pliku lub newf iledes jest poza dozwolonym zasięgiem deskryptorów plików, EMFILE - proces już osiągnął maksymalną liczbę otwartych deskryptorów plików, int dup2(int oldfiledes, int newfiledes) funcja zwraca nowy deskryptor -1 w przypadku wystąpienia błędu, oldf iledes - deskryptor zamykanego pliku newf iledes - nowy deskryptor. Wykonanie operacji close(1); dup(fd); jest równoważne operacji dup(1,fd) kody błędów podobnie jak w dup() 5
3 Zadania do samodzielnego wykonania 1. Program kopiujący zawartość pliku o nazwie podanej jako pierwszy parametr do istniejącego pliku którego nazwa podana jest jako drugi parametr. Wykorzystanie funkcji open, creat, read, write i close. 2. Program do kopiowania ostatnich 10 znaków, słów i ostatnich 10 linii jednego pliku do innego. 3. Program liczący ile jest słów w pliku (należy założyć, że słowa składają się z małych i dużych liter alfabetu oraz cyfr, a wszystkie pozostałe znaki są separatorami) 4. Program który wyświetla rozmiar pliku. Wykorzystanie funkcji open, lseek i close. 4 Literatura Havilland K., Gray D., Salama B., Unix - programowanie systemowe,1999 Stevens R.W., Programowanie w środowisku systemu UNIX, WNT, 2002. Rochkind M.J., Programowanie w systemie UNIX dla zaawansowanych, WNT, 1997. 6