CodeGuru Forums -
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic Newsletters VB Forums Developer.com


Newest CodeGuru.com Articles:

  • Installing SQL Server 2008
  • Writing UDFs for Firebird Embedded SQL Server
  • [Updated] Shutdown Manager
  • Building Windows Azure Cloud Service Applications with Azure Storage and the Azure SDK

  • Search CodeGuru:
     



    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > C++ (Non Visual C++ Issues)
    FAQ Members List Calendar Search Today's Posts Mark Forums Read

    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++.

    Reply
     
    Thread Tools Search this Thread Rate Thread Display Modes
      #1    
    Old December 1st, 2008, 05:44 PM
    ToddAtWSU ToddAtWSU is offline
    Junior Member
     
    Join Date: Dec 2008
    Posts: 2
    ToddAtWSU is an unknown quantity at this point (<10)
    Question Call Secondary Executable

    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.
    Reply With Quote
      #2    
    Old December 1st, 2008, 06:00 PM
    treuss's Avatar
    treuss treuss is offline
    Elite Member
     
    Join Date: Jan 2004
    Location: Düsseldorf, Germany
    Posts: 2,191
    treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)
    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.
    Reply With Quote
      #3    
    Old December 1st, 2008, 06:20 PM
    ToddAtWSU ToddAtWSU is offline
    Junior Member
     
    Join Date: Dec 2008
    Posts: 2
    ToddAtWSU is an unknown quantity at this point (<10)
    Re: Call Secondary Executable

    Solaris 10.
    Reply With Quote
      #4    
    Old December 2nd, 2008, 04:32 PM
    treuss's Avatar
    treuss treuss is offline
    Elite Member
     
    Join Date: Jan 2004
    Location: Düsseldorf, Germany
    Posts: 2,191
    treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)treuss is a splendid one to behold (750+)
    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;
    }
    A quick try under Linux and it seems to do exactly as promised:
    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.
    Reply With Quote
    Reply

    Bookmarks
    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > C++ (Non Visual C++ Issues)


    Thread Tools Search this Thread
    Search this Thread:

    Advanced Search
    Display Modes Rate This Thread
    Rate This Thread:

    Posting Rules
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is On
    Smilies are On
    [IMG] code is On
    HTML code is Off
    Forum Jump


    All times are GMT -5. The time now is 04:59 AM.



    Acceptable Use Policy

    internet.comMediabistrojusttechjobs.comGraphics.com

    WebMediaBrands Corporate Info


    Advertise | Newsletters | Feedback | Submit News

    Legal Notices | Licensing | Permissions | Privacy Policy


    Powered by vBulletin® Version 3.7.3
    Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
    Copyright WebMediaBrands Inc. 2002-2009