Signal Handling and Message Queue Communication in C

Basic Signal Handling

#include <signal.h>
#include <unistd.h>
#include <stdio.h>

void signal_handler(int signum) {
    if (signum == SIGINT) {
        printf("User pressed CTRL + C\n");
    }
}

int main() {
    // Capture SIGINT signal
    if (signal(SIGINT, signal_handler) == SIG_ERR) {
        perror("signal setup failed");
        return -1;
    }

    while (1) {
        printf("Processing...\n");
        sleep(1);
    }
    return 0;
}

Cleaning Up Zombie Processes with SIGCHLD

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>

void cleanup_handler(int signum) {
    if (signum == SIGCHLD) {
        while (waitpid(-1, NULL, WNOHANG) > 0);
    }
}

int main() {
    // Set up SIGCHLD handler
    if (signal(SIGCHLD, cleanup_handler) == SIG_ERR) {
        perror("signal setup failed");
        return -1;
    }

    for (int i = 0; i < 10; i++) {
        if (fork() == 0) {
            sleep(1);
            _exit(EXIT_SUCCESS);
        }
    }

    while (1);
    return 0;
}

Siumlating Card Dealing with SIGALRM

#include <signal.h>
#include <unistd.h>
#include <stdio.h>

void deal_card(int signum) {
    if (signum == SIGALRM) {
        printf("System dealt you a random card\n");
        alarm(5);
    }
}

int main() {
    // Set up SIGALRM handler
    if (signal(SIGALRM, deal_card) == SIG_ERR) {
        perror("signal setup failed");
        return -1;
    }

    alarm(5);
    char input = 0;
    while (1) {
        scanf("%c", &input);
        getchar();
        printf("You played card: %c\n", input);
        alarm(5);
    }
    return 0;
}

Message Queue Implementation

Sender Process

#include <sys/msg.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <string.h>

struct message_buffer {
    long msg_type;
    char msg_text[1024];
};

#define MSG_TEXT_SIZE sizeof(struct message_buffer) - sizeof(long)

int main() {
    key_t queue_key;
    if ((queue_key = ftok("/", 'k')) == -1) {
        perror("ftok failed");
        return -1;
    }
    printf("ftok successful, key=%#x\n", queue_key);

    int msg_queue_id;
    if ((msg_queue_id = msgget(queue_key, IPC_CREAT | 0664)) == -1) {
        perror("msgget failed");
        return -1;
    }
    printf("msgget successful, queue_id=%d\n", msg_queue_id);

    struct message_buffer msg;
    while (1) {
        memset(msg.msg_text, 0, sizeof(msg.msg_text));

        printf("Enter message type: ");
        scanf("%ld", &msg.msg_type);
        getchar();
        printf("Enter message content: ");
        fgets(msg.msg_text, sizeof(msg.msg_text), stdin);
        msg.msg_text[strlen(msg.msg_text) - 1] = '\0';

        msgsnd(msg_queue_id, &msg, MSG_TEXT_SIZE, 0);
        printf("Message sent\n");

        if (strcmp(msg.msg_text, "quit") == 0)
            break;
    }
    return 0;
}

Receiver Process

#include <sys/msg.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <string.h>

struct message_buffer {
    long msg_type;
    char msg_text[1024];
};

#define MSG_TEXT_SIZE sizeof(struct message_buffer) - sizeof(long)

int main() {
    key_t queue_key;
    if ((queue_key = ftok("/", 'k')) == -1) {
        perror("ftok failed");
        return -1;
    }
    printf("ftok successful, key=%#x\n", queue_key);

    int msg_queue_id;
    if ((msg_queue_id = msgget(queue_key, IPC_CREAT | 0664)) == -1) {
        perror("msgget failed");
        return -1;
    }
    printf("msgget successful, queue_id=%d\n", msg_queue_id);

    struct message_buffer msg;
    while (1) {
        memset(msg.msg_text, 0, sizeof(msg.msg_text));

        msgrcv(msg_queue_id, &msg, MSG_TEXT_SIZE, 2, 0);
        printf("Received message: %s\n", msg.msg_text);

        if (strcmp(msg.msg_text, "quit") == 0)
            break;
    }
    return 0;
}

Bidirectional Comunication Example

#include <sys/msg.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

struct message_buffer {
    long msg_type;
    char msg_text[1024];
};

#define MSG_TEXT_SIZE sizeof(struct message_buffer) - sizeof(long)

int main() {
    key_t queue_key;
    if ((queue_key = ftok("/", 'k')) == -1) {
        perror("ftok failed");
        return -1;
    }
    printf("ftok successful, key=%#x\n", queue_key);

    int msg_queue_id;
    if ((msg_queue_id = msgget(queue_key, IPC_CREAT | 0664)) == -1) {
        perror("msgget failed");
        return -1;
    }
    printf("msgget successful, queue_id=%d\n", msg_queue_id);

    pid_t child_pid = fork();
    if (child_pid > 0) {
        // Parent process - sender
        struct message_buffer msg;
        while (1) {
            memset(msg.msg_text, 0, sizeof(msg.msg_text));
            printf("Enter message type: ");
            scanf("%ld", &msg.msg_type);
            getchar();
            printf("Enter message content: ");
            fgets(msg.msg_text, sizeof(msg.msg_text), stdin);
            msg.msg_text[strlen(msg.msg_text) - 1] = '\0';

            msgsnd(msg_queue_id, &msg, MSG_TEXT_SIZE, 0);
            printf("Message sent\n");

            if (strcmp(msg.msg_text, "quit") == 0)
                break;
        }
    } else if (child_pid == 0) {
        // Child process - receiver
        struct message_buffer msg;
        while (1) {
            memset(msg.msg_text, 0, sizeof(msg.msg_text));
            msgrcv(msg_queue_id, &msg, MSG_TEXT_SIZE, 1, 0);
            printf("Received: %s\n", msg.msg_text);

            if (strcmp(msg.msg_text, "quit") == 0)
                break;
        }
        _exit(EXIT_SUCCESS);
    } else {
        perror("fork failed");
        return -1;
    }
    return 0;
}

Tags: C signals Message Queues IPC POSIX

Posted on Sat, 11 Jul 2026 17:27:23 +0000 by Phoenix~Fire