Чтение файла после уведомления об изменениях приносит старые значения
У меня есть небольшая проблема с использованием Inotify. Я смотрю файл конфигурации, ищу перезагрузить конфигурации в случае модификации. Модификация обнаружена без проблем, но когда я читаю значения конфигурации, я получаю старые значения. Давай у меня есть
attrib=value
и я изменяю это так
attrib =value1
Затем, когда я снова читаю файл, я получаю "значение" вместо "значение1". И если я снова изменю attrib, при чтении я получу "value1".
Изменить: PATH_FLDR_CONFIG указывает на сам файл.
Вот код:
int length, i = 0;
int inotify;
char buffer[EVENT_BUF_LEN];
if((inotify = inotify_init())<0){
pthread_exit(NULL);
}
inotify_add_watch( inotify, PATH_FLDR_CONFIG , IN_MODIFY );
while (true){
i=0;
length = read( inotify, buffer, EVENT_BUF_LEN );
if (length<0) continue;
while ( i < length ) {
read( inotify, buffer, EVENT_BUF_LEN );
struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
if ( event->mask & IN_MODIFY ) {
readConfigFile();
}
i += EVENT_SIZE + event->len;
}
}
Внутри readConfigFile() я делаю configCreate + различные чтения;
t_config *config_create(char *path) {
t_config *config = malloc(sizeof(t_config));
config->path = strdup(path);
config->properties = dictionary_create();
struct stat stat_file;
stat(path, &stat_file);
FILE* file = NULL;
file = fopen(path, "r");
if (file != NULL) {
char* buffer = calloc(1, stat_file.st_size + 1);
fread(buffer, stat_file.st_size, 1, file);
char** lines = string_split(buffer, "\n");
void add_cofiguration(char *line) {
if (!string_starts_with(line, "#")) {
char** keyAndValue = string_split(line, "=");
dictionary_put(config->properties, keyAndValue[0], keyAndValue[1]);
free(keyAndValue[0]);
free(keyAndValue);
}
}
string_iterate_lines(lines, add_cofiguration);
string_iterate_lines(lines, (void*) free);
free(lines);
free(buffer);
fclose(file);
}
return config;
}
char *config_get_string_value(t_config *self, char *key) {
return dictionary_get(self->properties, key);
}
1 ответ
Я не уверен, но я думаю, что стоит проверить, происходит ли ваше уведомление MODIFY в вашем файле конфигурации или в другом файле.
Многие редакторы записывают изменения в файл, сначала записывая временный файл. Например, если ваш файл был назван config.txt
это может быть написано в письменной форме .config.txt.new#1234
а затем переименовать .config.txt.new#1234
в config.txt
Поскольку inotify находится в каталоге, он может наблюдать создание и изменение временного файла, вызвать уведомление, и ваша программа считывает конфигурацию, прежде чем ее можно будет заменить новым файлом.
Другая возможная проблема заключается в том, что событие MODIFY происходит, как только для файла вызывается write(). Если файл записывается в нескольких вызовах записи, ваша программа может открыть и прочитать файл конфигурации, прежде чем он будет полностью записан. Из вашего примера словарь конфигурации может содержать старые значения, если они не были перезаписаны новым значением.
Вместо события MODIFY попробуйте вместо этого использовать CLOSE_WRITE.