Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Still stuck with some errors here. Someone said my code had issues with the signal handling, specifically that I needed to #include but it's already

Still stuck with some errors here. Someone said my code had issues with the signal handling, specifically that I needed to #include but it's already included in my code. Then when they provided an "updated version" of my code, it wound up showing blatant errors in replit. If you could please run your solution before submitting a fix that'd be great.

image text in transcribed

My code:

#include #include #include #include #include #include #include #include #include

#define MAX_ARGS 512 #define MAX_ARG_LEN 2048

// Declaring function prototypes: void str_replace(char *str, const char *old_str, const char *new_str); void expand_env(char *str);

// Signal handler for SIGINT and SIGTSTP void handle_signal(int signo) { printf(" "); fflush(stdout); }

// Function to replace a substring in a string with another string void str_replace(char *str, const char *old_str, const char *new_str) { size_t old_len = strlen(old_str); size_t new_len = strlen(new_str); char *pos = strstr(str, old_str); while (pos != NULL) { // Shift the characters after the old string to make room for the new string memmove(pos + new_len, pos + old_len, strlen(pos + old_len) + 1); // Copy the new string into the position of the old string memcpy(pos, new_str, new_len); // Look for the next occurrence of the old string pos = strstr(pos + new_len, old_str); } }

// Function to expand the environment variables in a string void expand_env(char *str) { int status; pid_t bg_pid = -1; // Declare the variable for background PID // Replace any occurrence of "$$" with the process ID char pid_str[16]; sprintf(pid_str, "%d", getpid()); str_replace(str, "$$", pid_str);

// Replace any occurrence of "$?" with the exit status char exit_str[16]; sprintf(exit_str, "%d", WEXITSTATUS(status)); str_replace(str, "$?", exit_str);

// Replace any occurrence of "$!" with the process ID of the most recent background process char bg_pid_str[16]; sprintf(bg_pid_str, "%d", bg_pid); str_replace(str, "$!", bg_pid_str);

// Replace any occurrence of "~/" at the beginning of a word with the value of HOME environment variable if (str[0] == '~' && (str[1] == '/' || str[1] == '\0')) { str_replace(str, "~/", getenv("HOME")); } }

int main() { // Set signal handlers for SIGINT and SIGTSTP struct sigaction sa; sa.sa_handler = handle_signal; sa.sa_flags = SA_RESTART; sigfillset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sigaction(SIGTSTP, &sa, NULL);

while (1) { // Check for any un-waited-for background processes pid_t pid; int status; while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) { if (WIFEXITED(status)) { printf("background pid %jd is done: exit value %d ", (intmax_t) pid, WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("background pid %jd is done: terminated by signal %d ", (intmax_t) pid, WTERMSIG(status)); } else if (WIFSTOPPED(status)) { printf("background pid %jd is stopped: signal %d ", (intmax_t) pid, WSTOPSIG(status)); kill(pid, SIGCONT); printf("background pid %jd is continued ", (intmax_t) pid); } }

// Print the prompt printf(": "); fflush(stdout);

// Read the command line input char input[MAX_ARGS * MAX_ARG_LEN]; if (fgets(input, sizeof(input), stdin) == NULL) { break; } // Check if the input string is empty or contains only whitespace characters int i; for (i = 0; i 1) { if (chdir(args[1]) != 0) { perror(args[1]); } } else { if (chdir(getenv("HOME")) != 0) { perror("cd"); } } } else { // Execute the command pid_t pid = fork(); if (pid == -1) { perror("fork"); } else if (pid == 0) { // Child process execvp(args[0], args); perror(args[0]); exit(1); } else { // Parent process if (args[arg_count - 1][0] == '&') { // Background process printf("background pid %jd ", (intmax_t) pid); } else { // Foreground process waitpid(pid, &status, 0); if (WIFSIGNALED(status)) { printf("terminated by signal %d ", WTERMSIG(status)); } } } } } return 0; }

\$gcc -std=c99 -o smallsh smallsh.c smallsh.c: In function 'main': smallsh.c:67:20: error: storage size of 'sa' isn't known struct sigaction sa; smallsh.c:69:17: error: 'SA_RESTART' undeclared (first use in this function) sa.sa_flags = SA_RESTART; smallsh.c:69:17: note: each undeclared identifier is reported only once for each function it appears in smallsh.c:70:3: warning: implicit declaration of function 'sigfillset' [-Wimplicit-function-declaration] sigfillset(8sa.sa_mask); smallsh.c:71:3: warning: implicit declaration of function 'sigaction' [-Wimplicit-function-declaration] sigaction(SIGINT, \&sa, NULL); smallsh.c:85:9: warning: implicit declaration of function 'kill' [-Wimplicit-function-declaration] kill(pid, SIGCONT)

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Database Concepts International Edition

Authors: David M. Kroenke

6th Edition International Edition

0133098222, 978-0133098228

More Books

Students also viewed these Databases questions