C++ Redirect Output - c++

Is there a way to redirect c++ output inside the code?
The situation is this, I am using some external .cpp and .h files which use printf's to put warnings to console. I wish to redirect "only" these outputs (not mine) to a file "without" modifying their code.
So; in my program, I can redirect ouput to a file, and when I will put some output redirect again to default console, after that again to file, so on...
Is it possible?

You can use freopen() on stdout to redirect stdout to a file.

printf will print to file descriptor 1, you can close it and open a file, this will give you another fd, possibly 1 because its the lowest fd available, if not you weren't fast enough.
If you just close(1); and then int fd = open(file); fd should be 1 if none has opened something between the close and the open. At that point anyone outputting to fd number 1 will print to your file.
This is because the system should give you the lowest available file descriptor number so it'll give you 1 which is exactly where printf writes.
As #roe mentioned you might prefer to do a dup() over 1 first to get another fd number where you can print to stdout.

Related

How to write in stdout after using freopen [duplicate]

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";

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);
}

What does fd represent when typing: int fd = open("file");?

I am looking at I/O operations in C++ and I have a question.
When opening a file like:
#include <fcntl.h>
int main() {
unsigned char buffer[16];
int fd = open (argv[1], O_RDONLY);
read(fd, buffer, sizeof(buffer));
return 0;
}
How can the variable fd represent a file as an integer when passing it to the open method? Is it repesenting a file in current folder? If I print the ´fd´variable, it prints 3. What does that mean?
Ps. I know there are several other ways to handle files, like stdio.h, fstream etc but that is out of the scope of this question. Ds.
How can the variable fd represent a file as an integer when passing it to the open method?
It's a handle that identifies the open file; it's generally called a file descriptor, hence the name fd.
When you open the file, the operating system creates some resources that are needed to access it. These are stored in some kind of data structure (perhaps a simple array) that uses an integer as a key; the call to open returns that integer so that when you pass it read, the operating system can use it to find the resources it needs.
Is it repesenting a file in current folder?
It's representing the file that you opened; its filename was argv[1], the first of the arguments that was passed to the program when it was launched. If that file doesn't exist, or open failed for some reason, then it has the value -1 and doesn't represent any file; you really should check for that before you try to do anything with it.
If I print the fd variable, it prints 3. What does that mean?
It doesn't have any particular meaning; but it has that value because it was the fourth file (or file-like thing) that was opened, after the input (0), output (1) and error (2) streams that are used by cin, cout and cerr in C++.
Because that is the index of the table of resources stored for your current process.
Each process has it own resources table, so you just need to pass the index to read/write/etc function
Generally, a file descriptor is an index for an entry in a kernel-resident data structure containing the details of all open files. In POSIX this data structure is called a file descriptor table, and each process has its own file descriptor table. The user application passes the abstract key to the kernel through a system call, and the kernel will access the file on behalf of the application, based on the key. The application itself cannot read or write the file descriptor table directly.
from: http://en.wikipedia.org/wiki/File_descriptor
open() returns the file descriptor of the file which is the C type int. To know more about File Descriptor refer http://en.wikipedia.org/wiki/File_descriptor.
"fd" stands for file descriptor. It is a value identifying a file. It is often an index (in the global table), an offset, or a pointer. Different APIs use different types. WinAPI, for example, uses different types of handles (HANDLE, HGDI, etc.), which are essentially typedefs for int/void*/long, and so on.
Using naked types like "int" is usually not a good idea, but if the implementation tells you to do so (like POSIX in this case), you should keep it.
The simplified answer is that fd is just an index into some array of file descriptors.
When most processes are started, they are given three open file descriptors to begin with: stdin (0), stdout (1), and stderr (2). So when you open your first file, the next available array entry is 3.

Redirect the stdout to buffer,not using >

I wrote my implementation of printf – myPrintf,which prints to stdout.
I want to verify that it works fine.In order to check the correctess of the printed output I want to compare it with char I expect to get. How can I write code to redirect the stdout to buffer,not using >.
I can use only printf!
You could redirect couts buffer by setting it's rdbuf() to a file you have opened.
Weird, C++ and only printf, but whatever.
It's also possible to redirect stdout in C.
Here is one way of doing it: https://rydow.wordpress.com/2007/10/26/c-code-to-redirect-stdout/
It involves dup and dup2.
There is also this option ( Rerouting stdin and stdout from C ) using freopen.

Question about STDIN STDOUT STDERR

I'm designing a MIPS simulator in c++ and my simplified OS must be able to run stat() occasionally (when a program being executed on my simulator requires an input or an output or something.)
The problem is, I need to be able to assert STDIN, STDOUT, and STDERR as parameters to stat "stat("stdin",buff)" where buff is the pointer to the insertion point, for the struct data returned, in memory. In reality I'll be using fstat() which uses file descriptors to point to the file to be stat-ed. My file descriptor table in my simple OS reserves 0, 1, and 2 for stdin, stdout, and stderr. I'm a bit confused about what STDIN, etc are. They're streams, I realize that, they're defined in stdio.h, but how in the world do I get a stat struct with all of the relevant information about the file for each of these streams?
On a POSIX system, you can use fileno() to convert from a FILE* (e.g. stdin, stdout, stderr) to an integer file descriptor. That file descriptor can be sent to fstat().
Here is a very well known example of how to determine if the standard terminal output is redirected to a file to illustrate the usage of POSIX's fileno function
if (!isatty(fileno(stdout))){
fprintf(stdout, "argv, argc, someone is redirecting me elsewhere...\n");
return 1;
}
If using the above code in a program and that said program was executed like this
foobar_program > foobar_program.output
'foobar_program.output' will contain
argv, argc, someone is redirecting me elsewhere...\n
A file stream pointer is nothing more than a structure of a pointer type to FILE, i.e. FILE *, fileno takes that structure and converts it to its relevant file descriptor, accordingly to the manual page for fileno here
The function fileno() examines the argument stream and returns
its integer descriptor.
and also here on the posix manual pages, and I'll quote fileno - map a stream pointer to a file descriptor....