This is part of a homework assignment. Well, I couldn't get things working in my homework, so I've pulled a snippet out and started toying with it to figure out what's wrong.
On linux in C I'm trying to open/create a text file, write something to it, close it, open it in read/write and append mode, and then append anything to the end of it (in this example, the string ", dude"). Nothing is being appended, though, but the write method is also not throwing an error. I'm not sure what's up.
Here's the code:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#define BUFFSIZE 4096
int main(){
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
int fd = open("tempfile.txt", O_RDWR | O_CREAT, mode);
char buf[BUFFSIZE] = {'t', 'h', 'y', ' ', 'f', 'a', 'l', 'l'};
size_t n = sizeof(buf);
if(write (fd, buf, n) < 0){
printf("Error in write\n");
printf("%s", strerror(errno));
return 1;
}
close(fd);
int fd2 = open("tempfile.txt", O_RDWR | O_APPEND);
printf("appending dude:\n");
char buf2[6] = {',', ' ', 'd', 'u', 'd', 'e'};
size_t p = sizeof(buf2);
if(write (fd2, buf2, p) < 0){
printf("Error in write\n");
printf("%s", strerror(errno));
return 1;
}
char buf3[BUFFSIZE];
lseek(fd2, 0, SEEK_SET);
if(read (fd2, buf3, BUFFSIZE) < 0){
printf("Error in read\n");
printf("%s", strerror(errno));
return 2;
}
int i;
for (i = 0; i < strlen(buf3); ++i){
printf("%c", buf3[i]);
}
printf("\n");
close(fd2);
return 0;
}
I've tried to eliminate the possibility of it being strictly a permissions issue by messing with a few different combinations, changing the mode variable to S_IRWXU | S_IRWXG | S_IRWXO, passing the mode as a third argument in my second open statement, only opening the file in append mode in the second open statement, passing the append mode as a third argument in the second open statement, etc.
The best I can do is open it in RDWR without the APPEND mode, and then write directly over the existing text... but that's not what I want. And note, I'm aware of things like lseek, but the purpose here is strictly to use the append mode to add text to the end of the file. I don't want to lseek.
Any clues from looking at this? I'm sure there's something obvious I just don't understand.
Many thanks.
You need to use the >> to append text to end of file. It is also useful to redirect and append/add line to end of file on Linux or Unix-like system.
O_APPEND flag forces file pointer to point at the end of file only. so if you do lseek from start of the file, it takes the updated file pointer position as a start of file i.e. end position of old file.
On success, open(), openat(), and creat() return the new file descriptor (a nonnegative integer). On error, -1 is returned and errno is set to indicate the error.
Well, I just tried your program and have an idea of what is going wrong.
Basically, it does work, but with a glitch. When you first write "thy fall" into the file, you use a char
array of 4096
bytes, and you write the entire array into the file. Which means you're writing "thy fall" followed by 4088
characters of random nothing. Later, when you append you're appending at the 4097th position onwards. This is probably not what you intended to do.
If you simply cat
the file you create, you will see the expected output "thy fall, dude". But when you read it entirely in your code, you are only reading 4096
characters. Hence, the ", dude" part is never read, which is why your program never outputs it.
My solution, you need to change your array size. And when reading, read in chunks of say 100 or 1000, until you hit EOF (read
will return -1).
The number of bytes you are trying to write is not correct,
char buf[BUFFSIZE] = {'t', 'h', 'y', ' ', 'f', 'a', 'l', 'l'};
size_t n = sizeof(buf);
if(write (fd, buf, n) < 0){
instead of that you should do
char buf[BUFFSIZE] = {'t', 'h', 'y', ' ', 'f', 'a', 'l', 'l', '\0'};
size_t n = strlen(buf); //use strlen
if(write (fd, buf, n) < 0){
Similarly, do this for other write and reads as well. If you are not writing '\0'
in the file to terminate string, you will not get it when you read data from file.
While reading you should try until entire file is read, ie. you get EOF
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With