Funkcie na narábanie s adresármi a súbormi sú neodmysliteľnou súčasťou výbavy každého programátora. V tomto článku si zhrnieme niektoré zaujímavé funkcie.
Okrem štandardných funkcií ako
fopen() fclose() fseek() a
ftell(), prípadne
read(), write(), fprintf() by mal programátor v prostredí operačného systému Linux poznať sadu užitočných funkcií, ktorú sa posnažíme zosumarizovať v tomto článku. V článku predpokladáme znalosť pojmu dekritor a určitá dávka programátorského pochopenia.
Funkcia fstat() a príbuzné lstat() a stat() nájdeme v hlavičkových súboroch
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
ich deklarácie sú nasledovné
int fstat(int filedes, struct stat *buf);
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);
Budeme sa zaoberať funkciou
fstat(), avšak vysvetlíme si rozdiel medzi
lstat() a
stat(). Ich chovanie je rozdielne pokiaľ parameter
path ukazuje na symbolický odkaz (symlink). Funkcia
stat() vráti informácie o súbore na ktorý odkaz odkazuje a
fstat() vracia informácie o samotnom súbore ktorý obsahuje
symlink.
Simlink je na rozdiel od
hardlinku odkaz pomocou "cesty" k súboru na ktorý odkazuje, a môže byť na neexistujúce súbory, prípadne sa rozprestierať cez partície a filesystémy. Naopak
hardlink je priamo odkaz na súbor a nesmie prekračovať partície alebo filesystémy. Jedná sa o ďalší ukazovateľ na reálny obsah alebo štruktúru, ktorá obsahuje dáta súboru. Počet
hardlinkov sa drží ako informácia vo filesystéme a súbor je reálne zmazaný(jeho obsah na médiu) až keď prestane existovať posledný
hardlink. Symlink takúto výsadu nemá a môže teda odkazovať na zmazaný alebo neexistujúci súbor.
U mazania súborov je ešte jedna dôležitá skutočnosť a tou je, že okrem
hardlinkov sa zohľadňujú aj otvorené
desktriptory. Pokiaľ existuje otvorený deskriptor, súbor ostáva rezidentný.
int filedes je deskriptor na súbor (získať sa dá zavolaním
open() alebo vytvorením z FILE* pomocou
fileno(), prípadne použitím
dup() alebo
dup2() )
Čo sa skrýva za štruktúrov
struct stat
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
Pre nás najzaujímavejšie položky sú
mode_t st_mode, uid_t st_uid, gid_t st_gid, off_t st_size. nlink_t st_nlink a položky
time_t st_atime, st_mtime, st_ctime.
mode_t st_mode - je to bitmask rôznych príznakov, pričom spodných 9 bitov patrí prístupovým právam, podľa klasického schématu RWXRWXRWX (R - read, W - write, X - execute) pričom prvá trojica je
vlastník, potom je
skupina a končí to
zvyškom sveta.
Makrá pre tieto položky sú nasledovné:
- S_IRWXU - nastaví všetky práva vlastníka
- S_IRWXG - nastaví všetky práva skupiny
- S_IRWXO - nastaví všetky práva zvyšku sveta
- S_IRUSR S_IWUSR S_IXUSR - nastaví práva čítania zápisu spustenia pre vlastníka
- S_IRGRP S_IWGRP S_IXGRP - nastaví práva čítania zápisu spustenia pre skupinu
- S_IRGRP S_IWGRP S_IXGRP - nastaví práva čítania zápisu spustenia pre skupinu
- S_IROTH S_IWOTH S_IXOTH - nastaví práva čítania zápisu spustenia pre zvyšok sveta
Iné zaujímavé flagy sú:
S_IFLNK(je to symbolický link),S_IFREG(normálny súbor),S_IFDIR(adresár)
A použiteľné makrá sú (parameter je
mode_t st_mode)
- S_ISREG(x) - zistí či je nastavný príznak toho, źe sa jedná o súbor
- S_ISDIR(x) - zistí či je nastavný príznak toho, źe sa jedná o adresár
- S_ISLNK(x) - zistí či je nastavný príznak toho, źe sa jedná o symbolický odkaz
- S_ISCHR(x), S_ISBLK(x), S_ISFIFO(x), S_ISSOCK(x) sú zaujímavé z pohľadu typu zariadenia alebo špecifického druhu súboru
- uid_t st_uid - user ID vlastníka
- gid_t st_gid - group ID vlastníka
- off_t st_size - veľkosť súboru v bajtoch
- nlink_t st_nlink - počet hardlinkov
time_t st_atime, st_mtime, st_ctime - časy posledného prístupu, poslednej zmeny práv, vlastníka skupiny alebo obsahu a čas poslednej zmeny obsahu
Vytvorenie súboru sa dá tradičnou cestou pomocou
open() prípadne
fopen() alebo použitím funkcie
mknod().Na jej použitie potrebujeme hlavičkové súbory
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>Deklarácia funkcie je:
int mknod(const char *pathname, mode_t mode, dev_t dev);
Vytvorí súbor s menom
pathname pričom ak súbor existuje, vráti chybu. Vytvára vlastne
hardlink (prvý), ak sa jedná o súbor. V reále vytvára uzol(node) vo filesystéme. Keďže v *nixe je súbor základný koncept, ktorý predstavuje obecne ľubovolnú vec (súbor, socket, zariadenie, pipu...), pomocou tejto funkcie sa realizuje práve toto.
Parameter
const char *pathname je cesta k súboru
Parameter
mode_t mode sa použije pri nastavení prístupových práv a aký druh uzlu aký sa má vytvoriť (súbor, adresár, zariadenie).
Medzi ne patria
S_IFREG(normálny súbor),
S_IFCHR(znakové zariadenie),
S_IFBLK(blokové zariadenie),
S_IFIFO(pomenovaná pipa),
S_IFSOCK(socket). Skutočné prístupové práva sa nastavia tak, že bity v premennej prostredia
umask sa v parametre
mode odmaskujú ( čize mask & (~umask) sú je reálne aplikovaný).
Hodnotu premennej
umask môžete nastaviť pomocou funkcie
mode_t umask(mode_t mask);
V prípade vytvorenia zariadenia sa zohľadňuje parameter
dev_t dev ktorý určuje minor a major číslo zariadenia. Inak sa ignoruje.
V prípade chyby vráti hodnotu -1 a v prípade úspechu 0. V prípade chyby sa
errno naplní jednou z nasledujúcich hodnôt.
EACCES - jeden z adresárov v ceste nedovolil procesu zápis
EEXIST - súbor už existuje
EFAULT - chyba v parametre
path
EINVAL - chyba v parametroch
ELOOP - príliž veľa symbolických linkov v
pathname
ENAMETOOLONG - príliš dlhý
pathname
ENOENT - položka v
pathname neexistuje alebo je nefunkčný symlink
ENOMEM - nedostatok pamäte v kerneli (fakt prúser)
ENOSPC - nedá sa vytvoriť uzol na danom zariadení, z dôvodu nedostatku miesta
ENOTDIR - položka v
pathname ktorá by mala byť adresárom nieje adresár
EPERM - ak nieje v danom filesysteme podpora pre vytvorenie daného uzlu, prípadne vlastník procesu nieje privilegovaný daný druh uzlu vytvoriť
EROFS - zápis do read-only filesystemu
Funkcia
int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev);
má rovnaké použitie, s tým rozdielom, že sa súbor vytvára relatívne k adresáru uvedenom pomocou parametru
int dirfd.
Keď už sme as tak rozrozprávali o prístupových právach, nejde nespomenúť funkcie
chmod() a
chown().
int chmod(const char *path, mode_t mode);
int fchmod(int fildes, mode_t mode);
Funkcia
chmod() zmení prístupové práva k súboru.
Chyby v
errno - EACCES, EFAULT, ELOOP, ENAMETOOLONG, ENOENT, ENOMEM, ENOTDIR, EPERM, EROFS sú rovnaké ako vyššie spomenuté chyby
Naviac sa vyskytuje chyba
EIO(nejaká I/O chyba) a
EBADF(zle zadaný parameter
int filedes)
Pre použitie funckie chown() treba hlavičkové súbory
#include <sys/types.h>
#include <unistd.h>Deklarácia funkcie je nasledovná:
int chown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, gid_t group);
Pričom funkcia lchown() pracuje so symlinkami a funkcia chown() so súbormi na ktoré ukazujú.
Funkcia vracia rovnkú množinu chýb ako v prípade
chmod() a zmení aktuálneho vlastníka a skupinu ktorej je vlastník členom.
Ďalej si povieme o tom ako vytvoriť adresár, pomenovnú pipu, nový
hardlink, a
symlink. Funkcie na vytvorenie pomenovnej pipy(
mkfifo()) a adresáru(
mkdir())sú viacmenej rovnaké, takže ich preberieme jedným dychom.
Na ich použitie treba hlavičkové súbory
#include <sys/stat.h>
#include <sys/types.h>a deklarácie týchto funkcií su nasledovné
int mkdir(const char *pathname, mode_t mode);
int mkfifo(const char *pathname, mode_t mode);
ich použitie i návratové chybové hodnoty v
errno sú rovnaké ako v prípade funkcie
mknod(), s tým rozdielom, že parameter
mode obsahuje len prístupové práva v už spomenutom schémate.
Vytvorenie
hardlinku(link()) a
symlinku(symlink())
je tiež viacmenej identické.
Treba použit hlavičkový súbor
#include <unistd.h>A deklarácie funkcií vyzerajú nasledovne:
int symlink(const char *oldpath, const char *newpath);
int link(const char *oldpath, const char *newpath);
Funkcie vytvoria hard/sym link zo súboru reprezentovaného parametrom oldpath v súbore reprezentovanom parametrom newpath.
Chyby sú zas rovnakého charakteru ako v prípade mknod().
Väčšina z vás si uź určite všimla, že vyššie spomenuté funkcie sú viacmenej len zjednodušením volania funkcie
mknod(). No čo by programátor pre uľahčenie a sprehľadnenie práce neurobil. ^_^
V nasledujúcom článku si povieme o funkciách pomocou ktorých sa súborov prípadne adresárov môžme zbaviť a ako sa v adresárovej štruktúre pohybovať. Povieme si aj niečo o zámkoch a o mapovaní súborov do pamäte, ale to až nabudúce.
Neprehliadnite: