0

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?

phuclv
  • 37,963
  • 15
  • 156
  • 475
Marvin Zhang
  • 169
  • 1
  • 8
  • 1
    Most likely, the file is created without enough permissions that would allow you to overwrite the file if it already exists. Check the return code from open, and I bet that you'll see it's returning -1 instead of a valid file handle. – bruceg Jan 25 '19 at 01:09
  • 1
    If the tutorial you are using really omits all error handling, you should stop using it immediately. Such a tutorial is irresponsible. – Roland Illig Jan 25 '19 at 02:05
  • 2
    `ls -l snazzyjazz.txt` would be quite informative as to why this is occurring. – David C. Rankin Jan 25 '19 at 02:32
  • Thanks so much for your help on this, my dear friend. I love stackoverflow, all question can find a answer here. – Marvin Zhang Jan 25 '19 at 12:05

1 Answers1

5

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.

Barmar
  • 741,623
  • 53
  • 500
  • 612