00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "defs.h"
00022 #include "uem.h"
00023 #include <sys/msg.h>
00024 #include <sys/sem.h>
00025 #ifdef POSIX_IPC
00026 #include <mqueue.h>
00027 #include <semaphore.h>
00028 #endif
00029
00030 #define SYSTEMV_MSG_NAME "/tmp/uemtst_systemv_msg"
00031 #define POSIX_MSG_NAME "/uemtst_posix_msg"
00032 #define POSIX_SEM_NAME "/uemtst_posix_sem"
00033 #define MSG_SIZE 100
00034 #define TEST_SIGNAL SIGHUP
00035
00036 static void handler_nothing(int signum)
00037 {
00038 printf("Got %d in handler\n", signum);
00039 }
00040
00041 static bool setup_signal(void)
00042 {
00043 pid_t pid;
00044
00045 if ((pid = fork()) == 0) {
00046 int i;
00047
00048 srand(getpid());
00049 for (i = 0; i < 10; i++) {
00050 sleep(rand() % 9 + 1);
00051 ec_neg1( kill(getppid(), TEST_SIGNAL) )
00052 }
00053 exit(EXIT_SUCCESS);
00054 }
00055 ec_false( uem_register_signal(TEST_SIGNAL, NULL) )
00056 return true;
00057
00058 EC_CLEANUP_BGN
00059 if (pid == 0)
00060 exit(EXIT_FAILURE);
00061 else
00062 return false;
00063 EC_CLEANUP_END
00064 }
00065
00066 static bool setup_systemv_sem(void)
00067 {
00068 int semid;
00069 key_t key;
00070 pid_t pid;
00071 struct sembuf sop;
00072
00073 ec_neg1( key = ftok(SYSTEMV_MSG_NAME, 2) )
00074 if ((semid = semget(key, 1, PERM_FILE)) != -1)
00075 (void)semctl(semid, 0, IPC_RMID, NULL);
00076 ec_neg1( semid = semget(key, 1, IPC_CREAT | PERM_FILE) )
00077 if ((pid = fork()) == 0) {
00078 int i;
00079
00080 sop.sem_num = 0;
00081 sop.sem_op = 1;
00082 sop.sem_flg = 0;
00083 srand(getpid());
00084 for (i = 0; i < 10; i++) {
00085 sleep(rand() % 9 + 1);
00086 ec_neg1( semop(semid, &sop, 1) )
00087 }
00088 exit(EXIT_SUCCESS);
00089 }
00090 sop.sem_num = 0;
00091 sop.sem_op = -1;
00092 sop.sem_flg = 0;
00093 ec_false( uem_register_svsem(semid, &sop, 1, NULL) )
00094 return true;
00095
00096 EC_CLEANUP_BGN
00097 if (pid == 0)
00098 exit(EXIT_FAILURE);
00099 else
00100 return false;
00101 EC_CLEANUP_END
00102 }
00103
00104 static bool setup_systemv_msg(void)
00105 {
00106 int mqid;
00107 key_t key;
00108 pid_t pid;
00109
00110 ec_neg1( key = ftok(SYSTEMV_MSG_NAME, 1) )
00111 if ((mqid = msgget(key, PERM_FILE)) != -1)
00112 (void)msgctl(mqid, IPC_RMID, NULL);
00113 ec_neg1( mqid = msgget(key, IPC_CREAT | PERM_FILE) )
00114 if ((pid = fork()) == 0) {
00115 int i;
00116 struct {
00117 long mtype;
00118 char mtext[MSG_SIZE - sizeof(long)];
00119 } msg;
00120
00121 msg.mtype = 1;
00122 srand(getpid());
00123 for (i = 0; i < 10; i++) {
00124 sleep(rand() % 9 + 1);
00125 snprintf(msg.mtext, sizeof(msg.mtext), "System V msg #%d", i);
00126 ec_neg1( msgsnd(mqid, &msg, sizeof(msg.mtext), 0) )
00127 }
00128 exit(EXIT_SUCCESS);
00129 }
00130 ec_false( uem_register_svmsg(mqid, MSG_SIZE, NULL) )
00131 return true;
00132
00133 EC_CLEANUP_BGN
00134 if (pid == 0)
00135 exit(EXIT_FAILURE);
00136 else
00137 return false;
00138 EC_CLEANUP_END
00139 }
00140
00141 static bool setup_posix_sem(void)
00142 {
00143 #ifdef POSIX_IPC
00144 sem_t *sem;
00145 pid_t pid;
00146
00147 if ((sem = sem_open(POSIX_SEM_NAME, O_RDWR | O_CREAT,
00148 PERM_FILE, NULL)) == SEM_FAILED)
00149 EC_FAIL
00150 if ((pid = fork()) == 0) {
00151 int i;
00152
00153 srand(getpid());
00154 for (i = 0; i < 10; i++) {
00155 sleep(rand() % 9 + 1);
00156 ec_neg1( sem_post(sem) )
00157 }
00158 exit(EXIT_SUCCESS);
00159 }
00160 ec_false( uem_register_pxsem(sem, NULL) )
00161 return true;
00162
00163 EC_CLEANUP_BGN
00164 if (pid == 0)
00165 exit(EXIT_FAILURE);
00166 else
00167 return false;
00168 EC_CLEANUP_END
00169 #else
00170 return true;
00171 #endif
00172 }
00173
00174 static bool setup_posix_msg(void)
00175 {
00176 #ifdef POSIX_IPC
00177 mqd_t mqd;
00178 pid_t pid;
00179
00180 ec_neg1( mqd = mq_open(POSIX_MSG_NAME, O_RDWR | O_CREAT,
00181 PERM_FILE, NULL) )
00182 if ((pid = fork()) == 0) {
00183 int i;
00184 char msg[MSG_SIZE];
00185
00186 srand(getpid());
00187 for (i = 0; i < 10; i++) {
00188 sleep(rand() % 9 + 1);
00189 snprintf(msg, sizeof(msg), "POSIX msg #%d", i);
00190 ec_neg1( mq_send(mqd, msg, MSG_SIZE, 0) )
00191 }
00192 exit(EXIT_SUCCESS);
00193 }
00194 ec_false( uem_register_pxmsg(mqd, NULL) )
00195 return true;
00196
00197 EC_CLEANUP_BGN
00198 if (pid == 0)
00199 exit(EXIT_FAILURE);
00200 else
00201 return false;
00202 EC_CLEANUP_END
00203 #else
00204 return true;
00205 #endif
00206 }
00207
00208 static bool setup_process(void)
00209 {
00210 pid_t pid;
00211
00212 if ((pid = fork()) == 0) {
00213 sleep(3);
00214 exit(1234);
00215 }
00216 ec_false( uem_register_process(pid, NULL) )
00217 return true;
00218
00219 EC_CLEANUP_BGN
00220 if (pid == 0)
00221 exit(EXIT_FAILURE);
00222 else
00223 return false;
00224 EC_CLEANUP_END
00225 }
00226
00227 static bool setup_fdset(void)
00228 {
00229 pid_t pid;
00230 int pfd1[2], pfd2[2];
00231 fd_set fdset;
00232
00233 ec_neg1( signal(SIGPIPE, SIG_IGN) )
00234 ec_neg1( pipe(pfd1) )
00235 ec_neg1( pipe(pfd2) )
00236 if ((pid = fork()) == 0) {
00237 int i;
00238
00239 srand(getpid());
00240 ec_neg1( close(pfd1[0]) )
00241 ec_neg1( close(pfd2[1]) )
00242 for (i = 0; i < 10; i++) {
00243 int x;
00244
00245 sleep(rand() % 9 + 1);
00246 ec_neg1( write(pfd1[1], &i, sizeof(i)) )
00247 ec_neg1( read(pfd2[0], &x, sizeof(x)) )
00248 }
00249 ec_neg1( close(pfd1[1]) )
00250 ec_neg1( close(pfd2[0]) )
00251 exit(EXIT_SUCCESS);
00252 }
00253 ec_neg1( close(pfd1[1]) )
00254 ec_neg1( close(pfd2[0]) )
00255 while (true) {
00256 setblock(pfd2[1], false);
00257 if (write(pfd2[1], "abcde", 5) == -1) {
00258 if (errno == EAGAIN)
00259 break;
00260 else
00261 EC_FAIL
00262 }
00263 }
00264 FD_ZERO(&fdset);
00265 FD_SET(pfd1[0], &fdset);
00266 ec_false( uem_register_fdset(pfd1[0] + 1, &fdset, UEM_FD_READ, NULL) )
00267 FD_ZERO(&fdset);
00268 FD_SET(pfd2[1], &fdset);
00269 ec_false( uem_register_fdset(pfd2[1] + 1, &fdset, UEM_FD_WRITE, NULL) )
00270 return true;
00271
00272 EC_CLEANUP_BGN
00273 if (pid == 0)
00274 exit(EXIT_FAILURE);
00275 else
00276 return false;
00277 EC_CLEANUP_END
00278 }
00279
00280 int main(void)
00281 {
00282 struct uem_event *e;
00283
00284 (void)close(open(SYSTEMV_MSG_NAME, O_WRONLY | O_CREAT, 0));
00285 ec_false( uem_bgn() )
00286 ec_false( setup_systemv_msg() )
00287 ec_false( setup_systemv_sem() )
00288 ec_false( setup_posix_msg() )
00289 ec_false( setup_posix_sem() )
00290 ec_false( setup_signal() )
00291 ec_false( setup_process() )
00292 ec_false( setup_fdset() )
00293 ec_false( uem_register_heartbeat(3 * 1000000, NULL) )
00294 while (true) {
00295 ec_null( e = uem_wait() )
00296 if (e->ue_errno != 0)
00297 printf("***** EVENT ERROR: (type = %d) -- %s\n",
00298 e->ue_reg->ur_type, strerror(e->ue_errno));
00299 else
00300 switch (e->ue_reg->ur_type) {
00301 case UEM_SVMSG:
00302 {
00303 struct msg {
00304 long mtype;
00305 char mtext[1];
00306 };
00307 printf("Got SysV message: %s\n",
00308 ((struct msg *)e->ue_buf)->mtext);
00309 }
00310 break;
00311 case UEM_PXMSG:
00312 printf("Got POSIX message: %s\n", (char *)e->ue_buf);
00313 break;
00314 case UEM_SVSEM:
00315 printf("Got SysV semaphore\n");
00316 break;
00317 case UEM_PXSEM:
00318 printf("Got POSIX semaphore\n");
00319 break;
00320 case UEM_FD_READ:
00321 {
00322 int n;
00323 ssize_t nread;
00324
00325 ec_neg1( nread = read(e->ue_result, &n, sizeof(n)) )
00326 if (nread == 0) {
00327 ec_neg1( close(e->ue_result) )
00328 ec_false( uem_unregister(e) )
00329 }
00330 else
00331 printf("Got fd -- read %d\n", n);
00332 }
00333 break;
00334 case UEM_FD_WRITE:
00335 {
00336 if (write(e->ue_result, "a", 1) == -1) {
00337 if (errno == EPIPE) {
00338 printf("EPIPE on pipe... unregistering\n");
00339 ec_neg1( close(e->ue_result) )
00340 ec_false( uem_unregister(e) )
00341 }
00342 else
00343 EC_FAIL
00344 }
00345 else
00346 printf("Got fd -- write\n");
00347 }
00348 break;
00349 case UEM_FD_ERROR:
00350 break;
00351 case UEM_SIG:
00352 printf("Got signal: %d\n", (int)e->ue_result);
00353 break;
00354 case UEM_PROCESS:
00355 printf("Got process status: %ld\n", (long)e->ue_result);
00356 break;
00357 case UEM_HEARTBEAT:
00358 printf("Got heartbeat\n");
00359 break;
00360 case UEM_NONE:
00361 default:
00362 printf("Strange event type: %d\n", e->ue_reg->ur_type);
00363 break;
00364 }
00365 uem_free(e);
00366 }
00367 ec_false( uem_end() )
00368 exit(EXIT_SUCCESS);
00369
00370 EC_CLEANUP_BGN
00371 exit(EXIT_FAILURE);
00372 EC_CLEANUP_END
00373 }