Do spisu tresci tematu 6

6.1 Otwieranie pliku - funkcja open()

Spis tresci


Wprowadzenie

Funkcja open() probuje otworzyc plik. Zwraca deskryptor pliku(nieujemna liczba uzywana przy czytaniu, pisaniu do pliku, itd.) lub -1 w przypadku bledu(kod bledu na zmiennej errno).


Definicja

int open(const char *pathname, int flags, int mode)

Wynik - deskryptor pliku(>=0), lub -1 w przypadku bledu.Patrz kody bledow.

pathname - sciezka dostepu do pliku

flags - okresla sposob otwierania pliku

mode - uzywane z flaga O_CREAT(wpp ignorowane). Okresla prawa dostepu do pliku. Jest modyfikowane przez atrybut umask procesu: prawa dostepu do tworzonego pliku beda rowne(mode & ~umask).

Stale uzywane jako parametr flags:

O_RDONLY,O_WRONLY,O_RDWR (otwieranie pliku odpowiednio tylko do czytania, tylko do pisania, do czytania/pisania. Flagi te mozemy modyfikowac bitowa operacja OR flagami opisanymi ponizej)

O_CREAT (jesli plik nie istnieje bedzie stworzony)

O_EXCL (uzywany z flaga O_CREAT, jesli plik juz istnieje zwroc blad)

O_NOCTTY (jesli pathname odnosi sie do terminala, to nie stanie sie on terminalem sterujacym, nawet jesli takowego proces nie posiada)

O_TRUNC (jesli plik juz istnieje obetnij go)

O_APPEND (poczatkowo oraz przed kazdym pisaniem wskaznik do pliku bedzie ustawiany na jego koncu)

O_NONBLOCK / O_NDELAY (open oraz kazda inna nastepna operacja na zwroconym deskryptorze bedzie konczyla sie bledem w przypadku koniecznosci czekania na jakies zdarzenie np. zdjecie blokady z pliku)

O_SYNC (dowolne operacje pisania na deskryptorze beda blokowaly proces az do momentu wykonania fizycznego zapisu na urzadzeniu docelowym)

Kody bledow zwracane na zmiennej errno w przypadku bledu

EEXIST (plik pathname juz istnieje - O_CREAT i O_EXCL ustawione)

EISDIR (otwierano katalog do pisania)

ETXTBSY(otwierano plik wykonwalny do pisania, ale jest on teraz wykonywany)

EFAULT (pathname wskazuje na obszar poza przestrzenia adresowa procesu)

EACCES (dostep do pliku zabroniony, lub jeden z katalogow w pathname nie zezwala na przeszukiwanie(wykonywanie))

ENAMETOOLONG(nazwa pathname za dluga)

ENOENT (katalog skladowy uzyty w sciezce nie istnieje lub jest nieprawidlowym dowiazaniem)

ENFILE (prog na maks. liczbe otwarych plikow w systemie zostal osiagniety

ENOMEM (niewystarczajaca ilosc pamieci dostepnej jadru systemu)

EROFS (plik z systemu plikow typu read-only otwierano do pisania)

ELOOP (pathname zawiera dowiazanie cykliczne tj takie, ze jego rozwiniecie nadal uzywa tego dowiazania )

ENOSPC (brak miejsca na urzadzeniu na utworzenie nowego pliku)


Spotkane ograniczenia na zasoby systemowe


Implementacja

int open(const char *pathname, int flags, int mode)


{

        file=get_empty_filp();/*file - wolna pozycja w tablicy plikow*/

        mode = mode & ~umask;/* uwzglednienie umask procesu*/

        Sprawdzenie praw, poprawnosci argumentow;

        if(flag&O_CREATE){

                inode=get_empty_inode(); /* inode - wolna pozycja w tablicy i-wezlow*/

                zainicjalizowanie pozycji inode w tablicy i-wezlow;

        }else

                inode=i-wezel pliku o nazwie pathname;

        if(flag&O_TRUNC) 

                do_truncate();

        if(plik otwarto do pisania)

                inode->i_writecount++;

        Zaincjalizowanie pozycji file w tablicy plikow;

        Poszukiwanie wolnej pozycji nr w tablicy deskryptorow fd procesu;

        fd[nr]=file;

        return (nr);

} 


Uwagi

  1. Wywolanie funkcji systemowej creat jest rownowazne wywolaniu open z flaga rowna O_CREAT|O_WRONLY|O_TRUNC
  2. Gdy nie ma wolnej pozycji w tablicy plikow, wowczas alokowana jest nie jedna struktura file lecz cala strona pamieci na (PAGE_SIZE/sizeof(struct file)) nowych pozycji w tablicy plikow. Patrz zrodla.
  3. Opisujac funkcje open opieralem sie na definicji zawartej w pliku "./include/asm-alpha/unistd.h". Innych miejsc z definicja funkcji open nie znalazlem. Dziwi mnie ten fakt, gdyz wydaje sie, ze podobna definicja powinna sie znajdowac np. w pliku "./include/asm-i386/unistd.h"..
  4. Opisujac funkcje open dokonalem malego przeklamania piszac, ze w przypadku bledu funkcja zwraca -1 a na zmiennej errno zwraca kod bledu (jak w interfejsie C do funkcji open )zamiast pisac, ze zwraca wtedy ten kod (jak w zrodlach). Uwazalem, ze opis funkcji open zgodny z rzeczywistoscia(zrodla) moglby byc mylacy dla potencjalnych czytelnikow-programistow.

Bibliografia

  1. Pliki zrodlowe Linuxa: ./include/asm-alpha/unistd.h, ./fs/open.c, ./fs/namei.c
  2. Pomoc ("man") dostepna pod Unixem

Autor: Marcin Rychlik