You split the command line into separate lines (command name, arguments), and you store them at the zero end of the array of character pointers. Then you fork and pass the command name and command + arguments to execvp() , if only it is verboten. In the end, you have to worry about channel redirection and I / O reassignment, but the basic idea remains the same.
char *args[MAXARGS]; args[0] = "cat"; args[1] = "foo.txt"; args[2] = 0; if ((pid = fork()) == 0) { execvp(args[0], args); ...print error... exit(1); } else if (pid < 0) ...fork failed... else ...wait for child to finish - or start other commands, or ...
You can dynamically allocate args in a real shell. This is one step harder if you must provide a custom environment for the executable. Basically, you will collect a copy of the environment, and then after forking set the global environment to a new value, but if the new environment contains a new value for PATH, it will affect the search for the command using execvp() . Because of this, you can write your own version of execvp() . If so, take a sheet from the BSD book (MacOS X); there is an execvp() function:
int execvP(const char *file, const char *search_path, char *const argv[]);
which allows you to specify the search path to use, even if you fixed the environment. The most fundamental call is execve() ; this is used by execvp() backstage (possibly through execv() ).
source share