Thread: Calling external program

  1. #1
    Registered User gandalf_bar's Avatar
    Join Date
    Oct 2003
    Posts
    92

    Talking Calling external program

    I try to make a simple program using gtkmm library that if you push the button, it will play file in spesific directory. I use external program. It is mplayer. But if I use system function like this:

    Code:
       Glib::ustring file_p;
        file_p = entry1->get_text();    
        Glib::ustring System = "mplayer " + file_p;
        system(System.c_str());
    when I push the button, it will play the file just I hope but then I can not do anything with my application's window anymore. I have to kill or wait the child process so that I can manipulate my application's window.

    I have read the faq. OS: Linux Slackware 9.1. Compiler: GNU C++ compiler v 3.2. There is no process.h and windows.h in my Linux box. So is there anyway I could call external program beside system function in my Linux box?
    A man asked, "Who are you?"
    Buddha answered, "I am awaked."

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    I suppose the easiest thing to do is append a "&" to the end of the string, so that the shell creates a background process

    Glib::ustring System = "mplayer " + file_p + " &";

    If that doesn't work, you have to get messy with fork() and execl()
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User gandalf_bar's Avatar
    Join Date
    Oct 2003
    Posts
    92
    That's work!!! I bow to you, Guru!!!! Thank.

    By the way, I have read about fork() and execl() stuff in FAQ. Because the example in FAQ has been poluted with process.h library, I can not test it in Linux box. I plan to google them.

    I hope someday, FAQ will be updated so there will be example with fork() and execl() stuff but not poluted with windows spesific library.
    A man asked, "Who are you?"
    Buddha answered, "I am awaked."

  4. #4
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Originally posted by gandalf_bar
    I hope someday, FAQ will be updated so there will be example with fork() and execl() stuff but not poluted with windows spesific library.
    Look again.
    http://faq.cprogramming.com/cgi-bin/...&id=1043284392
    The section headed "OPTION 3 - fork/exec"
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  5. #5
    Registered User gandalf_bar's Avatar
    Join Date
    Oct 2003
    Posts
    92
    Code:
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <sys/types.h>
    #include <unistd.h> 
    #include <process.h> 
    
    
    int main(void)
    {
      char *my_args[5];
      pid_t pid;
      
      my_args[0] = "child.exe";
      my_args[1] = "arg1";
      my_args[2] = "arg2";
      my_args[3] = NULL;
      
      puts ("fork()ing");
      
      switch ((pid = fork()))
      {
        case -1:
          /* Fork() has failed */
          perror ("fork");
          break;
        case 0:
          /* This is processed by the child */
          execv ("child.exe", my_args);
          puts("Uh oh! If this prints, execv() must have failed");
          exit(EXIT_FAILURE);
          break;
        default:
          /* This is processed by the parent */
          puts ("This is a message from the parent");
          break;
      }
      
      puts ("End of parent program");
      return 0;
    }
    
    /*
     * Program output:
     fork()ing
     This is a message from the parent
     End of parent program
     I am the child
     Arg 1 arg1
     Arg 2 arg2
     *
     */
    Is that what you mean? There is still process.h file that my Linux box doesn't support. When I said the example in FAQ is poluted by windows spesific library, I mean the process.h file.

    ----------------------------------

    Ok, I try this program. It works fine. I am sorry. It works after I remove process.h. So after all this, what do you think?
    1. I am so dumb
    2. The FAQ should be updated. At least, tell it to people that if you want to compile it in Linux box, you should remove the process.h library.

    Thank you.

    ----------------------------------

    Edited again by me. Ok, Maybe FAQ is not need to be updated because I found the answer in *nix section about fork stuff. By the way I think it would really be good if the administrator mark the code above in FAQ section How do I.... (level 2) as "windows only". I thought all the code in FAQ are os independent if there is no windows.h and conio.h.

    Thank you.
    Last edited by gandalf_bar; 03-26-2004 at 05:37 AM.
    A man asked, "Who are you?"
    Buddha answered, "I am awaked."

  6. #6
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    I've removed the reference to process.h in that FAQ part.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  7. #7
    Registered User gandalf_bar's Avatar
    Join Date
    Oct 2003
    Posts
    92
    Originally posted by Hammer
    I've removed the reference to process.h in that FAQ part.
    Wow, that's great. Thanx a lot. Now I have a problem. Consider this code:

    Code:
    void on_button1_clicked() {
       Glib::ustring file_p;
        file_p = entry1->get_text();    
        Glib::ustring System = "mplayer " + file_p;
        system(System.c_str());
    }
    The problem with this code is after I push the button, I can not do anything with my application's window because my program is hang up in system(System.c_str()) statement. Salem gave me solution. So my code will be like this:

    Code:
    void on_button1_clicked() {
       Glib::ustring file_p;
        file_p = entry1->get_text();    
        Glib::ustring System = "mplayer " + file_p + " & ";
        system(System.c_str());
    }
    Ok, the code above is great. After I push the button, I can manipulate my application's window but if I exit from the application before "mplayer" finish its jobs, the process is still there. It means after I quit from the application, I can still hear "mplayer" playing file. Is there anyway I can kill this child process automatically after I quit from the application? Or is system() could not fulfill my need anymore and I have to get messy with fork() stuff?

    Thanx.
    A man asked, "Who are you?"
    Buddha answered, "I am awaked."

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Yeah, if you want more detailed control then you're going to have to use fork() etc

    Code:
    pid_t play_pid = fork();
    if ( play_pid == 0 ) {
        char *argv[3] = { 0 };
        argv[0] = "mplayer";
        argv[1] = file_p;
        execv( argv[0], argv );
    } else
    if ( play_pid == -1 ) {
        // something wrong, there is no player
    }
    // carry on doing what you were doing when using system()
    Sometime later, when your application quits, you also do this
    Code:
    kill ( play_pid, SIGTERM );
    man 7 signal
    for a list of signal names

    If its a well behaved application, then SIGTERM should be enough to cause it to stop cleanly. If that doesn't work, then SIGINT, and certainly SIGKILL will get rid of it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User gandalf_bar's Avatar
    Join Date
    Oct 2003
    Posts
    92
    Ok, I got it works. My code like this:
    Code:
    pid_t play_pid;
    
    void window1::on_quit1_activate()
    {  
        hide();
        kill(play_pid, SIGTERM);
    }
    
    void window1::on_button1_clicked()
    {  
        Glib::ustring file_p;
        file_p = entry1->get_text();    
        play_pid = fork();
        if(play_pid==0) {
    	char *argv[3] = { 0 };
    	argv[0] = "/usr/bin/mplayer";
    	int length = file_p.length();
    	argv[1] = new char[length+1];
    	file_p.copy(argv[1],length,0);
    	argv[1][length] = '\0';
    	execl( argv[0], "mplayer", argv[1], NULL );
        }
        else if(play_pid==1) {
        }
    }
    Feel free to comment my code. So, I got one question. Not technical one. But this important ( for me, of course ). In opensource community, I found a lot of front end applications. Something like qtparted, synaptic, GPA ( gnupg frontends ), xcdroast. I just want to make one. Is this the way ( I mean the code ) how people make the front ends applications? Calling back ends applications by using fork(), execl(), execl(), execv() statements. Today, I googled about this ( signal stuff, fork() stuff, zombie process ) for hours. Looks these statement are not portable. Because almost in every tutorial I read, the authors mentioned about Unix. So I assumed I can not use this code under Windoze plafform. I mean maybe I can use fork() statement but I can not use signal stuff related code. Am I right? I hope I could make multi-platform front end applications. Thx.
    A man asked, "Who are you?"
    Buddha answered, "I am awaked."

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Easiest thing would be to goto say sourceforge and download the source for one of those programs you mentioned.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    No, fork() is not directly portable to Windows (compiler dependant anyway). If you're really after doing such a thing, maybe you'd just split the Windows and *nix functions to separate libraries, and then compile with the relevant one for the system you're on.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. having some trouble calling a function in the main program
    By CMakesMeSad :( in forum C Programming
    Replies: 19
    Last Post: 06-26-2009, 09:33 PM
  2. Program Plan
    By Programmer_P in forum C++ Programming
    Replies: 0
    Last Post: 05-11-2009, 01:42 AM
  3. Simple Timer, Call external program,
    By bliss in forum C++ Programming
    Replies: 2
    Last Post: 06-02-2005, 11:21 PM
  4. calling programs from a c++ program
    By md4u in forum C++ Programming
    Replies: 0
    Last Post: 05-04-2003, 07:39 AM
  5. calling c++ program from a webpage
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 10-04-2001, 09:41 AM