Link to home
Start Free TrialLog in
Avatar of themuppeteer
themuppeteerFlag for Belgium

asked on

general question on writing a file

Hello guys,

I have a program (written in c) which can save files. It runs on red hat linux 7
Now at certain moments the customer wants to make a backup of the files. How can I be sure that my program isn't writing a file at that time : since I write my files line by line (I don't have one big buffer, I open a file, write line by line and then close it), I can be that at the time of the automateed backup, there is only half a file present since the program is still writing.
Are there some known solutions to this problem ?

thnx!

ASKER CERTIFIED SOLUTION
Avatar of ddunlea
ddunlea

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of themuppeteer

ASKER

Hello ddunlea,
thanks for the quick answer.
Yes well I would prefer not changing the original program since if I do, it has to go thrue the complete test cycle again and then we lose a lot of time..+ there isn't a lot of disk space on the device that my program runs on and therefore I must also be careful. But it is a good idea and I'll put it away for the moment  in case nothing more practical for my case comes up.

I was more thinking/hoping that there would be a way for the backup system (which still has to be developed, we are thinking about scp) to let it check if a certain file is opened by some program and in that case log something about that or something.. Do you know if you check in linux if a file is opened ?

regards,
themuppeteer
SOLUTION
Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hello Kent,

I don't use streams, this is the function to write a file (note that the list thing is our own type):

void writeFile(char* name,list* lst)
{
   FILE* file;
   char* str;

   file=fopen(name,"wt");
   if (file==NULL) return;

   listStart(lst);

   while ((str=listNext(lst))!=NULL)
      fprintf(file,"%s\n",str);

   fflush(file);
   fclose(file);
}

Should something be changed to this (I hope not, but if I can lock a file I should consider it)?

Regards,
themuppeteer
Avatar of ddunlea
ddunlea

Hi themuppeteer,

I agree with Kdo that you could use oepn() to lock the file while reading it. But this doesn't change the fact that you will have to edit your original program. Which you clearly want to avoid.

If you want to completely avoid modifying the original program, then here is what I would suggest - If the file you want to back up is small, then do as follows:

Check the timestamp
Run backup
Re-Check timestamp and compare to original
If different, re-run
Else Done

If the file to be backed up is large, you can write a program that polls the time stamp whilst the file is being copied such that the copy can be aborted part-way through if the file changes.

Regards
sounds like a plan, problem there is that with scp, we will copy a complete directory and subdirectorys , not file per file. Since the customer can also put his own files in that directory if he choses and they should be backed up also.
So there there is a problem with the timestamps..
Another thing is that sometimes file A and file B have dependencies, so you should need a "global" timestamp (more like a checksum) to do this. Since otherwise you could have: file A written, file B backed up, file B written , file A backed up and you're in trouble since A and B don't correspond..
But it is also a good idea.
Howdy....

Sorry to say, but we've got a breakdown in terminology.  fopen() opens a stream, so you do use streams.

At some level, fopen() will call open() to establish the file access.  Here's a head start.



void writeFile(char* name,list* lst)
{
   int FileHandle;
   char* str;

   FileHandle = open (name, O_WRONLY|O_BINARY|O_TRUNC|O_CREAT, 0);  /*  0 is the share attributes.  You might want some level of sharing  */
   if (FileHandle < 0)
     return;

   listStart(lst);

   while ((str=listNext(lst))!=NULL)
   {
      write (FileHandle, str, strlen (str));
      write (FileHandle, "\r\n", 2);              /* write (FileHandle, "\n", 1) on unix systems  */
   }

   close (FileHandle);
}
Hi themuppeteer,

rsync. It's the answer. Definitely. Mirror the files with rsync. Build a checksum of some sort based on the files you have gathered. Re-run rsync, which will not copy anything if no changes have been made. Re-check the checksum. If it has changed, re-run rsych, otherwise, you're done.

woops, I was thinking c++ streams.. I didn't know fopen opened a stream.
Anyway, thanks for  modifying the code Kent.

Rsync, I worked once shortly with it before and it might indeed be the solution.

I'll bring both up in the next meeting on the subject.

I'm gonna thank you guys for your time and effort,
and I'm gonna split points (hope nobody minds about the one unsplittable point which I'm gonna give to the first replier for being first :)).

thanks!