This repository has been archived by the owner on Jul 3, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
job_control.c
137 lines (110 loc) · 4.04 KB
/
job_control.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
/*
* Copyright © 2018 Dimonchik0036. All rights reserved.
*/
#include "job_control.h"
#include "terminal.h"
#include <wait.h>
#include <signal.h>
JobController *job_controller_create() {
JobController *controller = malloc(sizeof(JobController));
check_memory(controller);
job_controller_init(controller);
return controller;
}
void job_controller_free(JobController *controller) {
size_t index;
for (index = 0; index < controller->number_of_jobs; ++index) {
job_free(controller->jobs[index]);
}
free(controller);
}
void job_controller_init(JobController *controller) {
memset(controller->jobs, 0, sizeof(Job *) * JOB_LIMIT);
controller->current_max_jid = 1;
controller->number_of_jobs = 0;
}
jid_t job_controller_add_job(JobController *controller,
pid_t pid,
Command const *command,
char status) {
return job_controller_add_conveyor(controller, pid, command, status, 1);
}
jid_t job_controller_add_conveyor(JobController *controller,
pid_t pid,
Command const *command,
char status,
size_t job_count) {
if (controller->number_of_jobs >= JOB_LIMIT - 1) {
fprintf(stderr, "shell: number of jobs (%d) exceeded\n", JOB_LIMIT);
return BAD_RESULT;
}
Command *copy_of_command = command_copy_for_job(command);
Job *job = job_create_conveyor(controller->current_max_jid++, pid, copy_of_command,
status, job_count);
controller->jobs[controller->number_of_jobs++] = job;
fprintf(stderr, "\n[%d] %d\n", job->jid, (int) job->pid);
return job->jid;
}
int job_controller_remove_job_by_index(JobController *controller,
size_t index) {
Job *current_job = controller->jobs[index];
size_t last_index = (size_t) (controller->number_of_jobs - 1);
memmove(controller->jobs + index, controller->jobs + index + 1,
(last_index - index) * sizeof(Job *));
--controller->number_of_jobs;
controller->jobs[controller->number_of_jobs] = NULL;
if (!controller->number_of_jobs) {
controller->current_max_jid = 1;
}
job_free(current_job);
return EXIT_SUCCESS;
}
int job_controller_release(JobController *controller) {
size_t index;
for (index = 0; index < controller->number_of_jobs; ++index) {
Job *current_job = controller->jobs[index];
killpg(current_job->pid, SIGHUP);
}
if (controller->number_of_jobs) {
printf("There are stopped jobs.\n");
}
return EXIT_SUCCESS;
}
void job_controller_print_all_jobs(JobController *controller) {
size_t index;
for (index = 0; index < controller->number_of_jobs; ++index) {
Job *current_job = controller->jobs[index];
job_print(current_job, stdout, "");
}
}
void job_controller_print_current_status(JobController *controller) {
size_t index;
for (index = 0; index < controller->number_of_jobs; ++index) {
Job *current_job = controller->jobs[index];
int status;
pid_t answer = waitpid(-current_job->pid, &status, WNOHANG | WUNTRACED);
while (answer != 0 && answer != BAD_RESULT) {
--current_job->count;
answer = waitpid(-current_job->pid, &status, WNOHANG | WUNTRACED);
}
if (answer == 0) {
continue;
}
job_set_status(current_job, status);
job_print(current_job, stdout, "\n");
if (WIFEXITED(status)) {
job_controller_remove_job_by_index(controller, index);
--index;
}
}
}
size_t job_controller_search_job_by_jid(JobController *controller, jid_t jid) {
size_t index;
for (index = 0; index < controller->number_of_jobs; ++index) {
Job *current_job = controller->jobs[index];
if (current_job->jid == jid) {
return index;
}
}
return (size_t) controller->number_of_jobs + 1;
}