I've fixed my problem with something teacher suggested me but this introduced another problem that I can't seem to fix. And he haven't yet answered me back...
The problem now, is that with this new code, if a command doesn't exist, my bash will stall in the while(fgWait) pause(); loop. It will stall there because as the command doesn't exist, execvp() will return an error and the child process will be immediately exited with exit status = 1 and so, when the parent process reaches the while(fgWait) loop, it will be waiting for a signal that was already sent.
Here's my updated code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wait.h>
#include <signal.h>
#include <sys/types.h>
#include <errno.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "data.h"
volatile bool fgWait = FALSE;
pid_t fgPid = -1;
void childSignalHandler(int signum) {
int status;
pid_t pid;
#ifdef WCONTINUED
pid = waitpid(WAIT_ANY, &status, WNOHANG | WUNTRACED | WCONTINUED);
#elif
pid = waitpid(WAIT_ANY, &status, WNOHANG | WUNTRACED);
#endif
if(pid == -1) {
perror("waitpid");
exit(1);
}
if(pid > 0) {
if(fgPid == pid) {
fgPid = -1;
fgWait = FALSE;
} else {
if(WIFEXITED(status)) {
printf("[%d] Terminated (Status: %d)\n", pid,
WEXITSTATUS(status));
return;
}
}
if(WIFSIGNALED(status)) {
printf("[%d] Terminated (Signal: %d)\n", pid, WTERMSIG(status));
return;
}
if(WIFSTOPPED(status)) {
printf("[%d] Stopped (Signal: %d)\n", pid, WSTOPSIG(status));
return;
}
#ifdef WIFCONTINUED
if(WIFCONTINUED(status)) {
printf("[%d] Continued...\n", pid);
return;
}
#endif
}
}
void intstpSignalHandler(int signum) {
if(fgPid != -1) {
kill(fgPid, signum);
}
}
int main(int argc, char **argv) {
char *bBuffer = NULL, *pArgs[MAXARGNUM], *aPtr = NULL, *sPtr;
bool bgProcess;
int aCount;
pid_t pid;
signal(SIGINT, intstpSignalHandler);
signal(SIGTSTP, intstpSignalHandler);
signal(SIGCHLD, childSignalHandler);
using_history();
while(1) {
free(bBuffer);
bBuffer = readline("\e[1;31mraBash \e[1;32m# \e[0m");
add_history(bBuffer);
if(!strcasecmp(bBuffer, "exit")) {
exit(0);
}
sPtr = bBuffer;
aCount = 0;
do {
aPtr = strsep(&sPtr, " ");
pArgs[aCount++] = aPtr;
} while(aPtr);
bgProcess = FALSE;
if(!strcmp(pArgs[aCount-2], "&")) {
pArgs[aCount-2] = NULL;
bgProcess = TRUE;
}
if(strlen(pArgs[0]) > 1) {
pid = fork();
if(pid == -1) {
perror("fork");
exit(1);
}
if(pid == 0) {
if(execvp(pArgs[0], pArgs) == -1) {
if(errno == ENOENT) {
printf("myBash: %s: command not found\n", pArgs[0]);
}
exit(1);
}
} else {
if(!bgProcess) {
fgPid = pid;
fgWait = TRUE;
while(fgWait) {
pause();
}
} else {
printf("[%d] Started...\n", pid);
}
}
}
}
return 0;
}
Any suggestions to fix this new problem?