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?
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.