-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
191 lines (153 loc) · 4.34 KB
/
Copy pathmain.c
File metadata and controls
191 lines (153 loc) · 4.34 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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// Jade Thompson, jet475
// Systems Programming, due 4/30/2023
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <time.h>
#include "semun.h"
#include "binary_sem.h"
#define OBJ_PERMS (S_IRUSR | S_IWUSR)
// shared memory segment -- stores number of pairs and the actual pairs
struct seg{
int randBlocks;
int blocks[20][2];
};
int checkError(int val, const char *msg){
if (val == -1){
perror(msg);
exit(EXIT_FAILURE);
}
return val;
}
int childStuff(struct seg* smap, int semid, int shmid){
int randLetter, randNum;
// attach shared memory
smap = shmat(shmid, NULL, 0);
if (smap == (void *) -1) {
checkError(-1, "shmat");
}
// seed rand()
srand(time(NULL));
checkError(reserveSem(semid, 0), "reserve child");
// generate number of pairs/blocks
smap->randBlocks = (rand() % 11) + 30;
// generate pairs/blocks
for (int i = 0; i < smap->randBlocks; i++){
randLetter = (rand() % 26) + 97;
randNum = (rand() % 9) + 2;
smap->blocks[i][0] = randNum;
smap->blocks[i][1] = randLetter;
}
checkError(releaseSem(semid, 1), "release parent");
checkError(reserveSem(semid, 0), "reserve child");
//detach memory
checkError(shmdt(smap), "shmdt in child");
checkError(releaseSem(semid, 1), "release parent");
return 0;
}
int parentStuff(struct seg* smap, int semid, int shmid){
int width, color;
int cnt = 0;
int printed = 0;
// attach shared memory
smap = shmat(shmid, NULL, 0);
if (smap == (void *) -1) {
checkError(-1, "shmat");
}
checkError(reserveSem(semid, 1), "reserve parent");
// seed rand()
srand(time(NULL));
// generate width of output (30-40)
width = (rand() % 11) + 30;
// uncomment below if you wanna see the pairs and stuff
// printf("Each line has %d characters.\n\n", width);
// printf("Printing %d count-character pairs:\n", smap->randBlocks);
// for (int i = 0; i < smap->randBlocks; i++){
// printf("(%d, %c) ", smap->blocks[i][0], smap->blocks[i][1]);
// }
// printf("\n\n");
// print the top border
printf("+");
for (int i = 0; i < width; i++){
printf("-");
}
printf("+\n|");
// print characters
for (int i = 0; i < smap->randBlocks; i++){
color = rand() % 7 + 31;
for (int j = 0; j < smap->blocks[i][0]; j++){
// using ansi color codes
printf("\e[0;%dm", color);
printf("%c", smap->blocks[i][1]);
printf("\e[0m");
printed++;
// check if width has been reached
if (printed == width){
printf("|\n|");
printed = 0;
}
}
cnt++;
// check if all characters are printed
if (cnt == smap->randBlocks){
// add spaces if necessary, finish row
for (int i = 0; i < width-printed; i++){
printf(" ");
}
printf("|\n");
}
}
// print the bottom border
printf("+");
for (int i = 0; i < width; i++){
printf("-");
}
printf("+\n");
checkError(releaseSem(semid, 0), "release child");
checkError(reserveSem(semid, 1), "reserve parent");
// detach memory
checkError(shmdt(smap), "shmdt");
}
/* Problem 7 -- implement function main */
int main(int argc, char *argv[])
{
struct seg *smap;
union semun unSem;
key_t semKey, shmKey;
int semid, shmid, blocks;
pid_t pid;
// set keys for semaphore set and shared memory
semKey = IPC_PRIVATE;
shmKey = IPC_PRIVATE;
// generate semaphore set
semid = checkError(semget(semKey, 2, IPC_CREAT| OBJ_PERMS), "semget");
// initialize child to available, parent to in use
checkError(initSemAvailable(semid, 0), "initSemAvailable"); //child
checkError(initSemInUse(semid, 1), "initSemInUse"); //parent
// generate shared memory
shmid = checkError(shmget(shmKey, sizeof(struct seg), IPC_CREAT | OBJ_PERMS), "shmget");
// create child process, check for error
pid = fork();
if (pid == -1){
perror("fork");
exit(EXIT_FAILURE);
}
// if in child...
if (pid == 0){
checkError(childStuff(smap, semid, shmid), "child function");
return 0;
}
// else if in parent...
else{
checkError(parentStuff(smap, semid, shmid), "parent function");
}
// delete semaphore set and shared memory
checkError(semctl(semid, 0, IPC_RMID), "semctl");
checkError(shmctl(shmid, 0, IPC_RMID), "shmctl");
exit(EXIT_SUCCESS);
}