-2

I need to create a program that takes input from the user and executes it just like it does in the terminal. I am using the execvp() function for this purpose. The requirement of the program is to keep taking input from the user unless the quit call is encountered. The problem here is that the current program is replaced after the execvp() call. So, using a goto is not an option either. I found this Fork–exec article but it doesn't tell how to create an indefinite number of processes. Here is my code:

#include <unistd.h>
#include <stdio.h>
#include <string.h>

void main() {

char *args[4];
char inputCommand[100];
fgets (inputCommand, 100, stdin);
printf ("Splitting string \"%s\" into tokens:\n",inputCommand);

/* Perfrom string tokenization here */

execvp(args[0], args);
}
Adeel Ahmad
  • 1,033
  • 1
  • 11
  • 24
  • 1
    What's bash-specific about this question at all? (If the answer is "nothing", why does it have the tag?) – Charles Duffy Mar 08 '16 at 16:23
  • ...using `execvp` doesn't go through a shell, so you're avoiding the overhead and risk of same. – Charles Duffy Mar 08 '16 at 16:23
  • 2
    Are you familiar with while-loops? That's how you repeat *any* task indefinitely. Fork-exec is no exception. – ruakh Mar 08 '16 at 16:24
  • Why can't you use `system(your_command)`? – ForceBru Mar 08 '16 at 16:24
  • @ForceBru, `system()` has both performance cost and room for security vulnerabilities such as shell injection -- using it without a specific reason to do so is not at all good practice. Look at all the folks who got unnecessarily bitten by ShellShock because they were using `system()` and had extra shell invocations when they could have just directly invoked external tools with no shell involved. And then there are all the folks doing unsafe string concatenation to generate shell commands to pass to `system()` in their programs, and thus vulnerable to malicious filenames. – Charles Duffy Mar 08 '16 at 16:25
  • 1
    ...though I'll concede that "just like it does in the terminal", if taken literally, *does* mean shell processing of redirections &c., so might make `system()` an appropriate tool. – Charles Duffy Mar 08 '16 at 16:28
  • 2
    Possible duplicate of [how to correctly use fork, exec, wait](http://stackoverflow.com/questions/19099663/how-to-correctly-use-fork-exec-wait) – Soren Mar 08 '16 at 16:29

2 Answers2

2

fork() can be called an indefinite number of times; as long as the return value indicates that you're the parent process, you can continue to operate as usual and call it again.

Thus, you can have a loop within which you fork, call an execvp() if you're the child process, and continue to the next iteration if you're the parent.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
2

Execvp replaces the current process image with the command you run. So it cancels your C program. To produce the desired effect, you should fork before execvp. It would look something like this:

int status = 0;
pid_t pid = fork();

if(pid > 0) {
    waitpid(pid, &status, 0);
    // is parent
} else if(pid == 0) {
    execvp(*args, args);
    // is child
} else {
    // fork didn't work
}
OxenMeat
  • 50
  • 1
  • 8
  • But this works for a single child process. I am trying to create an indefinite number of child processes. Putting all this code inside an infinite loop does not help either. – Adeel Ahmad Mar 08 '16 at 16:47
  • 2
    @AdeelAhmad If a while loop doesn't help you to perform a repeated task, then I'm afraid noone will. – Pavel Šimerda Mar 08 '16 at 16:55
  • You can just put the code in a loop to repeat it, just be careful not to forkbomb. – OxenMeat Mar 08 '16 at 17:01
  • @AdeelAhmad, ...if you put a fork/exec in a loop and it doesn't work as you intend, your question should *show the loop*, and describe the actual behavior you're getting. This answer is entirely correct, so any issue you're having has to be in the details; we can't help you with a problem grounded in details if you don't show the work in which those details are contained. – Charles Duffy Mar 08 '16 at 17:02