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?
