Linux C write buffer to file from a while loop issue - c

I have the following function (that dumps a process memory region). If I write to stdout write(STDOUT_FILENO, buf, rd); it outputs the buffer correctly, the problem rises when I want to write the buffer to a file, the file gets written but with the same date over and over:
void dump_region(int fd, off64_t start, off64_t end)
{
char buf[4096];
int fdo;
fdo = open("memdump_log", O_WRONLY | O_CREAT, 0644);
if (fdo == -1) {
fprintf(stderr, "open failed: %m\n");
close(fd);
exit(1);
}
lseek64(fd, start, SEEK_SET);
while(start < end) {
int rd;
rd = read(fd, buf, 4096);
write(fdo, buf, rd);
//write(STDOUT_FILENO, buf, rd);
start += 4096;
}
close(fdo);
}
The function is accessed from main() like this:
if(maps && mem != -1) {
char buf[BUFSIZ + 1];
while(fgets(buf, BUFSIZ, maps)) {
off64_t start, end;
sscanf(buf, "%llx-%llx", &start, &end);
dump_region(mem, start, end);
}
}
Any idea where am I wrong?

Modify
fdo = open("memdump_log", O_WRONLY | O_CREAT, 0644);
into
fdo = open("memdump_log", O_WRONLY | O_CREAT | O_APPEND, 0644);

You need to seek to the end of your output file, or passing the O_APPEND to open

You keep reopening the output file on every call to dump_region. When opening a file it will always start writing at the start. Either keep the file open all the time, seek to the end, or try the O_APPEND flag.

Related

Copying certain contents of a file to another

I am trying to limit the amount of lines I copy over to a file to x amount. I know how to copy the files, but how would I limit it, for example, 10 lines.
Code:
char buf[BUFSIZ];
int outft, inft,fileread;
if((outft = open("TMPFILE3", O_CREAT | O_APPEND | O_RDWR, 0644))==-1){
perror("open");
}
inft = open("TMPFILE", O_RDONLY);
if(inft >0){
fileread = read(inft, buf, sizeof(buf));
printf("%s\n", buf);
write(outft, buf, fileread);
close(inft);
}
close(outft);

Open() for output not creating file

I have this function that utilizes open to set i/o redirection:
void setOutput(char * buffer){
int file = open(buffer, O_WRONLY || O_CREAT, S_IWUSR);
if(file < 0){ printf("error opening %s for output\n", buffer); }
if(dup2(file, 1) < 0){ printf("error with dup2 opening %s for output\n", buffer); }
}
When I run it, it works fine for files that are already defined but returns -1 when it receives a non-created file. Not sure why
You need to change the following
int file = open(buffer, O_WRONLY || O_CREAT, S_IWUSR);
To
int file = open(buffer, O_WRONLY | O_CREAT, S_IWUSR);
Format :
int open( char *filename, int access, int permission );
access : Should be provided as a bit wise OR operator, that means using | not || which is logical OR

how to save the output of GCC in a file using pipes in C (linux)?

on execution, file creation is working well...but nothing gets written into it...what could be done...is there any other way apart from using file descriptors..??
I tried the following code:
memset(buffer, '\0', sizeof(buffer));
read_fp = popen("gcc test1.c", "r");
//fp = fopen("/home/pranav/Desktop/b4.txt","w");
fd = open("beejoutput2.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (read_fp != NULL)
{
chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
while (chars_read > 0)
{
/*writing to the file*/
while ((bytesread = read(3, buffer, chars_read)) > 0)
write(fd, buffer, bytesread);
buffer[chars_read-1] = '\0';
printf("Reading %d:-\n %s\n", BUFSIZ, buffer);
//fprintf(fp,"%d:-\n %s\n", BUFSIZ, buffer);
chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
}
pclose(read_fp);
exit(EXIT_SUCCESS);
}
//fclose(fp);
exit(EXIT_FAILURE);
return 0;
}
Error messages will be on stderr, so change this
read_fp = popen("gcc test1.c", "r");
to this
read_fp = popen("gcc test1.c 2>&1", "r");
You should test the output of open and write since they fail.
You should not use system calls like open and write directly, they have portable C wrappers like fopen and fwrite.
Close all the things at the end.

How to rewrite full content of a file in C

I have text file which uses for ajax source. Every 1 sec browser sends ajax request to read actual data from this file.
Also I have deamon written on C which writes actual data to that file. Look at the following code:
static void writeToFile_withLock(const char * file_path, const char * str)
{
struct flock fl = {F_WRLCK, SEEK_SET, 0, 0, 0 };
int fd;
const char * begin = str;
const char * const end = begin + strlen(str);
fl.l_pid = getpid();
if ((fd = open(file_path, O_CREAT | O_WRONLY)) == -1) {
perror("open");
exit(1);
}
printf("Trying to get lock...\n");
if (fcntl(fd, F_SETLKW, &fl) == -1) {
perror("fcntl");
exit(1);
}
printf("got lock\n");
printf("Try to write %s\n", str);
while (begin < end)
{
size_t remaining = end - begin;
ssize_t res = write(fd, begin, remaining);
if (res >= 0)
{
begin += res;
continue; // Let's send the remaining part of this message
}
if (EINTR == errno)
{
continue; // It's just a signal, try again
}
// It's a real error
perror("Write to file");
break;
}
fl.l_type = F_UNLCK; /* set to unlock same region */
if (fcntl(fd, F_SETLK, &fl) == -1) {
perror("fcntl");
exit(1);
}
printf("Unlocked.\n");
close(fd);
}
The problem: If former data was > the new data then old several symbols keeped at the end of the file.
How I can rewrite full file content?
Thanks in advance.
Add O_TRUNC to the open() call...
O_TRUNC
If the file already exists and is a regular file and the open mode
allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to
length 0. If the file is a FIFO or terminal device file, the O_TRUNC
flag is ignored. Otherwise the effect of O_TRUNC is unspecified.
You basically have two options. Either set the O_TRUNC bit of the 2nd parameter of open to discard all content when you open the file, or call ftruncate when you are finished to discard the content of the file that you do not want. (Or use truncate, but since you already have an open file descriptor, there's no advantage to doing that.)

fcntl not working

I have a small program that tires to change the files access mode after it has been opened.
int main(int argc, char* argv[])
{
int fd;
char *filename = argv[1];
char data[1];
int curval; //current flag value
int newval; //new flag value
fd = open(filename, O_RDONLY);
while(read(fd, data, 1)>0)
{
write(STDOUT_FILENO, data, 1);
}
lseek(fd, 0, SEEK_SET);
if((curval = fcntl(fd, F_GETFL, 0))<0)
{
perror("file flag get failed");
}
printf("%d\n", curval);
newval = curval | O_WRONLY | O_APPEND;
printf("%d\n", newval);
if(fcntl(fd, F_SETFL, newval)<0)
{
perror("file flag set failed");
}
if(write(fd, argv[2], strlen(argv[2]))<0) //appending more data to the file
{
perror("write failed");
}
lseek(fd, 0, SEEK_SET);
while(read(fd, data, 1)>0)
{
write(STDOUT_FILENO, data, 1);
}
close (fd);
return 0;
}
Here is the output when i run this program with a text file as input.
$ cat input
this is the inital data
$ ./a.out input newdata
this is the inital data
0
1025
write failed: Bad file descriptor
this is the inital data
Why is the write in the program failing? Also I'm not able to find where the file status flag constants are defined. I checked in usr/include/
The behavior you are trying to perform is not allowed. From the fcntl(2) man page:
F_SETFL (long)
Set the file status flags to the value specified by arg. File
access mode (O_RDONLY, O_WRONLY, O_RDWR) and file creation flags
(i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored.
On Linux this command can only change the O_APPEND, O_ASYNC,
O_DIRECT, O_NOATIME, and O_NONBLOCK flags.
If you read Linux manpage, you will see that fcntl cannot change file access modes (e.g., from read-only to read-write).

Resources