C Board  

Go Back   C Board > Platform Specific Boards > Linux Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 04-13-2008, 10:10 PM   #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!
HalNineThousand is offline   Reply With Quote
Old 04-13-2008, 11:23 PM   #2
Registered User
 
Join Date: Oct 2007
Posts: 22
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.
Valery Reznic is offline   Reply With Quote
Old 04-14-2008, 12:11 AM   #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.
HalNineThousand is offline   Reply With Quote
Old 04-14-2008, 09:56 AM   #4
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,683
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.

Salem is offline   Reply With Quote
Old 04-14-2008, 10:09 AM   #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?
HalNineThousand is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

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


All times are GMT -6. The time now is 05:33 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22