Send data to another C++ program - c++

Is it possible to send data to another C++ program, without being able to modify the other program (since a few people seem to be missing this important restriction)? If so, how would you do it? My current method involves creating a temporary file and starting the other program with the filename as a parameter. The only problem is that this leaves a bunch of temporary files laying around to clean up later, which is not wanted.
Edit: Also, boost is not an option.

Clearly, building a pipe to stdin is the way to go, if the 2nd program supports it. As Fred mentioned in a comment, many programs read stdin if either there is no named file provided, or if - is used as the filename.
If it must take a filename, and you are using Linux, then try this: create a pipe, and pass /dev/fd/<fd-number> or /proc/self/fd/<fd-number> on the command line.
By way of example, here is hello-world 2.0:
#include <string>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main () {
int pfd[2];
int rc;
if( pipe(pfd) < 0 ) {
perror("pipe");
return 1;
}
switch(fork()) {
case -1: // Error
perror("fork");
return 1;
case 0: { // Child
// Close the writing end of the pipe
close(pfd[1]);
// Create a filename that refers to reading end of pipe
std::ostringstream path;
path << "/proc/self/fd/" << pfd[0];
// Invoke the subject program. "cat" will do nicely.
execlp("/bin/cat", "cat", path.str().c_str(), (char*)0);
// If we got here, then something went wrong, then execlp failed
perror("exec");
return 1;
}
default: // Parent
// Close the reading end.
close(pfd[0]);
// Write to the pipe. Since "cat" is on the other end, expect to
// see "Hello, world" on your screen.
if (write(pfd[1], "Hello, world\n", 13) != 13)
perror("write");
// Signal "cat" that we are done writing
close(pfd[1]);
// Wait for "cat" to finish its business
if( wait(0) < 0)
perror("wait");
// Everything's okay
return 0;
}
}

You could use sockets. It sounds like both application are on the same host, so you just identify the peers as localhost:portA and localhost:port B. And if you do it this way you can eventually graduate to do network IO. No temp files, no mystery parse errors or file deletions. TCP guarantees packet delivery and guarantees they will be ordered correctly.
So yeah, I would consider creating an synchronous socket server (use asynchronous if you anticipate having tons of peers). One benefit over pipe oriented IPC is that TCP sockets are completely universal. Piping varies dramatically based upon what system you are on (consider Windows named pipes vs implicit and explicit POSIX pipes -> very different).

Related

Why does the output comes after sleep without newline?

I'm using gcc 7.3 and g++ 7.3. GCC and G++ makes error. For example,
#include <stdio.h>
#include <unistd.h>
int main() {
printf("a");
sleep(1);
return 0;
}
'a' prints after waiting 1 seconds but when I use printf("a\n"); it works correctly. It's same on C++. For example,
#include <iostream>
#include <unistd.h>
int main() {
std::cout << "a";
sleep(1);
return 0;
}
'a' prints after waiting 1 seconds, too. However, when I use std::cout << "a" << std::endl; it works correctly. What's the problem and how to fix it?
sleep() is like schedule a process manually. printf() puts the data into stdout stream not directly on monitor.
printf("a"); /* data is there in stdout , not flushed */
sleep(1); /* as soon as sleep(1) statement occurs your process(a.out) jumped to waiting state, so data not gets printed on screen */
So either you should use fflush(stdout) or use \n to clear the stdout stream.
You are seeing this behaviour because stdout will be usually line buffered when used with terminal and fully buffered when used with files, the strings will be stored in a buffer and can be flushed by entering new line or when buffer fills or when program terminates
You can also override buffer mode by using setvbuf as below
setvbuf(stdout, NULL, _IONBUF, 1024);
printf("a");
It will print a without buffering, have a look at https://www.tutorialspoint.com/c_standard_library/c_function_setvbuf.htm for using setvbuf
Also have a look at different types of buffering with streams.
Hope this helps you.

fprintf() / std::cout doesn't print part of the string to stdout/stderr

I have this strange problem with stdout/stderr.
I want to apologize for not being able to put here the original code, it's too long / too many libraries dependent etc...
So please let me know if you ever encountered anything like it, or what may cause this issue without getting the original code, only the idea and examples of the simple things I tried to do:
I'm using g++ (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4) on RHEL 6.3
I couldn't isolate the problem for putting it here, I'll give code examples of what I did.
fprintf() / printf() / std::cout stops working after a while.
I'm using boost::asio::io_service with deadline_timer in order to call a my_print() function.
This my_print() function prints to screen every 1 second some information.
In order to print, I use alignments, like the following:
fprintf(stdout, "%*s\n", -printWidth, someEnumToStr[i]);
fprintf(stdout, "%s\n", aString);
fprintf(stdout, "%u\n", num);
While aString is a std::string. Sometimes I construct aString from std::ostringstream.
Sometimes I construct it with snprintf().
I have an std::map with information, exactly 16 elements inside the map. I iterate over it, and for each element I try to print data with the example of fprintf() above.
For an unknown reason, the line of element 16 isn't printed.
If I call the executable, and redirect stdout to a file (./a.out > aaa.txt) the line of element 16 is getting printed.
If I open a new FILE* and fprintf() to this file, again, everything is getting printed (all lines, including line of element 16)
Before using fprintf() I tried to use std::cout (and alignments with std::cout.width(printWidth) << std::left...), The same behavior happened, but when line 16 wasn't drawn, stdout got stuck (I mean, the program still worked, but nothing was printed to stdout never again. I had to call std::cout.clear() for it to work again). Since a point in the code, which I couldn't lay my hands on, std::cout.failbit and badbit were 1.
If I run the code with valgrind this behavior doesn't happen. valgrind doesn't say anything wrong.
If I run it with gdb it happens, but gdb doesn't say anything wrong.
If I run it in an IDE (clion) in debug mode, it doesn't happen.
If I run it in IDE, without debug, it happens.
I figure it depends on the printWidth I give for the alignment in fprintf() - When printWidth is bigger, it happens sooner (when it's smaller, line 16 is randomly getting printed).
Another important thing: it happens more frequently when there is more to print.
I tried to give std::cout a bigger buffer (not his default) and it didn't work.
I tried to buffer all of the output into a buffer (instead of printing each line), then to only fprintf() once. Same behavior happens.
I didn't find anywhere in the code I try to print a NULL pointer.
I print with \n every couple of fprintf()s, and do fflush() in the end of my_print()
Please let me know if you know anything.
Illustration:
deadline_timer..... every 1 sec... my_print()
boost::asio::io_service.run
my_print() {
for(std::map<>::iterator... begin, end, ++it....) {
fprintf()s....
}
}
Non printable characters may be breaking terminal.
fprintf(stdout,"%s", astdstring.cstr() );
Is how to print std::string
I use boost::asio, I have a callback to read from stdin. this read is nonblocking - happens with async_read_some().
The problem was stdin was turned to be nonblocking, and it also caused stdout to be nonblocking as well because they point to the same file description (explanation).
It caused the fprintf() calls to fail (returned -1 with errno 11) and not all of the output got printed out on the screen.
It has no relation to boost.
I succeeded isolating the problem, the following code creates this problem:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
using namespace std;
int main(int argc, char *argv[]) {
const int problem = 8000;
const int myBuffSize = 32000;
char *myBuff = new char[myBuffSize];
int myoffset = 0;
memset(myBuff, '-', myBuffSize);
int flags;
bool toogle = true;
bool running = true;
// Comment from here
if ((flags = fcntl(STDIN_FILENO, F_GETFL, 0)) < 0) {
printf("error fcntl()\n");
return 0;
}
if (fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK) < 0) {
printf("error fcntl()\n");
return 0;
}
// Comment until here
while(running) {
toogle = toogle ? false : true;
if (toogle) {
snprintf(myBuff + problem, myBuffSize - problem, "fin\n\n");
} else {
snprintf(myBuff + problem, myBuffSize - problem, "end\n\n");
}
fprintf(stdout, "%s", myBuff);
sleep(1);
}
delete[] myBuff;
return 0;
}
If you'll comment the // Comment from here to // Comment untill here, it will print all of the output (fin and end will be printed).
One solution to this problem is to open another fd to the current tty using fopen(ttyname(STDOUT_FILENO), "w") and to print into it.
I believe another solution is to async_write() into screen.
The output might be stuck in a buffer, and not flushed before program termination.
Try adding exit(0) at the end of the program, and see if it helps.
http://www.cplusplus.com/reference/cstdlib/exit/
All C streams (open with functions in <cstdio>) are closed (and flushed, if buffered), and all files created with tmpfile are removed.

call gnuplot via fork and pipe and update plot

I want to do some realtime-plots during a simulation. For this, i would like to use octave or gnuplot. My current approach is to use a frontend to gnuplot, feedgnuplot, which fits actually very well.
The Simulation is written in C++, so i thought about forking (new process for feedgnuplot) and piping the relevant data to feedgnuplot.
The problem i have is that the output is only visible after the simulation.
But i want to see the plot updated during simulation.
Here is a MWE:
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
int main()
{
FILE* stream = popen("feedgnuplot", "w");
for(int i = 0; i < 10; ++i)
{
fprintf(stream, "%d\n", i * i);
fflush(stream);
sleep(1);
}
}
The program stops after 10 secons, showing the plot.
When using feedgnuplot directly in the shell, everything works as expected.
(That is, newly added data is plotted without the need to end the process)
What am i doing wrong? I think i lack some understanding of how popen really works.
First, let's write a fake feedgnuplot.c:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *buf = NULL;
size_t n = 0;
while (getline (&buf, &n, stdin) != -1) {
printf ("%s", buf);
}
free (buf);
return 0;
}
With this, your code works, i.e. the lines are printed as they arrive.
I suspect the problem lies in the way your feedgnuplot program reads incoming data. You should show the relevant part of that code.
If I had to take a guess, you probably need to add
setvbuf (stdin, NULL, _IOLBF, 0);
in feedgnuplot before you start to read from stdin.
That is because by default, when stdin corresponds to a terminal it is line buffered, whereas when it corresponds to a pipe it is fully buffered. The code above makes stdin line buffered no matter what so there should be no difference between reading from a terminal or a pipe.

Interrupt a getLine() while loop in C++

I made a console applications that accepts commands from two sources:
The actual console -> this is a while(getLine()) loop in a seperate thread.
A websocket server -> this also runs on a seperate thread
If there is a command entered, the command is stored in a vector until another while loop (that runs every 20ms) loops trough all the commands entered in the time passed. If he reads a command, he executes it.
Now, there is a Stop command who stops the application. When entered, the application shuts down as expected. But the problem is: this takes some time, and you can still enter text from the first command source (getline()). Once you type something, the shutdown sequence stops, and waits until you pressed enter.
I terminate the first thread (that contains the getline loop) once the shutdown sequence starts. But that doesn't work...
Any ideas?
Thanks in advance!
getline() is a blocking call, you'll probably have to use something different, if you want to receive messages (i.e. a shut down command) from other threads. You did not mention which library you use for multithreading and how you terminate the console reading thread (it's possible, that your way of stopping the thread still does not force it to exit from getline)
This question seems to have some relevant answers: Peek stdin using pthreads
By the way, you mentioned a vector, which is (if I understood it correctly) accessed from multiple threads. You'll have to take care about proper synchronization (e.g. using a mutex when accessing the vector).
Also, the fact that you have some kind of loop, which "polls" the vector every 20 ms is indicating that you may have some flaws in overall design of your application. Try to get rid of it by using more appropriate means for passing events between threads, such as condition variables.
The problem is that getline is a blocking call and will return just after you press ENTER in case of stdin.
I had a similar problem and solved it as shown below.
I used two file descriptors: one to monitor the stdin and an other to monitor a "self-pipe". The latter acts as a trigger to unlock the select in case some event happens. The former ensures getline is called just once it can read a full line.
#include <future>
#include <string>
#include <iostream>
#include <thread>
#include <unistd.h>
#include <stdio.h>
#include <sys/select.h>
int pipe_fd[2];
auto p = pipe(pipe_fd);
auto stdin_fd = fileno(stdin); // 0
fd_set check_fd;
int main(int argc, char const *argv[])
{
FD_ZERO(&check_fd);
FD_SET(stdin_fd, &check_fd);
FD_SET(pipe_fd[0], &check_fd);
auto t1 = std::async(std::launch::async, [] {
std::this_thread::sleep_for(std::chrono::seconds(10));
uint32_t dummy = 43;
// this will stop the data input
write(pipe_fd[1], &dummy, sizeof(dummy));
});
auto maxfd = pipe_fd[0] > pipe_fd[1] ? pipe_fd[0] : pipe_fd[1];
select(maxfd + 1, &check_fd, nullptr, nullptr, nullptr);
if (FD_ISSET(stdin_fd, &check_fd))
{
std::string input;
std::getline(std::cin, input);
std::cout << "You enterd:" << input << std::endl;
}
if (FD_ISSET(pipe_fd[0], &check_fd))
std::cout << "Event" << std::endl;
return 0;
}

How do I run a program from another program and pass data to it via stdin in c or c++?

Say I have an .exe, lets say sum.exe. Now say the code for sum.exe is
void main ()
{
int a,b;
scanf ("%d%d", &a, &b);
printf ("%d", a+b);
}
I wanted to know how I could run this program from another c/c++ program and pass input via stdin like they do in online compiler sites like ideone where I type the code in and provide the stdin data in a textbox and that data is accepted by the program using scanf or cin. Also, I wanted to know if there was any way to read the output of this program from the original program that started it.
The easiest way I know for doing this is by using the popen() function. It works in Windows and UNIX. On the other way, popen() only allows unidirectional communication.
For example, to pass information to sum.exe (although you won't be able to read back the result), you can do this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f;
f = popen ("sum.exe", "w");
if (!f)
{
perror ("popen");
exit(1);
}
printf ("Sending 3 and 4 to sum.exe...\n");
fprintf (f, "%d\n%d\n", 3, 4);
pclose (f);
return 0;
}
In C on platforms whose name end with X (i.e. not Windows), the key components are:
pipe - Returns a pair of file descriptors, so that what's written to one can be read from the other.
fork - Forks the process to two, both keep running the same code.
dup2 - Renumbers file descriptors. With this, you can take one end of a pipe and turn it into stdin or stdout.
exec - Stop running the current program, start running another, in the same process.
Combine them all, and you can get what you asked for.
This is my solution and it worked:
sum.cpp
#include "stdio.h"
int main (){
int a,b;
scanf ("%d%d", &a, &b);
printf ("%d", a+b);
return 0;
}
test.cpp
#include <stdio.h>
#include <stdlib.h>
int main(){
system("./sum.exe < data.txt");
return 0;
}
data.txt
3 4
Try this solution :)
How to do so is platform dependent.
Under windows, Use CreatePipe and CreateProcess. You can find example from MSDN :
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
Under Linux/Unix, you can use dup() / dup2()
One simple way to do so is to use a Terminal (like command prompt in windows) and use | to redirect input/output.
Example:
program1 | program2
This will redirect program1's output to program2's input.
To retrieve/input date, you can use temporary files, If you don't want to use temporary files, you will have to use pipe.
For Windows, (use command prompt):
program1 <input >output
For Linux, you can use tee utility, you can find detail instruction by typing man tee in linux terminal
It sounds like you're coming from a Windows environment, so this might not be the answer you are looking for, but from the command line you can use the pipe redirection operator '|' to redirect the stdout of one program to the stdin of another. http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true
You're probably better off working in a bash shell, which you can get on Windows with cygwin http://cygwin.com/
Also, your example looks like a mix of C++ and C, and the declaration of main isn't exactly an accepted standard for either.
How to do this (you have to check for errors ie. pipe()==-1, dup()!=0, etc, I'm not doing this in the following snippet).
This code runs your program "sum", writes "2 3" to it, and than reads sum's output. Next, it writes the output on the stdout.
#include <iostream>
#include <sys/wait.h>
#include <unistd.h>
int main() {
int parent_to_child[2], child_to_parent[2];
pipe(parent_to_child);
pipe(child_to_parent);
char name[] = "sum";
char *args[] = {name, NULL};
switch (fork()) {
case 0:
// replace stdin with reading from parent
close(fileno(stdin));
dup(parent_to_child[0]);
close(parent_to_child[0]);
// replace stdout with writing to parent
close(fileno(stdout));
dup(child_to_parent[1]);
close(child_to_parent[1]);
close(parent_to_child[1]); // dont write on this pipe
close(child_to_parent[0]); // dont read from this pipe
execvp("./sum", args);
break;
default:
char msg[] = "2 3\n";
close(parent_to_child[0]); // dont read from this pipe
close(child_to_parent[1]); // dont write on this pipe
write(parent_to_child[1], msg, sizeof(msg));
close(parent_to_child[1]);
char res[64];
wait(0);
read(child_to_parent[0], res, 64);
printf("%s", res);
exit(0);
}
}
I'm doing what #ugoren suggested in their answer:
Create two pipes for communication between processes
Fork
Replace stdin, and stdout with pipes' ends using dup
Send the data through the pipe
Based on a few answers posted above and various tutorials/manuals, I just did this in Linux using pipe() and shell redirection. The strategy is to first create a pipe, call another program and redirect the output of the callee from stdout to one end of the pipe, and then read the other end of the pipe. As long as the callee writes to stdout there's no need to modify it.
In my application, I needed to read a math expression input from the user, call a standalone calculator and retrieve its answer. Here's my simplified solution to demonstrate the redirection:
#include <string>
#include <unistd.h>
#include <sstream>
#include <iostream>
// this function is used to wait on the pipe input and clear input buffer after each read
std::string pipeRead(int fd) {
char data[100];
ssize_t size = 0;
while (size == 0) {
size = read(fd, data, 100);
}
std::string ret = data;
return ret;
}
int main() {
// create pipe
int calculatorPipe[2];
if(pipe(calculatorPipe) < 0) {
exit(1);
}
std::string answer = "";
std::stringstream call;
// redirect calculator's output from stdout to one end of the pipe and execute
// e.g. ./myCalculator 1+1 >&8
call << "./myCalculator 1+1 >&" << calculatorPipe[1];
system(call.str().c_str());
// now read the other end of the pipe
answer = pipeRead(calculatorPipe[0]);
std::cout << "pipe data " << answer << "\n";
return 0;
}
Obviously there are other solutions out there but this is what I can think of without modifying the callee program. Things might be different in Windows though.
Some useful links:
https://www.geeksforgeeks.org/pipe-system-call/
https://www.gnu.org/software/bash/manual/html_node/Redirections.html