Skip to content

Instantly share code, notes, and snippets.

@kuriringohankamehameha
Last active October 19, 2019 00:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kuriringohankamehameha/11b3f0acbf932c6705183214034d9c37 to your computer and use it in GitHub Desktop.
Save kuriringohankamehameha/11b3f0acbf932c6705183214034d9c37 to your computer and use it in GitHub Desktop.
Shell Shell Handling
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
static void shellHandler(int signo, siginfo_t* info, void* context)
{
// Passes it into the child first
if (signo == SIGINT || signo == SIGKILL || signo == SIGQUIT)
{
printf("Ahoy\n");
kill(childPID, signo);
kill(parentPID, SIGCHLD);
}
else if (signo == SIGTSTP)
{
// Suspend Signal
printf("Suspend Signal\n");
int fg_pid = findFG_STATUS(jobSet);
if (fg_pid != -1)
{
jobSet = changeStatus(jobSet, fg_pid, STATUS_SUSPENDED);
kill(fg_pid, SIGSTOP);
}
}
else if (signo == SIGCHLD)
{
printf("Child Handler\n");
if (!isSuspended)
{
pid_t child = info->si_pid;
jobSet = removeJob(jobSet, child);
signal(signo, SIG_DFL);
}
else{
printf("Case 2\n");
isSuspended = false;
kill(info->si_pid, SIGTSTP);
}
}
else
{
signal(signo, SIG_IGN);
printf("\n");
printPrompt();
}
}
int main(int argc, char* argv[])
{
int signalArray[] = {SIGINT, SIGKILL, SIGTSTP, -1};
sigset_t set = createSignalSet(signalArray);
struct sigaction sa;
sa.sa_handler = shellHandler;
sa.sa_flags = SA_SIGINFO;
// Parent must be blocked from these signals
sigprocmask(SIG_BLOCK, &set, NULL);
int pid = fork();
if (pid == 0)
{
// Child
if (isBackground == true)
{
printf("[bg]\t%d\n",getpid());
setpgid(0, 0);
}
else
{
// Add to foreground process group
pid_t cgrp = getpgrp();
tcsetpgrp(STDIN_FILENO, cgrp);
setpgid(getpid(), getppid());
}
//The child must receive the previously blocked signals
sigprocmask(SIG\_UNBLOCK, &set, NULL);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTSTP, &sa, NULL);
sigaction(SIGSTOP, &sa, NULL);
childPID = getpid();
}
else
{
// Parent
parentPID = getpid();
setpgid(0, 0);
if (isBackground)
{
Node node;
[node.pid](https://node.pid) = pid;
node.status = STATUS\_BACKGROUND;
char* name = (char*) malloc (sizeof(char));
strcpy(name, argVector[0]);
jobSet = insert(jobSet, node);
setpgrp();
}
else
{
int status;
if((waitpid(pid, &status, WUNTRACED | WNOHANG) >= 0)){
printf("PID = %d\\t", pid);
if (WIFEXITED(status)){
printf("Normal Exit\\n");
}
else if (WIFSIGNALED(status)){
printf("Job terminated by signal %d\\n", WTERMSIG(status));
}
else if (WIFSTOPPED(status)){
printf("Job stopped by signal %d\\n", WTERMSIG(status));
isSuspended = true;
}
sigaction(SIGCHLD, &sa, NULL);
}
waitpid(pid, NULL, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment