Запись пустого файла не записывает файл, запись слишком большого файла записывает пустой файл - PullRequest
0 голосов
/ 02 апреля 2019

Я пишу файловые операции для FUSE программы.Однако у меня есть некоторые проблемы с функцией file_operations.write.Проблема, с которой я столкнулся:

  • Попытка записи пустого файла (открыть в vim и сразу же сохранить, чтобы он написал 0L 0C записано), он вообще не пишет и оставляет содержимое без изменений,поэтому, если файл ранее содержал «текст», он все равно содержал бы «текст».
  • Попытка записи большого файла (около 10 КБ) приведет к пустому файлу.

Длячасть пустых файлов.Я уже попробовал несколько вещей, таких как проверка, если размер меньше 1, (который я предполагал равным размеру, указанному при записи пустых файлов), и просто указал char* на один '\0' байт.

Я также пытался разделить регистры 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) = '\0'; // Append NULL char to end file string.

    return size;
}

Здесь я ожидаю получить надлежащую обработку для пустых и больших файлов, потому что:

  • размер 0 (что наиболее логично для меня) перераспределить на символ * размером 0 + 1 (1 для нулевого байта)
  • , затем указать файл-> содержимое на него
  • , а затем скопировать 0 байтов избуфер в файл-> содержимое
  • записать символ '\0' в конец файла-> содержимое (в размере, равном length of the realloc'ed block - 1);в этом случае записывает '\0' по 0-му индексу.
  • возвращает записанный размер, в данном случае 0.

Однако vim закрывает сообщение, что оно записало 0L 0C в файл, но файл был нетронут.

Большие файлы:

  • функция будет вызывать запись несколько раз для записи кусками в файл
  • Однако пустой файлнаписано.

1 Ответ

1 голос
/ 02 апреля 2019

Я не буду использовать 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 \0 */
    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) = '\0'; 

    return size;
}
...