-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprocess.c
152 lines (129 loc) · 5.15 KB
/
process.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
#include "headers.h"
#include "tools.h"
void freeProcessList() {
struct ProcessNode *current = process_list_head;
while (current != NULL) {
struct ProcessNode *next = current->next;
free(current);
current = next;
}
}
int processExists(int pid) {
struct ProcessNode *current = process_list_head;
while (current != NULL) {
if (current->process_info.pid == pid) {
return 1;
}
current = current->next;
}
return 0;
}
void updateProcessState(int pid, const char *state) {
struct ProcessNode *current = process_list_head;
while (current != NULL) {
if (current->process_info.pid == pid) {
strncpy(current->process_info.state, state, sizeof(current->process_info.state) - 1);
current->process_info.state[sizeof(current->process_info.state) - 1] = '\0'; // Ensure null-termination
break; // Found and updated, exit loop
}
current = current->next;
}
}
// Function to insert a process into the linked list in lexicographic order
void insertProcess(ProcessInfo new_process) {
struct ProcessNode *new_node = malloc(sizeof(struct ProcessNode));
if (new_node == NULL) {
printError("malloc");
exit(EXIT_FAILURE);
}
new_node->process_info = new_process;
new_node->next = NULL;
snprintf(new_node->process_info.state, sizeof(new_node->process_info.state), "Running");
// If the list is empty or the new process should be the first,
// update the head pointer
if (process_list_head == NULL || new_process.pid < process_list_head->process_info.pid) {
new_node->next = process_list_head;
process_list_head = new_node;
} else {
struct ProcessNode *current = process_list_head;
while (current->next != NULL && new_process.pid > current->next->process_info.pid) {
current = current->next;
}
new_node->next = current->next;
current->next = new_node;
}
}
// Function to delete the latest process from the process list and return its PID
pid_t deleteLatestProcess() {
if (process_list_head == NULL) {
printError("Process list is empty.\n");
return -1; // Return an invalid PID
}
struct ProcessNode *current = process_list_head;
struct ProcessNode *prev = NULL;
// Traverse the list to find the latest process (the one at the end)
while (current->next != NULL) {
prev = current;
current = current->next;
}
pid_t latest_pid = current->process_info.pid;
// Delete the latest process from the list
if (prev != NULL) {
prev->next = NULL;
} else {
// If there was only one process in the list, update the head pointer
process_list_head = NULL;
}
// Free the memory occupied by the deleted node
free(current);
return latest_pid;
}
// Function to copy the contents of the latest process to the specified process
#include "headers.h" // Include your header file that defines ProcessNode and ProcessInfo
void copyProcessInfoToLatest(pid_t pid) {
struct ProcessNode *latest = process_list_head;
while (latest != NULL) {
if (latest->process_info.pid == pid) {
// Copy data from the latest process to the specified PID process
ProcessInfo *latest_info = &(latest->process_info);
// Find the specified PID process (excluding PID)
struct ProcessNode *current = process_list_head;
while (current != NULL) {
if (current->process_info.pid != pid) {
// Copy data except for PID
current->process_info.is_background = latest_info->is_background;
current->process_info.exit_status = latest_info->exit_status;
strncpy(current->process_info.state, latest_info->state, sizeof(current->process_info.state));
strncpy(current->process_info.command, latest_info->command, sizeof(current->process_info.command));
strncpy(current->process_info.complete_command, latest_info->complete_command,
sizeof(current->process_info.complete_command));
}
current = current->next;
}
break; // Exit loop after copying
}
latest = latest->next;
}
deleteLatestProcess();
}
// Function to handle the SIGCHLD signal
void sigchld_handler() {
int status;
pid_t child_pid;
while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
// Check if the child process exited successfully
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
printf("\tProcess with PID:(%d) exited normally\n", child_pid);
prompt(0);
fflush(stdout);
struct ProcessNode *current = process_list_head;
while (current != NULL) {
if (current->process_info.pid == child_pid) {
snprintf(current->process_info.state, sizeof(current->process_info.state), "Stopped");
break; // Found and updated, exit loop
}
current = current->next;
}
}
}
}