-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjobs.c
117 lines (107 loc) · 2.2 KB
/
jobs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <wait.h>
#include "jobs.h"
#include "prompt.h"
#include "rawio.h"
job *jobs;
int job_count = 0;
void init_jobs()
{
jobs = malloc(sizeof(job));
jobs->pid = 0;
jobs->next = NULL;
}
void add_job(int pid, char* name)
{
struct job* new_job = malloc(sizeof(struct job));
new_job->job_no = ++job_count;
new_job->pid = pid;
new_job->name = strdup(name);
new_job->next = NULL;
job* walk = jobs;
while (walk->next != NULL)
{
walk = walk->next;
}
walk->next = new_job;
}
void remove_job(int pid)
{
job* walk = jobs;
job* prev = jobs;
while (walk != NULL)
{
if (walk->pid == pid)
{
prev->next = walk->next;
}
prev = walk;
walk = walk->next;
}
}
char* get_job_name(int pid)
{
job* walk = jobs;
while (walk != NULL)
{
if (walk->pid == pid)
{
return walk->name;
}
walk = walk->next;
}
return NULL;
}
void child_handler(int signum)
{
int status;
pid_t pid;
while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED )) > 0)
{
char* name = get_job_name(pid);
if (name == NULL)
{
continue;
}
if (WIFEXITED(status)) {
printf("\n%s with pid %d exited normally\n",name, pid);
remove_job(pid);
}else if (WIFSTOPPED(status)) {
printf("%s with pid %d suspended normally\n",name, pid);
}else {
printf("%s with pid %d did not exit normally\n",name, pid);
remove_job(pid);
}
prompt();
printf("%s", inp);
}
}
void init_child_handler()
{
struct sigaction sa;
sa.sa_handler = child_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sigaction(SIGCHLD, &sa, NULL);
}
pid_t get_job(int index)
{
job *walk = jobs->next;
for (int i = 1; i <= job_count; i++)
{
if (walk == NULL)
{
return -1;
}
if (i == walk->job_no)
{
return walk->pid;
}
walk = walk->next;
}
return -1;
}