2

I want to run something like

cat file.tar | base64 | myprogram -c "| base64 -d | tar -zvt "

I use execlp to run the process.

When i try to run something like cat it works, but if i try to run base64 -d | tar -zvt it doesn't work.

I looked at the bash commands and I found out that I can run bash and tell him to run other programs. So it's something like:

execlp ("bash", "-c", "base64 -d | tar -zvt", NULL);

If I run it on the terminal, it works well, but using the execlp it dont work. If I use execlp("cat", "cat", NULL) it works.

Someone knows how to use the -c param on execlp to execute multiple "programs"? I cant use system because i use pipe and fork.

Now i noticed, if i try to use execlp("bash", "bash", "-c", "base64", NULL)... nothing happens. If i use execlp("cat", NULL) it's ok.. I'm writing to the stdin... i don't know if its the problem with the bash -c base64.. because if i run on the terminal echo "asd" | bash -c "cat" it goes well

Lefsler
  • 1,738
  • 6
  • 26
  • 46
  • 1
    I have shown [in a previous answer](http://stackoverflow.com/questions/7281894/how-do-i-chain-stdout-in-one-child-process-to-stdin-in-another-child-in-c/7282296#7282296) how you can chain an arbitrary number of processes with pipes. Hope that helps. – R. Martinho Fernandes Jan 11 '12 at 12:28
  • i thought about that, bit i'm trying to solve it with the bash, if i cant do that i will try the multiple pipe way :(... thanks. – Lefsler Jan 11 '12 at 12:30

1 Answers1

4

The first "argument" is what becomes argv[0], so you should call with something like:

execlp("bash", "bash", "-c", "base64 -d | tar -zvt", NULL);

Edit A small explanation what the above function does: The exec family of functions executes a program. In the above call the program in question is "bash" (first argument). Bash, like all other programs, have a main function that is the starting point of the program. And like all other main functions, the one in Bash receives two arguments, commonly called argc and argv. argv is an array of zero-terminated strings, and argc is the number of entries in the argv array. argc will always be at least 1, meaning that there is always one entry at argv[0]. This first entry is the "name" of the program, most often the path of the program file. All other program arguments on the command line is put into argv[1] to argv[argc - 1].

What execlp does is use the first argument to find the program to be executed, and all the other arguments will be put into the programs argv array in the order they are given. This means that the above call to execlp will call the program "bash" and set the argv array of Bash to this:

argv[0] = "bash"
argv[1] = "-c"
argv[2] = "base64 -d | tar -zvt"

Also, argc of Bash will be set to 3.

If the second "bash" is changed to "foo", then argv[0] of Bash will be set to "foo" as well.

I hope this clears it up a little bit.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • why i need to call the bash 2 times? – Lefsler Jan 11 '12 at 13:29
  • 1
    @user1109847 You only call bash once, but you must include the zero argument to the `main()` function of bash. – Some programmer dude Jan 11 '12 at 13:33
  • i use the bash to call the bash again? – Lefsler Jan 11 '12 at 13:37
  • @user1109847 In your own program, the `main` function has two arguments: `argc` and `argv`. `argv` is an array on `char *`, where `argv[0]` is the name of your program. The first argument of `execlp` is the actual program, and the rest is the values that are put into the `argv` array of the executed program. Read the [manual page](http://linux.die.net/man/3/execlp) a couple of times, and also experiment a little with the `argc` and `argv` arguments to `main`. – Some programmer dude Jan 11 '12 at 13:42
  • @user1109847 Extended my answer. – Some programmer dude Jan 11 '12 at 13:54
  • If i use execlp("cat", NULL) it works.. "i'm writing to the stdin and getting back the stdout" – Lefsler Jan 11 '12 at 17:22
  • Sorry, i tested it in another clean program, and it seems to work. – Lefsler Jan 11 '12 at 18:04