#include #include #include #include #include #include #include #include #include #include int _SHMID; tile_t *shmServerAt(); void setupServerShm() { _SHMID = getShmidServer(); _BOARD = shmServerAt(); for (int i = 0; i < _ROWS * _COLLUMS; i++) { _BOARD[i] = EMPTY; } } void setupClientShm() { printf(PCLIENT "Setting up shm\n"); _SHMID = getShmidClient(); _BOARD = shmClientAt(); } int getShmidClient() { return shmget(ftok(KEYFILE, SHMKEY), _ROWS * _COLLUMS * sizeof(tile_t), IPC_CREAT | S_IRUSR | S_IWUSR); } int getShmidServer() { key_t key = ftok(KEYFILE, SHMKEY); int shmid = shmget(key, _ROWS * _COLLUMS * sizeof(tile_t), IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); if (shmid == -1) { // if errno was set to EEXIST, that means the memory location is alredy allocated // the server fork and the child remove the memory if (errno == EEXIST) { char buf[100]; sprintf(buf, "The board alredy exit, I'll remove it now\n"); warningMsg(buf); pid_t pid = fork(); if (pid == 0) { char str_key[16]; sprintf(str_key, "0x%08x", key); char *vec[] = {"/bin/ipcrm", "-M", str_key, NULL}; if ((execv("/bin/ipcrm", vec)) == -1) { errExit("execv", "getShmidServer"); } } while (wait(0) == -1 && errno == EINTR); return getShmidServer(); } errExit("shmget", "getShmidServer"); } return shmid; } tile_t *shmServerAt() { tile_t *board = (tile_t *)shmat(_SHMID, NULL, 0); if (board == SHMERR) { errExit("shmat", "shmServerAt"); } return board; } tile_t * shmClientAt() { tile_t *board = (tile_t *)shmat(_SHMID, NULL, SHM_RDONLY); if (board == SHMERR) { errExit("shmat", "shmClientAt"); } return board; } void shmDt(void *shm_ptr) { if (shmdt(shm_ptr) == -1) { errExit("shmdt", "shmDt"); } } void shmServerRm(int shmid) { if (shmctl(shmid, IPC_RMID, NULL) == -1) { errExit("shmctl", "shmServerRm"); } }