stderr output when using popen in C++ linux - c++

when I use this simple program to get the standard output of the process, I also somehow get the standard error of the process, although the man page for popen says that only the standard output is redirected. Is it possible that this is related to the shell that is used when forking a process with popen? errEr is a simple program outputting to stderr (cerr << "hello";). I'm using RHEL 6.4. Thanks!
#include <iostream>
#include <cstdio>
using namespace std;
int main ()
{
FILE *fd = popen("errWr", "r");
char str [1024];
while (fgets(str, 1024, fd))
{
cout<<str<<endl;
}
return 0;
}

You're not getting the output from stderr in your program using popen.
Following simple example shows, that error stream from started application is printed in terminal, without being read in your program. popen redirects only stdout stream and stderr stream is not affected, so it's just printed to terminal.
#include <iostream>
#include <cstdio>
using namespace std;
int main ()
{
FILE *fd = popen("errWr", "r");
char str [1024];
while (fgets(str, 1024, fd))
{
cout << "=>" << str << "<=" << endl;
}
return 0;
}

Related

Piping text information from the Windows command interpreter (cmd.exe) to a character array

Is there a way to extract text information from the Windows command interpreter (cmd.exe) to a character array without creating a text file from the command interpreter?
Try _popen (<stdio.h>), the Microsoft's version of the POSIX popen function:
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
int main(void) {
FILE * pp;
char buf[1024];
string result;
if ((pp = _popen("dir", "r")) == NULL) {
return 0;
}
while (fgets(buf, sizeof(buf), pp)) {
result += buf;
}
_pclose(pp);
cout << result << endl;
return 0;
}

Continuously write to subprocess using popen in C++

I need to open a subprocess using popen, the process will continuously ask for user input... The main process need to send that data over the pipe.
This is my first attempt:
FILE *in;
char buff[1024];
if(!(in = popen("cd FIX/fix2/src; java -cp .:./* com.fix.bot", "w"))){
return 1;
}
while(1){
char buffer[] = { 'x' };
fwrite(buffer, sizeof(char), sizeof(buffer), in);
cout << "Wrote!" << endl;
usleep(1000000);
}
However the data is not sent! I need to close the pipe with pclose() so that the data is written to the process. How can I make sure to write the data without having to close the pipe everytime?
You'll want to call fflush(in) to make sure that the buffered data is actually written to the stream.
Also check that java -cp .:./* in the command isn't expanding to an invalid classpath. I think that'll end up expanding to several arguments if there's more than one file in the current directory, and not actual classpath entries.
This works for me:
#include <stdio.h>
#include <unistd.h>
#include <iostream>
int main(int argc, char ** argv) {
FILE *in;
char buff[1024];
if(!(in = popen("./2.sh", "w"))){
return 1;
}
while(1) {
char buffer[] = "xx\n";
fwrite(buffer, sizeof(char), sizeof(buffer), in);
fflush(in);
std::cout << "Wrote!" << std::endl;
usleep(1000000);
}
}
where 2.sh is:
#!/bin/sh
read INP
echo 'read: ' $INP
So I am really suspecting that the problem is missing \n.

Dev-C++ Hello world doesn't show

I am new to C++. I downloaded and run Dev-C++ and I write and run F9 this:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, world!";
return 0;
}
But no "Hello, world!" is printed, why?
Many IDE users have this problem. The program runs but it closes before you can see its results on the screen. One portable fix is to add this at the bottom of main before you return:
std::cin.get();
That way it will wait for you to enter some text before it exits.
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, world!";
getchar();
return 0;
}
Add getchar() at the end of your program as a simple "pause-method" as consoles seems to close so fast, so you need to "delay" to see your console.
The output is printed to a terminal, and you don't have a newline etc.... very unlikely that you will see it, so
Add a newline to the output
make sure you have time to read the output before the terminal window closes (add a sleep or something)
Don't use using namespace as that is a bad practice and will lead to trouble in your programming.
So like;
#include <iostream>
#include <unistd.h>
int main()
{
std::cout << "Hello, world!" << std::endl;
sleep(2);
return 0;
}

Alternative Console Output Streams

In C/C++ the standard output streams: stdout/stderr,std::cout/std::cerr print to the console (not to mention clog, wcout...). These can be independently redirected from the command line.
Is there a way to add an alternative output stream that:
Prints to the console like the standard streams;
Does not get redirected with either of the standard streams.
In particular, I am interested in having some console output that does not get logged by redirection.
If there are no standard ways, then platform dependent ways (Linux and Windows) will also be helpful.
On Linux systems, you might open /dev/tty and write to it. See tty(4). Read also console(4) and perhaps consider /dev/console (but I recommend /dev/tty)
AFAIK, the C++ standard does not define such an output stream.
See also (on Posix) syslog(3) which would be my preference (since /dev/tty wont work if you have no controlling terminal).
Following up on #BasileStarynkevitch suggestions, the same can be done on Windows replacing "dev/tty" with "con".
For completeness here's a full program demonstrating non-redirectable calls:
#include <stdio.h>
#include <iostream>
#include <fstream>
#ifndef DEVTTY
#define DEVTTY "con" // on Windows
// #define DEVTTY "/dev/tty" // on Linux/MacOS
#endif
using namespace std;
int main()
{
cout << "DEVTTY = " << DEVTTY << endl;
printf("Print[f]ed to stdout.\n");
fprintf(stdout, "Print[f]ed to stdout.\n");
cout << "Printed to std::cout" << endl;
fprintf(stderr, "Print[f]ed to stderr.\n");
cerr << "Printed to std::cerr" << endl;
{
// C, stdio version
FILE* fd = fopen(DEVTTY, "w");
fprintf(fd, "Printed to \"%s\"\n", DEVTTY); // will not be redirected
fclose(fd);
}
{
// C++, fstream version
std::ofstream ofs(DEVTTY);
ofs << "Printed via std::ofstream to \"" << DEVTTY << "\"" << endl; // will not be redirected
}
return EXIT_SUCCESS;
}
Redirecting both stdout and stderr as in StreamRedirection.exe > out.txt 2>&1 gives:
In out.txt:
DEVTTY = con
Print[f]ed to stdout.
Print[f]ed to stdout.
Printed to std::cout
Print[f]ed to stderr.
Printed to std::cerr
and in the Console (on Windows):
Printed to "con"
Printed via std::ofstream to "con"

cout vs printf when doing fork()

I am trying to understand fork() using some test program. And I find different behaviors between cout and printf() :
program 1:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int main()
{
printf("Hi , %d\n" , getpid());
fork();
return 0;
}
I get:
Hi , 9375
Hi , 9375
program 2:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int main()
{
cout << "Hi , " <<getpid() << endl;
fork();
return 0;
}
I get:
Hi , 7277
The only difference between two program is the first use printf() to print the output while second use cout
Can anyone explain it?
Thanks
When you use stdio, stdout is fully-buffered unless it's writing to a terminal; when writing to a terminal it's line-buffered.
So if you run Program 1 with output redirected to a file or pipe, printf writes the line to the output buffer, but doesn't flush the buffer. When the process forks, the buffer is duplicated in both processes. When they exit, they each flush their copy of the buffer, which prints the line.
You would get the same result in Program 2 if you'd written:
cout << "Hi , " <<getpid() << "\n";
But endl, in addition to outputting the newline character, also flushes the buffer. The equivalent in Program 1 would be:
printf("Hi , %d\n" , getpid());
fflush(stdout);