I first open the file with read write access then i write some stuff in it but when i open it again using read only mode the fd = -1 so my if statement doesn't run, can some please explain why it doesn't open again in read only mode?
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
int main()
{
int fd, i;
char buffer[80];
char str[50], ch;
printf("Enter a string: ");
i = 0;
ch = getchar();
while(ch != '\n')
{
str[i] = ch;
i ;
ch = getchar();
}
str[i] = '\0';
fd = open("Test01.txt", O_RDWR | O_CREAT | O_TRUNC);
printf("fd = %d", fd);
if(fd != -1)
{
printf("\n Test01.txt opened with read write access\n");
write(fd, str, sizeof(str));
lseek(fd, 0, SEEK_SET);
close(fd);
}
fd = open("Test01.txt", O_RDONLY);
printf("fd = %d", fd);
if(fd != -1)
{
printf("\n Test01.txt opened with read only access\n");
read(fd, buffer, sizeof(str));
printf("\n %s was written to my file\n", buffer);
close(fd);
}
return 0;
}
CodePudding user response:
This line,
fd = open("Test01.txt", O_RDWR | O_CREAT | O_TRUNC);
is missing the default access mode, the third parameter which is needed whenever O_CREAT
is used. This is a bug, and causes the C library to use some random number instead, often 0, which means "no access whatsoever to anybody".
That includes the user who created the file. Therefore, any attempts to open the file will fail.
If you fix this, say
fd = open("Test01.txt", O_RDWR | O_CREAT | O_TRUNC, 0666);
where 0666
is equal to S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
, or "read and write access to everybody". This will be modifed by the current umask
, which lets users decide what permissions their files get by default, by clearing typically write access from others (S_IWOTH = 0002
).
Simply put, 0666
is almost always used here. The exception is when creating scripts or executables, when 0777
is used, and when the data is assumed to be private, in which case 0660
(access only to owner user and groupor
0600` (access only to owner user).
CodePudding user response:
fd = open("Test01.txt", O_RDWR | O_CREAT | O_TRUNC);
is incomplete.
The full specification of open()
is (note the bolded portion):
SYNOPSIS
#include <sys/stat.h> #include <fcntl.h> int open(const char *path, int oflag, ...);
...
DESCRIPTION
The
open()
function shall establish the connection between a file and a file descriptor. It shall create an open file description that refers to a file and a file descriptor that refers to that open file description. The file descriptor is used by other I/O functions to refer to that file. Thepath
argument points to a pathname naming the file....
O_CREAT
If the file exists, this flag has no effect except as noted underO_EXCL
below. Otherwise, ifO_DIRECTORY
is not set the file shall be created as a regular file; the user ID of the file shall be set to the effective user ID of the process; the group ID of the file shall be set to the group ID of the file's parent directory or to the effective group ID of the process; and the access permission bits (see<sys/stat.h>
) of the file mode shall be set to the value of the argument following theoflag
argument taken as typemode_t
modified as follows ...
You need to specify the file mode when you create a file with open()
:
fd = open("Test01.txt", O_RDWR | O_CREAT | O_TRUNC, 0644 );