clow-level-io

writing files at a low level


I was reading the GNU C PROGRAMMING TUTORIAL online, and get some confusion on the code example for low level read & write.

The code is as below:

#include <stdio.h>
#include <fcntl.h>

int main()
{
  char my_write_str[] = "1234567890";
  char my_read_str[100];
  char my_filename[] = "snazzyjazz.txt";
  int my_file_descriptor, close_err;

  /* Open the file.  Clobber it if it exists. */
  my_file_descriptor = open (my_filename, O_RDWR | O_CREAT | O_TRUNC);

 /* Write 10 bytes of data and make sure it's written */
 write (my_file_descriptor, (void *) my_write_str, 10);
 fsync (my_file_descriptor);

 /* Seek the beginning of the file */
 lseek (my_file_descriptor, 0, SEEK_SET);

 /* Read 10 bytes of data */
 read (my_file_descriptor, (void *) my_read_str, 10);

 /* Terminate the data we've read with a null character */
 my_read_str[10] = '\0';

 printf ("String read = %s.\n", my_read_str);

 close (my_file_descriptor);

 return 0;
}

I compiled the code with gcc without issue. And run the first time, it is also ok. Output as below:

$ ./lowLevelWrite
String read = 1234567890.

The problem comes when i run the program second time:

$ ./lowLevelWrite
String read = .

Seems the code fails to write the string "1234567890" to the file second time. As we know from the GNU C manual, O_RDWR | O_CREAT | O_TRUNC these flag should allow us to truncate the file to 0 every time and then write to the file. I am not sure why it fails from second time execution.

Can anybody help me out of this confusion?


Solution

  • When you're creating a file with open() you need to pass a third argument, the permission modes:

    my_file_descriptor = open (my_filename, O_RDWR | O_CREAT | O_TRUNC, 0664);
    

    0664 is the permissions rw-rw-r--: readable and writable by the owner and group, readable by everyone else. These permissions will be further masked by your umask.

    Since you didn't pass this argument, open() used random stack garbage, and this probably didn't include write permission. So you couldn't open the file for writing when it already exists.