-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.c
More file actions
101 lines (84 loc) · 2.82 KB
/
Copy pathapp.c
File metadata and controls
101 lines (84 loc) · 2.82 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
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#define MAX_GROUPS 30
#define MAX_MESSAGE_LENGTH 256
typedef struct {
long mtype;
int group;
} Message;
typedef struct {
long mtype;
int user;
char mtext[MAX_MESSAGE_LENGTH];
int violations;
int grp_id;
int action;
int terminator;
} ModeratorMessage;
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <test_case_number>\n", argv[0]);
return EXIT_FAILURE;
}
// Construct path to input.txt inside the testcase folder.
char input_file[256];
snprintf(input_file, sizeof(input_file), "testcase_%s/input.txt", argv[1]);
FILE *file = fopen(input_file, "r");
if (!file) {
perror("Error opening input.txt");
return EXIT_FAILURE;
}
int num_groups;
int val_msgq_key;
int app_msgq_key;
int mod_msgq_key;
int violation_threshold;
if(fscanf(file, "%d %d %d %d %d", &num_groups, &val_msgq_key, &app_msgq_key, &mod_msgq_key, &violation_threshold) != 5){
fprintf(stderr, "Error reading input.txt\n");
fclose(file);
return EXIT_FAILURE;
}
// Read the group file paths.
char group_files[MAX_GROUPS][256];
for (int i = 0; i < num_groups; i++) {
fscanf(file, "%s", group_files[i]);
}
fclose(file);
printf("App: Using message queue key: %d (Group ↔ App)\n", app_msgq_key);
// Create (or connect to) the message queue for group termination (communication with app)
int msgq_id = msgget(app_msgq_key, IPC_CREAT | 0666);
if (msgq_id == -1) {
perror("msgget failed");
return EXIT_FAILURE;
}
// For each group, construct its full file path (prepend the testcase folder)
pid_t pids[MAX_GROUPS];
for (int i = 0; i < num_groups; i++) {
char full_path[512]; // Increased size to avoid truncation
snprintf(full_path, sizeof(full_path), "testcase_%s/%s", argv[1], group_files[i]);
if ((pids[i] = fork()) == 0) {
printf("Executing: ./group.out %s %s\n", argv[1], full_path);
execl("./group.out", "group.out", argv[1], full_path, NULL);
perror("execl failed");
exit(EXIT_FAILURE);
}
}
// Wait for group termination messages
int terminated_groups = 0;
Message msg;
while (terminated_groups < num_groups) {
if (msgrcv(msgq_id, &msg, sizeof(Message) - sizeof(long), 0, 0) > 0) {
printf("All users terminated. Exiting group process %d.\n", msg.group);
terminated_groups++;
}
}
// Cleanup the app↔group message queue
msgctl(msgq_id, IPC_RMID, NULL);
return EXIT_SUCCESS;
}