PDA

View Full Version : function similar to execvp()



Elkvis
09-21-2011, 12:05 PM
execvp() takes a path, and an array of parameters to spawn an external program, but I'm interested in a standard function that is equivalent, but instead of the path and parameters, I would like to send it a raw command string. does such a function exist? exec doesn't allow input redirection with the "|" character, to my knowledge, and I need that capability.

anduril462
09-21-2011, 12:10 PM
Are you looking for something like the system() function? I'm not sure that will support pipe redirection, but I think it's more what you're after. You can also look at the popen/pclose functions.

Elkvis
09-21-2011, 01:58 PM
Are you looking for something like the system() function? I'm not sure that will support pipe redirection, but I think it's more what you're after. You can also look at the popen/pclose functions.

system is close, but my attempts to use it failed (I'm trying to modify existing code that I didn't write).

what I'm trying to do is filter the output of "svn --xml -q status" through another program to sort the list by file path. my filter program works great, and running "svn --xml -q status | my_filter_program" gives the expected output, but the trouble is that the ide I'm using (codelite (http://www.codelite.org/)) uses execvp() to spawn svn with those options, and when I changed the source to use system() instead, it didn't show any changes in the svn tab, meaning that it didn't work as expected.

anduril462
09-21-2011, 02:52 PM
Okay, your issue just got less clear to me. Are you writing a plug-in for codelite? Does codelite have a built-in SVN integration you're trying to modify? What exactly do you want to do? Did you look into popen/pclose? They run a process and allow you to write to that process' stdin and read from it's stdout as though they're normal files. Is that what you want?

Also note, I'm not sure that system will be launched with the same PATH environment variable that you have, so you may need to specify a full path to my_filter_program.

Salem
09-21-2011, 11:02 PM
Well if you want a pipe, then you need to make use of the pipe() system call, mess about with the descriptors using close() and dup(), call fork() twice to create two more processes, and from each child, call exec() to run "svn --xml -q status" and "my_filter_program" respectively.

Elkvis
09-22-2011, 06:14 AM
codelite has a svn plugin already, that I'm trying to hack, so that the svn tab shows the changed files in alphabetical order, instead of the random order in which svn returns them.

all the virtual terminal and pipes are already set up. I suppose I could modify the code that parses the xml after it has it, and sort it at that point, but I was really hoping I wouldn't have to dive that deep into the code. It was pretty easy and straightforward to write a command line filter program, but maybe I'll just have to bite the bullet and put the sorting directly in codelite.

MK27
09-22-2011, 08:11 AM
Well if you want a pipe, then you need to make use of the pipe() system call, mess about with the descriptors using close() and dup(), call fork() twice to create two more processes, and from each child, call exec() to run "svn --xml -q status" and "my_filter_program" respectively.

Easier to use two popen()s.

Pipe to a Subprocess - The GNU C Library (http://www.gnu.org/s/hello/manual/libc/Pipe-to-a-Subprocess.html)

As it says, popen() is like system() but returns a read or write FILE* stream into the process (ala pipe+fork+dup), so you could read from the svn command and write that into the filter command. That would mean your end product is still on stdout.

If you need to read the final output back in you would have to use dup() as well.

IMO trying to hack around IDE issues at runtime is silly, if the IDE is a problem just execute normally.

MK27
09-22-2011, 08:32 AM
Eg:



#include <stdio.h>

int main(int argc, const char *argv[]) {
FILE *in = popen("ls --color=never -1", "r"),
*out = popen("grep test", "w");
char buffer[1024];
int bytes;

while ((bytes = fread(buffer, 1, 1024, in)) > 0)
fwrite(buffer, bytes, 1, out);

pclose(in);
pclose(out);

return 0;
}

Elkvis
09-22-2011, 09:58 AM
popen won't work in my situation, because the program sets up the execution environment with stdin and stdout file descriptors already created. I think my solution will be to sort the output of svn after the ide reads it from the process and parses the xml. that's probably going to be a lot less work than hacking the process spawning code.

anduril462
09-22-2011, 10:10 AM
popen won't work in my situation, because the program sets up the execution environment with stdin and stdout file descriptors already created. I think my solution will be to sort the output of svn after the ide reads it from the process and parses the xml. that's probably going to be a lot less work than hacking the process spawning code.
I would be surprised if an open source IDE like codelite doesn't have a plugin interface you you leverage to that effect, or at least a well-defined API.

As an alternative, why not kinda reverse the order of the two. Make your my_filter_program call svn (via system/popen) and sort that output, so you only hack the IDE to call my_filter_program instead of all this pipe/fork/exec/dup/popen business?

Elkvis
09-22-2011, 11:25 AM
I would be surprised if an open source IDE like codelite doesn't have a plugin interface you you leverage to that effect, or at least a well-defined API.

As an alternative, why not kinda reverse the order of the two. Make your my_filter_program call svn (via system/popen) and sort that output, so you only hack the IDE to call my_filter_program instead of all this pipe/fork/exec/dup/popen business?

that's actually not a bad idea, but as it turns out, sorting the results after codelite parses the xml was incredibly easy, requiring only about 6 lines of code to be added.