You may work alone or with one other classmate, and each person is expected to contribute equally to the effort. Note: if needed, a complete working version of the first part of the smart shell will be provided as a starting point.
int system(const char * command);This function executes the command specified as argument by invoking the Unix shell. The shell executes the command in the background, and passes the result to the calling program (-1 in case of an error, the value returned by the main function of program specified as command otherwise). To be able to use the system function, you need a working shell in the first place. Given that our ultimate goal is to write a shell from scratch, we'll have to assume that the system function is unavailable to us.
The main goal of this assignment is to write your own mysystem function with the
prototype:
void mysystem(const char * command);
The mysystem should execute the command supplied as an argument. If the command fails, the function should print an
error message.
Standard C offers a system function called execv that executes the command specified as the first argument:
execv(char * fullcmd, char * cmdargv[]);Here fullcmd is the full path for the file (command) to be executed, and cmdargv is an array of strings representing the arguments for fullcmd. By convention, the first string in cmdargv is the name of the file to be executed. The function execv returns to the calling program only if there is an error, such as not being able to find the executable. After a successful execv, there is no return to the calling program.
In building the full command for execv, you will make use of the global variable searchpath built by the function SaveSearchPaths from your previous assignment.
Implementation guidelines for mysystem(char * command):
char * fullcmd;To implement this step, spawn a child process using fork. The child process will be an exact copy of the calling process. The child process scans searchpaths and uses each entry i as follows:
char * fullcmd = malloc(strlen(searchpaths[i] + strlen(cmdargv[0]) + 2);
sprintf(fullcmd, "%s/%s", searchpaths[i], cmdargv[0]);
execv(fullcmd, cmdargv);If the executable fullcmd exists, then execv succeeds and your child process ends (because the child code, which included the loop, gets overwritten by the code of the executable cmdargv[0]). If the executable fullcmd does not exist, then the child continues with the instruction following the execv call. This instruction must free the memory dynamically allocated in this iteration, in preparation for the next loop iteration:
free(fullcmd);
Note: You may not use calls to execvp or exceve in this assignment.
Compile your project using the command
gcc smartshell2.c mysystem.c stringarray.c -o smartshell2The three source files will be linked into one executable file called smartshell2.