I'm using some LLVM tools (like llvm-nm
) as static libraries. I.e. i copied source llvm-nm.cpp, renamed main(..)
to llvm_nm(..)
and compiled it as static library. I'd like to forward standard output to my file.
I've tried to use the next approach:
int out_fd, err_fd;
fpos_t out_pos, err_pos;
// redirect out
fflush(stdout);
fgetpos(stdout, &out_pos);
out_fd = dup(fileno(stdout));
freopen(outFilename, "w", stdout);
// execute
int ret = llvm_nm(argc_, argv_);
// restore output
fflush(stdout);
dup2(out_fd, fileno(stdout));
close(out_fd);
clearerr(stdout);
fsetpos(stdout, &out_pos);
The problem is that it's not forwarded (it works if i add printf()
in nm source code but not for nm
output). I've looke to the source and i can see output is done using llvm::outs()
stream:
outs() << "Archive map" << "\n";
And it's implemented the next way:
/// outs() - This returns a reference to a raw_ostream for standard output.
00702 /// Use it like: outs() << "foo" << "bar";
00703 raw_ostream &llvm::outs() {
00704 // Set buffer settings to model stdout behavior.
00705 // Delete the file descriptor when the program exits, forcing error
00706 // detection. If you don't want this behavior, don't use outs().
00707 static raw_fd_ostream S(STDOUT_FILENO, true);
00708 return S;
00709 }
How can i redirect that output to my file?
I realize this is an old question, however, I came across it looking up some simple information for llvm's outs() stream which I found here.
One of the examples that comes with llvm "BrainF" uses it like this:
...
raw_ostream *out = &outs();
if (!JIT) {
if (OutputFilename == "") {
std::string base = InputFilename;
if (InputFilename == "-") { base = "a"; }
// Use default filename.
OutputFilename = base+".bc";
}
if (OutputFilename != "-") {
std::error_code EC;
out = new raw_fd_ostream(OutputFilename, EC, sys::fs::F_None);
}
}
...
if (out != &outs())
delete out;
...
So it seems to suggest that you are safe to redirect.
Note: in this example OutputFilename/InputFilename are std::string types created with llvm's Support Library CommandLine.
There does not seem to be an easy way to do so: there's no copy / assignment constructor in llvm::raw_fd_ostream
nor in llvm::raw_ostream
. And the freopen
trick does not work either because the file descritor integer is used to initialize the object returned by llvm::outs()
.
The only way I see is to use LD_PRELOAD to change the implementation of llvm::outs()
on the fly, or similar linker tricks, but that sounds very hacky to me. Maybe mark the original symbol as weak and then override it in your library?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With