lbr@holos0.UUCP (Len Reed) (03/17/89)
I am developing a system that runs on MD-DOS 3.x. I need to be able to save as much data as possible if the system crashes. The program may have written thousands of bytes to several files. Obviously there can be unwritten data in memory buffers, so some data loss is inevitable. As I understand it, MS-DOS doesn't update the directory entry on an output file until the file is closed. So if a file is opened (I'm using Microsoft C and ASM 5.1) with mode (O_CREAT | O_TRUNC | O_WRONLY), the directory entry says zero bytes and the pointer to the first cluster of the file is maintained in MS-DOS but not on the disk. If a crash occurs CHKDSK will put all the data into *.CHK files. If I open the file (O_CREAT | O_TRUNC | O_WRONLY), write one byte, close it, then open it O_WRONLY, I have a one byte file and the directory points to the first cluster. Adding clusters by issuing enough writes links everything up fine, with the only problem being that the directory still says the file size is one byte. After a crash, if the file had only one cluster, CHKDSK will have no complaints but the data will be invisible. Opening the file and LSEEKing to the "right" spot recovers the data. If it had more than one cluster, CHKDSK complains about the size and rounds it up to a full cluster: 4096, 8192, etc. on my hard disk. This means that the data at the end of the file will be garbage. So, is there a way to get MS-DOS to update the file size without closing the file? (Frequent close/open pairs are not acceptable in this application.) Several brute force methods suggest themselves: 1) Actually update the file size in the directory myself. 2) Maintain a file of file sizes. This file would be of fixed size and thus immune to the problem I describe. Use this file to control recovery. 3) Write a unique EOF marker (my files are not "text") with each write call. Before each write call lseek back over the EOF marker. After a crash, run a recovery program that finds the markers and uses lseek to adjust the file size. Is there a cleaner way? Is there any way to tell DOS to update the file size entry in the directory without closing the file? If you have a good answer to this, please e-mail me. I will summarize if there is interest. (This newsgroup expires quickly at my site; if you post your answer I may miss it.) Thanks. -- - Len Reed
Devin_E_Ben-Hur@cup.portal.com (03/19/89)
Len Reed asks about how to assure that data written to an open file is recoverable after a system crash before the file close. The accepted procedure for this is to duplicate the file handle and close the duplicate. This will flush internal dos buffers to disk and write the FAT and directory info associated with the file, but will leave the original file handle open and correctly positioned. Here's an asm fragment to do this: mov bx,file_handle mov ah,045h ;duplicate handle func int 021h jc error xchg bx,ax ;move duplicate handle to bx mov ah,03Eh ;close file func int 021h jc error Devin_Ben-Hur@Cup.Portal.Com ...ucbvax!sun!portal!cup.portal.com!devin_ben-hur
rmarks@KSP.Unisys.COM (Richard Marks) (03/21/89)
In article <1939@holos0.UUCP> lbr@holos0.UUCP (Len Reed) writes: >I am developing a system that runs on MD-DOS 3.x. I need to be able >to save as much data as possible if the system crashes. > >As I understand it, MS-DOS doesn't update the directory entry on an >output file until the file is closed. > >So, is there a way to get MS-DOS to update the file size without closing >the file? On DOS 3.3 use int 21, func 68, BX=handle to secure a file. Also on any DOS 2.x/3.x can try int 21, func 0D which resets the disk. On some BIOSes this will update all open files. Good Luck, Richard Marks rmarks@KSP.unisys.COM