The situation is that I have program started through system() or CreateProcess().
Now, is it possible to do stuff as that program outputs data into console. I mean as the program outputs it. That is not wait for the end, gather data and then process it, but just in the moment that this external program calls console with data that it wants to print, and then get hold of that data, process it and output something else on the console.
The easiest way is usually to start the program with _popen(your_program, "r");. That will return a FILE * you can read from, and what it reads will be whatever the child writes to its standard output. When you read EOF on that file, it means the child process has terminated. This makes it relatively easy to read and process the output from the child in real time.
On Linux, create a named pipe:
system("mkfifo pipename")
Then open the pipe in the first program, and start the program with:
system("program > pipename")
I'm not sure how to do this on Windows.
Call AllocConsole before creating child process, or use AttachConsole(ChildPID) function (in parent process).
After that, you may use any ReadConsoleXXX or WriteConsoleXXX functions.
Related
For my computer science class final project, I need to interact with a SQL database. Only problem is, my prof won't install the SQL c++ API for me. Is there a way I can still interact with SQL without the API?
If I'm understanding your question correctly, you want your program to be able to launch a child process (an SQL command line program in this case), and then be able to read the text it receives from the child process's stdout and/or stderr, and write text to the child process's stdin, the same way a user would if he/she were running that program interactively.
The answer is yes, it is possible to do this, although it takes some work. Under Linux/Unix/MacOSX, you can call forkpty() to spawn a child process -- the parent process will get a socket (via forkpty's first argument) that you can use to communicate with the child process's stdin and stdout. In the child process, you can then call execvp (or one of its variants) to run the SQL program in that process;
Under Windows, it's a bit more complex -- you'll need to set up some pipes and then call CreateProcess() to launch the child process, and communicate with it through those pipes. Microsoft has a page on the topic (including example code) here.
I am writing a program to run a different program over and over, giving it different input to a question each time, checking the output. system("the_program") accomplishes this, but how do I give that program input when it runs scanf()?
The simplest way is to write a file, and pass it to the child using redirection (system("the_program < the_file")).
But, and this is much better, you can make a pipe between your program and the child. The child needs to have its standard input (file descriptor 0) connected to the reading side of the pipe. system is synchronous, so besides pipe and dup2 you need the fork and execve system calls. Luckily, there is a wrapper for this process: popen("the_program", "w"). It returns a FILE* that you can write to. Close the FILE* with pclose, and be sure to read the manual because it is different from fclose!
In the case where you are writing both parent and child programs, there is no need to a solve a problem arising by simulating something else, when we can just pass in arguments:
system('./the_program the_scanf_input')
And of course the_program:
var = argv[1] //this was var = scanf('%', &var)
In my C++ program I need to execute a bash script. I need then to return the result obtained running the script in my c++ program.
I have two possibilities:
1. use system(script.sh). In script.sh I redirect the output in a file which is processd after I return to the c++ program.
2. use popen
I am interested which of this methods is preffered, considering that the output returned from script.sh could be big(100 M). Thanks.
When using system the parent process is blocked until the child process terminates. The child process will run with full performance.
popen will start the child process, but not wait until it ended. So the parent process can continue to do whatever it wants while the child is running, it can for example read the output of the child process. The parent process can decide if it wants to read blocking or non-blocking from the child's output pipe, depending on how much other things the parent process has to do. The child will run in parallel and write its output to the pipe. It might be blocked when writing if the parent process is not reading from the pipe and the pipe's memory limit is reached. So the parent process should keep on reading the output.
The system approach is a bit simpler. But popen gives you the possibility to read the process's output while it is still running. And you don't need the extra file (space). So I'd use popen.
I have two processes written in C++, piped one after the other. One gives some information to the other's stdin, then they both go on to do something else.
The problem is that the second process hangs inside cin.getline(), even though there's no more data to be exchanged. The solution was for the first process to fclose(stdout), and that works, except when I use the process wrapped up in a script. So apparently the stdout of the script is still open after closing it by the process - which seems fair but in my case, can I close it? Thanks
Since your program doesn't terminate, you can exec your-program in the script instead of just your-program and save an open file descriptor at the writing end of the pipe (and a bunch of other things).
Alternatively, start your program in the background and exit the script.
You can also close the standard output, but if you do that before you start your program, it won't be able to use the closed file descriptor. So you have to close it while the program is running. This is not exactly trivial. I can think of starting the program in the background, closing the standard output (use exec 1>&- for that) and bringing the program back to the foreground.
I'm writing a program with C++ and by native Win32 API. I'm creating a process from a SFX archive EXE in silent mode that no GUI is shown to user. But I want to show a progress bar in my application, while the SFX archive extracting.
How can I do that?
Thanks.
If the process you create produces some textual output to the standard output then you can probably parse that output somehow and show the progress. To know if it does, activate it in a command line windows and watch what you get from it.
win32's CreateProcess() allows you to redirect the standard output of the process to a pipe. This way you can receive the output as soon as it is produced.
If the process you're creating doesn't report its progress somehow then there's really not much you can do. You can try to come up with function between the size of the file and the average time it takes to extract it and then fake a progress bar. That will serve the purpose of setting the user's mind at ease but nothing more.
--Edit
The call to CreateProcess() returns as soon as the process is created. CreateProcess() fills up the struct PROCESS_INFORMATION with the handles of the process it creates. it contains the handle of the main thread of the process. If you want to wait for the process to finish you can WaitForSingleEvent() on that thread handle which gets signaled when the thread terminates. Don't forget to CloseHandle() those handles when you're done with them.