Как вы можете очистить запись, используя дескриптор файла?
Оказывается, все это непонимание open() и fopen() проистекает из багги I2C-драйвера в ядре Linux 2.6.14 на ARM. Бэкпординг драйвера с битым рабочим битком решил основную причину проблемы, которую я пытался решить здесь.
Я пытаюсь выяснить проблему с драйвером последовательного устройства в Linux (I2C). Похоже, что добавив временные ОС паузы (спит) между записью и чтением на устройстве, все работает... (намного) лучше.
Кроме того, характер I2C заключается в том, что каждый байт, считанный или записанный мастером, подтверждается устройством на другом конце провода (ведомый) - паузы, улучшающие ситуацию, побуждают меня думать о том, что драйвер работает асинхронно - что я не могу смириться с тем, как работает автобус. Anyhoo...
Я бы либо хотел, чтобы флеш был уверен в записи (вместо использования фиксированной паузы продолжительности), или каким-то образом проверили, что транзакция записи/чтения имеет завершено в многопоточном режиме.
Проблема с использованием fflush(fd);
заключается в том, что он требует, чтобы 'fd' был указателем потока (а не файловым дескриптором), т.е.
FILE * fd = fopen("filename","r+");
... // do read and writes
fflush(fd);
Моя проблема в том, что мне требуется использовать ioctl()
, который не использует указатель потока. то есть.
int fd = open("filename",O_RDWR);
ioctl(fd,...);
Предложения?
Ответы
Ответ 1
У вас есть два варианта:
-
Используйте fileno()
для получения файлового дескриптора, связанного с указателем потока stdio
-
Не используйте <stdio.h>
вообще, так что вам не нужно беспокоиться о флеше - все записи сразу перейдут на устройство, а для символьных устройств вызов write()
не будет даже вернуться до тех пор, пока IO нижнего уровня не завершится (теоретически).
Для IO уровня устройства я бы сказал, что довольно редко использовать stdio
. Я настоятельно рекомендую использовать более низкоуровневые open()
, read()
и write()
функции (на основе вашего более позднего ответа):
int fd = open("/dev/i2c", O_RDWR);
ioctl(fd, IOCTL_COMMAND, args);
write(fd, buf, length);
Ответ 2
Я думаю, что то, что вы ищете, может быть
int fsync(int fd);
или
int fdatasync(int fd);
fsync
очистит файл от буфера ядра до диска. fdatasync
также будет выполняться, за исключением метаданных.
Ответ 3
fflush()
только очищает буферизацию, добавленную уровнем stdio fopen()
, как управляемый объектом FILE *
. Основной файл, как видно из ядра, не буферизуется на этом уровне. Это означает, что записи, которые обходят слой FILE *
, используя fileno()
и raw write()
, также не буферизуются таким образом, что fflush()
будет скрываться.
Как указывали другие, попробуйте не смешивать два. Если вам нужно использовать "сырые" функции ввода-вывода, такие как ioctl()
, а затем open()
непосредственно файл, без, используя fopen<()
и друзей из stdio.
Ответ 4
Похоже, что вы ищете функцию fsync() (или fdatasync()?), или вы можете использовать флаг O_SYNC в вызове open().
Ответ 5
Если вы хотите перейти в другую сторону (связать FILE * с существующим файловым дескриптором), используйте fdopen():
FDOPEN(P)
NAME
fdopen - associate a stream with a file descriptor
SYNOPSIS
#include <stdio.h>
FILE *fdopen(int fildes, const char *mode);
Ответ 6
Вы пытались отключить буферизацию?
setvbuf(fd, NULL, _IONBF, 0);