Thread: Executing a Program With Arguments

  1. #1
    Registered User HalNineThousand's Avatar
    Join Date
    Mar 2008
    Posts
    43

    Executing a Program With Arguments

    I don't know how platform specific exec() and its relatives are, but my guess is it'd have to be.

    I'm running an executable from a C++ program this way:
    Code:
    	string cmd = "testprog", arg = "samp1", marg = "one two three";
    	execlp(cmd.c_str(), arg.c_str(), marg.c_str(), (char *) 0);
    When I use this to call a test program I've written in C++, it works and each string is taken as a separate argument. Then when I change from my test program to using Xine, I change the first argument to a music file that's in the same directory and remove the 2nd argument. If I run Xine from the command like this:

    xine music.flac

    it works just fine, but when I try to run it from my program, with xine as the first argument to execlp() and the file name as the 2nd, it doesn't play or do anything.

    To me, this isn't just a Xine issue. Whatever is making it not work with Xine could have the same effect with other programs.

    Why is it that Xine won't read in the argument and play it? Could the program specifically be checking to see how it is run and acting differently? Is this a problem I'll be running into with a lot of programs?

    Any help appreciated!

    Thanks!

  2. #2
    Registered User
    Join Date
    Oct 2007
    Posts
    32
    Quote Originally Posted by HalNineThousand View Post
    I don't know how platform specific exec() and its relatives are, but my guess is it'd have to be.

    I'm running an executable from a C++ program this way:
    Code:
    	string cmd = "testprog", arg = "samp1", marg = "one two three";
    	execlp(cmd.c_str(), arg.c_str(), marg.c_str(), (char *) 0);
    When I use this to call a test program I've written in C++, it works and each string is taken as a separate argument. Then when I change from my test program to using Xine, I change the first argument to a music file that's in the same directory and remove the 2nd argument. If I run Xine from the command like this:

    xine music.flac

    it works just fine, but when I try to run it from my program, with xine as the first argument to execlp() and the file name as the 2nd, it doesn't play or do anything.

    To me, this isn't just a Xine issue. Whatever is making it not work with Xine could have the same effect with other programs.

    Why is it that Xine won't read in the argument and play it? Could the program specifically be checking to see how it is run and acting differently? Is this a problem I'll be running into with a lot of programs?

    Any help appreciated!

    Thanks!
    Change your code too
    Code:
    	string cmd = "testprog", arg = "samp1", marg = "one two three";
    	err = execlp(cmd.c_str(), arg.c_str(), marg.c_str(), (char *) 0);
            if (err) {
                perror("EXECVP")
            }
    And look what errno says you.

    Alternative approach is run your program under strace as
    strace -f <your_program> [arguments]

    and you'll see what actual arguments execve receive.

    Valery.

  3. #3
    Registered User HalNineThousand's Avatar
    Join Date
    Mar 2008
    Posts
    43
    I get absolutely nothing from the error by changing the code. I did it slightly differently:
    Code:
            ecode = execlp(cmd.c_str(), arg.c_str(), marg.c_str(), (char *) 0);
            cout << "Error return code: " << ecode << endl;
            if (ecode) {
                perror("EXECVP")
            }
    (I already had ecode as an int so I used that.)

    It doesn't even print the first line after the execlp() function! I do get two lines of output from Xine, but it's the copyright notice and nothing useful. Even after I kill Xine (closing the window), my program exits and there's still no output from my program.

    I tried with strace, but I've never even heard of that before and there are thousands of lines of output so I'm still working on that. I didn't see any error codes where xine was mentioned in the output, but I'm still looking.

    After re-reading the exec() man page several times, it finally hit me what it means by "The exec family of functions shall replace the current process image with a new process image. The new image shall be constructed from a regular, executable file called the new process image file. There shall be no return from a successful exec, because the calling process image is overlaid by the new process image." In other words, I should not expect a call to exec() to ever return.

    So when calling exec(), is it essentially forking or starting an independent thread?

    This is the first step in what I am doing. I wanted to start a program and to be able to kill it after a length of time. This will be used to start a program to capture audio data and save it to a file for a set length of time. One thing I liked about exec() or, rather, execlp() was that I could have a config file that specified the program to run without needing the path and that I could pass a file name with the path to the program as an argument without having to scan it and add escape characters if it contains spaces or other troublesome characters.

    My original idea was to use pthreads to create a thread that would launch a program, wait the length of time it would record the incoming audio, then kill that thread. My experimenting with threads shows this doesn't work, and I would think that's due to exec() not actually returning.

    Is there something better for me to use or are there more ways to work with exec() so I can kill a program after I've started it? I've gotten a lot of noise when Googling on launching programs from within a C++ program. If I had to include the full path to the program I'm launching, I can deal with that, but I'd rather not have to scan a filename and escape the characters like spaces or quotation marks.
    Last edited by HalNineThousand; 04-14-2008 at 01:04 AM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Code:
            ecode = execlp(cmd.c_str(), arg.c_str(), marg.c_str(), (char *) 0);
            cout << "Error return code: " << ecode << endl;
            if (ecode) {
                perror("EXECVP")
            }
    If execlp() succeeds, then none of the commands which follow it will be executed.

    Also, its cmd, argv0, argv1 etc, so perhaps
    ecode = execlp(cmd.c_str(), cmd.c_str(), arg.c_str(), marg.c_str(), (char *) 0);
    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.

  5. #5
    Registered User HalNineThousand's Avatar
    Join Date
    Mar 2008
    Posts
    43
    Using the command as the 1st and 2nd argument does the trick. Thanks!

    Now is there any way to kill the process after it's been launched?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  2. executing another program
    By Jamsan in forum C++ Programming
    Replies: 2
    Last Post: 04-26-2003, 08:22 PM
  3. executing an other program (newbie)
    By martijn1967 in forum C++ Programming
    Replies: 1
    Last Post: 06-01-2002, 05:16 AM
  4. running program with arguments (linux)
    By N8760 in forum C++ Programming
    Replies: 2
    Last Post: 01-28-2002, 02:08 PM
  5. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM