473,785 Members | 2,761 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

fclose then fopen equivalent for stdout?

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? Maybe something like this:

fputc(stdout,EO F);

or this

freopen(NULL,"w b",stdout);

?

Thanks,

David Mathog
Oct 25 '06
20 7308
In article <eh**********@n aig.caltech.edu >
David Mathog <ma****@caltech .eduwrote:
>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_FI LENO); /* 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.
Oct 25 '06 #11


David Mathog wrote On 10/25/06 13:28,:
Eric Sosman wrote:

> Here's a suggestion: You're trying to obtain the effect
of fclose(), right? Does any particular function spring to
mind as being likely to perform the operations of fclose()?
How about ... <<wait for it>... fclose()?


I'm not trying to get fclose, I'm trying to get

fclose()
fopen()
Aha! Okay, sorry -- that wasn't clear to me.
How then does the program CONTINUE to write to stdout
so that data gets to the tape device after having called
fclose(stdout)?

What parameters for fopen() reassociate stdout with the same
output stream following the fclose()?
I don't think there's any way to do this in Standard C's
very simple model of I/O. In fact, I don't think what you're
doing with an explicit device name is guaranteed to work: C
only understands "files," not multi-file "volumes."

--
Er*********@sun .com

Oct 25 '06 #12


Harald van Dijk wrote On 10/25/06 13:29,:
Eric Sosman wrote:
>>David Mathog wrote On 10/25/06 12:48,:
>> freopen(NULL,"w b",stdout);

Undefined behavior: The first argument is supposed to
be a string (a string that names a file), but NULL is not
a string. It's much like trying fopen(NULL, "wb").

Actually, freopen() has special behaviour for a NULL filename. I don't
know enough about it to know if that special behaviour is useful here,
though.
Oh, drat! Serves me right for looking at a man page
instead of checking the Standard. The behavior is not
undefined, but implementation-defined .. and as far as
I can tell, it doesn't help the O.P.
> Here's a suggestion: You're trying to obtain the effect
of fclose(), right? Does any particular function spring to
mind as being likely to perform the operations of fclose()?
How about ... <<wait for it>... fclose()?

So how do you write to stdout again after closing it?
You don't. It's closed. (I had not realized that he
wanted to keep on writing until he counter-replied to my
reply. It was all there in the original message, if I'd
squinted at it hard enough -- not my day, evidently ...)

--
Er*********@sun .com

Oct 25 '06 #13
David Mathog wrote:
Eric Sosman wrote:
> Here's a suggestion: You're trying to obtain the effect
of fclose(), right? Does any particular function spring to
mind as being likely to perform the operations of fclose()?
How about ... <<wait for it>... fclose()?

I'm not trying to get fclose, I'm trying to get

fclose()
fopen()

How then does the program CONTINUE to write to stdout
so that data gets to the tape device after having called
fclose(stdout)?

What parameters for fopen() reassociate stdout with the same
output stream following the fclose()?
No guaranteed way. Read the manuals for your system. Most tape
units have some sort of control channel that can be told "Now write
an inter-file gap". Since this is system specific it is off-topic
here, where we deal in portable C programming. I have no idea what
your system is and thus no idea what newsgroup would be
appropriate.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net>
Oct 25 '06 #14

"David Mathog" <ma****@caltech .eduwrote in message
news:eh******** **@naig.caltech .edu...
>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.
what part of fclose exactly triggers the filemark writing? You probably
tried it, but it might be as simple as fflush
Oct 25 '06 #15

"David Mathog" <ma****@caltech .eduwrote in message
news:eh******** **@naig.caltech .edu...
Eric Sosman wrote:
Here's a suggestion: You're trying to obtain the effect
of fclose(), right? Does any particular function spring to
mind as being likely to perform the operations of fclose()?
How about ... <<wait for it>... fclose()?

I'm not trying to get fclose, I'm trying to get

fclose()
fopen()

How then does the program CONTINUE to write to stdout
so that data gets to the tape device after having called
fclose(stdout)?

What parameters for fopen() reassociate stdout with the same
output stream following the fclose()?
I'm a bit unfamiliar with pipes, but, won't closing stdout from your program
also close the pipe? How do you intend to keep the pipe open through an
open and close of stdout? I suspect this is a second issue no one else has
mentioned.

I think your best bet is to not use a pipe at all, and replace the fclose();
fopen() sequence with a routine specific to the tape drive which writes the
control data, (as Falconer suggested).

Another option would be to have a single control program which spawn()'s or
exec()'s, etc., a separate program which writes one file at a time. The
command line for the spawn'd or exec'd program could use a pipe, if desired.
Rod Pemberton
Oct 25 '06 #16
Serve Laurijssen wrote:
"David Mathog" <ma****@caltech .eduwrote in message
news:eh******** **@naig.caltech .edu...
>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.

what part of fclose exactly triggers the filemark writing? You probably
tried it, but it might be as simple as fflush
When the linux st driver receives a close operation following a write it
(the st driver) writes the filemark. The fclose() and fflush() don't
write that mark themselves. Apparently the only way to write multiple
files to tape through stdout, and to place a filemark between them,
is to use ioctl(). Even that is tricky, as doing something like:

fwrite(buffer1, BUFSIZE,1,stdou t);
ioctl( <appropriate parameters);
fwrite(buffer2, BUFSIZE,1,stdou t);

might result in the filemarks being written before all of the buffer1
data gets to the tape drive.

Thanks all,

David Mathog
Oct 26 '06 #17
David Mathog <ma****@caltech .eduwrites:
Serve Laurijssen wrote:
[...]
>what part of fclose exactly triggers the filemark writing? You
probably tried it, but it might be as simple as fflush

When the linux st driver receives a close operation following a write it
(the st driver) writes the filemark. The fclose() and fflush() don't
write that mark themselves. Apparently the only way to write multiple
files to tape through stdout, and to place a filemark between them,
is to use ioctl(). Even that is tricky, as doing something like:

fwrite(buffer1, BUFSIZE,1,stdou t);
ioctl( <appropriate parameters);
fwrite(buffer2, BUFSIZE,1,stdou t);

might result in the filemarks being written before all of the buffer1
data gets to the tape drive.
<SEMI-OT>

Perhaps this would work:

fwrite(buffer1, BUFSIZE,1,stdou t);
fflush(stdout);
ioctl( <appropriate parameters);
fwrite(buffer2, BUFSIZE,1,stdou t);

</SEMI-OT>

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 26 '06 #18
In article <eh**********@n ews2.zwoll1.ov. home.nl>,
Serve Laurijssen <se*@n.tkwrot e:
>"David Mathog" <ma****@caltech .eduwrote in message
news:eh******* ***@naig.caltec h.edu...
>>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.
>what part of fclose exactly triggers the filemark writing? You probably
tried it, but it might be as simple as fflush
As others have noted, it is part of the device driver, not a standard
C function.

Someone referenced a Linux ioctl(); that's certainly a possibility on
appropriate versions of Linux.

As additional off-topic information about the difficulty of doing this:
On SCSI tape devices, the end-of-file marker or end-of-medium markers
are handled by specific operation codes. If your device driver does not
provide an ioctl() or equivilent, then you may have to issue the
SCSI-layer command yourself, if your system provides a generalized
SCSI device driver.

Also it might be worth keeping in mind that most Unix-type systems
provide a command "mt" with a "weof" option. But then there's the
difficulty that "mt" wants the name of a tape device on its command
line, and if you are using stdout then you don't know the tape device
name. Since you'd be presuming a unix-type system for this purpose,
you could fstat() to find the major and minor device numbers
associated with stdout, and iterate through the standard tape drive
name /dev subdirectory and hope for a match... and then mangle that
name to ensure that you include the appropriate name code for
non-rewind.

I wonder if the OP took into account that if the invoking user
redirected to an autorewind tape device (as is likely if they
hadn't been hit over the head several times with this issue),
that the fclose() equivilent that is proposed to be done would
trigger a tape rewind...
How would I handle it? Well, I would code the application to
take a tape device name as a parameter, and write to that instead
of stdout; perhaps I'd allow the semi-standard use of a single dash
to indicate standard output, but in that case I'd have the program
balk if it would have been expected to write several file marks.

No matter what you know about your own system, I don't think you
can reasonably be expected to be able to write multiple file marks
in a scenario such as

$ OurTapeBackups basedirectory | \
ssh -c operator@remote host "dd of=/dev/tape"
--
"law -- it's a commodity"
-- Andrew Ryan (The Globe and Mail, 2005/11/26)
Oct 26 '06 #19
Walter Roberson wrote:
>
.... snip ...
>
I wonder if the OP took into account that if the invoking user
redirected to an autorewind tape device (as is likely if they
hadn't been hit over the head several times with this issue),
that the fclose() equivilent that is proposed to be done would
trigger a tape rewind...
In which case he might be surprised at how little tape is needed
for the complete dump.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net>
Oct 27 '06 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
6421
by: Marcus Jacobs | last post by:
Dear Group I have encountered a problem with fclose and I am wondering if anyone could provide some insight about this problem to me. Currently, I am working on a small personal project that is requiring for me to alter some existing code to a program. While running the unaltered code, I kept encountering an application (The exception unknown software exception(0xc00000fd) etc. .. etc... etc... I am running W2K Pro). Through a bit of...
10
2018
by: collinm | last post by:
hi is it better to do: FILE *fp; if((fp = fopen(local_led, "r"))!=NULL) { fclose(fp); } else
19
6810
by: lihua | last post by:
Hi, Group! I got one question here: We all know that fclose() must be called after file operations to avoid unexpected errors.But there are really cases when you forget to do that!Just like what happens in memory operations, everyone knows the importance of freeing the allocated memory, but there do have memory leaks from time to
17
14788
by: kathy | last post by:
if fopen failed, does it necessary to call fclose? I see an example like this: .... stream = fopen(...); if(stream == NULL) { .... } else
7
6605
by: Pietro Cerutti | last post by:
Hi group, I just noticed that a malloc w/out relative free occurs in the standard C library (or at least, on my implementation of it). #include <stdio.h> int main(void) { printf("%s\n", "Hello"); return (0); }
53
4484
by: Bartc | last post by:
This short program: #include <stdio.h> #include <stdlib.h> int main(void) { int status; status=fclose(0);
16
2602
by: Bill Cunningham | last post by:
Is it really necessary to check the return type (int) or fclose ? fopen I can understand but what about using fflsuh(fp); /* fopen's pointer */ fclose(fp); Would that take care of any unforseen truncation ? Bill
3
3305
by: wrenashe | last post by:
I am on windows 2003, basically my codes want to do such a thing: 1. fopen a file A. 2. dup2(A, stdout); 3. dup2(A, stderr); 4. fclose(A); 5. rename(A), and move it to somewhere else. 6, fopen(A); 7. dup2(A, stdout); 8. dup2(A, stderr);
0
9645
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9481
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10336
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10155
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
7502
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6741
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5383
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4054
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3655
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.