-
Notifications
You must be signed in to change notification settings - Fork 0
/
job.c
154 lines (143 loc) · 4.25 KB
/
job.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "job.h"
#include "global.h"
/* initializes the job list data structure */
void init_job(IronShellJob *job, char *command) {
job->head = job->tail = NULL;
strcpy(job->command, command);
job->process_count = 0;
job->command_status = RUNNING;
return;
}
/* adds sub job to the exisition job list data structure */
void add_sub_job(IronShellJob *job, char *command_name, pid_t pid) {
IronShellJobProcess *new_sub_job =
(IronShellJobProcess *)malloc(sizeof(IronShellJobProcess));
if(new_sub_job == NULL) {
PRINT_ERR("malloc failed");
}
strcpy(new_sub_job->process_name, command_name);
new_sub_job->pid = pid;
new_sub_job->next = NULL;
/* first job to the added in the list */
if(job->head == NULL && job->tail == NULL) {
job->head = job->tail = new_sub_job;
job->process_count++;
return;
}
new_sub_job->next = job->head;
job->head = new_sub_job;
job->process_count++;
return;
}
/* void traverse the job list */
void traverse_job(IronShellJob job) {
IronShellJobProcess *ptr = job.head;
while(ptr != NULL) {
printf("(%s, %d)\t", ptr->process_name, ptr->pid);
ptr = ptr->next;
}
printf("\n");
return;
}
/* destories the job and allocated resources */
void destroy_job(IronShellJob* job) {
IronShellJobProcess *ptr = job->head, *temp;
while(ptr != NULL) {
temp = ptr->next;
free(ptr);
ptr = temp;
}
job->head = job->tail = NULL;
job->process_count = 0;
return;
}
/* kills the job's running process
* Note : this frees the dynamically allocated resources
*/
void kill_job(IronShellJob *job) {
IronShellJobProcess *ptr = job->head;
while(ptr != NULL) {
kill(ptr->pid, SIGINT);
ptr = ptr->next;
}
destroy_job(job);
return;
}
/* suspends the job's running processes
* Note this doesn't free the dynamically allocated resources
*/
void suspend_job(IronShellJob *job) {
IronShellJobProcess *ptr = job->head;
while(ptr != NULL) {
kill(ptr->pid, SIGSTOP);
ptr = ptr->next;
}
job->command_status = STOPPED;
print_job(*job, iscb.jobs.count_jobs + 1);
return;
}
/* resumes the execution of the job and since any paritcular
* job contains many process thus execution all process is resumed.
*/
void resume_job(IronShellJob *job, int index) {
IronShellJobProcess *ptr = job->head;
if(ptr == NULL) {
PRINT_EXECPTION("job has no associated processes");
return;
}
while(ptr != NULL) {
kill(ptr->pid, SIGCONT);
ptr = ptr->next;
}
job->command_status = RUNNING;
print_job(*job, index);
return;
}
/* logs the message on the prompt regarding the job which is stopped or running
*/
void print_job(IronShellJob job, int index) {
IronShellJobProcess *ptr = job.head;
if(ptr == NULL) {
PRINT_EXECPTION("job has no associated processes");
return;
}
if(job.command_status == STOPPED) {
PRINT_JOB_PROCESS_HEAD(index, ptr->pid, ptr->process_name, "stopped");
} else {
PRINT_JOB_PROCESS_HEAD(index, ptr->pid, ptr->process_name, "running");
}
ptr = ptr->next;
while(ptr != NULL) {
if(job.command_status == STOPPED) {
PRINT_JOB_PROCESS_NODE(ptr->pid, ptr->process_name, "stopped");
} else {
PRINT_JOB_PROCESS_NODE(ptr->pid, ptr->process_name, "running");
}
ptr = ptr->next;
}
return;
}
/* deletes a sub job process with given pid */
bool delete_sub_job(IronShellJob *jobs, pid_t pid, int index) {
IronShellJobProcess *ptr = jobs->head, *temp = NULL;
while(ptr != NULL) {
if(ptr->pid == pid) {
/* you need to delete this particular node from the list */
if(temp == NULL) {
jobs->head = ptr->next;
if(jobs->head == NULL) {
jobs->tail = NULL;
}
} else {
temp->next = ptr->next;
}
PRINT_JOB_DONE(index, pid, ptr->process_name);
free(ptr);
jobs->process_count--;
return true;
}
temp = ptr;
ptr = ptr->next;
}
return false;
}