#include #include #include #include #include #include #include #include struct data { atomic_bool initialized; struct { sem_t sem; char text[256]; } item[5]; } *data; int main(int argc, char **argv) { if (argc < 2 || argc > 3) { printf("Usage:\n" " %s prints from item \n" " %s puts to item \n" " %s copies to item the text from item \n", argv[0], argv[0], argv[0]); return 1; } int fd = shm_open("/fiveItems", O_RDWR | O_CREAT | O_EXCL, 0666); char createSucceeded = (fd != -1); if (fd == -1) fd = shm_open("/fiveItems", O_RDWR, 0666); if (fd == -1) { perror("shm_open"); exit(1); } ftruncate(fd, sizeof(struct data)); data = mmap(NULL, sizeof(struct data), PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0); if (createSucceeded) { for (int i = 0; i < 5; ++i) sem_init(&data->item[i].sem, 1, 1); data->initialized = 1; } else while (!data->initialized); int argOne = atoi(argv[1]); if (argOne >= 5 || argOne < 0) return 1; if (argc == 2) { // print an item sem_wait(&data->item[argOne].sem); printf("%s\n", data->item[argOne].text); sem_post(&data->item[argOne].sem); return 0; } char *e; int argTwo = strtol(argv[2], &e, 10); if (*e == 0 && argTwo < 5 && argTwo >= 0 && argOne != argTwo) { // copy item to item sem_wait(&data->item[argOne].sem); sem_wait(&data->item[argTwo].sem); memcpy(data->item[argOne].text, data->item[argTwo].text, sizeof(data->item[argOne].text)); sem_post(&data->item[argTwo].sem); sem_post(&data->item[argOne].sem); } else { // assign new value sem_wait(&data->item[argOne].sem); memset(data->item[argOne].text, 0, sizeof(data->item[argOne].text)); strncpy(data->item[argOne].text, argv[2], sizeof(data->item[argOne].text) - 1); sem_post(&data->item[argOne].sem); } return 0; }