The shell i'm writing needs to execute a program given to it by the user. Here's the very shortened simplified version of my program
int main()
{
pid_t pid = getpid(); // this is the parents pid
char *user_input = NULL;
size_t line_sz = 0;
ssize_t line_ct = 0;
line_ct = getline(&user_input, &line_sz, stdin); //so get user input, store in user_input
for (;;)
{
pid_t child_pid = fork(); //fork a duplicate process
pid_t child_ppid = getppid(); //get the child's parent pid
if (child_ppid == pid) //if the current process is a child of the main process
{
exec(); //here I need to execute whatever program was given to user_input
exit(1); //making sure to avoid fork bomb
}
wait(); //so if it's the parent process we need to wait for the child process to finish, right?
}
}
Assume the user might input something like ls, ps, pwd
Thanks.
Edit:
const char* hold = strdup(input_line);
char* argv[2];
argv[0] = input_line;
argv[1] = NULL;
char* envp[1];
envp[0] = NULL;
execve(hold, argv, envp);
fork() to execute processes from bottom to up using wait() This can be done by using wait() system call. The parent process may then issue a wait() system call, which suspends the execution of the parent process while the child executes and when the child finishes execution, it returns exit status to operating system.
A call to wait() blocks the calling process until one of its child processes exits or a signal is received. After child process terminates, parent continues its execution after wait system call instruction.
fork() The fork() is one of the syscalls that is very special and useful in Linux/Unix systems. It is used by processes to create the processes that are copies of themselves. With the help of such system calls, the child process can be created by the parent process.
In fork() system call, child and parent process have separate memory space. While in vfork() system call, child and parent process share same address space. 2. The child process and parent process gets executed simultaneously. Once child process is executed then parent process starts its execution.
Here's a simple, readable solution:
pid_t parent = getpid();
pid_t pid = fork();
if (pid == -1)
{
// error, failed to fork()
}
else if (pid > 0)
{
int status;
waitpid(pid, &status, 0);
}
else
{
// we are the child
execve(...);
_exit(EXIT_FAILURE); // exec never returns
}
The child can use the stored value parent
if it needs to know the parent's PID (though I don't in this example). The parent simply waits for the child to finish. Effectively, the child runs "synchronously" inside the parent, and there is no parallelism. The parent can query status
to see in what manner the child exited (successfully, unsuccessfully, or with a signal).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With