Stdio remove () is not always removed in time

For specific homework, I am implementing a basic storage system using C sequential files that cannot load more than 1 record at a time. So, the main part is creating a new file, which stores the results of what we do with the original records. The previous file is renamed and a new one is created with a working name. Code compiled with MinGW 5.1.6 on Windows 7.

The problem is that this particular version of the code (I have almost identical versions of this floating around my functions) does not always delete the old file, so the rename is not done and hence the saved data is erased by Eorep ().

FILE *archivo, *antiguo;

remove("IndiceNecesidades.old");  // This randomly fails to work in time.
rename("IndiceNecesidades.dat", "IndiceNecesidades.old"); // So rename() fails.

antiguo = fopen("IndiceNecesidades.old", "rb");
// But apparently it still gets deleted, since this turns out null (and I never find the .old in my working folder after the program done).
archivo = fopen("IndiceNecesidades.dat", "wb"); // And here the data gets wiped.

      

Basically, any time the .old previously existed, there is a chance it won't get deleted in time for the rename () to take effect successfully. There are no possible name conflicts either internally or externally.

It is strange that it is only with this particular file. Identical snippets other than the name changed to Necesidades.dat (which happens in three different functions) works fine.

// I'm yet to see this snippet fail.
FILE *antiguo, *archivo;

remove("Necesidades.old");
rename("Necesidades.dat", "Necesidades.old");

antiguo = fopen("Necesidades.old", "rb");
archivo = fopen("Necesidades.dat", "wb");

      

Any ideas as to why this is happening and / or how I can ensure that the remove () command is in effect by the time the () is renamed? (I was thinking of just using a while loop to force-call remove () while fopen () returns a non-null pointer, but this is like asking for an OS overflow crash with delete requests or something. )

+1


a source to share


3 answers


So, after reading the mention of Scott's permissions, I thought about "Allow Denied" and did some googling. It turned out to be a fairly common, if unclear, mistake. the cafe was right, it was in a different code. Namely, I forgot to create the same file in the function for displaying content. Since I did not track this particular detail, it seemed random.



Disclaimer: The weekly math assimilations do very little at times. ¬¬

+3


a source


It would probably be nice to check the function remove()

for errors. man remove

says that the function returns 0

on success and -1

on failure, setting errno

to record an error. Try to replace the call

if (remove("IndiceNecesidades.old") != 0){
   perror("remove(\"IndiceNecesidades.old\") failed");
}

      

which should display an error message.

Also, it does not appear that deletion is necessary



person rename ()

The rename () system call calls the reference named old, which will be renamed to the new one. If a new one exists, it is removed first. Both old and new must be of the same type (that is, both must be either directories or non-directories) and must be on the same filesystem.

The rename () system call ensures that a new instance will always exist, even if the system should crash in the middle of an operation.

If the last component is an old symbolic link, the symbolic link is renamed, rather than the file or directory it points to.

EPERM will be returned if:

[EPERM] The directory containing the old one is marked sticky, and neither the containing directory nor the old one belongs to the effective user ID.

[EPERM] A new file exists, a directory containing a new sticky note, and neither containing a directory, but not new by User ID.

so the next step is to check if you have permission to access the containing directory

+1


a source


This sounds rather strange, and even more so when you say that the same code works fine with a different file name - I would strongly suspect a mistake elsewhere in your code. However, you can work around it by renaming the file you want to delete:

rename("IndiceNecesidades.old", "IndiceNecesidades.older");
remove("IndiceNecesidades.older");
rename("IndiceNecesidades.dat", "IndiceNecesidades.old");

      

+1


a source







All Articles