Files & dirs: historical reasons?

S

Sensei

I was having an interesting discussion about the ANSI C and some
``weird inconsistencies'', or at least what at first sight can be seen
as an imbalance. I hope someone can satisfy my curiosity.

The standard provides means to open files associating a /path/ with a
/stream/. The standard does not provide any means to handle
/directories/. There are three streams defined by the standard, stdin
stdout stderr. Am I right?

Now, what is the reason for /not/ defining the directory counterparts
for files (something like fopen, with a directory dopen)?

We know that there exist platforms (e.g. on firmwares) where we can
hardly use ``files'' (with /paths/) while we can play with the three
standard std* /streams/. Paths of files are highly system dependent
just like directories. Files on the other hand are more likely to exist
on many platforms, or at least it seems to us.

Is there any reason? Is the standard going to change? Are directories
treated as normal files?

I know it might be a stupid question, but I'm curious about the history
behind choices :)

Thanks!
 
R

Richard Heathfield

Sensei said:
I was having an interesting discussion about the ANSI C and some
``weird inconsistencies'', or at least what at first sight can be seen
as an imbalance. I hope someone can satisfy my curiosity.

The standard provides means to open files associating a /path/ with a
/stream/. The standard does not provide any means to handle
/directories/. There are three streams defined by the standard, stdin
stdout stderr. Am I right?

Almost. The only time the Standard uses the word "path" is in a different
context completely: "Other paths to program termination, such as calling
the abort function, need not close all files properly", which is obviously
not what you are talking about! Otherwise, yes, you are correct.

Now, what is the reason for /not/ defining the directory counterparts
for files (something like fopen, with a directory dopen)?

Not all file systems have the concept of "directory", and this includes some
prominent systems such as VM/CMS and OS390 (aka MVS). CP/M had no concept
of "directory" either. Nor did MS-DOS 1.0. Undoubtedly there are others,
too.

[...] Is the standard going to change?

It's very unlikely.
Are directories treated as normal files?

I'm pretty sure Unix thinks of directories as merely a weird kind of file.
For example, IIRC you can fopen them. Windows sees them as being separate
beasts altogether (and you can't fopen them). And, as I said, some systems
don't have the concept at all.
I know it might be a stupid question,

There are such things as stupid questions, but I don't think of this as
being one of them.

<snip>
 
W

Walter Roberson

Richard Heathfield said:
I'm pretty sure Unix thinks of directories as merely a weird kind of file.
For example, IIRC you can fopen them.

That depends on the Unix version. It was traditionally true in
System V unix with the 14 character path components and 2 character inode
numbers, but as filesystems became more advanced and directory files
become more complex, it wasn't uncommon for Unices to prevent users
from fopen'ing directories.
 
M

mensanator

Richard said:
Sensei said:


Almost. The only time the Standard uses the word "path" is in a different
context completely: "Other paths to program termination, such as calling
the abort function, need not close all files properly", which is obviously
not what you are talking about! Otherwise, yes, you are correct.



Not all file systems have the concept of "directory", and this includes some
prominent systems such as VM/CMS and OS390 (aka MVS). CP/M had no concept
of "directory" either. Nor did MS-DOS 1.0. Undoubtedly there are others,
too.

Yeah, the PDP-11 I used with an RT-11 OS had no subdirectories.
All the files were in one place, had to be unique names and limited
to 8 characters (I think). It was a real PITA.

OTOH, you never had to recurse subdirectories.
[...] Is the standard going to change?

It's very unlikely.
Are directories treated as normal files?

I'm pretty sure Unix thinks of directories as merely a weird kind of file.
For example, IIRC you can fopen them. Windows sees them as being separate
beasts altogether (and you can't fopen them). And, as I said, some systems
don't have the concept at all.
I know it might be a stupid question,

There are such things as stupid questions, but I don't think of this as
being one of them.

<snip>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
 
J

John Bode

Richard said:
Sensei said:

[snip]
Now, what is the reason for /not/ defining the directory counterparts
for files (something like fopen, with a directory dopen)?

Not all file systems have the concept of "directory", and this includes some
prominent systems such as VM/CMS and OS390 (aka MVS). CP/M had no concept
of "directory" either. Nor did MS-DOS 1.0. Undoubtedly there are others,
too.

HP MPE and Encore MPX are two that I worked on personally. IIRC, the
file naming syntax was something like group.account.filename, and none
of the three elements could exceed 8 characters.

C is a product of the early '70s and this is one area where it shows.
 
P

pete

Sensei said:
There are three streams defined by the standard, stdin
stdout stderr. Am I right?

stdin, stdout and stderr, are macros
which expand to expressions of type FILE *.
The proper names of the streams are "standard input",
"standard output", and "standard error".
However, the streams are frequemtly refered to by their
associated macros.
 
K

Kenneth Brody

John said:
Richard said:
Sensei said: [...]
Now, what is the reason for /not/ defining the directory counterparts
for files (something like fopen, with a directory dopen)?

Not all file systems have the concept of "directory", and this includes some
prominent systems such as VM/CMS and OS390 (aka MVS). CP/M had no concept
of "directory" either. Nor did MS-DOS 1.0. Undoubtedly there are others,
too.

HP MPE and Encore MPX are two that I worked on personally. IIRC, the
file naming syntax was something like group.account.filename, and none
of the three elements could exceed 8 characters.

C is a product of the early '70s and this is one area where it shows.

On the other hand, why should the C standard care about the layout
of the filesystem on which it's running? Sure, I suppose one could
add some standard library functions (which, I suppose, would fail on
systems without "directories" and the like), but why bother? There
is already a POSIX standard which you can stick with if necessary.

Sometimes, O/S-related things don't necessarily belong in the language
specification.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Kenneth Brody

pete said:
stdin, stdout and stderr, are macros
which expand to expressions of type FILE *.
The proper names of the streams are "standard input",
"standard output", and "standard error".
However, the streams are frequemtly refered to by their
associated macros.

I don't believe that the standard requires that they be macros. They
simply need to be of type FILE*.

(I'm going by memory here, as I believe someone else quoted C&V about
this in the not-too-distant past.)

That said, all implementations I've bothered looking at were, as I
recall, implemented as macros.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
S

Sensei

Thanks to everybody! I can now see some historical reasons for this
reason, I knew there were some :)
 
F

forkazoo

Sensei said:
Thanks to everybody! I can now see some historical reasons for this
reason, I knew there were some :)


--
Sensei <senseiwa@Apple's mail>

Research (n.): a discovery already published by a chinese guy one month
before you, copying a russian who did it in the 60s.

Not only historical reasons, but also forward looking reasons. Many OS
vendors have been rumbling for years about eliminating our concepts of
the file system, and replacing them with a real database. Others have
suggested doing things like file type conversions at the OS level, so
you could conveivably see things like this at some point in the future:
(just examples, future syntax would probably look completely
different!)

fopen("!/SELECT NEWEST FILE WHERE CREATOR='bobsmith@local' AND
TYPE='imagefile'");

or

fopen("/home/bobsmith/images/sunflower.jpg"); to open the jpeg file
fopen("/home/bobsmith/images/sunflower.jpg/?convert=PNG"); to have the
system automatically convert the image to PNG, and then open that file.

So, in the first example, there is nothing like a directory. In the
second example, it would be really hard to figure out if sunflower.jpg
is supposed to be treated as a file, or as a directory containing
everything that the system could give you. Some platforms could even
allow http:// addresses right in fopen if they wanted, I think.

So, it would be really handy to have functions for dealing with
directories, but there are potentially so many ways of getting at a
file that if the C standard were to decide on one particular way, it
would probably make it unlikely that anybody would bother to come up
with something better.

At least, that's my personal take on why you will probably never see
directory related functionality in the C standard.
 
R

Random832

2006-12-19 said:
Kenneth Brody wrote On 12/19/06 09:39,:

You believe wrongly, infidel.

The standard requires some things that are utterly pointless. Requiring
that stdin/stdout/stderr are macros is one of these. Requiring that FILE
be a complete type is another.
 
R

Rg

Yep. And, just for curiosity, there's this amusing piece of code in
Linux stdio.h header:

/* Standard streams. */
extern struct _IO_FILE *stdin; /* Standard input stream. */
extern struct _IO_FILE *stdout; /* Standard output stream. */
extern struct _IO_FILE *stderr; /* Standard error output
stream. */
/* C89/C99 say they're macros. Make them happy. */
#define stdin stdin
#define stdout stdout
#define stderr stderr
 
E

Eric Sosman

Random832 wrote On 12/19/06 13:01,:
The standard requires some things that are utterly pointless. Requiring
that stdin/stdout/stderr are macros is one of these. Requiring that FILE
be a complete type is another.

I'd agree with "pointless" but not with "utterly." For
example, #ifdef stdin is a portable way to test whether <stdio.h>
has or has not been included. I can't imagine much utility in
such a test, but my imagination is less than infinite.

However, the question was not about whether the Standard's
requirements are good or bad, but about what is required.
 
R

Random832

[comp.std.c added, followups set]

2006-12-19 said:
Random832 wrote On 12/19/06 13:01,:

I'd agree with "pointless" but not with "utterly." For
example, #ifdef stdin is a portable way to test whether <stdio.h>
has or has not been included. I can't imagine much utility in
such a test, but my imagination is less than infinite.

Well, if that was their reason, then they'd have done something like
"defines _STDIO_H" for all the headers. I think it was just a wording
flaw.
 
P

pete

Kenneth said:
I don't believe that the standard requires that they be macros. They
simply need to be of type FILE*.

(I'm going by memory here, as I believe someone else quoted C&V about
this in the not-too-distant past.)

I did.

Within this part of the ISO/IEC 9899: 1990 standard:
7.9 Input/output <stdio.h>
7.9.1 Introduction
you should locate this phrase: "The macros are",
and then you should keep reading until
you come to the period at the end of the sentence.
 
D

Dik T. Winter

> Yep. And, just for curiosity, there's this amusing piece of code in
> Linux stdio.h header:
>
> /* Standard streams. */
> extern struct _IO_FILE *stdin; /* Standard input stream. */
> extern struct _IO_FILE *stdout; /* Standard output stream. */
> extern struct _IO_FILE *stderr; /* Standard error output
> stream. */
> /* C89/C99 say they're macros. Make them happy. */
> #define stdin stdin
> #define stdout stdout
> #define stderr stderr

And from Solaris (similar to older versions of Unix):
#define stdin (&__iob[0])
#define stdout (&__iob[1])
#define stderr (&__iob[2])

Try to do that without macros. Traditionally many systems did use
macros for them for the above reason. Now I disremember why it is
a requirement, probably it is stated in the Rationale. Probably
to make the statements in that part of the standard concise.
 
R

Roland Pibinger

The standard requires some things that are utterly pointless. Requiring
that stdin/stdout/stderr are macros is one of these. Requiring that FILE
be a complete type is another.

FILE needs to be a complete type because otherwise you could not e.g.
implement getc as a macro.

Best regards,
Roland Pibinger
 
R

Random832

2006-12-20 said:
FILE needs to be a complete type because otherwise you could not e.g.
implement getc as a macro.

#define getc(F) fgetc(F) // I refute it thus.
 
E

Eric Sosman

Roland said:
FILE needs to be a complete type because otherwise you could not e.g.
implement getc as a macro.

Counterexample (non-conforming because of the requirement):

typedef _builtin_compiler_magic_file FILE;
#define getc(fp) _builtin_compiler_magic_getc(fp)

.... the point being that a conforming C implementation need not
be written in conforming C, or in C at all.

Like pretty much everyone else I don't see why the Committee
chose to require that FILE be a complete type. However, the
requirement is "harmless" in the sense that it doesn't limit the
implementation's freedom much. For example

typedef struct _file *FILE;

.... allows the implementation to hide its treasures in the
incomplete `struct _file' type while revealing the complete
type FILE (pointer to `struct _file') to the program at the
cost of an extra indirection (FILE* is now `struct _file **').
An implementation with a yen for privacy could use even more
densely obfuscated techniques if it wanted.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top