Re: fclose then fopen equivalent for stdout?



In article <eho4hq$6vb$1@xxxxxxxxxxxxxxxx>
David Mathog <mathog@xxxxxxxxxxx> wrote:
A program of mine writes to a tape unit. Output can be either through
stdout or through a file opened with fopen(). When all the data is
transferred to tape the program needs to close the output stream so that
the tape driver will write a filemark on the tape. Otherwise multiple
clumps of data saved to tape would all appear to be one big file on the
tape.

When the tape unit device was explicitly opened with fopen()
that's possible: call fclose() and then for the next batch
of data fopen() the tape device again and write some more.

However when data is going through stdout like:

program > /dev/nst0

is there an equivalent operation?

Not only is this impossible in Standard C, it is not even possible
on most POSIX systems. You can *close* the standard output stream
with:

fclose(stdout);

but you can never guarantee to get it open again. That is, if this
fclose succeeds, stdout is dead. (The next fopen() call may in
fact re-use the old stdout "FILE *", effectively resurrecting it,
but it also might not.)

By cheating -- going directly to POSIX file descriptors -- you can
avoid "killing" the C library stdout stream, while closing the
underlying file descriptor. For instance, something like this:

fflush(stdout); /* pass output to underlying fd */
close(STDOUT_FILENO); /* POSIX-specific: close stdout */
fd = open(path, openmode, creatmode_opt); /* POSIX-specific */
if (fd != STDOUT_FILENO) ... uh oh ...

(which relies on STDOUT_FILENO being the first available one so
that open() uses it), but you will need to find the "path" (by
"magic"; see below). Moreover, with this method -- just as with
the fopen(), fclose(), fopen() again method -- there is no guarantee
that the same pathname refers to the same physical device twice in
a row (consider what happens if the super-user renames /dev/nst0
to /dev/nst0.old and creates a new /dev/nst0, for instance).

Your best best for "truly safe" operation, given the non-portability
of the whole thing, is to use a system-specific operation (probably
an ioctl) to write tape-marks, without ever closing the device.
If that is unavailable or impractical, your second-best-bet is to
require the path-name; "recovering" the device name (by using,
e.g., fts_open() on "/dev" and comparing "st_dev" IDs in "stat"
structures) is possible but tricky.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
.



Relevant Pages

  • Re: fclose then fopen equivalent for stdout?
    ... transferred to tape the program needs to close the output stream so that ... the tape driver will write a filemark on the tape. ... However when data is going through stdout like: ...
    (comp.lang.c)
  • Re: fclose then fopen equivalent for stdout?
    ... stdout or through a file opened with fopen. ... the tape driver will write a filemark on the tape. ... Also it might be worth keeping in mind that most Unix-type systems ... and if you are using stdout then you don't know the tape device ...
    (comp.lang.c)
  • Re: Mounting tape drives between systems
    ... N.B. Unsolicited email from vendors will not be appreciated. ... > tar will allow you to output to stdout. ... > rsh to dd on the remote system and thence to the tape. ...
    (AIX-L)
  • Re: fclose then fopen equivalent for stdout?
    ... transferred to tape the program needs to close the output stream so that ... the tape driver will write a filemark on the tape. ... However when data is going through stdout like: ...
    (comp.lang.c)
  • Re: fclose then fopen equivalent for stdout?
    ... transferred to tape the program needs to close the output stream so that ... the tape driver will write a filemark on the tape. ... what part of fclose exactly triggers the filemark writing? ...
    (comp.lang.c)