How to write in stdout after using freopen [duplicate] - c++

This question already has answers here:
How to redirect the output back to the screen after freopen("out.txt", "a", stdout)
(6 answers)
Closed 8 years ago.
After freopen-ing stdout, How can I print on terminal?
freopen("out", "w", stdout); // reopen stdout
/* something */
printf("Now I want to print this on terminal");

I believe this is what you are looking for:
Once I've used freopen, how can I get the original stdout (or stdin) back?
There's no portable solution. But the link also explains a possible solution using your own stream and a non-portable solution that'll work on most posix systems.
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. Try using your own
explicit output (or input) stream variable, which you can reassign at
will, while leaving the original stdout (or stdin) undisturbed. For
example, declare a global
FILE *ofp;
and replace all calls to printf( ... ) with fprintf(ofp, ... ).
(Obviously, you'll have to check for calls to putchar and puts, too.)
Then you can set ofp to stdout or to anything else.
You might wonder if you could skip freopen entirely, and do something
like
FILE *savestdout = stdout;
stdout = fopen(file, "w"); /* WRONG */
leaving yourself able to restore stdout later by doing
stdout = savestdout; /* WRONG */
but code like this is not likely to work, because stdout (and stdin
and stderr) are typically constants which cannot be reassigned (which
is why freopen exists in the first place).
It may be possible, in a nonportable way, to save away information
about a stream before calling freopen to open some file in its place,
such that the original stream can later be restored. The most
straightforward and reliable way is to manipulate the underlying file
descriptors using a system-specific call such as dup or dup2, if
available. Another is to copy or inspect the contents of the FILE
structure, but this is exceedingly nonportable and unreliable.
Under some systems, you might be able to reopen a special device file
(such as /dev/fd/1 under modern versions of Unix) which is still
attached to (for example) the original standard output. You can, under
some systems, explicitly re-open the controlling terminal, but this
isn't necessarily what you want, since the original input or output
(i.e. what stdin or stdout had been before you called freopen) could
have been redirected from the command line.

You can do it by:
#include <fstream>
ofstream out("out.txt");
out<<"something";
then
cout<<"something";

Related

Send Character TO CONIN$ (Windows Console)

If you want to spawn a Windows console in an otherwise SUBSYSTEM:WINDOWS application you can use this code:
if (AllocConsole())
{
FILE* file = nullptr;
_wfreopen_s(&file, L"CONIN$", L"r", stdin);
_wfreopen_s(&file, L"CONOUT$", L"w", stdout);
_wfreopen_s(&file, L"CONOUT$", L"w", stderr);
}
The _wfreopen_s function maps stdin to CONIN$ and provides a pointer to pointer in the file variable (which we are effectively discarding).
What I'd like to do is instead map an input from something other than stdin, for example, another file stream and then write that stream to CONIN$.
For a larger picture of what I'm trying to do here, I've got a secondary thread running std::getline(std::cin... which blocks. I'd like the thread context object to just send a \n to the console to break the blocking call.
If there are other ideas, I'm open. The alternative currently is that I print a message to the console that says "Shutting down, press ENTER to quit..." Which, I guess, also works ;)
What I tried was using the FILE* conin = new FILE(); and then did a memcpy to fill it with a \n and then I used WriteFile to that pointer, thinking that it might write the file stream out to CONIN$, and while the code compiles, and the contents of the FILE* appears to be correct (0x0a), it does not appear to send that stream to the console.
I tested this by having std::cout above and below the code testing the stream write. If it works, I'd expect the two lines to be on separate lines, but they always show up on the same, suggesting that I'm not sending the file stream.
Thanks for reading!
You should not discard the FILE* handle, otherwise you won't be able to manipulate it, in particular you won't be able to properly flush/close it if required.
If you're working with threads, simply give the FILE* to the thread that requires it. Threads share the same memory space.
If you're working with processes, then you should create a pipe between the two processes involved (see Win32 API for CreatePipe for details), and connect one's stdout to the other's stdin.

Check/list all bash commands in C++?

Basically, is there a simple way to get a list of all bash commands in the PATH environment variable in C++? My current solution is to run a command beforehand that lists all the commands into a .txt, which is then read into the C++ program. I want to be able to cut out this step, if possible.
ls ${PATH//:/ } > commands.txt
If you do NOT need to use stdin in your C++ program
This is the easy solution. Just pipe the output of the ls command to your C++ program. Then, in your C++ program, read the contents of the file from stdin like you would read from a normal file. Literally use stdin wherever you need to provide a file descriptor. So, your command would look something like
ls ${PATH//:/ } | ./a.out
The | denotes a pipe in bash. It takes stdout from the first program (here ls) and redirects it to stdin of the second program (here your C++ program).
If you do need to use stdin in your C++ program
This is going to be tricky. You essentially need to make your C++ program do everything itself. The first way to this that comes to mind is
Read $PATH using getenv().
Parse $PATH by replacing all occurrences of : with (a blank space). This is easy enough to do in a loop, but you could also use std::replace.
Now that you have the directory paths from $PATH, you simply need the contents of each directory. This post will help you get the contents of a directory.
UPDATE: Another Approach
I've thought of another way to approach your problem that allows you to use IO redirection (ie. use the pipe), and also use stdin at the same time. The problem is that it is probably not portable.
The basic idea is that you read the output of ls from stdin (using the pipe operator in bash). Next, you essentially reset stdin using freopen. Something along the lines of
#include <stdio.h>
int main(void)
{
char buf[BUFSIZ];
puts("Reading from stdin...");
while(fgets(buf, sizeof(buf), stdin))
fputs(buf, stdout);
freopen("/dev/tty", "rw", stdin);
puts("Reading from stdin again...");
while(fgets(buf, sizeof(buf), stdin))
fputs(buf, stdout);
return 0;
}
The above code is from here. It reads stdin, resets stdin, and reads from stdin again. I would suggest not using this approach for anything important, or for something that needs to work on several platforms. While it is more convenient since it allows you to use IO redirection while retaining the ability to use stdin, it is not portable.

read stdout of a process in itself using c++

Consider we have some_function and it prints result to stdout instead returning it.Changing it's defination is out of our scope and there's no alternative to it. We're left with option of reading it from stdout. So the question.
How to read stdout of C++ program in itself.
It is possible to get pid I searched if we can get fd of the same programm but I'm not able to find anything.
#include <unistd.h>
#include <sys/types.h>
#include <iostream>
void some_function(){
std::cout<<"Hello World";
}
int main(){
int pid = ::getpid();
string s = //What to write here.
cout<<"Printing";
some_function(); //This function prints "Hello World" to screen
cout<<s; //"PrintingHello World"
return 0;
}
How to attach pipe to same process i.e instead of creating child process.
Some might think of creating child process and call some_function in it, to be able to read its stdout in parent process, but No, some_function depends on process which calls it and hence we want to call it the very process instead of creating child process.
This isn't hard to do, but IMO it's quite a hack, and it won't work with a multithreaded program:
// make a temp file to store the function's stdout
int newStdOut = mkstemp( "/tmp/stdout.XXXXXXX" );
// save the original stdout
int tmpStdOut = dup( STDOUT_FILENO );
// clear stdout
fflush( stdout );
// now point the stdout file descriptor to the file
dup2( newStdOut, STDOUT_FILENO );
// call the function we want to collect the stdout from
some_function();
// make sure stdout is empty
fflush( stdout );
// restore original stdout
dup2( tmpStdOut, STDOUT_FILENO );
// the tmp file now contains whatever some_function() wrote to stdout
Error checking, proper headers, syncing C stdout with C++ cout, and reading from and cleaning up the temp file are left as exercises... ;-)
Note that you can't safely use a pipe - the function can write enough to fill up the pipe, and you can't read from the pipe because you've called the function.
How to read stdout of C++ program in itself?
There are very few reasons to do that and that is usually (but not always) a design bug.
Be aware of an important thing (at least in a single-threaded program). If your program is both reading from its "stdout" and writing (as usual) in it, it could be stuck in a deadlock: unable to read so not reaching any output routine, (or unable to write because the pipe is full).
So a program which both reads and writes the same thing (actually, the two sides of the same pipe(7)) should use some multiplexing call like poll(2). See also this.
Once you understand that, you'll have some event loop. And before that, you'll make a pipe(7) using pipe(2) (and dup2(2)).
However, pipe to self is a good thing in some signal(7) handling (see signal-safety(7)). That trick is even recommended in Qt Unix signal handling.
Read more about Unix system programming, e.g. ALP or some newer book. Read also intro(2) & syscalls(2).
I have looked for pipe and it requires fd
Wrong. Read much more carefully pipe(2); on success it fills an array of two file descriptors. Of course it could fail (see errno(3) & perror(3) & strerror(3))
Maybe you just need popen(3). Or std::ostringstream. Or open_memstream(3).
Consider we have some_function and it prints result to stdout instead returning it. Changing it's definition is out of our scope and there's no alternative to it
If some_function is your code, or is some free software, you could and probably should improve it to give a result somewhere....

How to listen to stderr in C/C++ for sending to callback?

How do I passively listen to stderr and obtain it as string for sending to callback? I have seen posts on reading stderr but I want to listen to it rather than actively reading it.
Background:
I have a cross-platform piece that uses 3rd party library (libcurl) which will output verbose info into stderr. This cross-platform piece is to be used by more than 1 non-cross-platform applications.
I would like to log these info, which I can do by providing FILE* to libcurl. But instead of doing that, I want to see if I can capture (passively listen to) the output in stderr as string, and send back to the calling main application via callback. This has the benefit of 1. main app can keep a single log using whatever logging tool it wants. 2. it will keep this piece cross-platform.
Doing this in a single process is a little tricky, but you can probably do it.
1: Using freopen() you can redirect your stderr to a named file. You can simultaneously open that file for reading on another handle. You might also need to call setvbuf() on stderr to turn off buffering on output to stderr so that you will be able to read it right away from the 2nd handle. Since it is being written to a file you can read it at anytime - when it is convenient. The unix function "select" is what you need if you want to be notified when the file changes. (see also fileno()).
2: More tricky would be to setup stderr as the write end of a pipe. Should be doable using dup3(), though this isn't exactly cross-platform (to non-unixy OS's). It would also require that a 2nd thread be reading from the pipe to prevent the writer from being blocked if they write very much.
Like:
FILE *stream = freopen("stderr.out", "w", stderr); // Added missing pointer
setvbuf(stream, 0, _IONBF, 0); // No Buffering
FILE *input = fopen("stderr.out", "r");
fprintf(stderr, "Output to stderr dude\n");
//fflush(stderr); // You can explicitly flush instead of setting no buffering.
char buffer[1024];
while (fgets(buffer, 512, input))
{
printf(">>>%s\n", buffer);
}

C/C++: is it possible to pass binary data through the console? [duplicate]

This question already has answers here:
What is the simplest way to write to stdout in binary mode?
(2 answers)
Closed 7 years ago.
I would like to know if it is possible that an utility yields binary data (i.e. graphical images) and outputs them through IO console, while another application, instructed about the nature of those data and informed of the number of the incoming bytes, is able to read it from IO console.
Yes, it is possible. While it's true that often stdin/stdout are meant to be text there are many programs that are designed to get binary input or write binary output from standard I/O channels.
The only thing you should pay attention is that normally stdout/stdin are opened in text mode under Windows, so you should switch them to binary mode to avoid character translation.
To set binary mode on stdin/stdout on Windows you need to use the _setmode call:
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
int main( void )
{
int result;
// Set "stdin" to have binary mode:
result = _setmode( _fileno( stdin ), _O_BINARY );
if( result == -1 )
perror( "Cannot set mode" );
else
printf( "'stdin' successfully changed to binary mode\n" );
}
Note also to pay attention to file buffering. Often programs will flush the buffer on newlines ONLY when the output is to an interactive console and not when it's another process. So if you need synchronizaton remember to call fflush after writing a message because otherwise the other process will not be able to get the data.
You can use traditional socket or lighter named pipe for this kind of thing.
You could Base 64-Encode/Decode the data. This will avoid the need to send pure "bits" over the standard input/output stream.
If the process is to be hosted within another process that will capture your stdout from the process that writes binary data then there is no need to encode it. In that case you can write the raw binary data to the output and be done with it. This is for example how the image writing dot tool from graphviz works, it doesn't encode it's input by default. These kinds of tools are also pretty easy to pipe to a file by the use of > in the command shell.
Only if the output from the data is going to be seen on the console are you going to need to encode it. It's not a very good idea to print the contents of say an image file.
You can do it if you choose an appropriate encoding, as the console is a text stream. Use for example Base64 encoding for your binary data and it will work fine. Another alternative is the "Quoted-printable" format. You end up of course with more bytes than the original binary data, but IMHO the only way to do it safely using the console.