| CodeGuru Home | VC++ / MFC / C++ | .NET / C# | Visual Basic | Newsletters | VB Forums | Developer.com |
|
|||||||
| C++ (Non Visual C++ Issues) Ask or answer C and C++ questions not related to Visual C++. This includes Console programming, Linux programming, or general ANSI C++. |
![]() |
|
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
I have a C++ program that I need to call a secondary program. I know I can make a system call to call the program, but this program I want to call normally takes input from the user in a prompt atmosphere. Unfortunately, the program is an old Fortran program with which I no longer have the code for, therefore I cannot just rewrite the code into C++ and add it to my program. How can I call this executable and then provide it automated answers, all of which I will be able to calculate? Thanks for your help and please let me know if you need any more information.
|
|
#2
|
||||
|
||||
|
Re: Call Secondary Executable
What platform ?
__________________
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf Premature optimization is the root of all evil --Donald E. Knuth Computer programming requires a great deal of attention to detail and an ability to read and understand abstract instructions. Posting a question to this forum in a way that it will get answered, requires the same, though too far smaller degree. Thus, if you don't get your question answered here, maybe it's time to accept that programming is not your thing. --Yours truly Please read Information on posting before posting, especially the info on using [code] tags. |
|
#3
|
|||
|
|||
|
Re: Call Secondary Executable
Solaris 10.
|
|
#4
|
||||
|
||||
|
Re: Call Secondary Executable
The system calls you should be looking at, are fork, pipe, and execv (et al). I would recommend you to get a book about UNIX IPC as the topic is quite complex.
Anyways, below is some test program I wrote many years ago (some of it might be taken from the net). It shows you the principles. Code:
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
pid_t exec_redirect(char * prog, char * args[], int* infd, int* outfd, int* errfd)
{
// Fork new process
pid_t pchild = fork();
if (pchild == 0) {
// Child process
// Redirect standard input
if (infd[0] >= 0) {
close(STDIN_FILENO);
dup2(infd[0], STDIN_FILENO);
}
// Redirect standard output
if (outfd[1] >= 0) {
close(STDOUT_FILENO);
dup2(outfd[1], STDOUT_FILENO);
}
// Redirect standard error
if (errfd[1] >= 0) {
close(STDERR_FILENO);
dup2(errfd[1], STDERR_FILENO);
}
// Close unneeded ends of pipes
if (infd[1] >= 0) close(infd[1]);
if (outfd[0] >= 0) close (outfd[0]);
if (errfd[0] >= 0) close (outfd[0]);
// Execute the command
execv(prog, args);
return 0;
} else {
// Parent process
// Close unneeded ends of pipes
if (infd[0] >= 0) close(infd[0]);
if (outfd[1] >= 0) close (outfd[1]);
if (errfd[1] >= 0) close (errfd[1]);
return pchild;
}
}
void readFromPipe(int pfd) {
char buf;
bool newline = true;
while (read(pfd, &buf, 1) > 0) {
if (newline) {
std::cout << "[Child] ";
newline = false;
}
std::cout << buf;
if (buf == '\n') {
newline = true;
}
}
}
int main(int argc, char* argv[]) {
if (argc < 1) {
std::cerr << "Please supply an argument\n";
exit(1);
}
char * childproc = argv[1];
char ** childprocargs = new char*[argc];
std::cout << "Executing ";
for (int i = 1; i < argc; ++i) {
std::cout << argv[i] << " ";
childprocargs[i-1] = strdup(argv[i]);
}
childprocargs[argc-1] = 0;
std::cout << "\n";
// Creating pipes for communication
int pfddown[2]; // down: Parent writes, child reads
int pfdup[2]; // up: Child writes, parent reads
int pfderr[2]; // err: Child writes, parent reads
if (pipe(pfdup) != 0 || pipe(pfddown) != 0 || pipe(pfderr) != 0) {
std::cerr << "Unable to create pipes. Aborting\n";
exit(1);
}
pid_t child = exec_redirect(childproc, childprocargs, pfddown, pfdup, pfderr);
std::cout << "Forked child, pid is " << child << "\n";
std::cout << "Sending Hello\\n\n";
write(pfddown[1],"Hello\n",6);
std::cout << "Sending World!\\n\n";
write(pfddown[1],"World!\n",7);
close(pfddown[1]);
readFromPipe(pfdup[0]);
close(pfdup[0]);
wait(0);
// cleaning the nasty arg array
for (int i = 0; i < argc-1; ++i) {
free(childprocargs[i]);
}
delete [] childprocargs;
}
Code:
treuss@foo:~/src$ ./test /bin/cat Executing /bin/cat Forked child, pid is 9514 Sending Hello\n Sending World!\n [Child] Hello [Child] World! treuss@foo:~/src$ ./test /usr/bin/tac Executing /usr/bin/tac Forked child, pid is 9526 Sending Hello\n Sending World!\n [Child] World! [Child] Hello treuss@foo:~/src$ ./test /bin/sed -e's/o/x/g' Executing /bin/sed -es/o/x/g Forked child, pid is 9532 Sending Hello\n Sending World!\n [Child] Hellx [Child] Wxrld!
__________________
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf Premature optimization is the root of all evil --Donald E. Knuth Computer programming requires a great deal of attention to detail and an ability to read and understand abstract instructions. Posting a question to this forum in a way that it will get answered, requires the same, though too far smaller degree. Thus, if you don't get your question answered here, maybe it's time to accept that programming is not your thing. --Yours truly Please read Information on posting before posting, especially the info on using [code] tags. |
![]() |
| Bookmarks |
|
||||||
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|