#c #memcpy #fuse
#c #memcpy #предохранитель
Вопрос:
Я пишу файловые операции для программы FUSE. Однако у меня возникли некоторые проблемы с file_operations.write
функцией. Проблема, с которой я сталкиваюсь, заключается в:
- Попытка записать пустой файл (открыть в vim и сразу сохранить, поэтому написано 0L 0C), он вообще не записывается и оставляет содержимое нетронутым, поэтому, если файл ранее содержал «текст», он все равно будет содержать «текст».
- Попытка записать большой файл (около 10 КБ) приведет к созданию пустого файла.
Для части пустых файлов. Я уже пробовал несколько вещей, таких как проверка, меньше ли размер 1 (который, как я предполагал, является размером, заданным при записи пустых файлов) и просто сделал char*
точку одним ''
байтом.
Я также пробовал отдельные случаи if и обнаружил, что размер равен -2 по какой-то странной причине, однако, когда я попытался записать пустой файл, как описано выше, когда найдено -2, это все равно не сработало.
Для файлов слишком большого размера я понятия не имею.
static int fs_write(const char* path, const char* buffer, size_t size, off_t offset, struct fuse_file_info* ffinfo) {
// Find the associated file_t* and dir_t* to the file.
file_t* file = get_file_from_path(path);
dir_t* directories = get_parents_from_path(path);
// The contents of a file are stored in a char* so I have to realloc
// the previous pointer and memcpy the new contents from buffer to
// file->contents, using size and offset as an indication of how large
// to make the realloc and what to copy over.
char* file_contents_new = (char*) realloc(file->contents, (size 1) * sizeof(char));
// realloc failed
if (file_contents_new == NULL)
return -ENOMEM;
// point the previous file contents pointer to the newly allocated section.
file->contents = file_contents_new;
// Copy from buffer offset to the file contents with the size provided.
memcpy(file->contents, buffer offset, size);
*(file->contents size) = ''; // Append NULL char to end file string.
return size;
}
Здесь я ожидаю получить надлежащую обработку и для пустых и больших файлов, потому что:
- размер 0 (который имеет наибольший смысл для меня) будет перераспределен на символ * размером 0 1 (1 для нулевого байта)
- затем укажите file-> contents на него
- затем скопируйте 0 байт из буфера в файл-> содержимое
- запишите
''
символ в конец файла-> содержимое (по размеру, который являетсяlength of the realloc'ed block - 1
); в этом случае записывает''
с 0-м индексом. - верните записанный размер, в данном случае 0.
Однако vim закрывается, сообщая, что он записал 0L 0C в файл, но файл не был затронут.
Большие файлы:
- функция будет вызывать write несколько раз, чтобы записывать фрагменты в файл
- Однако записывается пустой файл.
Комментарии:
1. Ваш
realloc
вызов кажется странным, разве это не должно быть что-то вродеrealloc(file->contents, size file->size);
?2. @Mathieu Я пробовал
realloc(file->contents, strlen(file->contents) use_size 1);
, это ничего не изменило. Я предположил, чтоsize
это новый размер буфера. Вместо добавления данных, он перезапишет данные. итак, если бы я хотел записать «test» в файл, он был бы перераспределен до символа * размером 4 1, чтобы в основном сгенерировать «test 0». поэтому я перераспределяю, просто4 1 * sizeof(char)
пишу «test», затем добавляю нулевой байт.3. Эта функция каждый раз перезаписывает содержимое файла новым значением. Вам нужно показать, как вы вызываете эту функцию.
Ответ №1:
Я не использую FUSE, но я думаю, что вы плохо используете аргументы (см.https://github.com/libfuse/libfuse/blob/master/example/passthrough.c )
buffer
: данные для записиsize
: размер буфераoffset
: позиция для записи в файл.
Итак, ваш код выглядит как:
static int fs_write(const char* path, const char* buffer, size_t size, off_t offset, struct fuse_file_info* ffinfo)
{
// Find the associated file_t* and dir_t* to the file.
file_t* file = get_file_from_path(path);
dir_t* directories = get_parents_from_path(path);
/* realloc to store data. Note the 1 to store the final */
char* file_contents_new = realloc(file->contents, file->size size 1);
// realloc failed
if (file_contents_new == NULL)
return -ENOMEM;
// point the previous file contents pointer to the newly allocated section.
file->contents = file_contents_new;
/* update size too, without to 1 to prevent adding one at each write call */
file->size = file->size size;
// Copy buffer to the file taking offset into account
memcpy(file->contents offset, buffer, size);
/* Append NULL char to end file string. */
*(file->contents file->size) = '';
return size;
}
Комментарии:
1. Проблема, вероятно, заключалась в источнике, который я использовал, чтобы выяснить, что означает «смещение». Они описали это как
- offset: offset from where chunk should start
, я интерпретировал это как смещение в буфере. но имеет смысл использовать смещение в файле.2. Однако это все еще не исправлено. Возможно ли, что запись завершается ошибкой, потому что функция чтения также неверна? Или это не должно влиять на запись.