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 working bit bashed driver solved the root cause of the problem I was trying to address here.
Aside: The nature of I2C is that each byte read or written by the master is acknowledged by the device on the other end of the wire (slave) - the pauses improving things encourage me to think of the driver as working asynchronously - something that I can't reconcile with how the bus works. Anyhoo ...
FILE * fd = fopen("filename","r+");
... // do read and writes
int fd = open("filename",O_RDWR);
You have two choices:
fileno() to obtain the file descriptor associated with the
stdio stream pointer
<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
write() functions instead (based on your later reply):
int fd = open("/dev/i2c", O_RDWR); ioctl(fd, IOCTL_COMMAND, args); write(fd, buf, length);