[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [OT] C e inotify



Il 22 luglio 2016 17:32, Alessandro Baggi <alessandro.baggi@gmail.com>
ha scritto:
> La modifica del file, modifica attributi e spostamento vengono rilevati
> mentre la cancellazione (con rm, unlink) non viene rilevato con evento
> IN_DELETE_SELF ma IN_ATTRIB.
[...]
> Dato che su questo specifico file è aperto un file descriptor, e avendo
> letto che il delete_self non viene rilevato con un fd aperto sul file, ho
> provato anche a non aprire il file in lettura (per altre operazioni) senza
> esito positivo.

Non riesco a riprodurre il tuo problema, quello che vedo io è questo:
$ touch file
$ ./a.out file
$ rm file
file 00000004: IN_ATTRIB
file 00000400: IN_DELETE_SELF
file 00008000: IN_IGNORED
Cioè, vedo anche io un IN_ATTRIB, ma seguito come mi aspetto da IN_DELETE_SELF
e IN_IGNORED. Non è che in uscita dalla read() leggi solo il primo e
scarti gli altri?

> Ho notato anche che la modifica del file con un editor (nel mio caso vi) non
> riporta un evento modify ma un move e un attrib (forse perche vi crea un
> file in /tmp e poi lo sposta sul'originale?)
Quasi. Al momento di salvare il file, vim lo rinomina in 'nomefile~', crea un
nuovo file 'nomefile' e se tutto va a buon fine elimina 'nomefile~'.
Per questo motivo, non puoi aspettarti un IN_MODIFY perchè una volta che vim
ha fatto rename(), il tuo processo continuerà ad osservare 'nomefile~' che non
verrà toccato se non per fare unlink() alla fine.
La sequenza che vedo salvando un file con vim è questa:
$ ./a.out file
file 00000800: IN_MOVE_SELF
file 00000004: IN_ATTRIB
file 00000400: IN_DELETE_SELF
file 00008000: IN_IGNORED
cioè il risultato di rename() e unlink()

Ti allego il file sorgente con cui ho fatto le prove: vedi sulla tua macchina
come si comporta.

Ciao
Mattia
#include <errno.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[])
{
	int fd, wd;
	char buf[4096]
		__attribute__ ((aligned(__alignof__(struct inotify_event))));
	const struct inotify_event *event;
	ssize_t len;
	char *ptr;

	if (argc < 2) {
		fprintf(stderr, "Usage: %s PATH\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	fd  = inotify_init();
	if (fd == -1) {
		fprintf(stderr, "inotify_init failed: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}

	wd = inotify_add_watch(fd, argv[1], IN_ATTRIB | IN_DELETE_SELF | IN_MODIFY | IN_MOVE_SELF);
	if (wd == -1) {
		fprintf(stderr, "Cannot watch %s: %s\n", argv[1], strerror(errno));
		exit(EXIT_FAILURE);
	}

	while(1) {
		len = read(fd, buf, sizeof buf);
		if (len == -1) {
			fprintf(stderr, "read failed: %s\n", strerror(errno));
			exit(EXIT_FAILURE);
		}

		for (ptr = buf; ptr < buf + len;
				ptr += sizeof(struct inotify_event) + event->len) {
			event = (const struct inotify_event *) ptr;

			printf("%s %08X:", argv[1], event->mask);
			if (event->mask & IN_ATTRIB)
				printf(" IN_ATTRIB ");
			if (event->mask & IN_DELETE_SELF)
				printf(" IN_DELETE_SELF ");
			if (event->mask & IN_MODIFY)
				printf(" IN_MODIFY ");
			if (event->mask & IN_MOVE_SELF)
				printf(" IN_MOVE_SELF ");
			if (event->mask & IN_IGNORED)
				printf(" IN_IGNORED ");
			printf("\n");
		}
	}

	close(fd);
	exit(EXIT_SUCCESS);
}

Reply to: