Topic: fstream and good ol' file descriptors


Author: Koen Deforche <jozef@minerf.gv.kotnet.org>
Date: 1998/08/22
Raw View
In comp.std.c++ Fergus Henderson <fjh@cs.mu.OZ.AU> wrote:
> "Jim Cobban" <Jim.Cobban.jcobban@nt.com> writes:

>>The biggest piece of missing
>>functionality is fstat.  As far as I can see all of the other functionality
>>of a file descriptor is already available.

> There's also select(), ioctl(), mmap(), ...

> And something analgous to fdopen() would be useful too.

True, and what about pipes ? I've had very much trouble using an
ostream for both an ofstream and an ostream to a pipe.

Especially, because man pages to popen() state that you have to close
the file with pclose(). So is this allowed ? Is there a better way ?

(when trying something like this with reading instead of writing,
i got into trouble)

{
   FILE *apipe = popen((const char *)name, "w");
   ofstream file(fileno(apipe));

   /* do things with file */

   pclose(apipe);
}


koen.

--

/- What linux really needs is a National Park.
   Like Yosemite. Perhaps with themes.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: tony@ns.cook.ml.org (Tony Cook)
Date: 1998/06/30
Raw View
Paul D. DeRocco (pderocco@ix.netcom.com) wrote:
: Tony Cook wrote:
: >
: > Some file systems don't include the notion of a stream of bytes.  With
: [snip my own text]

: That all sounds like ancient history. (Especially since Wang went
: belly-up.) Was that an actual C++ compiler, or just a C compiler?

Just a C compiler.

:Does
: anyone think that it is important that the modern C++ standard (or at
: least the I/O library) be implementable on some arcane machine that
: absolutely doesn't have any means of presenting a file as an array of
: raw bytes?

That isn't the question though - if a system usually implements a
'text file' as a list of records, then the C or C++ library on that
system should be able to open that file as a FILE or fstream.

I believe currently used[1] VMS and some IBM mainframe operating systems
can also use record-oriented files as text files (but I'm on very
shaky ground here).

[1] I think


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/07/01
Raw View
Tony Cook wrote:
>> Some file systems don't include the notion of a stream of bytes.
>> With one system I used (Wang VS), the compiler implemented binary
>> files as a file with 1 byte fixed-length records[1], but normal text
>> files were files of variable length records - the file system stored
>> the files fitting as many records per block as would fit and then
>> moved onto the next block.  There weren't any line separators, just
>> record lengths.  ...

Paul D. DeRocco wrote:
> That all sounds like ancient history. (Especially since Wang went
> belly-up.) Was that an actual C++ compiler, or just a C compiler? Does
> anyone think that it is important that the modern C++ standard (or at
> least the I/O library) be implementable on some arcane machine that
> absolutely doesn't have any means of presenting a file as an array of
> raw bytes?

Ah, ancient history.  The real reason behind the Y2K bug.

I can tell by your questions that you've never worked on a
mainframe.  I can also tell that your experience with computers
has been limited to PCs and Unixes.  Don't take this as an insult,
just realize that you've led a sheltered life compared to those
of us a little older than you.

Fully 85% of all business computing today runs on mainframes.
Most of those programs are written for IBM mainframes, and most
of those are CICS applications.  So mainframes are alive and doing
quite well (have you seen IBM's net revenues lately?).

And yes, C has been successfully implemented on IBM mainframes,
as well as a large variety of other mainframes.  Almost all of
them handle I/O as records arranged in blocks within files
residing on physical devices.  It is possible to implement the
ISO stdio functions on top of such a system, and they have been.
One of the reasons that ISO C standardized the stdio functions was
because they provide a very useful and general abstraction of I/O,
and can thus theoretically be implemented fairly efficiently on
practically all existing I/O systems.

Many applications running on mainframes are written in C and C++.
Indeed, you can even write CICS applications in C and C++ on P/390
systems.  IBM has done quite a lot in the last few years, adding
C and C++ interfaces to their systems and utilities, as have many
of the other big iron makers.  And they take an interest in the
ISO standards for C and C++.  Is I recall, IBM has a representative
on both committees.  I would wager that IBM does indeed think it's
important that they can implement the modern C++ library on their
hardware.

And let's not forget other "arcane" operating environments, such
as embedded palmtop computers, which simulate file systems in
nonvolatile memory.  The stdio API works quite well in those
systems, too.

Don't forget that the stdio functions are implemented in Unix
and MS-DOS on top of the open/read/write/seek calls, which
communicate with the underlying file system drivers in units of
blocks, not bytes.  What you see as individual characters and
newlines is a fiction provided to you by the operating system
for your convenience.  It's simply that some operating systems
give you a nicer fiction to work with than others.  But that
doesn't make the other systems any less important.

-- David R. Tribble, dtribble@technologist.com --
-- C++, the PL/1 of the 90s.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: tony@ns.cook.ml.org (Tony Cook)
Date: 1998/06/29
Raw View
Paul D. DeRocco (pderocco@ix.netcom.com) wrote:
: Jerry Leichter wrote:
: >
: > c)  In any case, Standard C FILE*'s are *not* "strings of bytes":
: > They come in two flavors, binary, and text, and the text files
: > deliberately allow for "record-like" semantics.

: But aren't the text semantics (/r/n <-> /n conversion, for instance)
: built built on top of an underlying file system that is byte-oriented?
: And aren't the record semantics of COBOL files built on top of an
: underlying byte-oriented file system?

No.

Some file systems don't include the notion of a stream of bytes.  With
one system I used (Wang VS), the compiler implemented binary files as
a file with 1 byte fixed-length records[1], but normal text files were
files of variable length records - the file system stored the files
fitting as many records per block as would fit and then moved onto the
next block.  There weren't any line separators, just record lengths.
You could also open fixed length record files as "text", which only
had the length in the file entry[2].

[1] which was extraordinarily inefficient in the number of system
calls that needed to be made.  A later version of the RTL bypassed the
record system and opened the file in block mode, which had other
problems.

[2] I don't remember the exact terminology, like an inode in *nix.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jkanze@otelo.ibmmail.com
Date: 1998/06/29
Raw View
In article <35959BCF.B65B2882@ix.netcom.com>,
  "Paul D. DeRocco" <pderocco@ix.netcom.com> wrote:
>
> Jerry Leichter wrote:
> >
> > c)  In any case, Standard C FILE*'s are *not* "strings of bytes":
> > They come in two flavors, binary, and text, and the text files
> > deliberately allow for "record-like" semantics.
>
> But aren't the text semantics (/r/n <-> /n conversion, for instance)
> built built on top of an underlying file system that is byte-oriented?

The text semantics are built on top of the type of file system supported
by the host OS.  Under UNIX or Windows, this is a byte-oriented stream.
Under most other systems, though, it is a record oriented system.  This
is why, for example, the C standard does not guarantee that white space
at the end of line will be preserved.

> And aren't the record semantics of COBOL files built on top of an
> underlying byte-oriented file system?

See above: the record semantics of COBOL files are built on top of the
OS specific file system.  In fact, COBOL files are designed the way they
are to conform to the way most systems at the time organized their files.

> > If, indeed, having a Standard C FILE*'s semantics is what you are
> > after, I have to repeat the question:  What will you do with it that
> > you couldn't do with the iostream level to begin with?  Wouldn't it be
> > better to add those things to iostreams than to force the C++
> > Standard, and all C++ implementations, to carry around two complete
> > I/O abstraction?
>
> There is nothing intrinsically wrong with iostreams, other than that
> they are built on top of streambufs that provide buffering.

Neither C nor C++ offer any direct access to the underlying system reads
and writes.

> I personally
> don't mind writing mystream.read(buf, sizeof(buf)), but I'd also like to
> be able to get at the lower level stuff, in places where the added
> features of streambufs and streams isn't appropriate (for instance, when
> writing a database engine).

Agreed.  But it isn't covered in the language standard; you'll have
to use system dependant code to do it.

> > | > The size of a file, in terms meaningful to the program, may be
> > | > impossible to determine by any method easier than reading the
> > | ?  whole file using the stream's semantics and counting....
> > |
> > | Is there really any operating system that isn't capable of reporting
> > | the size of the file, at least in those cases where the data really
> > | is a file and not some pseudo-file like keyboard input? ...
> >
> > Of course; you're merely proving that you don't know how
> > record-oriented file systems work.
> >
> > Consider a system which maps COBOL-style record I/O directly into the
> > file system.  Each record comes with a marker that says how many lines
> > are to be advanced before and after it.  When you read such a file
> > into a stream emulation package, the package strips off the marker -
> > let's for the sake of argument say it's two bytes long, one byte each
> > for the count of leading and trailing line advances - it first
> > generates as many newlines as the leading count calls for; then the
> > actual data bytes; then the number of newlines the trailing count
> > calls for; and finally moves on to the next record.
>
> Are there really any operating systems that have C++ implementations
> (with fstreams and filebufs that make the files look like arrays of
> bytes) that have an underlying file system that is intrinsically
> record-oriented, so the only way you can treat a file as an array of
> bytes is by doing whatever translation the fstream or filebuf does?

Yes.  Unisys, I believe.  And there have been C implementations for
IBM mainframes, whose OS works this way.

> I
> find it hard to believe that COBOL-style record-based file systems
> aren't built on top of some sort of file system that presents a file as
> an array of bytes, numbered 0 to n-1, where n is the known length of the
> file.

At the lowest level, of course, ALL file systems are built on a record
based system, with fixed length records.  UNIX was, and still is, more
or less an exception in only providing a byte stream abstraction to
access this; the result is that most serious data bases under UNIX access
the raw disk, rather than use the file system.  (But I suspect that this
is true for most other systems as well.)

> Sure, once you've built a record-oriented file system (or for that
> matter a text-oriented file system that does /r/n <-> /n conversions) on
> top of a raw file system, the low-level information as to file size or
> position is no longer meaningful. But I assume that in all such systems
> you _can_ read and write at the low level where such sizes and positions
> are meaningful. I can imagine that there may be certain specific files
> that one is arbitrarily prohibited from accessing in this way, but I
> can't imagine that _all_ files on the system, including those that the
> programmer normally accesses through fstreams in C++, are record-based
> at the lowest level.
>
> I'm saying that the C++ standard should require that that low-level
> byte-array interface be exported and standardized, and that the way that
> filebufs talk to this raw file system should be specified, just as the
> way fstreams talk to filebufs is specified.

At least in the case of C, the semantics of FILE were designed expressedly
as to be reasonably implementable on systems which do NOT have a byte
stream as an underlying abstraction.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
        +49 (0)69 66 45 33 10    mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orientee objet --
              -- Beratung in objektorientierter Datenverarbeitung

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Darron Shaffer <darron.shaffer@beasys.com>
Date: 1998/06/29
Raw View
tony@ns.cook.ml.org (Tony Cook) writes:

> Paul D. DeRocco (pderocco@ix.netcom.com) wrote:
> : Jerry Leichter wrote:
> : >
> : > c)  In any case, Standard C FILE*'s are *not* "strings of bytes":
> : > They come in two flavors, binary, and text, and the text files
> : > deliberately allow for "record-like" semantics.
>
> : But aren't the text semantics (/r/n <-> /n conversion, for instance)
> : built built on top of an underlying file system that is byte-oriented?
> : And aren't the record semantics of COBOL files built on top of an
> : underlying byte-oriented file system?
>
> No.
>
> Some file systems don't include the notion of a stream of bytes.  With
> one system I used (Wang VS), the compiler implemented binary files as
> a file with 1 byte fixed-length records[1], but normal text files were
> files of variable length records - the file system stored the files
> fitting as many records per block as would fit and then moved onto the
> next block.  There weren't any line separators, just record lengths.
> You could also open fixed length record files as "text", which only
> had the length in the file entry[2].
>

VOS, from Stratus, also has a file system that used to have no "stream
of bytes" files.  Text files are variable length records, without the
'\n' stored on the disk.  No line may be longer than 32k.  The number
of bytes is a file is NOT STORED (just records & block counts).

Then eventually added a "stream" file type, for Unix programmers that
couldn't figure things out.  It still has limitations, and is useful
mainly to store binary "fwrite(&str, sizeof(str), 1, outfp)" type
files.  You can store text in these files, but you don't gain much.

They support ANSI C, but not POSIX -- no fstat, etc.

Oh, and you can open any file in "RAW" mode -- this is used for
generic file copy programs.  I understand that even stream files had
extra bytes that could be seen in this mode.  They really had records,
underneath.

--
 __  __  _
 _ ) ___ _\   Enterprise Middleware Solutions Darron J. Shaffer
 __) __    \  BEA Systems Inc.   Sr. Software Engineer
              17101 Preston Rd   darron.shaffer@beasys.com
              LB# 115, Ste 260    Voice: (972) 738-6137
              Dallas, TX 75248    Fax:   (972) 738-6111
       http://www.beasys.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/06/29
Raw View
Tony Cook wrote:
>
> Some file systems don't include the notion of a stream of bytes.  With
> one system I used (Wang VS), the compiler implemented binary files as
> a file with 1 byte fixed-length records[1], but normal text files were
> files of variable length records - the file system stored the files
> fitting as many records per block as would fit and then moved onto the
> next block.  There weren't any line separators, just record lengths.
> You could also open fixed length record files as "text", which only
> had the length in the file entry[2].
>
> [1] which was extraordinarily inefficient in the number of system
> calls that needed to be made.  A later version of the RTL bypassed the
> record system and opened the file in block mode, which had other
> problems.
>
> [2] I don't remember the exact terminology, like an inode in *nix.

That all sounds like ancient history. (Especially since Wang went
belly-up.) Was that an actual C++ compiler, or just a C compiler? Does
anyone think that it is important that the modern C++ standard (or at
least the I/O library) be implementable on some arcane machine that
absolutely doesn't have any means of presenting a file as an array of
raw bytes?

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/06/28
Raw View
Jerry Leichter wrote:
>
> c)  In any case, Standard C FILE*'s are *not* "strings of bytes":
> They come in two flavors, binary, and text, and the text files
> deliberately allow for "record-like" semantics.

But aren't the text semantics (/r/n <-> /n conversion, for instance)
built built on top of an underlying file system that is byte-oriented?
And aren't the record semantics of COBOL files built on top of an
underlying byte-oriented file system?

> If, indeed, having a Standard C FILE*'s semantics is what you are
> after, I have to repeat the question:  What will you do with it that
> you couldn't do with the iostream level to begin with?  Wouldn't it be
> better to add those things to iostreams than to force the C++
> Standard, and all C++ implementations, to carry around two complete
> I/O abstraction?

There is nothing intrinsically wrong with iostreams, other than that
they are built on top of streambufs that provide buffering. I personally
don't mind writing mystream.read(buf, sizeof(buf)), but I'd also like to
be able to get at the lower level stuff, in places where the added
features of streambufs and streams isn't appropriate (for instance, when
writing a database engine).

> | > The size of a file, in terms meaningful to the program, may be
> | > impossible to determine by any method easier than reading the
> | ?  whole file using the stream's semantics and counting....
> |
> | Is there really any operating system that isn't capable of reporting
> | the size of the file, at least in those cases where the data really
> | is a file and not some pseudo-file like keyboard input? ...
>
> Of course; you're merely proving that you don't know how
> record-oriented file systems work.
>
> Consider a system which maps COBOL-style record I/O directly into the
> file system.  Each record comes with a marker that says how many lines
> are to be advanced before and after it.  When you read such a file
> into a stream emulation package, the package strips off the marker -
> let's for the sake of argument say it's two bytes long, one byte each
> for the count of leading and trailing line advances - it first
> generates as many newlines as the leading count calls for; then the
> actual data bytes; then the number of newlines the trailing count
> calls for; and finally moves on to the next record.

Are there really any operating systems that have C++ implementations
(with fstreams and filebufs that make the files look like arrays of
bytes) that have an underlying file system that is intrinsically
record-oriented, so the only way you can treat a file as an array of
bytes is by doing whatever translation the fstream or filebuf does? I
find it hard to believe that COBOL-style record-based file systems
aren't built on top of some sort of file system that presents a file as
an array of bytes, numbered 0 to n-1, where n is the known length of the
file.

Sure, once you've built a record-oriented file system (or for that
matter a text-oriented file system that does /r/n <-> /n conversions) on
top of a raw file system, the low-level information as to file size or
position is no longer meaningful. But I assume that in all such systems
you _can_ read and write at the low level where such sizes and positions
are meaningful. I can imagine that there may be certain specific files
that one is arbitrarily prohibited from accessing in this way, but I
can't imagine that _all_ files on the system, including those that the
programmer normally accesses through fstreams in C++, are record-based
at the lowest level.

I'm saying that the C++ standard should require that that low-level
byte-array interface be exported and standardized, and that the way that
filebufs talk to this raw file system should be specified, just as the
way fstreams talk to filebufs is specified.

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/06/26
Raw View
In comp.std.c++ Jim Cobban <Jim.Cobban.jcobban@nt.com> wrote:
: In article <6mpc8f$5bj@marianna.psu.edu>,
: Oleg Zabluda  <zabluda@math.psu.edu> wrote:
: >: Only that functionality which is useful and
: >: does not conflict with other filebuf functionality should be exposed.  The
: >: file descriptor itself must not be exposed.  The biggest piece of missing
: >: functionality is fstat.  As far as I can see all of the other functionality
: >: of a file descriptor is already available.
: >
: >Oh yeh? What about fcntl(), dup()/dup2(), close(), select(),
: >socket stuff, mmap()/munmap(), and dealing with fie descriptors
: >you got from pipe(), socketpair() and such?

: Those functions apply only to specific types of files.

Not all. fcntl(), dup()/dup2(), close(), select() and poll()
can be applied to any file descriptor. I am not quite sure
what exactly limitations on mmap() are.

: They therefore
: should be implemented in derived streams, not in the general purpose
: filebuf.

I was not talking about implementing, say pipebuf. I was talking
more about being able to construct a filebuf or filestream from
a file desriptor and attach a file descriptor to an already
existing filestream. All this makes perfect sense under Posix and
I hope will be incorporated in a Posix C++ extentions. Amen.
Extracting a file descriptor from an open filestream is also very
clear, but I don't know the answer. See later.

: Remember that you are free to implement your own derived
: streambufs (I've done it myself).  Say we call this myfilebuf.  You are
: entirely free to have myfilebuf include a file descriptor and to expose
: whatever functionality from that filebuf that you want to expose.  Since you
: write the code which implements myfilebuf you can do whatever you want to
: the file descriptor.  You can then define a new iostream, say myiostream,
: which in turn provides access to the functionality exposed by myfilebuf.

: As a specific example of this, as implemented as an extension by Gnu C++,
: there is a class pfstream which implements stream access to a pipe.  If you
: have that then you do not need to use pipe().

Right. Now we have to standartize it all in Posix++. Amen.

: You mention file descriptor close().  What functionality does this provide
: that is not provided by fstream::close()?

For example, it's relatively common for a program to close() _all_
possible file descriptors it might have inherited from a parent. There
is no way to fstream::close() all fstreams it might have inherited from
a parent.

: My point is that there is NOTHING in the C++ standard which prevents you
: from accessing all of the functionality of a file descriptor through a
: stream.

That's right. However doing it in my own, non-standard, way
is ugly, obscure, error-prone and wasteful.

: However this discussion has been asking a different question.  It
: has been asking that std::filebuf provide a method which directly exposes
: the file descriptor which is assumed to be part of the implementation of
: std::filebuf.  I think that it is, in general, a very bad idea to have a
: method in ANY class which returns a reference to a private member, since by
: doing so you have simply made that private member public.  std::filebuf
: should expose as much as possible of the capabilities of the underlying file
: system as it can in a generic fashion.  I agree that the existing
: specification does not expose enough.  But std::filebuf should NOT expose the
: mechanism by which it delivers those capabilities.

This I might buy. The question is whether Posix people believe
there might be filestreams not associated with file descriptors
or such that the underlying file descriptor is impossible or
undesireble to extract. Fortunately, it's easy enough to find
out, Because they already answered this question. Can somebody
look up whether fileno(3) is Posix or not. We'll have the answer.

 [Moderator's note: yes, fileno() is part of POSIX.1. -fjh.]

We already know the answer to the other question -- if we should be
able to construct a filebuf from a file descriptor. The answer is
yes, as witnessed by fdopen().

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jerry Leichter <leichter@smarts.com>
Date: 1998/06/23
Raw View
| > You're making the common, erroneous assumption that all file systems
| > are Unix file systems.
| >
| > With a record-oriented file system, the underlying object almost
| > certainly will not support positioning except to record boundaries.
| > The stream implementation will have to emulate byte positioning by
| > defining a position in terms of a record and and offset within the
| > record.
|
| That's right. My point is that if they can get the fstream library to
| make any file system look like a string of bytes, then they ought to
| be able to get a standard file library make to any file system look
| like a Unix or Posix file system.

a)  As far as Standard C is concerned, there is nothing "below" a FILE*.
Unix programmers generally assume that there's a file descriptor below
the FILE*, with certain semantics; but that's a system-specific assump-
tion that will fail on other systems.

b)  Sure, you could mandate that a C++ implementation make something
much like a C FILE* visible.  If you require exactly the semantics
that's in Standard C for such a thing, it can probably be implemented
pretty easily, though a C++ implementation that was *not* constrained by
the need to maintain the fiction of a FILE* level might do better.
(Even a Unix implementation of iostreams would probably do best to avoid
using stdio.)

c)  In any case, Standard C FILE*'s are *not* "strings of bytes":  They
come in two flavors, binary, and text, and the text files deliberately
allow for "record-like" semantics.

If, indeed, having a Standard C FILE*'s semantics is what you are after,
I have to repeat the question:  What will you do with it that you
couldn't do with the iostream level to begin with?  Wouldn't it be
better to add those things to iostreams than to force the C++ Standard,
and all C++ implementations, to carry around two complete I/O
abstraction?

| > The size of a file, in terms meaningful to the program, may be
| > impossible to determine by any method easier than reading the whole
| > file using the stream's semantics and counting....
|
| Is there really any operating system that isn't capable of reporting
| the size of the file, at least in those cases where the data really is
| a file and not some pseudo-file like keyboard input? ...

Of course; you're merely proving that you don't know how record-oriented
file systems work.

Consider a system which maps COBOL-style record I/O directly into the
file system.  Each record comes with a marker that says how many lines
are to be advanced before and after it.  When you read such a file into
a stream emulation package, the package strips off the marker - let's
for the sake of argument say it's two bytes long, one byte each for the
count of leading and trailing line advances - it first generates as many
newlines as the leading count calls for; then the actual data bytes;
then the number of newlines the trailing count calls for; and finally
moves on to the next record.

Sure, the OS probably records the total number of bytes allocated to the
file.  If I tell you a file as 1000 bytes allocated to it, can you tell
me the output of the following program, assuming fin points to the file?

 int i = 0;
 char c;
 while (c << fin)
  i++;
 cout << i << endl;

In fact, for the most general implementation, the result could be
anything from 0 (the file consists entirely of empty records with both
leading and trailing line counts set to 0) to some very large number
(the file consists entirely of empty records with both leading and
trailing line counts set to 255).  (We can't give the exact number in
the latter case because we don't know how record boundaries are marked.
Perhaps the records are of fixed size, so there is no marker; perhaps
there is a 2- or 4-byte length; perhaps there's an end-or-record
character analogous to \n.)

Even if you know the number of records in the file, you can't do more
than (sometimes very) roughly approximate the size - and most systems do
*not* keep a record count:  Code typically doesn't need it, and
maintaining it when files were being accessed for shared write would be
expensive.

Lest you think this is an artificial example - you can almost duplicate
it on VMS.  New VMS programmers coming over from Unix regularly ask how
to determine the "size" of a file.  Yes, they can easily get the number
of bytes the OS has set aside - but that isn't what they are looking
for!

BTW, on a system like this, think about what seeking to an arbitrary
byte would involve!
       -- Jerry


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1998/06/23
Raw View
"Jim Cobban" <Jim.Cobban.jcobban@nt.com> writes:

>The biggest piece of missing
>functionality is fstat.  As far as I can see all of the other functionality
>of a file descriptor is already available.

There's also select(), ioctl(), mmap(), ...

And something analgous to fdopen() would be useful too.

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/06/24
Raw View
Jerry Leichter <leichter@smarts.com> wrote:
: | > You're making the common, erroneous assumption that all file systems
: | > are Unix file systems.
: | >
: | > With a record-oriented file system, the underlying object almost
: | > certainly will not support positioning except to record boundaries.
: | > The stream implementation will have to emulate byte positioning by
: | > defining a position in terms of a record and and offset within the
: | > record.
: |
: | That's right. My point is that if they can get the fstream library to
: | make any file system look like a string of bytes, then they ought to
: | be able to get a standard file library make to any file system look
: | like a Unix or Posix file system.

: a)  As far as Standard C is concerned, there is nothing "below" a FILE*.
: Unix programmers generally assume that there's a file descriptor below
: the FILE*, with certain semantics; but that's a system-specific assump-
: tion that will fail on other systems.

I think you are giving wrong impression about unix programmers.
Posix standartizes file descriptor semantics and provides
relationships between file descriptors an FILEs. Look at
fdopen() for an example. Another example is that by default
stdin, stdout and stderr are connected to file descriptors
0, 1 and 2 respectively. All this is inherited by C++,
of course.

: b)  Sure, you could mandate that a C++ implementation make something
: much like a C FILE* visible.  If you require exactly the semantics
: that's in Standard C for such a thing, it can probably be implemented
: pretty easily, though a C++ implementation that was *not* constrained by
: the need to maintain the fiction of a FILE* level might do better.
: (Even a Unix implementation of iostreams would probably do best to avoid
: using stdio.)

There is no problem in Unix to recreate a FILE* from a file
descriptor. It's all in Posix (see above). And with stdio it is
particularly easy (see above).

: c)  In any case, Standard C FILE*'s are *not* "strings of bytes":  They
: come in two flavors, binary, and text, and the text files deliberately
: allow for "record-like" semantics.

: If, indeed, having a Standard C FILE*'s semantics is what you are after,
: I have to repeat the question:  What will you do with it that you
: couldn't do with the iostream level to begin with?  Wouldn't it be
: better to add those things to iostreams than to force the C++ Standard,
: and all C++ implementations, to carry around two complete I/O
: abstraction?

No, because Posix has stuff that not all sustems have. You can't
force then on everyone by including it in std C++.

: | > The size of a file, in terms meaningful to the program, may be
: | > impossible to determine by any method easier than reading the whole
: | > file using the stream's semantics and counting....
: |
: | Is there really any operating system that isn't capable of reporting
: | the size of the file, at least in those cases where the data really is
: | a file and not some pseudo-file like keyboard input? ...

: Of course; you're merely proving that you don't know how record-oriented
: file systems work.

[...]

You are merely proving that you don't know how abstractions work.
If you can define what "size" means it is possible to report it.
On Posix systems it is required.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/06/24
Raw View
In comp.std.c++ Jim Cobban <Jim.Cobban.jcobban@nt.com> wrote:
: In article <6mcfvk$ipr@marianna.psu.edu>,
: Oleg Zabluda  <zabluda@math.psu.edu> wrote:
: >Raja R Harinath <harinath@cs.umn.edu> wrote:
: >: Nowhere does (nor IMHO should) the standard imply that fstreams should
: >: be implemented in terms of another file abstraction.  Codifying
: >: `filebuf::fd()' would pretty much do that.  It would also limit
: >: `fstream' to be based on an underlying implementation whose
: >: characteristics should all be accessible from just one value.
: >
: >That's the beauty of abstractions. No matter what the implementation,
: >if it's a file, you should be able to get a file desriptor pointing
: >to it.

: While there is functionality available on file descriptors which is not
: available from streams, there is a lot of functionality which should NOT be
: exposed because it could create conflicts.  For example I can imagine quite
: horrible things happening if you issued a close against the file descriptor
: since its state would not be out of synch with the encapsulating stream.

I can imagine quite horrible things happening if you memset all
bits of an fstream to zero. So what?

: You cannot expose the file descriptor without exposing ALL of its
: functionality.

: The file descriptor therefore, if present at all, must be a
: private member of the filebuf.

The beauty of abstractions is that it doesn't have to be
a member at all.

: Only that functionality which is useful and
: does not conflict with other filebuf functionality should be exposed.  The
: file descriptor itself must not be exposed.  The biggest piece of missing
: functionality is fstat.  As far as I can see all of the other functionality
: of a file descriptor is already available.

Oh yeh? What about fcntl(), dup()/dup2(), close(), select(),
socket stuff, mmap()/munmap(), and dealing with fie descriptors
you got from pipe(), socketpair() and such?

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Jim Cobban" <Jim.Cobban.jcobban@nt.com>
Date: 1998/06/25
Raw View
In article <6mpc8f$5bj@marianna.psu.edu>,
Oleg Zabluda  <zabluda@math.psu.edu> wrote:
>: Only that functionality which is useful and
>: does not conflict with other filebuf functionality should be exposed.  The
>: file descriptor itself must not be exposed.  The biggest piece of missing
>: functionality is fstat.  As far as I can see all of the other functionality
>: of a file descriptor is already available.
>
>Oh yeh? What about fcntl(), dup()/dup2(), close(), select(),
>socket stuff, mmap()/munmap(), and dealing with fie descriptors
>you got from pipe(), socketpair() and such?

Those functions apply only to specific types of files.  They therefore
should be implemented in derived streams, not in the general purpose
filebuf.  Remember that you are free to implement your own derived
streambufs (I've done it myself).  Say we call this myfilebuf.  You are
entirely free to have myfilebuf include a file descriptor and to expose
whatever functionality from that filebuf that you want to expose.  Since you
write the code which implements myfilebuf you can do whatever you want to
the file descriptor.  You can then define a new iostream, say myiostream,
which in turn provides access to the functionality exposed by myfilebuf.

As a specific example of this, as implemented as an extension by Gnu C++,
there is a class pfstream which implements stream access to a pipe.  If you
have that then you do not need to use pipe().

You mention file descriptor close().  What functionality does this provide
that is not provided by fstream::close()?

My point is that there is NOTHING in the C++ standard which prevents you
from accessing all of the functionality of a file descriptor through a
stream.  However this discussion has been asking a different question.  It
has been asking that std::filebuf provide a method which directly exposes
the file descriptor which is assumed to be part of the implementation of
std::filebuf.  I think that it is, in general, a very bad idea to have a
method in ANY class which returns a reference to a private member, since by
doing so you have simply made that private member public.  std::filebuf
should expose as much as possible of the capabilities of the underlying file
system as it can in a generic fashion.  I agree that the existing
specification does not expose enough.  But std::filebuf should NOT expose the
mechanism by which it delivers those capabilities.

--
Jim Cobban   |  jcobban@nortel.ca                   |  Phone: (613) 763-8013
Nortel (MCS) |                                      |  FAX:   (613) 763-5199
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Jim Cobban" <Jim.Cobban.jcobban@nt.com>
Date: 1998/06/22
Raw View
In article <358A86E7.357C@smarts.com>,
Jerry Leichter  <leichter@smarts.com> wrote:
>
>You're making the common, erroneous assumption that all file systems are
>Unix file systems.
>
>With a record-oriented file system, the underlying object almost
>certainly will not support positioning except to record boundaries.  The
>stream implementation will have to emulate byte positioning by defining
>a position in terms of a record and and offset within the record.

The existing definition of filebuf::seekpos warns that a seek to a position
which was not returned by a previous call to seekoff or seekpos is
undefined.  This is clearly necessary in a record oriented file system.

>The size of a file, in terms meaningful to the program, may be
>impossible to determine by any method easier than reading the whole file
>using the stream's semantics and counting.  (Many file organizations
>include embedded meta-information.  There can be an arbitrary relation-
>ship between the physical size of the file as the lower layers see it,
>and the number of bytes it gets "normalized" to as a stream.)

This is a very valid concern.  However it eliminates a large class of
reasonable programs which prefer to optimize their file processing by
bringing the entire file into contiguous memory, working on it there, and
then writing the entire file back out.  This style of program is much more
likely to be written now than in the past because of the low cost of RAM.
The memory available on most desk-top computers now exceeds the size of 99%
of all files on all media.  It therefore seems a reasonable action to bring
the file into memory to optimize processing.  However that is defeated if
the language does not provide a mechanism to obtain the size of the file
without reading it.

Of course all of the existing mechanisms for obtaining this information are
deficient in that none of them support files larger than 4GB, but then there
are very few of us with more than 4GB of RAM on our computers today.
However in a couple of years, who knows?  The IOStreams definition uses only
abstract types for things like seek positions, which could be implementation
defined to larger types if available in the compiler (as for example the Gnu
C++ long long unsigned int type).

I agree with all of the comments that access to old style file descriptors
is a bad idea.  However I do feel that this does deny access to the useful
information which is available through fstat.  The programmer can,
in many cases, obtain this information through stat or lstat.  However one
place where stat cannot be used is if the input file has been piped through
stdin, because in this case the program has no access to the file name.
--
Jim Cobban   |  jcobban@nortel.ca                   |  Phone: (613) 763-8013
Nortel (MCS) |                                      |  FAX:   (613) 763-5199


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Jim Cobban" <Jim.Cobban.jcobban@nt.com>
Date: 1998/06/23
Raw View
In article <6mcfvk$ipr@marianna.psu.edu>,
Oleg Zabluda  <zabluda@math.psu.edu> wrote:
>Raja R Harinath <harinath@cs.umn.edu> wrote:
>: Nowhere does (nor IMHO should) the standard imply that fstreams should
>: be implemented in terms of another file abstraction.  Codifying
>: `filebuf::fd()' would pretty much do that.  It would also limit
>: `fstream' to be based on an underlying implementation whose
>: characteristics should all be accessible from just one value.
>
>That's the beauty of abstractions. No matter what the implementation,
>if it's a file, you should be able to get a file desriptor pointing
>to it.

While there is functionality available on file descriptors which is not
available from streams, there is a lot of functionality which should NOT be
exposed because it could create conflicts.  For example I can imagine quite
horrible things happening if you issued a close against the file descriptor
since its state would not be out of synch with the encapsulating stream.
You cannot expose the file descriptor without exposing ALL of its
functionality.

The file descriptor therefore, if present at all, must be a
private member of the filebuf.  Only that functionality which is useful and
does not conflict with other filebuf functionality should be exposed.  The
file descriptor itself must not be exposed.  The biggest piece of missing
functionality is fstat.  As far as I can see all of the other functionality
of a file descriptor is already available.

--
Jim Cobban   |  jcobban@nortel.ca                   |  Phone: (613) 763-8013
Nortel (MCS) |                                      |  FAX:   (613) 763-5199
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/06/23
Raw View
Jim Cobban wrote:
>
> The file descriptor therefore, if present at all, must be a
> private member of the filebuf.  Only that functionality which is
> useful and does not conflict with other filebuf functionality should
> be exposed.  The file descriptor itself must not be exposed.

By that logic, the filebuf must be a private member of the fstream,
since things done directly to the filebuf could screw up what happens in
the fstream.

All I'm trying to say is that, just as the library spells out how
fstream is built on top of filebuf, it should spell out how filebuf is
built on top of some conceptual file object that has the common Posix
file semantics, since practically every machine in the universe has a
file system that can be mapped to that interface with almost no
translation.

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jerry Leichter <leichter@smarts.com>
Date: 1998/06/19
Raw View
| > | [Standard way to get the "file descriptor" underlying a stream]
| >
| > Fine, but just what is it you're going to standardize? ...[You want]
| > access to some lower level "file access" object - but the actual
| > operations available on such objects, much less the true semantics,
| > is so variable from system to system that by the time you're done
| > it's unlikely you can find any interesting common operations at all.
|
| I think there are plenty of things that could be standardized, such as
| reading, writing, positioning, getting the position, getting the size,
| opening, closing, creating, and truncating. All these operations
| (except truncating) are defined on standard fstreams, so they could
| also be defined on some abstract fileid, where a fileid maps to some
| type like int or void* that can be passed in a register and copied at
| will. Why bother? Because underneath all the implementations of
| standard fstreams that I've used, there really is some such type, and
| some such set of OS operations that could be made to conform to a
| common standard with almost no translation.

You're making the common, erroneous assumption that all file systems are
Unix file systems.

With a record-oriented file system, the underlying object almost
certainly will not support positioning except to record boundaries.  The
stream implementation will have to emulate byte positioning by defining
a position in terms of a record and and offset within the record.

The size of a file, in terms meaningful to the program, may be
impossible to determine by any method easier than reading the whole file
using the stream's semantics and counting.  (Many file organizations
include embedded meta-information.  There can be an arbitrary relation-
ship between the physical size of the file as the lower layers see it,
and the number of bytes it gets "normalized" to as a stream.)

Opening the underlying file yourself may not be possible if the stream
implementation makes assumptions about open-time options that must be
selected for the stream code to work.  I don't know what you might gain
by closing the file yourself other than losing information buffered at
the stream level.  On systems with many different file formats, it's
possible that the stream implementation will only work with some;
creating (or opening) a file with the wrong format may not work in any
meaningful way.

Or consider NT.  File handles and network connection handles are both
32-bit integers, and many file operations apply ot network connection
handles - but you close them differently.

Reading and writing?  Well, probably, though synchronization between
reads and writes you issue yourself and those issued by the stream
implementation will get pretty hairy.

It's true that many - perhaps most - implementations of C++ on such
systems are built on the base of a C implementation that provides a
(more or less accurate) emulation of Unix descriptors and file
semantics.  In that case, what you'd get would really look like a Unix
file descriptor - but it would *not* correspond to the real, underlying
OS object.  You actually gain very little in performance or functional-
ity by using this layer instead of the stream layer.  On the other hand,
these emulation layers also often don't work right if you directly
access the OS file object under *them*.
       -- Jerry
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/06/20
Raw View
Jerry Leichter wrote:
>
> You're making the common, erroneous assumption that all file systems
> are Unix file systems.
>
> With a record-oriented file system, the underlying object almost
> certainly will not support positioning except to record boundaries.
> The stream implementation will have to emulate byte positioning by
> defining a position in terms of a record and and offset within the
> record.

That's right. My point is that if they can get the fstream library to
make any file system look like a string of bytes, then they ought to be
able to get a standard file library make to any file system look like a
Unix or Posix file system.

C did this partially successfully with FILE objects. I'm merely saying
that fstreams ought to be built on top of some standardized abstract
file whose implementation isn't nailed down to FILE objects. That is,
the abstract file ought to be identified by a file_t, which the library
can choose to represent as a FILE* if that is appropriate, or an
unsigned int OS file descriptor if that is more appropriate. I'll bet
under every implementation of fstream, there exists some type that could
serve this purpose, and some interface that could be beaten into
compliance with some standardized set of operations.

> The size of a file, in terms meaningful to the program, may be
> impossible to determine by any method easier than reading the whole
> file using the stream's semantics and counting.  (Many file
> organizations include embedded meta-information.  There can be an
> arbitrary relationship between the physical size of the file as the
> lower layers see it, and the number of bytes it gets "normalized" to
> as a stream.)

Is there really any operating system that isn't capable of reporting the
size of the file, at least in those cases where the data really is a
file and not some pseudo-file like keyboard input? Even MS-DOS 1.0 could
report file sizes. Even CP/M-80 could report file sizes, with 128-byte
granularity; on such a system, always reporting a size that's a multiple
of 128 bytes is reasonable, because you can always read that number of
bytes, even if originally you wrote somewhat fewer. But that's ancient
history. When reading from some device where the file size really isn't
known, the file size function could simply report an error.

> Opening the underlying file yourself may not be possible if the stream
> implementation makes assumptions about open-time options that must be
> selected for the stream code to work. I don't know what you might gain
> by closing the file yourself other than losing information buffered at
> the stream level.  On systems with many different file formats, it's
> possible that the stream implementation will only work with some;
> creating (or opening) a file with the wrong format may not work in any
> meaningful way.

It's every bit as possible to design (and standardize) an fstream
library that does all file I/O through Posix-like calls, without relying
on OS-specific open-time options. Requiring that this be done is no more
burdensome than other requirements of the C++ standard, in my view. And
whether or not fstreams don't work properly with certain file formats,
the underlying file I/O system ought to allow a file to be accessed as
an array of bytes.

> Or consider NT.  File handles and network connection handles are both
> 32-bit integers, and many file operations apply ot network connection
> handles - but you close them differently.

But a network connection handle is not a file. I wouldn't expect a
stream object that talks directly over a TCP/IP connection to be an
fstream. It would be some other kind of stream, and wouldn't do its
underlying I/O by calls to open, read, write and close.

> It's true that many - perhaps most - implementations of C++ on such
> systems are built on the base of a C implementation that provides a
> (more or less accurate) emulation of Unix descriptors and file
> semantics.  In that case, what you'd get would really look like a Unix
> file descriptor - but it would *not* correspond to the real,
> underlying OS object.  You actually gain very little in performance or
> functional- ity by using this layer instead of the stream layer.  On
> the other hand, these emulation layers also often don't work right if
> you directly access the OS file object under *them*.

What you would get, given the sort of standardization that I suggest, is
access to the file as a random access array of raw bytes, without any
crlf to newline conversion or other such crud, since that should be done
in the stream. And by guaranteeing that fstreams are built in top of
this interface, you could get access to the files underneath the
standard streams. That is, if the standard requires that there be a cin,
cout and cerr, then this suggested standard would guarantee that you
could access these as raw bytes by operating on cin.rdbuf().fd(), etc.

--

Ciao,
Paul


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/06/20
Raw View
Paul D. DeRocco <pderocco@ix.netcom.com> wrote:
: Oleg Zabluda wrote:
: >
: > Guess what? Such a standard already exists. It's called POSIX --
: > Portable
: > Operating System Interface (X doesn't stand for anything). Posix is
: > not Unix. It was designed specifically to allow an implementations
: > on other systems.

: Exactly.

: > When Posix C++ extentions are standartized, amen, there will be
: > a portable way to extract a file descriptor from an fstream.
: > For now, use nonportable, but the de-facto standard method
: > fstreambuf::fd().

: Hear, hear. I've expressed elsewhere the opinion that standards like
: that should be incorporated into C++. If it isn't always possible, then
: they there should be some flag in the header that can be tested to see
: if the features are available, as is done with some of the numeric
: limits.

Like somebody already pointed, what do you do after you've
got the file desriptor? There should be a well-defined and
standartized set of operations you can perform on them.
So you need such a standard as a prerequisite to extracting
file desriptor from the fstream. Posix would be an excellent
choice. So you are back to square one -- you need to be in a Posix
environment prior to extracting fd's from fstream, because otherwise,
there is nothing you can portably do with them anyway. But then you
might as well wait for the real Posix C++ extentions, amen.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/06/19
Raw View
Paul D. DeRocco <pderocco@ix.netcom.com> wrote:
: Oleg Zabluda wrote:
: >
: > Not all OS have the concept of file descriptors. Some OSes
: > use FCB (File Control Blocks) or other wierd contortions
: > instead. Therefore neither ISO C nor ISO C++ have this concept
: > either. However, your compiler vendor probably provides you
: > with extentions to manipulate underlying file desriptors.
: > You might have to define something (like POSIX_SOURCE) or use
: > some compiler flags to enable non-ISO extentions.

: Here's a case where there ought to be a standardized concept under a
: standardized name, even if the underlying implementation varies from a
: simple integer on one system to a pointer to a complicated data
: structure on another.

Guess what? Such a standard already exists. It's called POSIX -- Portable
Operating System Interface (X doesn't stand for anything). Posix is
not Unix. It was designed specifically to allow an implementations
on other systems. And it was implemented on other non-unix systems.
In particular, you can buy it for NT, or you can get a free one
from Cygnus. Unfortunately, in this case, `free'' as in `free beer'').

When Posix C++ extentions are standartized, amen, there will be
a portable way to extract a file descriptor from an fstream.
For now, use nonportable, but the de-facto standard method
fstreambuf::fd().

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/06/19
Raw View
Raja R Harinath <harinath@cs.umn.edu> wrote:
: "Paul D. DeRocco" <pderocco@ix.netcom.com> writes:
: > Oleg Zabluda wrote:
: > > Not all OS have the concept of file descriptors. Some OSes
: > > use FCB (File Control Blocks) or other wierd contortions
: > > instead. Therefore neither ISO C nor ISO C++ have this concept
: > > either. However, your compiler vendor probably provides you
: > > with extentions to manipulate underlying file desriptors.
: > > You might have to define something (like POSIX_SOURCE) or use
: > > some compiler flags to enable non-ISO extentions.
: >
: > Here's a case where there ought to be a standardized concept under a
: > standardized name, even if the underlying implementation varies from a
: > simple integer on one system to a pointer to a complicated data
: > structure on another.

: That presumes an underlying implementation that is meaningful and
: interesting.  Nothing prevents an implementation of fstream that wrote
: to the raw disk without any intervening layers.

: Nowhere does (nor IMHO should) the standard imply that fstreams should
: be implemented in terms of another file abstraction.  Codifying
: `filebuf::fd()' would pretty much do that.  It would also limit
: `fstream' to be based on an underlying implementation whose
: characteristics should all be accessible from just one value.

That's the beauty of abstractions. No matter what the implementation,
if it's a file, you should be able to get a file desriptor pointing
to it.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/06/19
Raw View
Oleg Zabluda wrote:
>
> Guess what? Such a standard already exists. It's called POSIX --
> Portable
> Operating System Interface (X doesn't stand for anything). Posix is
> not Unix. It was designed specifically to allow an implementations
> on other systems.

Exactly.

> When Posix C++ extentions are standartized, amen, there will be
> a portable way to extract a file descriptor from an fstream.
> For now, use nonportable, but the de-facto standard method
> fstreambuf::fd().

Hear, hear. I've expressed elsewhere the opinion that standards like
that should be incorporated into C++. If it isn't always possible, then
they there should be some flag in the header that can be tested to see
if the features are available, as is done with some of the numeric
limits.

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/06/18
Raw View
Raja R Harinath wrote:
>
> That presumes an underlying implementation that is meaningful and
> interesting.  Nothing prevents an implementation of fstream that wrote
> to the raw disk without any intervening layers.

Other than sanity.

> Nowhere does (nor IMHO should) the standard imply that fstreams should
> be implemented in terms of another file abstraction.  Codifying
> `filebuf::fd()' would pretty much do that.  It would also limit
> `fstream' to be based on an underlying implementation whose
> characteristics should all be accessible from just one value.

I'll bet all existing implementations could live with that, as long as
the value has enough bits to hold a pointer.

--

Ciao,
Paul


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/06/18
Raw View
Jerry Leichter wrote:
>
> | Here's a case where there ought to be a standardized concept under a
> | standardized name, even if the underlying implementation varies from
> | a simple integer on one system to a pointer to a complicated data
> | structure on another.
>
> Fine, but just what is it you're going to standardize? An opaque block
> of bits with no defined operations on them?  The whole point is to
> provide access to some lower level "file access" object - but the
> actual
> operations available on such objects, much less the true semantics, is
> so variable from system to system that by the time you're done it's
> unlikely you can find any interesting common operations at all.

I think there are plenty of things that could be standardized, such as
reading, writing, positioning, getting the position, getting the size,
opening, closing, creating, and truncating. All these operations (except
truncating) are defined on standard fstreams, so they could also be
defined on some abstract fileid, where a fileid maps to some type like
int or void* that can be passed in a register and copied at will. Why
bother? Because underneath all the implementations of standard fstreams
that I've used, there really is some such type, and some such set of OS
operations that could be made to conform to a common standard with
almost no translation.

--

Ciao,
Paul


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: nospam@nospam.com (Itay Zandbank)
Date: 1998/06/14
Raw View
  I was disappointed to discover the age-old method of obtaining an
fstream's file descripter (rdbuf()->fd()) doesn't work any more. The
thing is, I need the file descriptor (fstat() is funny this way). Is
there any way to get the fstream's file descriptor (when the stream is
opened, of course)?

  Thanks in advance,

   Itay, trying to fight off spammers
   email: itayz at tase point co dot il
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/06/15
Raw View
In comp.std.c++ Itay Zandbank <nospam@nospam.com> wrote:
:   I was disappointed to discover the age-old method of obtaining an
: fstream's file descripter (rdbuf()->fd()) doesn't work any more. The
: thing is, I need the file descriptor (fstat() is funny this way). Is
: there any way to get the fstream's file descriptor (when the stream is
: opened, of course)?

Not all OS have the concept of file descriptors. Some OSes
use FCB (File Control Blocks) or other wierd contortions
instead. Therefore neither ISO C nor ISO C++ have this concept
either. However, your compiler vendor probably provides you
with extentions to manipulate underlying file desriptors.
You might have to define something (like POSIX_SOURCE) or use
some compiler flags to enable non-ISO extentions.

I hope it will get standartized when POSIX C++ extentions
are adopted.

Amen.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]