Question
#include smallsh.h #include #include #include #include #include #include #include #define MAX_JOBS 100 struct Job jobs[MAX_JOBS]; int numJobs = 0; // Function declarations void handleSIGCHLD(int signo);
#include "smallsh.h" #include
#define MAX_JOBS 100
struct Job jobs[MAX_JOBS]; int numJobs = 0;
// Function declarations void handleSIGCHLD(int signo); void handleSIGINT(int signo); void handleSIGTSTP(int signo); void launchForeground(char* command, char* args[], int* status); void launchBackground(char* command, char* args[]); void updateJobsStatus(); void initJobs(); void addJob(pid_t pgid, const char* command, bool running); void removeJob(pid_t pgid); void printJobs();
int main() { // Set up signal handlers signal(SIGCHLD, handleSIGCHLD); signal(SIGINT, handleSIGINT); signal(SIGTSTP, handleSIGTSTP);
initJobs();
while (1) { char command[100]; // Get user input printf("Command> "); fgets(command, sizeof(command), stdin); command[strcspn(command, " ")] = '\0'; // Remove the newline character
// Exit the loop if the user enters "exit" or "quit" if (strcmp(command, "exit") == 0 || strcmp(command, "quit") == 0) { break; }
// Handle Ctrl+C if (strcmp(command, "^C") == 0) { if (jobs[0].running) { kill(-jobs[0].pgid, SIGINT); } else { printf("No foreground process to interrupt. "); } continue; // Skip to the next iteration }
// Handle Ctrl+Z if (strcmp(command, "^Z") == 0) { if (jobs[0].running) { kill(-jobs[0].pgid, SIGTSTP); addJob(jobs[0].pgid, jobs[0].command, false); } else { printf("No foreground process to suspend. "); } continue; // Skip to the next iteration }
}
return 0; }
// Implement other functions as needed
void handleSIGCHLD(int signo) { // Handle SIGCHLD to reap terminated child processes pid_t pid; int status;
while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) { // Find the job associated with the terminated process for (int i = 0; i
void handleSIGINT(int signo) { // Handle SIGINT (^C) if (jobs[0].running) { kill(-jobs[0].pgid, SIGINT); } else if (numJobs > 0) { // If there are background processes, interrupt the most recent one kill(-jobs[numJobs - 1].pgid, SIGINT); } else { printf("No process to interrupt. "); } }
void handleSIGTSTP(int signo) { // Handle SIGTSTP (^Z) if (jobs[0].running) { kill(-jobs[0].pgid, SIGTSTP); addJob(jobs[0].pgid, jobs[0].command, false); } else { printf("No foreground process to suspend. "); } }
void launchForeground(char* command, char* args[], int* status) { // Implement code to launch a process in the foreground pid_t pid = fork(); if (pid == 0) { setpgid(0, 0); execvp(command, args); perror("execvp"); exit(EXIT_FAILURE); } else if (pid
void launchBackground(char* command, char* args[]) { // Implement code to launch a process in the background pid_t pid = fork(); if (pid == 0) { setpgid(0, 0); execvp(command, args); perror("execvp"); exit(EXIT_FAILURE); } else if (pid
void updateJobsStatus() { for (int i = 0; i
if (result == -1) { perror("waitpid"); } else if (result > 0) { if (WIFEXITED(status) || WIFSIGNALED(status)) { // Process has exited or terminated jobs[i].running = false; printf("Job [%d] %s terminated ", i + 1, jobs[i].command); } else if (WIFSTOPPED(status)) { // Process has been stopped jobs[i].running = false; printf("Job [%d] %s stopped ", i + 1, jobs[i].command); } else if (WIFCONTINUED(status)) { // Process has been continued jobs[i].running = true; printf("Job [%d] %s continued ", i + 1, jobs[i].command); } } } }
void initJobs() { // Initialize the jobs array for (int i = 0; i
void addJob(pid_t pgid, const char* command, bool running) { // Add a new job to the jobs array if (numJobs
void removeJob(pid_t pgid) { // Remove a job from the jobs array for (int i = 0; i
void printJobs() { // Print the list of jobs printf("Jobs: "); for (int i = 0; i
run my code it doesnt get me the results i need because it always says No foreground process to suspend. did i do the right thing finish the entrie program forme with running code you will get a thumbs up
Vhat to submit Fu need to submit the following: (a) your "smallsh,s" and "smallsh,h" program files. (b) MS Word document including the screenshot from the following scenarios: (1) Scenario 1 S>./smallsh Command >./ progl\& Command >.progl\& Command >.progl C (2) Scenario 2 S>./smallsh Command > ./progl\& Command > ./progl\& Command > ./progl ' Z (3) Scenario 3 S>./smallsh Command >./ progl\& Command >./ progl\& Command > ./progl C Command > jobs (4) Scenario 4 S>./smallsh Command >./ progl\& Command >./ progl\& Command >.prog 1 ' Z Command > jobs (5) Scenario 5 S>./smallsh Command >./ progl\& Command >./ progl\& Command >.prog 1 'Z Example Suppose that you have a program that includes 1 fork system call. Let's name that executable file as "prog1". For example, you may use the following program as "prog1.c" int main() \{ int i=0; for (i=0;iprog1& Command > prog1\& Command > prog 1 ... Then there are 3 jobs created where each job contains 2 processes. One job is running in foreground, and two jobs are running in background. 1. Alter smallsh from Chapter 5 so that it handles interrupts more like a real shell: (1) Your smallsh process shouldn't be terminated upon CtrlC type-in. Currently, if you type CtrlC, your smallsh process will be terminated and exited. (2) When you type inStep by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started