In SunOS and BSD/386 I find:
int ftruncate(int fd, off_t length)
truncate a file to a specified length
In DOS Turbo C++ I find:
int chsize(int handle,k long size)
Changes the file size.
Thanks for any suggestions,
Craig H. Anderson
C4 Network, Inc.
518 17th Street, Suite 1400
Denver, CO 80202
(303) 825-8183
FAX (303) 893-6510
c4c...@csn.org
I hope that the POSIX standard has ftruncate(), but let's hope this will
be answered by someone who knows.
If you want to be portable to most ANSI C implementations (including those
which are not POSIX conforming) then the answer is ugly. Use fopen() to
create a new file with some name that you think will be acceptable (e.g.
will be located on the same physical device and partition and probably
directory as the old file), copy the contents of the old file to the new
one, stop where you want it truncated, fclose() the new file, remove() the
old one, and rename() the new one. There is no guarantee that this will
work (disk space might be exceeded or the implementation can return failure
status for any reasons it wishes) but this is as close as you can get.
This will probably lose the file permissions and various other OS-dependent
stuff that were set on the old file.
I would define a few flags at compile time and do stuff like
#if have_unix_fds && have_ftruncate
status = ftruncate(fileno(my_file), where);
#else
all that garbage
#endif
>In DOS Turbo C++ I find:
>int chsize(int handle,k long size)
> Changes the file size.
If you only want to port to POSIX conforming systems, you'll have UNIX-style
file descriptor numbers (which are probably the same as handles) and, I hope,
ftruncate. If you want to port to all ANSI C implementations, you'll have
to change all of your handles to use stdio-style files.
--
Norman Diamond dia...@jit081.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.
"Yeah -- bad wiring. That was probably it. Very bad."
POSIX (IEEE Std 1003.1-1988) doesn't have truncate or ftruncate. And not
all DOS C compilers have chsize. Sounds like a job for #ifdef :-(
Rewrite the program to avoid using it.
Really. That's the only way. There are operating systems which *cannot*
*do* this operation, so ANSI C does not provide it. And there are older
Unix implementations which can't do it, since Unix V7 -- the ancestor of
all modern Unixes -- did not have such a facility, and hence POSIX 1003.1
doesn't include it either.
--
There is nothing wrong with making | Henry Spencer @ U of Toronto Zoology
mistakes, but... make *new* ones. -D.Sim| he...@zoo.toronto.edu utzoo!henry
>Staying within POSIX-1, one good algorithm is
> a) copy from the original file to a temp file (the length in question)
> b) close and re-open the original file to truncate it to zero length
> c) copy from the temp file back to the original
> d) close files
> e) [optional] use utime() to reset the file mod times, etc.
>This preserves ownership, access permissions, links, etc.
[I think that should work in nearly all ANSI C implementations, except where
are exceeded. utime() is not available in all ANSI C implementations, and
I think I can imagine a configuration where permissions aren't saved, but
it's still quite good. Inefficient of course, but that's all we've got.]
Some C-coded Unix implementations of Fortran descended from AT&T "f77" do
exactly what this posting suggests, albeit in a particularly simpleminded
way.
The Fortran 77 standard defines a sequential access file which permits READ,
WRITE, BACKSPACE, and REWIND operations; it dictates that whenever the user
moves the file position backwards and executes a WRITE, the file must be
truncated.
I had the pleasure of fixing a Unix "f77" which used "fork" and "exec" to run
"/bin/cp" to copy from the temp file back to the original: the bug report was
that the user program executed correctly but the OS ran out of swap space
when the program terminated. Poor Unix didn't realize it was copying 100Mb
of core image for the sole purpose of overlaying it with "/bin/cp".
My observations are:
(1) It's a pity that ANSI C and POSIX do not support a reasonably
efficient implementation of one of the most common programming
languages.
(2) Although there surely exist file systems which do not provide
truncation, they are probably less common than C folklore suggests,
because most of them (even, nowadays, Unix) have been required by
the marketplace to provide a reasonably efficient Fortran.
I can see that perhaps POSIX should consider this, but isn't it
a bit much to expect ANSI C (a programming language standard) to
include features in order to better support f77 (another programming
language standard) (:^)?
--
Jim Patterson Cognos Incorporated
Sr Consulting Engineer P.O. BOX 9707
UUNET:ji...@cognos.COM 3755 Riverside Drive
PHONE:(613)738-1338 x3385 Ottawa, Ont K1G 3Z4
If C were intended to be an application language that would do everything
for the application programmer, I would have the same opinion. But C was
invented as a replacement for assembly language, to do nearly everything
that system programmers would need in support of higher level operations.
This higher level operation was developed around 11 years before the
invention of C.
I think we have to invent a new system programming language all over again.
Followups to alt.lang.cfutures. Whoops, not C. OK, I give up.