Deranger Deranger - 6 months ago 9
Linux Question

How To Append To File in C, using Open in O_APPEND Mode on linux?

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.

Answer

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.