Path: utzoo!attcan!uunet!husc6!bbn!uwmcsd1!ig!agate!ucbvax!RAND-UNIX.ARPA!bridger%newton
From: bridger%newton@RAND-UNIX.ARPA (Bridger Mitchell)
Newsgroups: comp.os.cpm
Subject: file truncation in CP/M 2.2?
Message-ID: <8806010017.AA28247@newton.arpa>
Date: 1 Jun 88 00:17:52 GMT
Sender: daemon@ucbvax.BERKELEY.EDU
Organization: The Internet
Lines: 40


Unlike CP/M Plus, CP/M 2.2 has no truncate-file function.  This
is a useful function when a large file (e.g. a database or library file)
needs to be "lopped off", or packed down, and there's a lack of disk
space to create a temporary duplicate file.

Is there a portable method of truncating a CP/M 2.2 file, using only
BDOS calls?  I believe the following approach will work so long as the
shorter file's final physical extent (i.e. directory entry) is the
same as the original file's:

	open the file
	get file size, to set extent, S2, and record count bytes
	change record count to new number of records in final
	  logical extent
	change extent number, if necessary, to new final logical
	  extent
	clear bit 7 of S2, to mark the file/fcb "modified"
	close the file
	use function 37 to log off the drive (use the FRESET routine,
	  or function 13, if run on the buggy DRI BDOS).

The BDOS will write the changed fcb (directory entry) to the directory
when the file is closed, then rebuild the allocation vector for the
drive using the new number of records.

BUT...what can be done if the truncation results in eliminating the
last physical extent(s)?  The BDOS internally opens and closes each
physical extent of a multi-extent file.  Suppose, for example, you read
randomly the last record you wish to keep in the new file and  it's
not in the last physical extent.  Then you use the procedure above,
and the intermediate extent will be modified in the directory.

But the final extent will remain in the directory, unchanged.  Disk
logins will continue to keep the data groups reserved in that entry
allocated; they are effectively stranded.  And directory utilities
that sort extents will be badly confused.  You'd like to "erase" just
that final extent.  But this can't be done by BDOS calls.  Or can it?

-- bridger mitchell