manipulate fd underlying stream

J

John Kelly

comp.lang.c FAQ 12.33 says:
Q: How can I redirect stdin or stdout to a file from within a program?
A: Use freopen. If you're calling a function f() which writes to stdout,
and you want to send its output to a file, and you don't have the option
of rewriting f, you can use a sequence like:

freopen(file, "w", stdout);
f();

Hmmm ...

See, however, question 12.34.
Question 12.34
Q: Once I've used freopen, how can I get the original stdout (or stdin) back?
A: There isn't a good way. If you need to switch back, the best solution is not
to have used freopen in the first place.


Why not leave the stream unchanged, and manipulate its underlying file
descriptor:

a) fflush() the stdio stream
b) dup the stdio fd to an unused fd, saving a copy of it.
c) close the stdio fd
d) use open() to get an fd for the desired file, and compare the fd
number to STDIN_FILENO or STDOUT_FILENO, as appropriate, to be sure
it matches; if not, use dup2() to copy it to the stdio fd
e) when done, use dup2() to copy the saved fd back to the stdio fd
 
I

Ian Collins

comp.lang.c FAQ 12.33 says:



Hmmm ...







Why not leave the stream unchanged, and manipulate its underlying file
descriptor:

Because there isn't a standard way of doing that.
a) fflush() the stdio stream
b) dup the stdio fd to an unused fd, saving a copy of it.

That assumes dup().
 
E

Eric Sosman

comp.lang.c FAQ 12.33 says:



Hmmm ...






Why not leave the stream unchanged, and manipulate its underlying file
descriptor:

"File descriptoer?" What's a "file descriptor?"
a) fflush() the stdio stream
b) dup the stdio fd to an unused fd, saving a copy of it.

What do you mean, "dup?"
c) close the stdio fd

"Close?" What's that?
d) use open() to get an fd for the desired file, and compare the fd
number to STDIN_FILENO or STDOUT_FILENO, as appropriate, to be sure

What's "open?" And what are these strange, all-caps things
that sort of look like they might be macros?
it matches; if not, use dup2() to copy it to the stdio fd
e) when done, use dup2() to copy the saved fd back to the stdio fd

"Dup2?" Hunh?

In short, you're assuming (1) a specific kind of host system,
and (2) a whole lot about the way C streams are implemented on that
system. In CS-speak, you are writing to the implementation rather
than to the interface.

I recall dealing with some code that tried to mix-'n-match C's
streams with POSIX primitives: It would fread() from a file until it
came to something it knew would be a blob, then it did an lseek() to
the fseek() position to synchronize the two current offsets, then
it slurped the blob with read() "because it's more efficient," then
did an fseek() to the lseek() spot to re-synchronize. Clever, clever,
clever -- and utterly hopeless on VMS, the platform I was porting to.
Dirtbag code with a dirtbag outcome.
 
J

John Kelly

In short, you're assuming (1) a specific kind of host system,
and (2) a whole lot about the way C streams are implemented on that
system. In CS-speak, you are writing to the implementation rather
than to the interface.

I think of a dominant implementation as a virtual interface.

I recall dealing with some code that tried to mix-'n-match C's
streams with POSIX primitives: It would fread() from a file until it
came to something it knew would be a blob, then it did an lseek() to
the fseek() position to synchronize the two current offsets, then
it slurped the blob with read() "because it's more efficient," then
did an fseek() to the lseek() spot to re-synchronize. Clever, clever,
clever -- and utterly hopeless on VMS, the platform I was porting to.
Dirtbag code with a dirtbag outcome.

VMS? What's that?
 
T

Tim Harig

Why not leave the stream unchanged, and manipulate its underlying file
descriptor:

a) fflush() the stdio stream
b) dup the stdio fd to an unused fd, saving a copy of it.
c) close the stdio fd
d) use open() to get an fd for the desired file, and compare the fd
number to STDIN_FILENO or STDOUT_FILENO, as appropriate, to be sure
it matches; if not, use dup2() to copy it to the stdio fd
e) when done, use dup2() to copy the saved fd back to the stdio fd

As others have pointed out, this is POSIX specific and you will probably
get better advice from comp.unix.programming.

Looking at the man page for dup on Linux, I don't see anything that
explicitly prevents you from copying the file descriptor and copying it
back; but, that doesn't mean there might not be implementation bugs on some
platform that make it an unwise choice to use.

Personally, I don't understand why you would bother going through all of
that trouble instead of just leaving stdin alone and using fprinf()
explicitly. Then there is never any confusion about where stdin points at
any given time.
 
J

John Kelly

As others have pointed out, this is POSIX specific and you will probably
get better advice from comp.unix.programming.

Looking at the man page for dup on Linux, I don't see anything that
explicitly prevents you from copying the file descriptor and copying it
back; but, that doesn't mean there might not be implementation bugs on some
platform that make it an unwise choice to use.

I've not experienced any problems on Linux.

Personally, I don't understand why you would bother going through all of
that trouble instead of just leaving stdin alone and using fprinf()
explicitly. Then there is never any confusion about where stdin points at
any given time.

Maybe I have generic code that uses stdin/stdout, and the caller wants
to manipulate fds and point them somewhere else.
 
R

ralph

No POSIX on Windows?

Too ways to look at this ...
1) Windows NT and Windows 2000 O/S did support a POSIX subsystem.
Windows XP and later do not.
2) The more popular C compilers for Windows still support POSIX to
some degree or the other.
The VC++ compiler* still supports POSIX, but it is considered
"deprecated". Details can be found in the help files.

[*as of VC 2008, not sure about the 2010 release.]

Microsoft O/S and compilers only support POSIX 1003.1 which was
earlier than even current versions available at the time, and thus
limited in POSIX services, as well as denied access to many Windows
services.

So the answer to your question is technically 'yes' for some versions
of Windows and very simple applications, but generally 'no' for use as
a migration or cross-platform tool.

-ralph
 
J

John Kelly

Too ways to look at this ...
1) Windows NT and Windows 2000 O/S did support a POSIX subsystem.
Windows XP and later do not.

What's this:

Step 1: Turning on the SUA features
The Subsystem for Unix-based Applications (SUA) is part of the Windows
OS distribution. Installing the subsystem requires no additional CD or
download. It's a component/feature of the base distribution of Windows
Server 2008, Windows Server 2008/R2, Windows Server 2003 R2, Windows 7
and Windows Vista Ultimate & Enterprise. All you need to do is turn the
feature on.

http://www.suacommunity.com/SUA.aspx


So the answer to your question is technically 'yes' for some versions
of Windows and very simple applications, but generally 'no' for use as
a migration or cross-platform tool.


Step 2: Installing the Utilities and SDK for Unix-based Applications
Once the SUA "feature" is turned on, the next step is to download the
Utilities and SDK. From the Start menu, under All Programs then under
Subsystem for Unix-based Applications you can find the link to download
the Utilities and SDK from the Microsoft website. Alternatively, you
can visit the download site directly: Installing and Using Utilities and
SDK for Unix-based Applications. This page is important as it outlines
the difference between a standard (default) installation and a custom
install.

Note: A common pitfall is to just accept the default installation. The
default install does not include the GNU utilities and GNU SDK.

Note: We recommend for a Windows systems that the installation happen as
the Local Administrator (not as a user in the Administrators Group).
 
S

Seebs

Do you want to shoo away Linux C programmers from c.l.c?

Not likely -- my day job is about 98% Linux these days. But I generally
don't talk about the POSIX-specific stuff here, because that's not
related to C. With a few exceptions (and admittedly, I actually
work with those exceptions a fair bit!), the POSIX stuff I do is
language-agnostic, and you could ask the same questions, and get the
same answers, when talking about perl or Ruby programs that were
working with the POSIX interfaces.

I think the big thing people are pursuing in trying to direct
people to other newsgroups is to maximize discussion quality and
value. If you ask POSIX questions here, there are two likely
problems:

1. The discussion will be at best totally uninteresting to a large
number of readers. This makes the group less valuable to them and
might cause them to leave -- but there are some very serious C experts
who happen to mostly not be using Unix.

2. The discussion will pick up a lot of things said by people who
aren't that interested in or good at POSIX, and who as a result don't
really know what they're talking about -- but the real POSIX experts
are mostly not here, or not here with intent to talk about POSIX.

So if instead those questions are asked in a group more specific
to the environment they apply in, everyone gets a better newsgroup
experience, and the questions get better answers -- which are seen
by people more interested in those answers.

Long story short, it seems that, as long as there's enough traffic
to justify multiple newsgroups, everyone seems to win when those
newsgroups keep to their topics, and separation of topics is observed.

(And keep in mind, I'm writing this from the perspective of someone
who has written some code which does stuff like "intercept underlying
file operations and manipulate the values apparently returned by
the library." I know more about what happens in several common C
libraries when you start messing around with file descriptors than
anyone but a library maintainer is ever likely to have reason to
know; I just don't think it's topical here.)

-s
 
R

ralph

What's this:

Step 1: Turning on the SUA features
The Subsystem for Unix-based Applications (SUA) is part of the Windows
OS distribution. Installing the subsystem requires no additional CD or
download. It's a component/feature of the base distribution of Windows
Server 2008, Windows Server 2008/R2, Windows Server 2003 R2, Windows 7
and Windows Vista Ultimate & Enterprise. All you need to do is turn the
feature on.

http://www.suacommunity.com/SUA.aspx



Step 2: Installing the Utilities and SDK for Unix-based Applications
Once the SUA "feature" is turned on, the next step is to download the
Utilities and SDK. ...

LOL

I knew I'd be in trouble the second I hit the return.

I didn't mention SUA/Interix as I was under the impression that
SUA/Interix was not fully POSIX complaint. That apparently is not
true.
 
K

Kenny McCormack

....
Do you want to shoo away Linux C programmers from c.l.c?

Obviously, yes. Their whole goal is to shoo everyone away, so that they
can do their collective jerk-off over the Almight C Standards document.

I assumed you understood that by now.
 
J

James Dow Allen

     "File descriptoer?"  What's a "file descriptor?"
     What do you mean, "dup?"
     "Close?"  What's that?
     What's "open?"  And what are these strange, all-caps things
     "Dup2?"  Hunh?

I'm not sure to what extent Mr. Sosman seeks to edify and
to what extent he seeks to amuse, but I don't think I'm alone
in saying that programming for a non-Unix system has no
conceivable purpose in the ivory tower. Non-Unix programmers have
some other purpose: avarice for filthy lucre, writing viruses,
etc.

In a newsgroup on restaurants we wouldn't be condemned if we
assumed OP is not some villain serving rat poison to customers.
Why then, in a C programming forum, do we ask why OP isn't some
sado-masochist programming a system without open() and close()?

James Dow Allen
 
K

Kenny McCormack

comp.std.c appears to be alive

But, no, they won't stay there.
Code is more fun than standards.

Not to these jerkoffs.

And this is probably as good a time as any for me to re-iterate a point
I've made many times before. These people are actually almost all old
Unix hands and they are perfectly comfortable with Unix-isms (like
read() and write()). Normally, there'd be no problem discussing Unix-y
things here, but the problem is that when, in the early 90s, the Unix
guys saw the world going MS and Windows (sorry, guys, but it is true),
they went apeshit and they realized that their beloved newsgroups (and
specifically CLC) were about to go all "lpParm" on them and they
couldn't stand that.

So, they concocoted this "What's in the standard and only what's in the
standard" nonsense and made a pact to stand by it. Part of that pact
was that they had to pretend not to understand or know anything about
the Unix-y stuff (or any other so-called "system specific" stuff). That
was the price paid to ward off the evils of "lpParm".

(And yes, just in case it isn't clear to the numskulls, I'm using
"lpParm" as a metaphor for all the Windows-y stuff. The stuff that
drives these guys to madness...)
 
J

John Kelly

Not to these jerkoffs.

And this is probably as good a time as any for me to re-iterate a point
I've made many times before. These people are actually almost all old
Unix hands and they are perfectly comfortable with Unix-isms (like
read() and write()). Normally, there'd be no problem discussing Unix-y
things here, but the problem is that when, in the early 90s, the Unix
guys saw the world going MS and Windows (sorry, guys, but it is true),
they went apeshit

For Windows XP:

a) download Windows Services for UNIX Version 3.5
http://www.microsoft.com/downloads/...88-601b-44f1-81a4-02878ff11778&displaylang=en

b) get hotfixes and apply
http://www.rockbox.org/wiki/InterixDevelopment

c) add complete toolset from sua community site
http://www.suacommunity.com/SUA.aspx
ftp://ftp.interopsystems.com/pkgs/bundles/pkg-current-bundlecomplete35.exe


Looks POSIXy to me ...
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top