©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

c7/uemtst.c

Go to the documentation of this file.
00001 /*
00002     Unified Event Manager test program
00003     AUP2, Sec. 5.18.2
00004 
00005     Copyright 2003 by Marc J. Rochkind. All rights reserved.
00006     May be copied only for purposes and under conditions described
00007     on the Web page www.basepath.com/aup/copyright.htm.
00008 
00009     The Example Files are provided "as is," without any warranty;
00010     without even the implied warranty of merchantability or fitness
00011     for a particular purpose. The author and his publisher are not
00012     responsible for any damages, direct or incidental, resulting
00013     from the use or non-use of these Example Files.
00014 
00015     The Example Files may contain defects, and some contain deliberate
00016     coding mistakes that were included for educational reasons.
00017     You are responsible for determining if and how the Example Files
00018     are to be used.
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) /* note strange error return */
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 }

Generated on Fri Apr 23 10:57:01 2004 for AUP2 Example Source by doxygen 1.3.1