Question
For some reason my code is printing certain things that shouldn't be printed, and then not accessing the files/directories that it's supposed to, which is
For some reason my code is printing certain things that shouldn't be printed, and then not accessing the files/directories that it's supposed to, which is preventing it from looking like the example output from the test script. Can somebody help me understand why that's the case? I understand the process of debugging, but I'm looking for help - hence the post - so an explanation/solution would be much appreciated. THE CODE FOR THE TEST SCRIPT CANNOT BE ALTERED. If any changes are to be made it's to MY code so that it creates output like the example output.
Example Output: My Output: My Code:
#define _POSIX_C_SOURCE 200809L
#include
#define _GNU_SOURCE #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); if (sigaction(SIGINT, &sa, NULL) == - 1) { perror("sigaction: SIGINT"); exit(1); } if (sigaction(SIGTSTP, &sa, NULL) == - 1) { perror("sigaction: SIGTSTP"); exit(1); } 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; }
Script Code:
s. Smallsh/testscript.sh . /smallsh Beginning Test Scriptl Variable expansions Reported expansion of $: "274850" (Expecting "274850", 10 points) Reported expansion of $7:"0 " (Expecting " 0 ", 5 points) Reported expansion of $1:" : (Expecting " ", 10 points) Reported expansion of /:"/tmp/tmp.6 TVNPdjMzB/" (Expecting "/tmp/tmp.6TVNPdjMzB", 10 points) Testing: bash - c 'exit 166 Reported expansion of \$?: "166" (Expecting "166", 5 points) Testing: echo PID=\$\$. Status=\$?. There's no place like / Home! (10 points) PID =274850. Status=166. There's no place like /tmp/tmp.6TvNPdjMzB/Homel Parsing Comments Testing: echo success! \# ...notl This shouldn't be printed! 5 points) Success I Testing built-in cd command Testing: pwd /tmp/tmp.vwErHvbJEC Testing: cd Testing: pwd (Expecting "/tmp/tmp.6TVNPdjMzB", 15 points) /tmp/tmp.6TVNPdjMzB Testing: mkdir pid-\$\$-dir Testing: 15 (Expecting "pid-274850-dir", 10 points) pid-274850-dit Testing: cd pid-274850-dir Testing: pwd (Expecting "/tmp/tmp.6TVNPdjMzB/pid-274850-dir", 10 points) /tmp/tmp.6TVNPdjMzB/pid-274850-dit Testing built-in exit command Testing: exit 166 exit Smallsh exited with value: 166 (expected 166,15 points) Checking for zombies: (-5 points if detected) none detectedt starting next set of testsi Input / Output redirection operators Testing: head -c 1000 /dev/random > 1k-random-bytes Testing: wc -c 1k-random-bytes (Expecting "1000 1k-random-bytes", 15 points) 10001k-random-bytes Testing: wc c10k-random-bytes Testing: wc -c 10k-random-bytes (Expecting "10000 10k-random-bytes", 15 points) 10000010k-random-bytes Background Commands Testing: sleep 1 \& (Expecting "Child process 281733 done. Exit status 0.", 15 points for pid, 5 points for status.) Child process 281733 done. Exit status . Sending SIGSTOP to a sleeping proccess (Expecting "Child process 292073 stopped. Continuing.", 5 points) Child process 292073 stopped. Continuing. Sending SIGINT to a background process (Expecting "Child process 297288 done. Signaled 2.", 10 points) child process 297288 done. Signaled 2. echo \$hr printf $ (tput bold setaf 4 ) Testing built-in exit command $ (tput sgr0) printf Testing: S(tput bold lexit \$randval\$(tput sgro) exit \$randval _EOF _OUTEREOF bgpid $ ! wait \$!! stat =$ ? echo \$hr printf "Smallsh exited with value: \$stat (expected Srandval, \$(tput setaf 4 bold) 15 points ( tput sgro) n steep 1 printf "Checking for zombies: (\$ (tput setaf 4 bold)-5 points $ (tput sgro) if detected) \ " pgrep -af 5$ ! II echo none detected! pkill 9-s $! timeout 10 env - PS1=" HOME=" "homedir" setsid bash <_outereof__ export ifs exec . __eof echo printf bold setaf input output redirection operatorss sgro testing: tput c1000 dev>1k-random-bytes $ (tput sgro) 1n head -c 1000/ dev/random >1k random-bytes printf Testing: S(tput bold)we - 1 1k-random-bytes\$(tput sgr0) (Expecting "1000 1k-random-bytes", \$(tput setaf 4 bold)15 pointss(tput sgr0) wc c 1k-random-bytes printf Testing: S(tput bold)wc c10k-random-bytes $( tput sgro) head c 18000 dev/random >10k random-bytes wC c 10k-random-bytes echo \$hr printf $( tput bold setaf 4)Background Commands\$(tput sgro) \ n sleep 1& status.) \ n sleep 2 5leep 100& printf \$(tput bold)Sending SIGSTOP to a sleeping proccess\$(tput sgr0) (Expecting "Child process IIIS! stopped. Continuing.", $( tput setaf 4 bold)5 points\$(tput sgre))1n kill -SIGSTOP. IIIS! sleep 1 steep 100& printf $( tput bold)Sending SIGINT to a background process\$(tput sgr0) (Expecting "Child process III\$! done. Signaled 2 .", $(tput setaf 4 bold)10 points\$(tput sgr0)) kill -SIGINT IIIs! sleep 1 _EOF _ OUTEREOF wait $ ! stat =$ ? echo \$hr sleep 1Step 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