1. Can you think of why we use `fork/execvp` instead of just calling `execvp` directly? What value do you think the `fork` provides?
> **Answer**: We need to use fork() because execvp() replaces the current process entirely. If we just called execvp() directly, our shell would be replaced by the command and then exit. By using fork(), we create a copy of our shell process first, so the child process can run the command while the parent shell process stays alive to accept more commands. This also lets us run multiple commands and wait for them to finish.
2. What happens if the fork() system call fails? How does your implementation handle this scenario?
> **Answer**: If fork() fails, it returns -1 and sets errno to indicate the error. Our implementation would print an error message and exit the program.
3. How does execvp() find the command to execute? What system environment variable plays a role in this process?
> **Answer**: execvp() searches for the command in the directories listed in the PATH environment variable.
4. What is the purpose of calling wait() in the parent process after forking? What would happen if we didn't call it?
> **Answer**: The purpose of calling wait() in the parent process after forking is to wait for the child process to finish and get its exit status. This allows the parent process to handle the child process's output or errors. If we didn't call wait(), the parent process would continue immediately after forking, without waiting for the child process to finish.
5. In the referenced demo code we used WEXITSTATUS(). What information does this provide, and why is it important?
> **Answer**: WEXITSTATUS() provides the exit status of the child process. It's important because it allows the parent process to check if the child process exited normally or with an error.
6. Describe how your implementation of build_cmd_buff() handles quoted arguments. Why is this necessary?
> **Answer**: I copy all characters in an argument except for quotation marks to a new string and use it for execvp(). All leading and trailing spaces are also removed before that. This is necessary since excecvp() does not automatically remove quotation marks, but without them, one argument with white spaces in between is treated as multiple arguments.
7. What changes did you make to your parsing logic compared to the previous assignment? Were there any unexpected challenges in refactoring your old code?
> **Answer**: In this implementation, I used a simple parsing approach that splits the command line into the executable name and arguments using strtok(). The first token becomes the command name, and the rest becomes the arguments. The main challenge was making sure to properly NULL-terminate the argv array for execvp() to work correctly.
8. For this quesiton, you need to do some research on Linux signals. You can use [this google search](https://www.google.com/search?q=Linux+signals+overview+site%3Aman7.org+OR+site%3Alinux.die.net+OR+site%3Atldp.org&oq=Linux+signals+overview+site%3Aman7.org+OR+site%3Alinux.die.net+OR+site%3Atldp.org&gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBBzc2MGowajeoAgCwAgA&sourceid=chrome&ie=UTF-8) to get started.
- What is the purpose of signals in a Linux system, and how do they differ from other forms of interprocess communication (IPC)?
> **Answer**: The purpose of signals in a Linux system is to allow processes to communicate with each other. Signals are different from other forms of IPC like pipes or sockets because they are asynchronous and unidirectional.
- Find and describe three commonly used signals (e.g., SIGKILL, SIGTERM, SIGINT). What are their typical use cases?
> **Answer**: Three common signals are:
> - SIGINT (Ctrl+C): Used to interrupt a program from the keyboard. Most programs catch this to clean up before exiting.
> - SIGKILL (kill -9): Forces a program to stop immediately. Can't be caught or ignored, used when a program is stuck.
> - SIGTERM: The normal way to ask a program to terminate. Programs can catch this to clean up before exiting.
- What happens when a process receives SIGSTOP? Can it be caught or ignored like SIGINT? Why or why not?
> **Answer**: When a process receives SIGSTOP, it freezes (suspends) immediately. Unlike SIGINT, SIGSTOP cannot be caught or ignored because it's designed to always give control back to the user. This is important for debugging and process control - you need a reliable way to stop a process. The process can be resumed later with SIGCONT.