Question
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
My code:
#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
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