00001
00002
00003
00004 #include <sys/types.h>
00005 #include <sys/ipc.h>
00006 #include <sys/shm.h>
00007 #include <sys/sem.h>
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #include "alloc.h"
00012
00013 #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
00014
00015 #else
00016
00017 union semun {
00018 int val;
00019 struct semid_ds *buf;
00020 unsigned short int *array;
00021 struct seminfo *__buf;
00022 };
00023 #endif
00024
00025 inline int CreateSem(int key)
00026 {
00027 int semid;
00028 union semun arg;
00029
00030
00031 if ((semid = semget((key_t) key, 1, 0660 | IPC_CREAT)) == -1) {
00032 perror("semget");
00033 exit(1);
00034 }
00035
00036
00037 arg.val = 1;
00038 if (semctl(semid, 0, SETVAL, arg) == -1) {
00039 perror("semctl");
00040 exit(1);
00041 }
00042
00043 return 0;
00044 }
00045
00046 inline int ShmSemLock(int key)
00047 {
00048 int semid;
00049 struct sembuf sb = {0, -1, 0};
00050
00051
00052 if ((semid = semget(key, 1, 0)) == -1) {
00053 perror("semget");
00054 exit(1);
00055 }
00056
00057 if (semop(semid, &sb, 1) == -1) {
00058 perror("semop");
00059 exit(1);
00060 }
00061
00062 return 0;
00063 }
00064
00065 inline int ShmSemUnlock(int key)
00066 {
00067 int semid;
00068 struct sembuf sb = {0, 1, 0};
00069
00070
00071 if ((semid = semget(key, 1, 0)) == -1) {
00072 perror("semget");
00073 exit(1);
00074 }
00075
00076 if (semop(semid, &sb, 1) == -1) {
00077 perror("semop");
00078 exit(1);
00079 }
00080
00081 return 0;
00082 }
00083
00084 inline void DeleteShm(int key)
00085 {
00086 int shmid;
00087 unsigned char *shm;
00088
00089 if ((shmid = shmget((key_t) key, sizeof(int), IPC_CREAT | 0660)) < 0) {
00090 perror("shmget");
00091 exit(1);
00092 }
00093 shmctl(shmid, IPC_RMID, NULL);
00094 }
00095
00096 inline void PutIntoShm(int key, unsigned char *data, int size, int lockkey = 0)
00097 {
00098 int shmid;
00099 unsigned char *shm;
00100 int totsize = size+sizeof(int);
00101
00102 if (lockkey)
00103 ShmSemLock(lockkey);
00104
00105 DeleteShm(key);
00106
00107 if ((shmid = shmget((key_t) key, totsize, IPC_CREAT | 0660)) < 0) {
00108 perror("shmget");
00109 exit(1);
00110 }
00111 if ((shm = (unsigned char *) shmat(shmid, NULL, 0)) == (unsigned char *) -1) {
00112 perror("shmat");
00113 exit(1);
00114 }
00115
00116 memcpy(shm, &size, sizeof(int));
00117 memcpy(shm+sizeof(int), data, size);
00118
00119 shmdt((char *) shm);
00120
00121 if (lockkey)
00122 ShmSemUnlock(lockkey);
00123 }
00124
00125 inline void GetFromShm(int key, unsigned char **dataptr, int *size, int lockkey = 0)
00126 {
00127 int shmid;
00128 unsigned char *shm;
00129
00130 if (lockkey)
00131 ShmSemLock(lockkey);
00132
00133 if ((shmid = shmget((key_t) key, sizeof(int), IPC_CREAT | 0660)) < 0) {
00134 perror("shmget");
00135 exit(1);
00136 }
00137 if ((shm = (unsigned char *) shmat(shmid, NULL, SHM_RDONLY)) == (unsigned char *) -1) {
00138 perror("shmat");
00139 exit(1);
00140 }
00141
00142 memcpy(size, shm, sizeof(int));
00143
00144 shmdt((char *) shm);
00145
00146 if ((shmid = shmget((key_t) key, *size+sizeof(int), IPC_CREAT | 0660)) < 0) {
00147 perror("shmget");
00148 exit(1);
00149 }
00150 if ((shm = (unsigned char *) shmat(shmid, NULL, 0)) == (unsigned char *) -1) {
00151 perror("shmat");
00152 exit(1);
00153 }
00154
00155 unsigned char *data = NULL;
00156 ALLOC1D(&data, *size);
00157 *dataptr = data;
00158 memcpy(data, shm+sizeof(int), *size);
00159
00160 shmdt((char *) shm);
00161
00162 if (lockkey)
00163 ShmSemUnlock(lockkey);
00164 }
00165
00166 inline void DeleteSem(int key)
00167 {
00168 int semid;
00169 union semun arg;
00170
00171
00172 if ((semid = semget((key_t) key, 1, 0)) == -1) {
00173 perror("semget");
00174 exit(1);
00175 }
00176
00177
00178 if (semctl(semid, 0, IPC_RMID, arg) == -1) {
00179 perror("semctl");
00180 exit(1);
00181 }
00182 }
00183