In article <eho4hq$6vb$>
David Mathog <> 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.