Cómo usar la API inotify en lenguaje C

Cómo usar la API inotify en lenguaje C
Inotify es una API de Linux utilizada para el monitoreo de eventos del sistema de archivos.

Este artículo le mostrará cómo se utiliza inotify para rastrear la creación, eliminación o modificación de archivos y directorios del sistema de archivos Linux.

Para monitorear un archivo o directorio específico con inotify, siga estos pasos:

  1. Crear una instancia de inotify usando el inotify_init ()
  2. Agregue la ruta completa del directorio o el archivo para monitorear y los eventos para ver con la función inotify_add_watch (). En la misma función, especificamos qué eventos (en crear, en acceso, en modificar, etc.), los cambios en los archivos o los cambios en el directorio deben ser monitoreados.
  3. Espere a que ocurran los eventos y lean el búfer, que contiene uno o más eventos que ocurrieron, utilizando el leer() o seleccionar()
  4. Procesar el evento que ha ocurrido, luego regrese al paso 3 para esperar más eventos y repetir.
  5. Elimine el descriptor de reloj con el inotify_rm_watch ()
  6. Cierre la instancia de inotify.

Ahora, veremos las funciones que se utilizan para la API inotify.

Archivo de cabecera: sys/inotify.H

inotify_init () función :

Sintaxis: int inotify_init (void)

Argumentos: sin argumentos.

Valores de retorno: en el éxito, la función devuelve un nuevo descriptor de archivo, para el fracaso, la función devuelve -1.

inotify_add_watch () función:

Sintaxis: int inotify_add_watch (int fd, const char *pathname, uint32_t máscara)

Argumentos:

Esta función toma tres argumentos.

El 1calle El argumento (FD) es un descriptor de archivo que se refiere a la instancia inotify (valor de retorno de inotify_init () función) .

El 2Dakota del Norte El argumento es la ruta del directorio o archivo que se está monitoreando.

Los 3rd El argumento es una masa de bits. La máscara de bits representa los eventos que se están viendo. Podemos ver uno o más eventos usando bitwise-o.

Valores de retorno: En el éxito, la función devuelve un descriptor de reloj, para el fracaso, la función devuelve -1.

inotify_rm_watch () función:

Sintaxis: int inotify_rm_watch (int fd, int32_t wd)

Argumentos:

Esta función toma dos argumentos.

El 1calle El argumento (FD) es un descriptor de archivo que se refiere a la instancia inotify (valor de retorno de inotify_init () función) .

El 2Dakota del Norte El argumento (WD) es un descriptor de reloj (valor de retorno de inotify_add_watch () función) .

Valores de retorno: En el éxito, la función devuelve 0, para el fracaso, la función devuelve -1.

Usamos leer() función (declarada en unistd.H encabezamiento archivo) para leer el búfer, que se almacena la información de los eventos ocurridos en forma de inotify_event estructura. El inotify_event La estructura se declara en sys/inotify.H archivo de cabecera:

struct inotify_event
int32t wd;
máscara uint32_t;
cookie uint32_t;
uint32_t len;
nombre del personaje[];

El inotify_event La estructura representa un evento del sistema de archivos devuelto por el sistema inotify y contiene los siguientes miembros:

  • WD: Ver descriptor (valor de retorno de inotify_add_watch () función)
  • mascarilla: Una máscara de poco que incluye todos los tipos de eventos
  • Galleta: Número único que identifica eventos
  • fila: Número de bytes en el campo Nombre
  • nombre: Nombre del archivo o directorio en el que ocurrió el evento

A continuación se muestra un ejemplo de trabajo, utilizando la API inotify:

Inotificar.Cile C:

#incluir
#incluir
#incluir
#incluir
#incluir
#include // biblioteca para la función fcntl
#define max_events 1024 /* número máximo de eventos para procesar* /
#define Len_name 16 /* suponiendo que la longitud del nombre de archivo
no excederá 16 bytes*/
#define event_size (sizeOf (struct inotify_event)) /*tamaño de un evento* /
#define buf_len (max_events * (event_size + len_name))
/*Buffer para almacenar los datos de los eventos*/
int fd, wd;
void sig_handler (int sig)
/* Paso 5. Elimine el descriptor de reloj y cierre la instancia de inotify*/
inotify_rm_watch (fd, wd);
cerrar (fd);
salida (0);

int main (int argc, char ** argv)
char *path_to_be_watched;
señal (Sigint, Sig_handler);
path_to_be_watched = argv [1];
/* Paso 1. Inicializar inotify */
fd = inotify_init ();
if (fcntl (fd, f_setfl, o_nonblock) < 0) // error checking for fcntl
salida (2);
/* Paso 2. Agregar reloj */
wd = inotify_add_watch (fd, path_to_be_watched, in_modify | in_create | in_delete);
if (wd ==-1)
printf ("No se pudo ver: %s \ n", path_to_be_watched);

demás
printf ("observar: %s \ n", path_to_be_watched);

mientras (1)
int i = 0, longitud;
Char Buffer [buf_len];
/* Paso 3. Leer Buffer*/
longitud = leer (fd, buffer, buf_len);
/* Etapa 4. Procesar los eventos que han ocurrido */
mientras yostruct inotify_event *event = (struct inotify_event *) & buffer [i];
if (event-> len)
if (event-> mask & in_create)
if (event-> Mask & in_isdir)
printf ("Se creó el directorio %s.\ n ", evento-> nombre);

demás
printf ("Se creó el archivo %s.\ n ", evento-> nombre);


else if (event-> mask & in_delete)
if (event-> Mask & in_isdir)
printf ("El directorio %s se eliminó.\ n ", evento-> nombre);

demás
printf ("El archivo %s se eliminó.\ n ", evento-> nombre);


else if (event-> mask & in_modify)
if (event-> Mask & in_isdir)
printf ("El directorio %s se modificó.\ n ", evento-> nombre);

demás
printf ("El archivo %s se modificó.\ n ", evento-> nombre);



i + = event_size + event-> len;


Producción:

Para ejecutar el programa y ver la salida, primero debemos abrir dos terminales. Se utiliza una terminal para ejecutar el programa Inotificar.C. En el segundo terminal, vamos al camino que está siendo observado por el inotify.C. Si creamos algún directorio o archivo, modificamos cualquier archivo o eliminamos cualquier directorio o archivo, los veremos en el primer terminal.

En el Inotificar.C Ejemplo, el unistd.H El archivo de encabezado se utiliza para el leer() y cerca() función, el stdlib.H El archivo de encabezado se utiliza para el salida() función, el señal.H El archivo de encabezado se utiliza para el señal() función y el Sig_int macro (consulte el manejo de la señal para más detalles) y el fcntl.H El archivo de encabezado se utiliza para el fcntl () función.

Declaramos fd (instancia inotify) y WD (Mira el descriptor) como variables globales para que estas variables sean accesibles desde todas las funciones.

El fcntl () La función se usa para que cuando leemos usando el fd Descriptor, el hilo no se bloqueará.

A continuación, agregamos un reloj con el inotify_add_watch () función. Aquí, pasamos FD, el camino del directorio que se verá y la máscara. Puede pasar la máscara de los eventos que desea monitorear utilizando bitwise-o.

Ahora, lee el búfer. La información sobre uno o más eventos se almacena en el búfer. Puede procesar todos los eventos uno por uno usando el bucle. Puede verificar el evento-> máscara para saber qué tipo de eventos han sucedido.

Usamos un bucle infinito mientras verificamos continuamente cuándo ocurrieron los eventos. Si no han sucedido eventos, la función Read () regresa con un 0. El valor de retorno de la función Read () se almacena en la variable de longitud. Cuando el valor de la variable de longitud es mayor que cero, se han producido uno o más eventos.

Usamos el Sig_int señal (presione CTRL+C) para salir del proceso. Cuando presionas Ctrl+C, el Sig_handler () se llama función (ver manejo de señal para más detalles). Esta función elimina el descriptor de reloj, cierra la instancia inotify fd, y sale del programa.

Conclusión

Puede usar la API inotify en sus propias aplicaciones para monitoreo, depuración, automatización y más, a su manera. Aquí, hemos visto el flujo de ejecución de la API inotify.