Jak używać INotify API w języku C

Jak używać INotify API w języku C
Inotify to interfejs API Linux używany do monitorowania zdarzeń systemu.

W tym artykule pokaże Ci, w jaki sposób Inotify jest używany do śledzenia tworzenia, usunięcia lub modyfikacji plików i katalogów systemu plików Linux.

Aby monitorować określony plik lub katalog za pomocą inotify, wykonaj następujące kroki:

  1. Utwórz instancję Inotify za pomocą inotify_init ()
  2. Dodaj pełną ścieżkę katalogu lub pliku do monitorowania i zdarzenia do oglądania za pomocą funkcji inotify_add_watch (). W tej samej funkcji określamy, które zdarzenia (na tworzenie, na dostęp, na modyfikując itp.), zmiany w plikach lub zmiany w katalogu muszą być monitorowane.
  3. Poczekaj, aż zdarzenia się wystąpią i przeczytaj bufor, który zawiera jedno lub więcej zdarzeń, które miały miejsce, używając Czytać() Lub wybierać()
  4. Przetworzyć zdarzenie, które miało miejsce, a następnie wróć do kroku 3, aby poczekać na więcej zdarzeń i powtórzyć.
  5. Usuń deskryptor zegarków za pomocą inotify_rm_watch ()
  6. Zamknij instancję INOTIFIF.

Teraz zobaczymy funkcje używane do INotify API.

Plik nagłówka: SYS/Inotify.H

inotify_init () funkcja:

Składnia: int inotify_init (void)

Argumenty: Brak argumentów.

Wartości zwracane: Po sukcesie funkcja zwraca nowy deskryptor pliku dla porażki, funkcja zwraca -1.

inotify_add_watch () funkcjonować:

Składnia: int inotify_add_watch (int fd, const char *Pathname, Uint32_T Mask)

Argumenty:

Ta funkcja przyjmuje trzy argumenty.

1St Argument (FD) to deskryptor pliku, który odnosi się do instancji INOTIFIF (wartość zwracania inotify_init () funkcjonować) .

2Nd Argument jest ścieżką monitorowanego katalogu lub pliku.

3r & D Argument to maska ​​bitowa. Maska bitowa reprezentuje zdarzenia, które są oglądane. Możemy oglądać jedno lub więcej wydarzeń za pomocą Bitwise-or lub.

Zwracaj wartości: Po sukcesie funkcja zwraca deskryptor zegarków, dla awarii funkcja zwraca -1.

inotify_rm_watch () funkcjonować:

Składnia: int inotify_rm_watch (int fd, int32_t wd)

Argumenty:

Ta funkcja przyjmuje dwa argumenty.

1St Argument (FD) to deskryptor pliku, który odnosi się do instancji INOTIFIF (wartość zwracania inotify_init () funkcjonować) .

2Nd Argument (WD) jest deskryptorem zegarka (wartość zwracana inotify_add_watch () funkcjonować) .

Zwracaj wartości: Po sukcesie funkcja zwraca 0, dla niepowodzenia funkcja zwraca -1.

Używamy Czytać() funkcja (zadeklarowana w unistd.H nagłówek plik) w celu odczytania bufora, który jest przechowywany przez informacje o zdarzeniach wystąpiły w formie inotify_event Struktura. inotify_event Struktura jest zadeklarowana w SYS/Inotify.H plik nagłówka:

struct inotify_event
int32t wd;
maska ​​uint32_t;
uint32_t Cookie;
uint32_t len;
Nazwa char [];

inotify_event Struktura reprezentuje zdarzenie systemu plików zwrócone przez system Inotify i zawiera następujące członki:

  • wd: Obejrzyj deskryptor (wartość zwracana inotify_add_watch () funkcjonować)
  • maska: Maska bitowa, która zawiera wszystkie typy zdarzeń
  • ciastko: Unikalny numer identyfikujący zdarzenia
  • Len: Liczba bajtów w polu nazwy
  • nazwa: Nazwa pliku lub katalogu, w którym zdarzyło się zdarzenie

Poniżej znajduje się działający przykład, używając API INOTIFY:

Inotyfy.plik C:

#włączać
#włączać
#włączać
#włączać
#włączać
#include // biblioteka dla funkcji FCNTL
#definicja Max_Events 1024 /* Maksymalna liczba zdarzeń do przetwarzania* /
#Define len_name 16 /* Zakładając, że długość nazwy pliku
nie przekroczy 16 bajtów*/
#Define Event_Size (sizeof (struct inotify_event)) /*Rozmiar jednego zdarzenia* /
#Define buf_len (max_events * (event_size + len_name)))
/*bufor do przechowywania danych zdarzeń*/
int fd, WD;
void sig_handler (int sig)
/* Krok 5. Usuń deskryptor zegarków i zamknij instancję INOTIFIF*/
inotify_rm_watch (fd, wd);
Zamknij (FD);
wyjście (0);

int main (int argc, char ** argv)
char *path_to_be_watched;
sygnał (sigint, sig_handler);
path_to_be_watched = argv [1];
/* Krok 1. Zainicjuj Inotify */
fd = inotify_init ();
if (fcntl (fd, f_setfl, o_nonblock) < 0) // error checking for fcntl
wyjście (2);
/* Krok 2. Dodaj zegarek */
wd = inotify_add_watch (fd, path_to_be_watched, in_modify | in_create | in_delete);
if (wd ==-1)
printf („Nie można obejrzeć: %s \ n”, ścieżka_to_be_watched);

w przeciwnym razie
printf („oglądanie: %s \ n”, ścieżka_to_be_watched);

while (1)
int i = 0, długość;
Char Buffer [buf_len];
/* Krok 3. Odczyt bufora*/
długość = odczyt (fd, bufor, buf_len);
/* Krok 4. Przetworzyć zdarzenia, które miały miejsce */
podczas gdy jastruct inotify_event *event = (struct inotify_event *) i bufor [i];
if (event-> len)
if (event-> maska ​​i in_create)
if (event-> maska ​​i in_isdir)
printf („Utworzono katalog %s.\ n ", zdarzenie-> nazwa);

w przeciwnym razie
printf („utworzono plik %s.\ n ", zdarzenie-> nazwa);


else if (event-> maska ​​i in_delete)
if (event-> maska ​​i in_isdir)
printf („ %S %s został usunięty.\ n ", zdarzenie-> nazwa);

w przeciwnym razie
printf („Plik %s został usunięty.\ n ", zdarzenie-> nazwa);


else if (event-> maska ​​i in_modify)
if (event-> maska ​​i in_isdir)
printf („ %S %s został zmodyfikowany.\ n ", zdarzenie-> nazwa);

w przeciwnym razie
printf („Plik %s został zmodyfikowany.\ n ", zdarzenie-> nazwa);



i + = event_size + event-> len;


Wyjście:

Aby wykonać program i zobaczyć dane wyjściowe, musimy najpierw otworzyć dwa terminale. Jeden terminal służy do uruchamiania programu Inotyfy.C. W drugim terminalu idziemy na ścieżkę obserwowaną przez Inotify.C. Jeśli utworzymy dowolny katalog lub plik, zmodyfikujesz dowolny plik lub usuniemy dowolny katalog lub plik, zobaczymy je na pierwszym terminalu.

w Inotyfy.C przykład unistd.H plik nagłówka jest używany dla Czytać() I zamknąć() funkcja, stdlib.H plik nagłówka jest używany dla Wyjście() funkcja, sygnał.H plik nagłówka jest używany dla sygnał() funkcja i Sig_int makro (szczegółowe informacje patrz obsługa sygnału) i fcntl.H plik nagłówka jest używany dla fcntl () funkcjonować.

Deklarujemy FD (InTify Instance) i wd (Obejrzyj deskryptor) jako zmienne globalne, aby te zmienne były dostępne ze wszystkich funkcji.

fcntl () funkcja jest używana tak, aby podczas czytania za pomocą FD deskryptor, wątek nie zostanie zablokowany.

Następnie dodajemy zegarek za pomocą inotify_add_watch () funkcjonować. Tutaj przekazujemy FD, ścieżkę katalogu, który będzie obserwowany, i maska. Możesz przekazać maskę zdarzeń, które chcesz monitorować za pomocą Bitwise-or lub.

Teraz przeczytaj bufor. Informacje o jednym lub więcej wydarzeniach są przechowywane w buforze. Możesz przetwarzać wszystkie zdarzenia jeden po drugim za pomocą pętli. Możesz sprawdzić zdarzenie-> maska, aby wiedzieć, jaki rodzaj wydarzeń się wydarzył.

Używamy nieskończoności podczas ciągłego sprawdzania, kiedy zdarzenia wystąpiły. Jeśli nie wydarzyły się żadne zdarzenia, funkcja Read () powraca z 0. Wartość zwracana funkcji Read () jest przechowywana w zmiennej długości. Gdy wartość zmiennej długości jest większa niż zero, wystąpiło jedno lub więcej zdarzeń.

Używamy Sig_int sygnał (naciśnij Ctrl+C), aby wyjść z procesu. Po naciśnięciu Ctrl+C, sig_handler () Funkcja jest wywoływana (szczegółowe informacje patrz Obsługa sygnału). Ta funkcja usuwa deskryptor zegarków, zamyka instancję Inotify FD, i wychodzi z programu.

Wniosek

Możesz użyć INOTIFY API we własnych aplikacjach do monitorowania, debugowania, automatyzacji i innych, na swój własny sposób. Tutaj widzieliśmy przepływ wykonywania API Inotify.