It turns out this whole misunderstanding of the open() versus fopen() stems from a buggy I2C driver in the Linux 2.6.14 kernel on an ARM. Backporting a worki
You have two choices:
Use fileno()
to obtain the file descriptor associated with the stdio
stream pointer
Don't use <stdio.h>
at all, that way you don't need to worry about flush either - all writes will go to the device immediately, and for character devices the write()
call won't even return until the lower-level IO has completed (in theory).
For device-level IO I'd say it's pretty unusual to use stdio
. I'd strongly recommend using the lower-level open()
, read()
and write()
functions instead (based on your later reply):
int fd = open("/dev/i2c", O_RDWR);
ioctl(fd, IOCTL_COMMAND, args);
write(fd, buf, length);
It sounds like what you are looking for is the fsync() function (or fdatasync()?), or you could use the O_SYNC flag in your open() call.
fflush()
only flushes the buffering added by the stdio fopen()
layer, as managed by the FILE *
object. The underlying file itself, as seen by the kernel, is not buffered at this level. This means that writes that bypass the FILE *
layer, using fileno()
and a raw write()
, are also not buffered in a way that fflush()
would flush.
As others have pointed out, try not mixing the two. If you need to use "raw" I/O functions such as ioctl()
, then open()
the file yourself directly, without using fopen<()
and friends from stdio.
Have you tried disabling buffering?
setvbuf(fd, NULL, _IONBF, 0);
If you want to go the other way round (associate FILE* with existing file descriptor), use fdopen() :
FDOPEN(P)
NAME
fdopen - associate a stream with a file descriptor
SYNOPSIS
#include <stdio.h>
FILE *fdopen(int fildes, const char *mode);
I think what you are looking for may be
int fsync(int fd);
or
int fdatasync(int fd);
fsync
will flush the file from kernel buffer to the disk. fdatasync
will also do except for the meta data.