Thread: Redirecting I/O

  1. #1
    suwie
    Join Date
    Aug 2004
    Posts
    6

    Redirecting I/O

    Hi everyone,

    Did anyone know how to communicate between C program and a GUI program?

    example :

    If i have a C program which does all the operation. And a GUI program written in GTK which provides all the nice interface for the C program.

    The C program and GTK program are two separate program.....
    which means that C program is runnable through command line without the need of the GUI.

    However if i want to make both of them communicate in term of messages. For example, usually the error messages is displayed in the terminal / console..but when i am using a GUI as a front end to run the C program, the error message will be display in the window in the GUI program instead of in the console....

    Is there a way to send over the message from C program to GUI?

    Anyone got example or sample code?

    Thank you.

    Happy coding.....

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    man popen
    If you understand what you're doing, you're not learning anything.

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    Yes it very possible.
    In Linux, I think you shoudl use the dup() functions... I don't know that APi very well.
    In windows:
    Call VOID GetStartupInfo(); to get your default startup information. Then start your console app with CreateProcess function, and send you GUI input/output handles to the console app.
    Code:
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    GetStartupInfo(&si);
    //one's output is another's input
    HANDLE temp = si.hStdInput;
    si.hStdInput = si.hStdOutput;
    si.hStdOutput = temp;
    CreateProcess("consoleapp.exe","command lines",0,0,TRUE,0,0,0,&si,&pi);
    I think this would work, although I don't know if the handles can be inherited, nor I know if that HANDLE switching is safe.
    Last edited by xErath; 09-30-2004 at 09:22 PM.

  4. #4
    Registered User
    Join Date
    Jun 2004
    Posts
    84
    xEarth, man! What a hell are you talking about? You can retrieve standard handles from STARTUPINFO if and only if dwFlags is set to STARTF_USESTDHANDLES. So to retrieve them you must allways use GetStdHandle(); And you haven't set fields cb, dwFlags and hStdError. Not to mention you are using C++ compiler again...
    This _corrected_ program will redirect all streams of "program.exe" to itself:
    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
    
        ZeroMemory(&si, sizeof(si));
        ZeroMemory(&pi, sizeof(pi));
    
        si.cb         = sizeof(si);
        si.dwFlags    = STARTF_USESTDHANDLES;
        si.hStdInput  = GetStdHandle(STD_INPUT_HANDLE);
        si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
        si.hStdError  = GetStdHandle(STD_ERROR_HANDLE);
    
        if (!CreateProcess("program.exe", NULL, NULL, NULL,
                           TRUE, 0, NULL, NULL, &si, &pi))
        {
            printf("CreateProcess() failed!\n");
            exit(EXIT_FAILURE);
        }
    
        WaitForSingleObject(pi.hProcess, INFINITE);
    
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    
        return 0;
    }
    BTW. sorry suwie, I know it have nothing to do with what you wanted to know.

  5. #5
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    I wrote that in the reply text box.. I've not compiled nor tested... And I know for sure that my code isn't reliable.. I only intended with that to show a little example. And If a non-console process is started, yes, one must get the standard handles to the console, because none was instantiated.
    About field cb, it's set...
    Code:
    GetStartupInfo(&si);
    Plus... C++ where???

  6. #6
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Quote Originally Posted by xErath
    I wrote that in the reply text box.. I've not compiled nor tested... And I know for sure that my code isn't reliable.. I only intended with that to show a little example. And If a non-console process is started, yes, one must get the standard handles to the console, because none was instantiated.
    About field cb, it's set...
    Code:
    GetStartupInfo(&si);
    Plus... C++ where???
    You have declarations of more variables after statements start. The list of windows compilers that support C99 to any extent is rather short...
    hello, internet!

  7. #7
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    I apologize in advance as I have never actually programmed on a Unix box... but I am pretty sure this does the trick. I'd compile and test if I had a Unix box =/

    Code:
    // remember to #include headers, i haven't done that
    
    int main (int argc, char **argv)
    {
      int tnout[2]; // write pipe to the child
      int tnin[2];  // read pipe from the child
    
      pid_t childp;
    
    
      if (pipe (tnout) || pipe (tnin))
      {
        fprintf (stderr, "Not enough file handles!\n");
        exit (EXIT_FAILURE);
      }
    
      childp = fork ();
    
      if (childp == -1)
      {
        fprintf (stderr, "Out of memory!\n");
        exit (EXIT_FAILURE);
      }
    
      else if (childp == 0)
      { // child process
        // close the unused pipe-ends
        close (tnout[1]);
        close (tnin[0]);
    
        // set stdin, stdout, to the open pipe ends
        dup2 (tnout[0], 0);
        dup2 (tnin[1], 1);
    
        // start child program
        // replace "telnet localhost 23" with whatever program
        // you wish to call and whichever exec* is convienent
        execl ("telnet", "telnet", "localhost", "23", (char *) 0);
        // shouldn't return
        fprintf (stderr, "Couldn't start telnet!\n");
        exit (EXIT_FAILURE);
      }
    
      // parent process
      
      // tnout[1] can be used to write to the child's stdin
      close (tnout[0]);
      // tnin[0] can be used to read from the child's stdout
      close (tnin[1]);
    
      return 0;
    }
    Last edited by moi; 09-30-2004 at 09:56 PM.
    hello, internet!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. asynchronized I/O == multiplexing I/O?
    By George2 in forum C Programming
    Replies: 1
    Last Post: 07-24-2006, 10:06 AM
  2. why page based I/O can improve performance?
    By George2 in forum C Programming
    Replies: 1
    Last Post: 06-12-2006, 07:42 AM
  3. Nonblocking I/O
    By fnoyan in forum Linux Programming
    Replies: 4
    Last Post: 11-29-2005, 04:37 PM
  4. redirecting console I/O
    By Slavisa in forum Windows Programming
    Replies: 0
    Last Post: 06-25-2003, 07:40 AM
  5. Overlapped I/O and Completion Port :: Winsock
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 10-30-2002, 05:14 PM