Repository navigation
Expand file tree
/
Copy pathcontrolRealProcess.c
More file actions
160 lines (141 loc) · 5.02 KB
/
Copy pathcontrolRealProcess.c
File metadata and controls
160 lines (141 loc) · 5.02 KB
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
154
155
156
157
158
159
160
/*For task 4-control real process*/
/*Notice that, there are some redundancy in this code, for example, write->kill->read->verify can be pipelined*/
/*But since most instructions are just a single line, e.g. read(process->pipes_out[0], &byte, sizeof(byte)) != sizeof(byte)*/
/*For a clear presentation and readablity purpose I didn't put them into functions*/
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <signal.h>
#include "controlRealProcess.h"
#include "printResult.h"
int createRealProcess(process_t* process, unsigned int time) {
//if this process haven't been created
if(process->pid != -1){
perror("Create:trying to create a process that has been created already");
}
pid_t pid;
if (pipe(process->pipes_in) < 0 || pipe(process->pipes_out) < 0) {
perror("Create:pipe");
return -1;
}
if ((pid = fork()) < 0) {
perror("Create:fork");
return -1;
} else if (pid == 0) {
// Redirect standard input and output to pipes
if (dup2(process->pipes_in[0], STDIN_FILENO) == -1 || dup2(process->pipes_out[1], STDOUT_FILENO) == -1) {
perror("Create:dup2");
exit(EXIT_FAILURE);
}
// Execute the process
//char* args[] = {"./process", "-v", process->name, NULL};
char* args[] = {"./process", process->name, NULL};
execvp(args[0], args);
perror("execvp");
exit(EXIT_FAILURE);
} else {
// Write the 32-bit value to the process's standard input
unsigned int value = htonl(time);
if (write(process->pipes_in[1], &value, sizeof(value)) != sizeof(value)) {
perror("Create:write:");
return -1;
}
// read 1 byte from the process's standard output
unsigned char byte;
if (read(process->pipes_out[0], &byte, sizeof(byte)) != sizeof(byte)) {
perror("Create:read");
return -1;
}
// Verify that it matches the least significant byte of the value
if (byte != ((time >> 0) & 0xFF)) {
fprintf(stderr, "createProcess: Verification failed: expected %02X, got %02X\n", (time >> 0) & 0xFF, byte);
return -1;
}
process->pid = pid;
}
return 0;
}
int suspendRealProcess(process_t* process, unsigned int time) {
//if this process haven't been created
if(process->pid == -1){
perror("Suspend:trying to suspend a process which hasn't been created");
return -1;
}
// write the 32-bit value to the process's standard input
unsigned int value = htonl(time);
if (write(process->pipes_in[1], &value, sizeof(value)) != sizeof(value)) {
perror("Suspend:write:");
return -1;
}
// send the SIGTSTP signal to process
if (kill(process->pid, SIGTSTP) == -1) {
perror("Suspend:SIGTSTP");
return -1;
}
int wstatus; // Wait for the process to enter a stopped state
pid_t w;
do {
w = waitpid(process->pid, &wstatus, WUNTRACED);
if (w == -1) {
perror("Suspend: waitpid");
return -1;
}
} while (!WIFSTOPPED(wstatus));
return 0;
}
int continueRealProcess(process_t* process, unsigned int time){
//if this process haven't been created
if(process->pid == -1){
perror("Continue:trying to continue a process which hasn't been created");
}
// Send simulation time to process
unsigned int value = htonl(time);
if (write(process->pipes_in[1], &value, sizeof(value)) != sizeof(value)) {
perror("continue: write");
return -1;
}
// send SIGCONT signal to process
if (kill(process->pid, SIGCONT) == -1) {
perror("continue: SIGCONT");
return -1;
}
// Read 1 byte from the standard output of process and verify
unsigned char byte;
if (read(process->pipes_out[0], &byte, sizeof(byte)) != sizeof(byte)) {
perror("Continue:read");
return -1;
}
if (byte != ((time >> 0) & 0xFF)) {
fprintf(stderr, "continueProcess:Verification failed: expected %02X, got %02X\n", (time >> 0) & 0xFF, byte);
return -1;
}
return 0;
}
int terminateRealProcess(process_t* process, unsigned int time) {
// Write the 32-bit value to the process's standard input
unsigned int value = htonl(time);
if (write(process->pipes_in[1], &value, sizeof(value)) != sizeof(value)) {
perror("Termination:write - ");
return -1;
}
// Send SIGTERM signal to process
if (kill(process->pid, SIGTERM) < 0) {
perror("Termination:kill");
return -1;
}
// read from the process's standard output
char output[65];
if (read(process->pipes_out[0], output, sizeof(output) - 1) < 0) {
perror("Termination:read");
return -1;
}
// null-terminate the output and print it out
output[64] = '\0';
printFinishHash(time, process->name, output);
process->pid = -1;
return 0;
}