This next section of code is the mainline. It's responsible for:

Notice the check against the return value from MsgReceive(); a zero indicates it's a pulse (and we don't do any strong checking to ensure that it's our pulse), a non-zero indicates it's a message. The processing of the pulse or message is done by gotAPulse() and gotAMessage().

main (void)                 // ignore command-line arguments
    int rcvid;              // process ID of the sender
    MessageT msg;           // the message itself

    if ((chid = ChannelCreate (0)) == -1) {
        fprintf (stderr, "%s:  couldn't create channel!\n",
        perror (NULL);
        exit (EXIT_FAILURE);

    // set up the pulse and timer
    setupPulseAndTimer ();

    // receive messages
    for (;;) {
        rcvid = MsgReceive (chid, &msg, sizeof (msg), NULL);

        // determine who the message came from
        if (rcvid == 0) {
            // production code should check "code" field...
            gotAPulse ();
        } else {
            gotAMessage (rcvid, &msg.msg);

    // you'll never get here
    return (EXIT_SUCCESS);