La funzione inotify nell'OS Unix, monitora i cambiamenti avvenuti nel filesystem (cancellazione, modifiche, creazione, ...) di file e cartelle.
Sapete come lavora alla base questa funzione??
La stavo riproducendo utilizzando una struttura ad albero di directory, con tutti gli attributi e un puntatore ad un array di File.
Una volta creata questa struttura nel main thread a partire da un percorso da me specificato, faccio partire un thread che effettua un confronto ogni tot secondi con il filesystem e il mio albero di directory, modificandolo in caso di cambiamenti nel filesystem e notificando gli aggiornamenti.
Su 20 Gb di dati, la struttura la crea in 9 secondi, ma la fase di aggiornamento non è molto veloce, dato che parto dalla directory root nell'albero delle directory e ricorsivamente controllo che il path di quella cartella ancora sia presente nel filesystem, se esiste allora confronto i file contenuti e permessi, ultima modifica, timestamp ecc...
Qualcuno mi potrebbe suggerire qualche altra strategia?
Buon weekend e grazie per qualsiasi tipo di consiglio.
Posto un pò di codice per chi possa essere interessato.
=== Struct ===
struct directory{
char* path;
long size;
struct directory** subDir;
int num_subdir;
struct file_info** files;
int num_files;
};
struct file_info{
char* path;
long size;
char* rights;
double timestamp;
};
=== InitTree ===
Directory* initTree(char* path, Directory* root, time_t t_server)
{
struct dirent *in_file;
DIR *fd;
fd = opendir(path);
if (fd == NULL) {
perror("File not found");
return NULL;
}
setDirectory(root,path);
while (in_file = readdir(fd)) {
if (!strcmp(in_file->d_name, ".")) continue;
if (!strcmp(in_file->d_name, "..")) continue;
size_t length = strlen(in_file->d_name) + strlen(path) + 2;
char *name = (char*)calloc(length , sizeof(char));
strncpy(name, path, strlen(path));
strncat(name, "/", 1);
strncat(name, in_file->d_name, strlen(in_file->d_name));
struct stat buf;
if (lstat(name, &buf) < 0) {
perror("Error: lstat\n");
return NULL;
};
char *perm = calloc(3,sizeof(char));
perm[0] = buf.st_mode & S_IEXEC ? 'x' : '-'; //x
perm[1] = buf.st_mode & S_IREAD ? 'r' : '-'; //r
perm[2] = buf.st_mode & S_IWRITE ? 'w' : '-'; //w
if( S_ISDIR(buf.st_mode) && in_file->d_name[0] != '.')
{
Directory* d = (Directory*)malloc(sizeof(Directory)*1);
addSubDir(root,d);
initTree(name, d, t_server);
root->size+=d->size;
}
else
{
FileInfo* fileInfo = setFileInfo(name,buf,perm,t_server);
root->size += fileInfo->size;
addFile(root, fileInfo);
}
free(perm);
free(name);
}
closedir(fd);
return root;
}