C language, reading own source file and editing source file - c

I am currently working on a project which involves reading its own source code, editing it, then recompiling it. My question is how does the fopen function actually work? Is it affected when the source file calling it is open?
I have currently already written a function which reads in and finds the areas in the source code that I have to edit. When I open my source file I am able to read it in, store it in memory, iterate through it, and find what I need. The problem is when I attempt to check if the area to edit is correct through a strcmp function call nothing happens even though it is exact (I have accounted for newlines etc.).
When I copy the source code to another .c file, and have my program read that file instead (an exact copy) it works perfectly fine. I am really confused why that file works and why my source code file does not. They are exactly the same file.

If you are using windows, then beware that a file can usually only be open in a single process at a time.
So if the source file you are trying to open is already opened in your IDE, you may not be able to open in in your program using fopen.

Related

How would I know that file is opened and it is saved after some writing operation using C code?

I have a set of configuration files (10 or more), and if user opens any of these file using any editor (e.g vim,vi,geany,qt,leafpad..). How would I come to know that which file is opened and if some writing process is done, then it is saved or not (using C code).
For the 1st part of your question, please refer e.g. to How to check if a file has been opened by another application in C++?
One way described there is to use a system tool like lsof and call this via a system() call.
For the 2nd part, about knowing whether a file has been modified, you will have to create a backup file to check against. Most editors already do that, but their naming scheme is different, so you might want to take care of that yourself. How to do that? Just automatically create a (hidden) file .mylogfile.txt if it does not exist by simply copying mylogfile.txt. If .mylogfile.txt exists, is having an older timestamp than mylogfile.txt, and differs in size and/or hash-value (using e.g. md5sum) your file was modified.
But before re-implementing this, take a look at How do I make my program watch for file modification in C++?

How to move the cursor to write a new line in a file without having to read the whole existing line? [duplicate]

This question already has answers here:
Append to the end of a file in C
(2 answers)
Closed 3 years ago.
I'm trying to write a log file to my code but I have some restrictions and don't know how to surpass them.
My code runs for several days and loops every 1 minute. I want to write in the log file at the end of every loop, so the log file will have thousands of lines. So, my two main points about this are:
I would like to be able to open and close the file at every loop (after I finish the operations, I open the file, write what I want and then close it). This way I can open the log file anytime to check how the code is going.
Each line of the log file will have a different length depending of what happened in the loop. Since the file will have thousands of lines, I would like to be able to go to the next line without having to read all the previous existing lines.
I've tried to use the fseek function like this:
fseek(fp,-1,SEEK_END);
but had no success (I ended up writing over the already existing line).
It's important to say that I'm writing this code in linux but would like it to be portable.
Everything I found here on other questions shows people reading the whole line and I don't need to read or store the existing lines.
I just to want to open the file and write in a new line. Does anyone know how I can do this?
Open the file in append mode ("a" in fopen). That way all writes will go to the end of the file; no seeking required.
Also, there is no point in opening/closing the same file repeatedly. Just open the file once, before the loop starts. Keeping a file open does not prevent others from reading it. If you're concerned with delays caused by buffering, you can just fflush() the handle after every line of output.

Does file type rely on file extension?

As a general question: What's the role of file extension when determining file types?
For example, I can change .jpeg file to .png extension and even .txt. Of course, in the case of changing to .txt, it will neither be opened as picture, nor readable.
To determine file type, it seems the safe way is to parse the first few bytes of the file. If extension is not trustable, extension is no more than file name.
As a general rule, you should ALWAYS parse the COMPLETE file in order to be sure that the file is what the extension says. As you can easily imagine, it is pretty simple to create a binary file resembling a e.g. BMP (with a correct header) but then containing something different.
You should never trust the extension neither the header because otherwise a malicious user could exploit some of your code to generate e.g. a buffer overflow, and this is absolutely paramount if you are writing programs that must run at root/admin privilege.
Having said the obvious, the file extension nowadays is mainly used so that the OS can associate a program to that particular file (usually calling the program and passing the selected file as first parameter), and then it's up to the program to determine the file content.
It is a little bit different when talking about executable files. Under Unix, in order to be executable a file has to have the "x" flag set, otherwise it would not run, regardless of the extension. Under Windows, there is not such thing and the OS relies on only a few extensions (EXE, COM, BAT, etc.) to determine which files can be executed.
The EXE file, for example, has to start with "MZ" followed by some information for its allocation and size (http://www.delorie.com/djgpp/doc/exe/) and the OS surely checks its internal headers. Other formats (e.g. the COM executable format of the MS-DOS era) is just "pure" assembly code, so there is no check done by the OS. It just interprets those opcodes, hoping that everything will be fine.
So, to summarize:
File extension is mainly used so that the OS can call the appropriate program to open it (and passing the filename as the first parameter, argc/argv in C language for example)
Windows relies on some file extension to know if a file is executable, while Unix/Mac relies on a particular flag (x) associated with the file
Two things that are not well known about file extensions: directory names can have extension too, and extension can be way longer than the usual 3 characters.
With the help of file extension, you know how to read the first few and all the rest of the bytes. You also know what program to use to read the file. Or if it is an executable, you know that it is to be executed and not shown as a picture.
Yes you can change the file extension, but what does it mean then? It only means that OS (or any program that tried to read the file) is working correctly. Only you are providing bad data to it.
File extension is not something that some bytes of data inherently have. Extensions are given to those bytes depending upon the protocol followed to write them that way. After you have encoded the letters in binary form, you provide that binary form with .txt extension so that the text reader knows that these bytes convert to letters. That's the role of file extension. With bad file extension, this role is not fulfilled, resulting in incomprehension of the data you saved in binary.
As a general question: What's the role of file extension when determining file types?
The file extension usually identifies the application that opens a file.
If you rename a .JPG to a .PNG and while having JPG and PNG opened by the same application (usually an image viewer) that application can read the image stream and process it correctly regardless of having an incorrect file stream.
The problem arises if you rename the file in such a way that the file gets routed to an application that cannot handle the file's content.
If you rename a .DOCX (word) file to an Autocad extension (.DWG), opening the word file in autocad is likely to produce errors (unless per chance autocad can read word files).

permission denied for rename function in C on windows

I have an application developed in C. This application is supported across multiple platforms. There is one functionality where we are transferring files via file transfer protocol to different machine or to any other directory on local machine. I want to include a functionality where I can transfer the file with some temporary name and once the transfer is complete, I want to rename the file with the correct name (the actual file name).
I tried using simple rename() function. It works fine in Unix and Linux machines. But it does not work on Windows. It is giving me an error code of 13(Permission denied error).
First thing, I checked in msdn to know the functionality of rename if I have to grant some permissions to the file etc.
I granted full permissions to the file (lets say it is 777).
I read in few other posts that I should close the file descriptor before renaming the file. I did that too. It still gives the same error.
Few other posts mentioned about the owner of the file and that of the application. The application will run as a SYSTEM user. (But this should not affect the behavior, because I tried the same rename function in my application as follows:
This works fine from my application:
rename("C:/abc/aaa.txt","C:/abc/zzz.txt");
but
rename(My_path,"C:/abc/zzz.txt");
doesn't work, where My_path when printed displays C:/abc/test.txt.
How can I rename a file? I need it to work on multiple platforms.
Are there any other things I should be trying to make it work.?
I had this same problem, but the issue was slightly different. If I did the following sequence of function calls, I got "Permission Denied" when calling the rename function.
fopen
fwrite
rename
fclose
The solution was to close the file first, before doing the rename.
fopen
fwrite
fclose
rename
If
rename("C:/abc/aaa.txt","C:/abc/zzz.txt");
works but
rename(My_path,"C:/abc/zzz.txt");
does not, in the exact same spot in the program (i.e. replacing one line with another and making no changes), then there might be something wrong with the variable My_path. What is the type of this variable? If it is a char array (since this is C), is it terminated appropriately? And is it exactly equal to "C:/abc/aaa.txt"?
(I wish I could post this as a comment/clarification rather than as an answer but my rep isn't good enough :( )

Untarring file fails when fd is not previously closed

Consider the following scenario: I am opening a tar file (say abc.tar.gz), writing the data, and before closing the file descriptor, I am trying to extract the same file.
I am unable to do so. But if I extract the file after having closing the fd, it works fine.
I wonder what could be the reason.
All files has a position where data is read or written. After writing to the file, the position is at the end. Trying to read will attempt to read from that position. You have to change the position to the beginning of the file with a function like lseek.
Also, you did open the file in both read and write mode?
Edit
After reading your comments, I see you do not actually read the file from inside your program, but from an external program. Then it might be as simple as you not flushing the file to disk, which happens automatically when closing a file. You might want to check the fsync function for that, or possible the sync function.

Resources