Appending a binary file to another with c - c

people of StackOverflow,
I'm pretty new to c and wanted to set myself a challenge:
Adding a binary file (like a .exe file) to another, so when the second one is started, bot files are executed. This is the code I tried:
FILE* fp1;
FILE* fp2;
fp1 = fopen("path_to_file1","rb");
fp2 = fopen("path_to_file2","ab");
fseek(fp1,0, SEEK_END);
int size = ftell(fp1);
rewind(fp1);
unsigned long buffer[size];
fread(buffer,sizeof(buffer),1,fp1);
fclose(fp1);
fwrite(buffer,sizeof(buffer),1,fp2);
fclose(fp2);
All of this is running in the main function.
The problem is when executing the code, instead of appending the first file to the second, it overrides the first one, and on execute only executes the second file.
I really hope you can help me :)

Your code is incorrect because by doing this
unsigned long buffer[size];
you're writing sizeof(buffer) which is sizeof(unsigned long) times too big. So the first file is appended to the second file all right, but a lot of garbage is appended too.
You should declare:
unsigned char buffer[size];
so sizeof(buffer) yields the correct result.
Also, check the return value of your fopen statements.
EDIT: it just hit me that you want to append 2 executables together. The above (fixed) code works to append 2 binary files (data files) together, but for executables it just doesn't work.
Appending an executable in the end of another one is likely to be ignored by the operating system. The first executable header contains the logical size of the program segments. It doesn't read the file beyond that (well, it can be done by a lot of hacking and it's called a virus), which explains that your updated files runs like if nothing was appended.
One could imagine running a disassembler on both files, modify start points+add a wrapper to call both start points, and reassemble to another executable.
The easiest way to execute one program, then the other one, just call them in a script (bash, .bat, whatever) or in C system calls.
system("path_to_file1");
system("path_to_file2");

Related

How to write at the middle of a file in c

Is it possible to write at the middle of a file for example I want to insert some string at the 5th position in the 2nd line of a file in c ?
I'm not very familiar with some of C functions that are related to handling files , if someone could help me I would appreciate it
I tried using fputs but I couldn't insert characters at the desired location
open a new output file
read the input file line by line (fgets) writing each line out to a new file as you read.
When you hit the place you want to insert write the new line(s)
The carry on copy the old lines to the new file
close input and output
rename output file to input
Continuing from my comments above. Here's what I'd do:
Create two large, static char[] buffers of the same size--each large enough to store the largest file you could possibly ever need to read in (ex: 10 MiB). Ex:
#define MAX_FILE_SIZE_10_MIB (10*1024*1024)
static char buffer_file_in[MAX_FILE_SIZE_10_MIB];
static char buffer_file_out[MAX_FILE_SIZE_10_MIB];
Use fopen(filename, "r+") to open the file as read/update. See: https://cplusplus.com/reference/cstdio/fopen/. Read the chars one-by-one using fgetc() (see my file_load() function for how to use fgetc()) into the first large char buffer you created, buffer_file_in. Continue until you've read the whole file into that buffer.
Find the location of the place you'd like to do the insertion. Note: you could do this live as you read the file into buffer_file_in the first time by counting newline chars ('\n') to see what line you are on. Copy chars from buffer_file_in to buffer_file_out up to that point. Now, write your new contents into buffer_file_out at that point. Then, finish copying the rest of buffer_file_in into buffer_file_out after your inserted chars.
Seek to the beginning of the file with fseek(file_pointer, 0, SEEK_SET);
Write the buffer_file_out buffer contents into the file with fwrite().
Close the file with fclose().
There are some optimizations you could do here, such as storing the index where you want to begin your insertion, and not copying the chars up to that point into buffer_file_in, but rather, simply copying the remaining of the file after that into buffer_file_in, and then seeking to that point later and writing only your new contents plus the rest of the file. This avoids unnecessarily rewriting the very beginning of the fie prior to the insertion point is all.
(Probably preferred) you could also just copy the file and the changes you insert straight into buffer_file_out in one shot, then write that back to the file starting at the beginning of the file. This would be very similar to #pm100's approach, except using 1 file + 1 buffer rather than 2 files.
Look for other optimizations and reductions of redundancy as applicable.
My approach above uses 1 file and 1 or 2 buffers in RAM, depending on implementation. #pm100's approach uses 2 files and 0 buffers in RAM (very similar to what my 1 file and 1 buffer approach would look like), depending on implementation. Both approaches are valid.

Can an already opened FILE handle reflect changes to the underlying file without re-opening it?

Assuming a plain text file, foo.txt, and two processes:
Process A, a shell script, overwrites the file in regular intervals
$ echo "example" > foo.txt
Process B, a C program, reads from the file in regular intervals
fopen("foo.txt", "r"); getline(buf, len, fp); fclose(fp);
In the C program, keeping the FILE* fp open after the initial fopen(), doing a rewind() and reading again does not seem to reflect the changes that have happened to the file in the meantime. Is the only way to see the updated contents by doing an fclose() and fopen() cycle, or is there a way to re-use the already opened FILE handle, yet reading the most recently written data?
For context, I'm simply trying to find the most efficient way of doing this.
On Unix/Linux, when you create a file with a name which already existed, the old file is not deleted or altered in any way. A new file is created and the directory is updated to point at the new file instead of the old one.
The old file will continue to exist as long as some directory entry points at it (Unix file systems allow the same file to be pointed to by multiple directories) or some program has an open file handle to the file, which is more relevant to your question.
As long as you don't close fp, it continues to refer to the original file, even if that file is no longer referenced by the filesystem. When you close fp, the file will get garbage collected automatically, and the next time you open foo.txt, you'll get a file descriptor for whatever file happens to have that name at that point in time.
In short, with the shell script you indicate, your C program must close and reopen the file in order to see the new contents.
Theoretically, it would be possible for the shell script to overwrite the same file without deleting it, but (a) that's tricky to get right; (b) it's prone to race conditions; and (c) closing and reopening the file is not that time-consuming. But if you did that, you would see the changes. [Note 1]
In particular, it's common (and easy) to append to an existing file, and if you have a shell script which does that, you can keep the file descriptor open and see the changes. However, in that case you would normally have already read to the end of the file before the new data was appended, and the standard C library treats the feof() indicator as sticky; once it gets set, you will continue to get an EOF indication from new reads. If you suspect that some process will be writing more data to the file, you should reset the EOF indication with fseek(fp, 0, SEEK_CUR); before retrying the read.
Notes
As #amadan points out in a comment, there are race conditions with echo text > foo.txt as well, although the window is a bit shorter. But you can definitely avoid race conditions by using the idiom echo text > temporary_file; mv -f temporary_file foo.txt, because the rename operation is atomic. Of course, that would definitely require you to close and reopen the file. But it's a good idea, particularly if the contents being written are long or critical, or if new files are created frequently.

Function that creates a different csv file every time it is run

I am making a c program that can save matrices and vectors in CSV files so I can then perform operations between them. In one of my functions I create a matrix with random numbers and then save it inside a CSV file.
The problem is that I don't know how to create a different file every time the function is run so each array can be stored in a different CSV file. Because of this I have to save all the matrices inside the same file which makes the rest of the process a lot harder. How could I make the function that makes a different file every time without it having completely random names.
Here is a link to the project in replit
How could i make the function that makes a different file every time without it having completely random names.
Some possible solutions:
use timestamp as part of filename
use counter
For a timestamp, example code:
char filename[80];
snprintf(filename, sizeof(filename), "prefix.%d", time(NULL));
FILE *fout = fopen(filename, "wt");
For a counter, use the same code as above, but check if the file prefix.${counter} exists (see man access). If it does, increment the counter and try again. If it doesn't, use the filename.

c, how do i detect if another process is writing to a file

I do open large files with fopen under c with a kind-of observed folder logic.
I'd like to fopen (or at least to fread) the file as soon as it has been copied completely to my observed folder.
How can i detect if another process is writing to a file?
Is that possible with standard-c?
Thanks
There's no way to do it with standard C. The best you can do is heuristically notice when file stops changing, e.g. read the last few blocks of the file, sleep n seconds, then read the blocks again and compare against the previous read. You could also try just watching the end of file seek pointer to see when it stops moving, but for large files (size greater than what will fit in a signed long) the POSIX function ftello() is required to do it portably.
It's kind of "rude" but you could keep trying to open it in write mode; as long as it's being written to by some other file, the fopen will fail. Something like this:
FILE* f;
while( (f = fopen( fname, "w" )) == NULL ) {
sleep( 100 ); // we want to be moderately polite by not continually hitting the file
}

Inserting data to file in c

I need to add a string before the 45th byte in an existing file. I tried using fseek as shown below.
int main()
{
FILE *fp;
char str[] = "test";
fp = fopen(FILEPATH,"a");
fseek(fp,-45, SEEK_END);
fprintf(fp,"%s",str);
fclose(fp);
return(0);
}
I expected that this code will add "test" before the 45th char from EOF, instead, it just appends "test" to the EOF.
Please help me to find the solution.
This is continuation of my previous question
Append item to a file before last line in c
Open it with mode r+ (if it already exists) or a+ (if it doesn't exist and you want to create it). Since you're seeking to 45 bytes before the end of file, I'm assuming it already exists.
fp = fopen(FILEPATH,"r+");
The rest of your code is fine. Also note that this will not insert the text, but will overwrite whatever is currently at that position in the file.
ie, if your file looks like this:
xxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxx
Then after running this code, it will look like this:
xxxxxxxtestxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxx
If you really want to insert and not overwrite, then you need to read all the text from SEEK_END-45 to EOF into memory, write test and then write the text back
Don't open it as append (a) if you plan to write at arbitrary positions; it will force all writes to the end of the file. You can use r+ to read or write anywhere.
To avoid platform-specific configurations, always explicitely indicate the binary or text mode in your fopen() call.
This will save you hours of desperations if you port your code one day.

Resources