Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ‘safe’ to remove() open file?

Tags:

c

stdio

I think about adding possibility of using same the filename for both input and output file to my program, so that it will replace the input file.

As the processed file may be quite large, I think that best solution would to be first open the file, then remove it and create a new one, i.e. like that:

/* input == output in this case */
FILE *inf = fopen(input, "r");
remove(output);
FILE *outf = fopen(output, "w");

(of course, with error handling added)

I am aware that not all systems are going to allow me to remove open file and that's acceptable as long as remove() is going to fail in that case.

I am worried though if there isn't any system which will allow me to remove that open file and then fail to read its' contents.

C99 standard specifies behavior in that case as ‘implementation-defined’; SUS doesn't even mention the case.

What is your opinion/experience? Do I have to worry? Should I avoid such solutions?

EDIT: Please note this isn't supposed to be some mainline feature but rather ‘last resort’ in the case user specifies same filename as both input and output file.

EDIT: Ok, one more question then: is it possible that in this particular case the solution proposed by me is able to do more evil than just opening the output file write-only (i.e. like above but without the remove() call).

like image 572
Michał Górny Avatar asked Jan 24 '23 06:01

Michał Górny


2 Answers

No, it's not safe. It may work on your file system, but fail on others. Or it may intermittently fail. It really depends on your operating system AND file system. For an in depth look at Solaris, see this article on file rotation.

Take a look at GNU sed's '--in-place' option. This option works by writing the output to a temporary file, and then copying over the original. This is the only safe, compatible method.

You should also consider that your program could fail at any time, due to a power outage or the process being killed. If this occurs, then your original file will be lost. Additionally, for file systems which do have reference counting, your not saving any space, over the temp file solution, as both files have to exist on disk until the input file is closed.

If the files are huge, and space is at premium, and developer time is cheap, you may be able to open a single for read/write, and ensure that your write pointer does not advance beyond your read pointer.

like image 102
brianegge Avatar answered Jan 25 '23 19:01

brianegge


All systems that I'm aware of that let you remove open files implement some form of reference-counting for file nodes. So, removing a file removes the directory entry, but the file node itself still has one reference from open file handle. In such an implementation, removing a file obviously won't affect the ability to keep reading it, and I find it hard to imagine any other reasonable way to implement this behavior.

like image 40
Pavel Minaev Avatar answered Jan 25 '23 18:01

Pavel Minaev