fstat getting file size zero - c

File is there and having json data inside it. I want to know length of file.but when i try below code it but size remains 0.
int file_contentl_Len = 0;
int fd_0 ;
fd_0 = open(FILE_PATH_CONFIG_0, O_WRONLY | O_TRUNC | O_CREAT, 0644);
if(fd_0 < 0)
{
printf("\r\nError opening Config file %s: %s\n",FILE_PATH_CONFIG_0, strerror(errno));
return -1;
}
struct stat buf;
fstat(fd_0, &buf);
file_contentl_Len = buf.st_size;
printf("\r\nConfig file %s content length: %d\r\n", FILE_PATH_CONFIG_0, file_contentl_Len);

You opened the file for writing with truncation, creating it if necessary — O_WRONLY | O_TRUNC | O_CREAT.
The size of zero tells you the truncation worked, or the file was created empty.
If you wanted to read what was in the file, use O_RDONLY instead. Or use O_RDWR and think carefully about whether to allow the file to be created.

Related

How to check if a file exist, delete content or create it

i would like to check if a file exist, delete content if it exists or create it if not.
I have tried :
open("screenshot.bmp", O_CREAT | O_RDWR | O_TRUNC);
But the file don't update if it already exists, if it doesn't the file is created correctly.
if ((fd = open("screenshot.bmp", O_CREAT, S_IRWXU)) > -1)
return (-1);
close (fd);
if ((fd = open("screenshot.bmp", O_TRUNC)) > -1)
return (-1);
But the file looks corrupted/empty after that (it should be filled by the rest of my code)
I also tried other ways.
Thanks for help !
Try using FILE *fd = fopen("screenshot.bmp", "w");
Accorsing to tutorialspoint:
FILE *fopen(const char *filename, const char *mode)
"w"
Creates an empty file for writing. If a file with the same name already exists, its content is erased and the file is considered as a new empty file.
Update:
OP says fopen(...) isn't allowed, but...
According to the docs you can achieve the same result as the fopen(...) call using:
open (filename, O_WRONLY | O_CREAT | O_TRUNC, mode)
For example (from the docs):
The following example opens the file /tmp/file, either by creating it (if it does not already exist), or by truncating its length to 0 (if it does exist). In the former case, if the call creates a new file, the access permission bits in the file mode of the file are set to permit reading and writing by the owner, and to permit reading only by group members and others.
If the call to open() is successful, the file is opened for writing.
#include <fcntl.h>
...
int fd;
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
char *filename = "/tmp/file";
...
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
...

Copy program: File Permission Denied

My following program, which copies a file, won't allow me to copy files because of "permission denied". However, I gave it permissions.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
int fdinput, fdoutput; //file pointers
char arrbuf[5000]; //size of what can be read in file
ssize_t bytesR, bytesW;//number of what input returns
mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH |S_IXOTH ;
fdinput = open(argv[1], O_RDONLY); //pointing to read file
fdoutput = open(argv[2], O_WRONLY);//pointing to write file
if(fdinput == -1){
perror("the source file cant be opened");
return 1;
}
if(fdoutput == -1){
perror("the written file cant be opened");
return 2;
}
while((bytesR = read(fdinput, arrbuf, sizeof arrbuf)) > 0){
bytesW = write(fdoutput, arrbuf, (ssize_t) bytesR);
}
close(fdinput);
close(fdoutput);
return 0;
}
The problem is in the call to the system call open() for the destination file (i.e.: the file to be created as a result of the copy):
fdoutput = open(argv[2], O_WRONLY);
Making possible the creation of the destination file
First, the call above to open() opens the file with the given name by argv[2], only if it already exits. Otherwise, the system call fails (errno is set to ENOENT) and perror() produces:
the written file cant be opened: No such file or directory
In order to create the file if it does not exist yet, the O_CREAT flag has to ORed together with O_WRONLY.
Truncating an already existing destination file
If the destination file already exist you surely want to truncate the length of that already existing file to zero at the moment of open()ing. That can by achieved by ORing the O_TRUNC flag together with the other flags.
Providing the permissions for the file to be created
Let's look at the open() system call's prototype:
int open(const char *path, int oflag, ...);
The ... at the end is to specify a kind of optional argument. That argument is used by open() only when a new file is being created. It provides the mode bits to be applied for the file to be created. This is not exactly the permissions for the file to be created, but it is strongly related to them (for more info see: file mode creation mask).
You created mode of type mode_t but just forgot to pass it to open().
With all exposed above in mind, your call should look like:
fdoutput = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, mode);

Using open(), read() and write() system calls to copy a file

I'm having trouble using read(), write(), and open() to copy a file into a new directory. I'm able to create a new file with open() and I'm able to write to the terminal with write() but I was under the assumption that if I passed my int file descriptor from open to write, write would write to the specified file.
In addition to this, once I open a file the permissions are all funky and I can only open it as root. Each time I create a file, it's completely empty but I can see the entire file I just read be printed out in the terminal.
I've read through the man files for each system call but I'm still not grasping what the issue is here.
Here's my code:
void *scanFile( s_request *request )
{
//TODO Print out all struct variables.
pthread_mutex_lock(&mutex);
int readFileReference;
int writeFileReference;
int bufferSize = request->bufferSize;
int numberOfBytesRead = bufferSize;
int *buffer[bufferSize];
if ((readFileReference = open(request->file, O_RDONLY)) == -1)
{
printf("Failed to open file. Aborting.\n");
exit(EXIT_FAILURE);
}
if ((writeFileReference = open("newfile.txt", O_CREAT | O_APPEND | O_RDWR) == -1))
{
printf("Failed to open write file. Aborting.\n");
exit(EXIT_FAILURE);
}
while ((read(readFileReference, buffer, numberOfBytesRead)) != 0)
{
write(writeFileReference, buffer, bufferSize);
bzero(buffer, bufferSize);
}
pthread_mutex_unlock(&mutex);
}
Fixed the issue:
Updated code:
void *scanFile( s_request *request )
{
//TODO Print out all struct variables.
pthread_mutex_lock(&mutex);
int readFileReference;
int writeFileReference;
int bufferSize = request->bufferSize;
int numberOfBytesRead = bufferSize;
int *buffer[bufferSize];
if ((readFileReference = open(request->file, O_RDONLY)) == -1)
{
printf("Failed to open file. Aborting.\n");
exit(EXIT_FAILURE);
}
if ((writeFileReference = open("newfile.txt", O_CREAT | O_WRONLY, 0777)) == -1)
{
printf("Failed to open write file. Aborting.\n");
exit(EXIT_FAILURE);
}
while ((read(readFileReference, buffer, numberOfBytesRead)) != 0)
{
write(writeFileReference, buffer, bufferSize);
bzero(buffer, bufferSize);
}
close(writeFileReference);
close(readFileReference);
pthread_mutex_unlock(&mutex);
}
if ((writeFileReference = open("newfile.txt", O_CREAT | O_APPEND | O_RDWR) == -1))
You've got the parentheses wrong on this line. (It's correct on the readFileReference line.) What you want is:
if ((writeFileReference = open("newfile.txt", O_CREAT | O_APPEND | O_RDWR)) == -1)
^^^ ^^^
Your original version of that line was calling open(), performing a comparison to -1, then assigning the result of that comparison to writeFileReference.
Additionally:
As noted by Zan Lynx in a comment, you need to pass a permissions value to open() when creating a file. 0666 is typically correct -- it'll create the file as readable/writable. (It's modified by the process umask, so it'll end up creating the file as 0644 under a typical configuration.)
You need to save the return value from read somewhere and pass that as the third argument to write (instead of bufferSize). Otherwise, your program will write more bytes than were read, e.g. when copying small files.
Technically, you should be checking the return value from write(). Just like read(), it's not guaranteed to complete a full write every time it's called. (In practice, when working with regular files, it will always either complete the write or return an error, but there are some esoteric situations where this may not be the case.)
You don't need to bzero() the buffer after writing from it.

C: cannot create or append to a file

I am trying to open a file for both read and write operations.
If the file is already there, it should append. (I want to be able to write to it, and maybe read from it later)
However, if the file is there, I cannot append to it (I get a permission denied: cannot create file)
int main()
{
int file;
file = open("redirect.txt", O_RDWR | O_APPEND | O_CREAT, 777);
if(!(file == -1)) //edited per comment
{
close(file);
}
else
perror("File could not be created\n");
return 0;
}
This only opens a new file if it does not exist, but does not append to an existing file if it does exist.
You're forgetting that the mode parameter to open() must be in octal. This will work:
file = open("redirect.txt", O_RDWR | O_APPEND | O_CREAT, 0777);
As zwol also mentioned, it's generally a good idea to create files with 0666 (since they don't need to be executable).

C How to stop file from being overwritten

Currently the the file gets created and overwritten. I am trying to get it so that if the file already exists it just exits the program. open must be used.
if ((dest = open(argv[2], O_WRONLY | O_CREAT, 0644)) == -1) {
printf("Error File %s exists", argv[2]);
return 3;
}
Just use O_EXCL:
O_EXCL Ensure that this call creates the file: if this flag is
specified in conjunction with O_CREAT, and pathname already exists,
then open() will fail.

Resources