[BUG] file Truncate is it really busted?

Greg A. Woods woods at weird.com
Thu Nov 29 03:45:48 UTC 2001


[ On Thursday, November 29, 2001 at 13:36:25 (+1300), Richard A. O'Keefe wrote: ]
> Subject: Re: [BUG] file Truncate is it really busted?
>
> woods at weird.com (Greg A. Woods) replied to my explanation of the
> 'f' prefixes in C file handling functions.
> 
> 	Well there's also the fact that the two uses of the 'f' prefix are
> 	really in fundamentally different levels of the API -- or depending on
> 	your point of view maybe even completely different APIs.
> 
> Fundamentally different?

Note I said "completely different", not "fundamentaly different"  ;-)

>  Some of them are in the kernel, and some of them
> are in the C stdio library,

Well on most unix and unix-like systems both the kernel system call
functions and the stdio functions are in libc.  If the system call
interfaces had ever been supplied separately it might have been in a
library called libsys.  Libc has become a mess of a whole slew of other
very much unrelated APIs.

> but from the point of view of your average UNIX
> programmer this is a distinction without a difference.

Perhaps that's true, though I don't really believe anyone with even a
small amount of C programming experience could confuse the set of kernel
interface functions that deal with file descriptors and the set of
"higher" stdio functions that deal with the buffered file I/O using
pointers to structures in which the library maintains internal state.

>  open() and fopen()
> are *both* in POSIX.

Yeah, sure, but that's really got nothing whatsoever to do with their
differences.....  POSIX defines the API for many unrelated sets of
functions.

>  A UNIX look-alike could quite legitimately place
> fopen() in the kernel and open() in a library, just like it is on my Mac
> at home.  (Yep, Think C layered the UNIX functions on top of the stdio
> functions, and they were layered on top of the MacOS ones.)

Hmmm... that's not really an important distinction in a single user
system where the hardware doesn't properly isolate the data and code of
the system from the data and code of user programs.  The implementation
of a difference between lower-level "kernel" file access functions and a
layer of buffered I/O functions in a single address space, especially in
C or something even lower-level, kind of makes all these distinctions
artificial.

> 	The stdio library functions that have an 'f' prefix operate on
> 	FILE structures.  The system calls that have an 'f' prefix
> 	operate on kernel file descriptors.
> 	
> Yes, I know.  That's pretty much what I said.  That's the PROBLEM.

I don't see how there can be a problem so long as you keep a separate
view in your mind of the kernel API and the stdio API, and never attempt
to mix the two without first gaining a deep understanding of the
potential interactions of the particular mix you contemplate.

Since we're discussing this in a forum and in a context that relates to
interfaces in an object-oriented system how about we simply declare that
the lower level file-descriptor functions are in one class, and that the
stdio functions are in another class (perhaps a richer class derived
from the former one).  The distiction is somewhat arbitrary from a C
compiler's point of view, and it's only if you use the Unix manual
chapters as a way of separating one class definition from another that
you'll see a literal distinction.

>  The getchar(), getc(), putchar, putc(), printf(), and scanf()
> functions, amongst others, operate on the internal elements of a FILE
> structure, but don't have a FILE * argument.

Ah, now you're taking the analogy backwards and far too far.

It's irrelevant whether there are also stdio functions which expect a
FILE* parameter but which do not have an 'f' prefixing their name.

You're perhaps confusing naming conventions between two unrelated APIs.
There's no direct connection between the 'f' prefix and the fact that
the function is a stdio function.  If you read again very carefully
exactly what I wrote above, and don't go on and read more into it than
I've written, you'll also see that what I said was _not_ an attempt to
imply that all stdio functions taking a FILE* parameter have an 'f'
prefix either (or correspondingly that not all system calls expecting a
file descriptor parameter will have an 'f' prefix either)!  ;-)

> Some stdio functions with a FILE* prefix have an f prefix.  Some don't.

Exactly!  ;-)

> A uniform rule appears to have been applied to *both* the (2) and (3s)
> functions:  if you want a file handling function, and there is already
> one with the name you want, stick an 'f' in front.

Yup, that's proabably a good enough analysis of how the names might have
been created.

>  Anyone looking for
> a deeper level of meaning is looking for consistency that just isn't there.

Indeed!  ;-)

> I'm sorry, but this is precisely why it WOULD make sense to have fftruncate(),
> because ftruncate(fileno(fp)) just plain doesn't work.  I *think* the
> following code will work, but of course it isn't portable to systems that
> don't have f{un,}lockfile():

Ah, I see -- you have some rather extravagant expectations!  :-)

'ftruncate(fileno(fp))' does in fact work, perfectly even -- it just
doesn't leave the FILE* pointed to by 'fp' in any kind of useful state,
and expecting it to do so is perhaps unrealistic since you're mixing too
many operations between different levels.

Any programmer wanting to use your fftruncate() would I think be
creating something more complex than he apparently understands.

Generally speaking any experienced Unix programmer will endeavour to
never mix stdio operations on a given file with low-level file
descriptor I/O operations on the same file.  Perhaps this strange
example of ftruncate(fileno(fp) is a strange exception that might have
some use in a program that may have been handed an already open file
descriptor and thus might not know its pathname and so might use this
construct to truncate the file.  The result of course will generally
make the FILE* unusable unless the programmer has taken care to
implement something like the mechanism you suggested.

-- 
							Greg A. Woods

+1 416 218-0098      VE3TCP      <gwoods at acm.org>     <woods at robohack.ca>
Planix, Inc. <woods at planix.com>;   Secrets of the Weird <woods at weird.com>




More information about the Squeak-dev mailing list