[comp.sys.ibm.pc] Truncating MS-DOS files

lewan@gpu.utcs.toronto.edu (S. Lewandowsky) (02/15/87)

How can I truncate a file using DOS?  For example, I may open a
file, write to it and read from it extensively, and as a result its size
--when I use the close file handle call--would be about 120K or greater.
However, I only want to save the first 10K of that file, so I'd like to
place the file pointer to whereever I want the file to end, and then 
truncate it so that the information beyond the pointer is discarded
and the file size is reduced to 10K.
There is a truncate procedure in Turbo Pascal, so there must be a way
of doing it--but how do I do it in an ASM program using INT 21H?

mlandau@Diamond.UUCP (02/16/87)

In comp.sys.ibm.pc (<1987Feb15.123004.21019@gpu.utcs.toronto.edu>), 
lewan@gpu.utcs.toronto.edu (S. Lewandowsky) writes:
>
>How can I truncate a file using DOS?  

Once upon a time about a year ago, I spent several days with a debugger
tracing what I thought was an errant program which seemed to shorten its own
data files inexplicably.  In so doing, I discovered an interesting thing:

If you seek to a file position, write zero bytes, and close the file, the
file is truncated at the seek position.  This behavior is consistent in all
versions of PC- and MS-DOS from 2.0 to 3.2, but since it is not documented,
there's no guarantee it won't go away sometime in the future.

Does make it easy to implement truncate() and ftruncate() for the PC,
though.
-- 
 Matt Landau      	 		BBN Laboratories, Inc.
    mlandau@diamond.bbn.com		10 Moulton Street, Cambridge MA 02238
 ...seismo!diamond.bbn.com!mlandau      (617) 497-2429

tenney@well.UUCP (02/16/87)

In article <4141@diamond.Diamond.BBN.COM> mlandau@Diamond.BBN.COM (Matt Landau) writes:
>If you seek to a file position, write zero bytes, and close the file, the
>file is truncated at the seek position.  This behavior is consistent in all
>versions of PC- and MS-DOS from 2.0 to 3.2, but since it is not documented,
>there's no guarantee it won't go away sometime in the future.
>...
That is exactly the way it is documented!
RTFM:  function 28 Random Block Write
   ...  If CX is zero upon entry, no records are written, but the
        file is set to the length specified by the random record field,
        whether longer or shorter than the current file size.
!!!

-- Glenn Tenney 
UUCP: {hplabs,glacier,lll-crg,ihnp4!ptsfa}!well!tenney
ARPA: well!tenney@LLL-CRG.ARPA        Delphi and MCI Mail: TENNEY
As Alphonso Bodoya would say... (tnx boulton)
Disclaimers? DISCLAIMERS!? I don' gotta show you no stinking DISCLAIMERS!

roy@gitpyr.UUCP (02/17/87)

In article <2596@well.UUCP>, tenney@well.UUCP (Glenn S. Tenney) writes:
> That is exactly the way it is documented!
> RTFM:  function 28 Random Block Write
>    ...  If CX is zero upon entry, no records are written, but the
>         file is set to the length specified by the random record field,
>         whether longer or shorter than the current file size.

Well, quite some time ago I also heard that CX=0 on a write would truncate
the file.  When I became curious about it recently, I looked in the IBM
PC-DOS Technical reference manuals for DOS 2.1 and 3.0 (the only ones I
had available).  I looked in the function documentation distributed to
OEM's by Microsoft for MS-DOS 2.0.  I also looked in the book
"Advanced MS-DOS" by Ray Duncan.

None of these sources mentioned a thing about CX=0 being a legal value or
not, much less saying that it allows you to truncate a file.

I know what RTFM means, and I consider it rude, especially when it involves
something as (apparently) obscurely documented as this "feature" of MS-DOS.

Perhaps you could give us some clue about WHERE you saw it stated, instead
of simply yelling at us for being so ignorant as to overlook the
documentation.  Thanks for your time.
-- 
Roy J. Mongiovi		Systems Analyst		Office of Computing Services
Georgia Institute of Technology		Atlanta GA  30332.	(404) 894-4660
 ...!{akgua, allegra, amd, hplabs, ihnp4, masscomp, ut-ngp}!gatech!gitpyr!roy

ashok@softart.UUCP (02/17/87)

> There is a truncate procedure in Turbo Pascal, so there must be a way
> of doing it--but how do I do it in an ASM program using INT 21H?

The way to do it is to issue the Int 21H write data call with the byte count
set to zero bytes (ie write zero bytes) AFTER you have done the lseek call.
This will truncate the file for you.  NOT documented in every DOS Tech. Ref.
Manual I came across but it is documented in the Norton book.

------------------------------
Ashok C. Patel
Softart Microsystems Inc.

tenney@well.UUCP (02/17/87)

In article <3105@gitpyr.gatech.EDU> roy@gitpyr.gatech.EDU (Roy Mongiovi) writes:
> ...
>I know what RTFM means, and I consider it rude, especially when it involves
>something as (apparently) obscurely documented as this "feature" of MS-DOS.

No rudeness intended, just the shortest, easiest way to say it is in
the manual (the version I have).

> ...
>Perhaps you could give us some clue about WHERE you saw it stated, instead
>of simply yelling at us for being so ignorant as to overlook the
>documentation.  Thanks for your time.

IBM PCDOS 2.00 manual #6936752 January 1983, first edition, page D-29

Glenn Tenney

zhahai@gaia.UUCP (02/17/87)

In article <1987Feb15.123004.21019@gpu.utcs.toronto.edu> lewan@gpu.utcs.toronto.edu (S. Lewandowsky) writes:
>How can I truncate a file using DOS?  For example, I may open a
>file, write to it and read from it extensively, and as a result its size
>--when I use the close file handle call--would be about 120K or greater.
>However, I only want to save the first 10K of that file, so I'd like to
>place the file pointer to whereever I want the file to end, and then 
>truncate it so that the information beyond the pointer is discarded
>and the file size is reduced to 10K.
>There is a truncate procedure in Turbo Pascal, so there must be a way

Writing 0 bytes (ie: CX = 0 when doing the write) will do this.  I think
it works for all DOS 2.X and above.  Due to MS DOS's 2 parents (CP/M and UN*X)
there are two sets of file i/o functions (one based on each).  For function
28 (hex) "Random Block Write" this is documented pn page 5-28 of the DOS 2.1
tech ref manual, and page 6-85 for the DOS 3.1 tech ref manual.  For function
40 (hex) it is described on page 6-126 of the DOS 3.1 tech ref, but is not
mentioned in the older DOS 2.1 tech ref manual.  Others can tell us if these
functions are documented differently for DOS 2.0, 3.0, 3.2, etc - these are
the only tech ref manuals I have.  I hope this helps.   ~z~
-- 
Zhahai Stewart
{hao | nbires}!gaia!zhahai

krause@uiucdcsm.UUCP (02/19/87)

> Well, quite some time ago I also heard that CX=0 on a write would truncate
> the file.  When I became curious about it recently, I looked in the IBM
> PC-DOS Technical reference manuals for DOS 2.1 and 3.0 (the only ones I
> had available).  I looked in the function documentation distributed to
> OEM's by Microsoft for MS-DOS 2.0.  I also looked in the book
> "Advanced MS-DOS" by Ray Duncan.
> 
> None of these sources mentioned a thing about CX=0 being a legal value or
> not, much less saying that it allows you to truncate a file.
> ...
> Perhaps you could give us some clue about WHERE you saw it stated, instead
> of simply yelling at us for being so ignorant as to overlook the
> documentation.  Thanks for your time.
> -- 
> Roy J. Mongiovi
> ...!{akgua, allegra, amd, hplabs, ihnp4, masscomp, ut-ngp}!gatech!gitpyr!roy

I checked two of the three sources mentioned and found the CX=0 behavior
documented (Advanced MS-DOS, p. 320, and IBM DOS Tech. Ref. Ver. 2.10, p. 5-28)
under function call 28H, as specified in the posting to which you are
referring.  I didn't check the DOS 3.0 manual because I don't have one.

Perhaps you could give us some clue about WHERE you looked?? :-)

What I would like to know is, does this work with the handle file calls?
(i.e. function call 40H, Write to file or device, after a lseek)

				James Krause
				krause@uicsrd.CSRD.UIUC.EDU

P.S.  It took me a while to realize what "RTFM" meant and then I, too,
	was offended a bit....

nomad@gitpyr.UUCP (02/19/87)

Quoting from the Microsoft MS-DOS Version 3 Programmer's Utility Pack,
published Zenith Data Systems, page 4.212,

	The write system call (Function 40H) with a count of 
	zero (CX = 0) will truncate the file at the current position.

Jay K. Joiner
Georgia Insitute of Technology, Atlanta, Georgia 30332
...!{akgua,allegra,amd,hplabs,ihnp4,seismo,ut-ngp}!gatech!gitpyr!nomad

perry@omepd.UUCP (02/19/87)

In article <3105@gitpyr.gatech.EDU> roy@gitpyr.gatech.EDU (Roy Mongiovi) writes:
>In article <2596@well.UUCP>, tenney@well.UUCP (Glenn S. Tenney) writes:
>> That is exactly the way it is documented!
>> RTFM:  function 28 Random Block Write
>>    ...  If CX is zero upon entry, no records are written, but the
>>         file is set to the length specified by the random record field,
>>         whether longer or shorter than the current file size.
>
> [...Roy telling us where he DIDN'T find this documented...]
>
>I know what RTFM means, and I consider it rude, especially when it involves
>something as (apparently) obscurely documented as this "feature" of MS-DOS.
>Perhaps you could give us some clue about WHERE you saw it stated, instead
>of simply yelling at us for being so ignorant as to overlook the
>documentation.  Thanks for your time.

Well, I don't know where Glenn got his quotation, but my MSDOS Programmer's
Reference Manual says exactly that in its description of function 28H
(though the wording is different). If this official MSDOS description makes
explicit mention of the feature, it can hardly be *obscurely documented*.
By the way, the equivalent handle write function (40H) has the same feature
(length=0 -> set file size), so it is definitively intended and not just some
underhanded side effect.

I am somewhat surprised that most of You don't seem to read the Programmer's
Reference Manual; after all, it's by definition the primary reference source
for (the external appearence of) MSDOS! Though it does have its oddities and
bugs, I have found it to be a decent, halfway complete description of the
MSDOS programming interface.

P.S.: What DOES *RTFM* mean?
------------------------------------------------------------------------
  <<  Perry The Cynic >>	      ...!tektronix!ogcvax!omepd!inteloa!perry
						...!verdix!omepd!inteloa!perry
    (Peter Kiehtreiber)		      -or try- perry@inteloa.intel.com
------------------------------------------------------------------------
  <<  Perry The Cynic >>	      ...!tektronix!ogcvax!omepd!inteloa!perry
						...!verdix!omepd!inteloa!perry
    (Peter Kiehtreiber)		      -or try- perry@inteloa.intel.com

perry@omepd.UUCP (02/19/87)

In article <1987Feb15.123004.21019@gpu.utcs.toronto.edu> lewan@gpu.utcs.toronto.edu (S. Lewandowsky) writes:
>How can I truncate a file using DOS?  For example, I may open a
>file, write to it and read from it extensively, and as a result its size
>--when I use the close file handle call--would be about 120K or greater.
>However, I only want to save the first 10K of that file, so I'd like to
>place the file pointer to whereever I want the file to end, and then 
>truncate it so that the information beyond the pointer is discarded
>and the file size is reduced to 10K.
>There is a truncate procedure in Turbo Pascal, so there must be a way
>of doing it--but how do I do it in an ASM program using INT 21H?

Fresh from the MSDOS Programmer's Reference Manual:

Both the `random block write' (28H) and the `write handle' (40H) functions
of MSDOS process a special case: If you specify a write length of zero
(i.e., CX=0), the file length is set. The FCB function (28H) sets the
length to the `relative record' field in the FCB, while the handle operation
(40H) uses the current file pointer. In both cases, the result is either a
lengthening or a truncation.

			Commercial Time:

Allow me to point out once more that the
		MSDOS PROGRAMMER'S REFERENCE MANUAL
contains BY DEFINITION all the official answers to the programming interface
of MSDOS. If it isn't in there, it isn't official. This manual also includes
a set of migration rules (i.e., what features to avoid) that might give your
programs a MUCH brighter future.

Of course, IBM has its own `official' definition of MS- pardon PCDOS. But I
think they have mainly tinkered with the internals, not the interface.
I wouldn't know for sure, I don't buy anything from IBM...

Disclaimer: No relation to Microsoft, except as a (sometimes frustrated) user.
------------------------------------------------------------------------
  <<  Perry The Cynic >>	      ...!tektronix!ogcvax!omepd!inteloa!perry
						...!verdix!omepd!inteloa!perry
    (Peter Kiehtreiber)		      -or try- perry@inteloa.intel.com
------------------------------------------------------------------------
  <<  Perry The Cynic >>	      ...!tektronix!ogcvax!omepd!inteloa!perry
						...!verdix!omepd!inteloa!perry
    (Peter Kiehtreiber)		      -or try- perry@inteloa.intel.com

campbell@maynard.UUCP (02/19/87)

In article <3105@gitpyr.gatech.EDU> roy@gitpyr.gatech.EDU (Roy Mongiovi) writes:

>Well, quite some time ago I also heard that CX=0 on a write would truncate
>the file.  When I became curious about it recently, I looked in the IBM
>PC-DOS Technical reference manuals for DOS 2.1 and 3.0 (the only ones I
>had available).  I looked in the function documentation distributed to
>OEM's by Microsoft for MS-DOS 2.0.  I also looked in the book
>"Advanced MS-DOS" by Ray Duncan.
>
>None of these sources mentioned a thing about CX=0 being a legal value or
>not, much less saying that it allows you to truncate a file.

My IBM "DOS Technical Reference", publication no. 6138536 (for DOS 3.10)
documents this behavior, both for function 0x28 (random block write, pg. 6-85)
and function 0x40 (write to a file or device, pg. 6-126).

Also, my Microsoft "MS-DOS Operating System Programmer's Reference Manual",
document no. 8411-200-00 (for DOS 2.01) documents this behavior, both for
function 0x28 (pg. 1-84) and function 0x40 (pg. 1-117).

The latter document is copyright 1981 and 1983 by Microsoft, so this
information has been available for at least four years.
-- 
Larry Campbell                                The Boston Software Works, Inc.
Internet: campbell@maynard.uucp             120 Fulton Street, Boston MA 02109
uucp: {alliant,wjh12}!maynard!campbell              +1 617 367 6846
ARPA: campbell%maynard.uucp@harvisr.harvard.edu      MCI: LCAMPBELL

perry@omepd.UUCP (02/19/87)

In article <1987Feb15.123004.21019@gpu.utcs.toronto.edu> lewan@gpu.utcs.toronto.edu (S. Lewandowsky) writes:
>How can I truncate a file using DOS?  For example, I may open a
>file, write to it and read from it extensively, and as a result its size
>--when I use the close file handle call--would be about 120K or greater.
>However, I only want to save the first 10K of that file, so I'd like to
>place the file pointer to whereever I want the file to end, and then 
>truncate it so that the information beyond the pointer is discarded
>and the file size is reduced to 10K.
>There is a truncate procedure in Turbo Pascal, so there must be a way
>of doing it--but how do I do it in an ASM program using INT 21H?

Fresh from the MSDOS Programmer's Reference Manual:

Both the `random block write' (28H) and the `write handle' (40H) functions
of MSDOS process a special case: If you specify a write length of zero
(i.e., CX=0), the file length is set. The FCB function (28H) sets the
length to the `relative record' field in the FCB, while the handle operation
(40H) uses the current file pointer. In both cases, the result is either a
lengthening or a truncation.

			Commercial Time:

Allow me to point out once more that the
		MSDOS PROGRAMMER'S REFERENCE MANUAL
contains BY DEFINITION all the official answers to the programming interface
of MSDOS. If it isn't in there, it isn't official. This manual also includes
a set of migration rules (i.e., what features to avoid) that might give your
programs a MUCH brighter future.

Of course, IBM has its own `official' definition of MS- pardon PCDOS. But I
think they have mainly tinkered with the internals, not the interface.
I wouldn't know for sure, I don't buy anything from IBM...

Disclaimer: No relation to Microsoft, except as a (sometimes frustrated) user.


------------------------------------------------------------------------
  <<  Perry The Cynic >>	      ...!tektronix!ogcvax!omepd!inteloa!perry
						...!verdix!omepd!inteloa!perry
    (Peter Kiehtreiber)		      -or try- perry@inteloa.intel.com

brandon@tdi2.UUCP (02/21/87)

Quoted from <3105@gitpyr.gatech.EDU> ["Re: Truncating MS-DOS files"], by roy@gitpyr.gatech.EDU (Roy Mongiovi)...
+---------------
| In article <2596@well.UUCP>, tenney@well.UUCP (Glenn S. Tenney) writes:
| > That is exactly the way it is documented!
| > RTFM:  function 28 Random Block Write
| >    ...  If CX is zero upon entry, no records are written, but the
| >         file is set to the length specified by the random record field,
| >         whether longer or shorter than the current file size.
| 
| Well, quite some time ago I also heard that CX=0 on a write would truncate
| the file.  When I became curious about it recently, I looked in the IBM
| PC-DOS Technical reference manuals for DOS 2.1 and 3.0 (the only ones I
| had available).  I looked in the function documentation distributed to
| OEM's by Microsoft for MS-DOS 2.0.  I also looked in the book
| "Advanced MS-DOS" by Ray Duncan.
| 
| None of these sources mentioned a thing about CX=0 being a legal value or
| not, much less saying that it allows you to truncate a file.
+---------------

Well, we now have *another* reason not to buy Big Blue!  This was quite
clearly documented in my ITT DOS manual, which came with the computer.

++Brandon
-- 
``for is he not of the Children of Luthien?  Never shall that line fail, though
the years may lengthen beyond count.''  --J. R. R. Tolkien

Brandon S. Allbery	           UUCP: cbatt!cwruecmp!ncoast!tdi2!brandon
Tridelta Industries, Inc.         CSNET: ncoast!allbery@Case
7350 Corporate Blvd.	       INTERNET: ncoast!allbery%Case.CSNET@relay.CS.NET
Mentor, Ohio 44060		  PHONE: +1 216 255 1080 (home) +1 216 974 9210