Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

freopen usage

12 views
Skip to first unread message

Hlk....@gmail.com

unread,
Aug 21, 2007, 5:29:19 PM8/21/07
to
Hi All,

I have a question regarding the standard C library.

Is it possible to have one process (program) that
redirects its stdin to a file, and have a second program
use that file write/append to that file. The first program
will then read its redirected standard input file and
process that...

The first program is like this:

#include <stdio.h>
#include <string.h>

void main (void)
{
FILE *f_stdin = NULL;
char buf [501];

f_stdin = freopen ("stdin", "a+", stdin);
if (f_stdin != NULL)
{
buf[0] = '\0';
while (1)
{
fgets (buf, 500, f_stdin);
if (strlen (buf) > 0)
printf ("buf: %s\n", buf);
if (strcmp (buf, "q") == 0)
break;
buf[0] = '\0';
}
}
else
{
perror ("error(first prog)");
}
}

The second program is:

#include <stdio.h>

void main (void)
{
FILE *f_stdin = NULL;

f_stdin = fopen ("stdin", "a+");
if (f_stdin != NULL)
{
fputs ("a test", f_stdin);
}
else
{
perror ("error(second prog)");
}
}

The code below (creating two executables) compiles.
I can redirect stdin in the first program and can open
and write in the second program. Altough the string is
written to the file, I can not read that from the first
program.

Can you see anything wrong in the above code? Is the
freopen usage correct? Can freopen be used to
redirect std streams to files and have other processes
write to these files and command the first proces?

Regards,
ht
--
comp.lang.c.moderated - moderation address: cl...@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.

Hans-Bernhard Bröker

unread,
Sep 4, 2007, 1:09:20 PM9/4/07
to
Hlk....@gmail.com wrote:
> I have a question regarding the standard C library.

Actually, no. While freopen() exists in the standard library, all
aspects involving more than one program are entirely outside the scope
of the C standard.

Jonathan Leffler

unread,
Sep 4, 2007, 1:09:52 PM9/4/07
to


"a+" positions the read pointer at the end of the file, so the first
program gets EOF immediately. Try using just "r" since you are not
modifying the file.


--
Jonathan Leffler #include <disclaimer.h>
Email: jlef...@earthlink.net, jlef...@us.ibm.com
Guardian of DBD::Informix v2007.0226 -- http://dbi.perl.org/

Jack Klein

unread,
Sep 4, 2007, 1:10:24 PM9/4/07
to
On 21 Aug 2007 21:29:19 GMT, Hlk....@gmail.com wrote in
comp.lang.c.moderated:

> Hi All,
>
> I have a question regarding the standard C library.

Actually, you don't, you have a question regarding the behavior of
your platform.

> Is it possible to have one process (program) that
> redirects its stdin to a file, and have a second program
> use that file write/append to that file. The first program
> will then read its redirected standard input file and
> process that...

You most certainly have a program redirect its stdin to come from a
file, if that file has already been successfully created, written, and
closed by another program.

The C standard does not define or even recognize the concept of a
"process", multiple threads of execution, or more than one C program
executing at one time.

> The first program is like this:
>
> #include <stdio.h>
> #include <string.h>
>
> void main (void)

main() returns an int. Always. So your program has undefined
behavior.

> {
> FILE *f_stdin = NULL;
> char buf [501];
>
> f_stdin = freopen ("stdin", "a+", stdin);
> if (f_stdin != NULL)
> {
> buf[0] = '\0';
> while (1)
> {
> fgets (buf, 500, f_stdin);

Presumably, if the fgets() call hits end of file on the first call, it
will set the EOF indicator for the stream and no further read
operations will be successful unless you do something to reset EOF
first. Consult your C reference for the use of the standard library
clearerr() function.

> if (strlen (buf) > 0)
> printf ("buf: %s\n", buf);
> if (strcmp (buf, "q") == 0)
> break;
> buf[0] = '\0';
> }
> }
> else
> {
> perror ("error(first prog)");

freopen() is not obliged to set errno on failure, so there is no
guarantee that the output of perror() will be meaningful.

> }
> }
>
> The second program is:
>
> #include <stdio.h>
>
> void main (void)
> {
> FILE *f_stdin = NULL;
>
> f_stdin = fopen ("stdin", "a+");
> if (f_stdin != NULL)
> {
> fputs ("a test", f_stdin);

Failing to terminate the last line of a text file with a newline has
implementation-defined consequences, including the possibility that
the last line, which is the only line in this case, may not actually
be written to the file.

> }
> else
> {
> perror ("error(second prog)");
> }
> }
>
> The code below (creating two executables) compiles.
> I can redirect stdin in the first program and can open
> and write in the second program. Altough the string is
> written to the file, I can not read that from the first
> program.
>
> Can you see anything wrong in the above code? Is the
> freopen usage correct? Can freopen be used to
> redirect std streams to files and have other processes
> write to these files and command the first proces?

Again, the answer is that C does not specify an answer to your
question, as it has no concept of or support for "other processes".

You need to ask this question on a group that supports your specific
compiler/OS combination, as this has a lot to do with your operating
system.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html

Douglas A. Gwyn

unread,
Sep 4, 2007, 1:11:56 PM9/4/07
to
Hlk....@gmail.com wrote:
> Is it possible to have one process (program) that
> redirects its stdin to a file, and have a second program
> use that file write/append to that file. The first program
> will then read its redirected standard input file and
> process that...

Since access to a file by multiple concurrent processes is not
part of the Standard C model, there are no guarantees.

On Unix-based (POSIX) systems, it is better to pipe the two
processes together. See popen(3) etc.

A problem with the scheme you described is that an attempt to
read from the file past the end of the currently available
data will return an EOF indication (unlike a pipe, which
will block so long as the writer process is still alive).
As of C99 EOF is "sticky", so you have to reposition the
file to clear the EOF status. fseek(,0,SEEK_CUR) should
be used since SEEK_END would have a race condition.

The writer of course must use fflush() to force out each
record.

There is also a race in the data itself; the reader could
see an incompletely written record.

Use a pipe or some other system-sanctioned form of IPC.

ta0...@yahoo.com

unread,
Sep 4, 2007, 1:13:49 PM9/4/07
to
On Aug 21, 5:29 pm, Hlk.T...@gmail.com wrote:
> Hi All,
>
> I have a question regarding the standard C library.
>
> Is it possible to have one process (program) that
> redirects its stdin to a file, and have a second program
> use that file write/append to that file. The first program
> will then read its redirected standard input file and
> process that...


For one, the first argument needs to be the file name, and "stdin"
isn't generally going to be the file name of where standard input
reads from. In many cases it won't be a file at all, such as when
using command-line pipes and terminals. Secondly, the appropriate way
to do this would be to have the second program write to standard
output and the first read from standard input with no file stream
changes, then use a command line pipe (program2 | program1.) The most
likely reasons you can't read input in the first program are 1) you
are using a getline function and the second program doesn't output a
newline, 2) without a newline, printf doesn't provide an implicit
buffer flush.
Kevin P. Barry

0 new messages