I need to understand some things about direct I/O in C. I have a toy code that uses direct I/O to write a character array and it works just fine:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#define MSG_SIZE 4500
#define BLOCK_SIZE 4096
int main(int argc, char **argv) {
char thefile[64];
int fd;
int write_success, bytes_to_write, block_size=BLOCK_SIZE;
// set array size to some multiple of BLOCKSIZE:
bytes_to_write = ((MSG_SIZE + block_size - 1)/block_size)*block_size;
char message[bytes_to_write] __attribute__ ((aligned(BLOCKSIZE)));
memset(message, 0, bytes_to_write);
sprintf(message,"The curfew tolls the knell of parting day");
printf("%s\n", message);
sprintf(thefile, "diotestfile.dat");
if ((fd = open(thefile,O_DIRECT | O_RDWR | O_CREAT, S_IRWXU)) == -1) {
printf("error opening file\n");
exit(1);
}
printf("%s\n", strerror(errno));
write_success = write(fd, message, bytes_to_write);
printf("write succes? %s\n", strerror(errno));
close(fd);
}
A cat
of the output file gives the message. But I need to be able to do this with a pointer instead an array. If I redefine message
as a pointer, that is, I replace
char message[bytes_to_write] __attribute__ ((aligned(BLOCKSIZE)));
memset(message, 0, bytes_to_write);
with
char *__attribute__ ((aligned(BLOCKSIZE))) message;
message = (char *__attribute__ ((aligned(BLOCKSIZE))))calloc(bytes_to_write, sizeof(char));
then the write
function returns an error of invalid argument
.
The things that haven't worked so far are trying several different alignment sizes, casting message
to a void pointer in write(), and defining message
as
char *__attribute__ ((aligned(BLOCKSIZE))) message;
instead of
char *__attribute__ ((aligned(BLOCKSIZE))) message;
Anyone see what I'm doing wrong?