Signal

Given the following source code:

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

void handler(int sig) {
    printf("Received Signal: %d\n", sig);
    signal(SIGINT, SIG_DFL);
}

int main() {
    signal(SIGINT, handler);

    while (1);
}
  1. Compile and launch the program.
  2. What is happening when typing Ctrl+C ? Explain.
  3. Relaunch the program in background using the & modifier and send the SIGINT signal to the process. (Check out the man pages for kill command)

Pipe

Given the following source code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

static void child_process(const int *pipe_fd) {
    char character = 0;
    char buffer[200];
    int index = 0;
    printf("Child process attempts to read from pipe...\n");
    do {
        if (read(pipe_fd[0], &character, 1) == 1) {
            buffer[index] = character;
            index++;
            printf("Read character: %c\n", character);
        }
    } while (character != 'q');
    buffer[index] = 0;
    printf("Read message: %s\n", buffer);
}

static void parent_process(const int *pipe_fd) {
    char *message = "I am your father!q";
    write(pipe_fd[1], message, strlen(message));
    printf("Parent process sent message to child process...\n");
}

int main(int argc, char *argv[]) {

    int pipe_fd[2];
    pipe(pipe_fd);

    int pid = fork();
    if (pid > 0) {
        parent_process(pipe_fd);
        while (getchar());

    } else if (pid == 0) {
        child_process(pipe_fd);
    } else {
        perror("Unable to fork process...");
    }

    return EXIT_SUCCESS;
}
  1. What is the result of the pipe system call on the pipe_fd variable ?
  2. What is the aim of the q char in the message sent by the father to the child ?
  3. Modify the program so that the child respond to its father.

Shared Memory

Given the following source code files:

shared_memory.h

#ifndef OPERATING_SYSTEM_TRAINING_4_SHARED_MEMORY_H
#define OPERATING_SYSTEM_TRAINING_4_SHARED_MEMORY_H

#define KEY 12345

typedef struct {
    int a;
    double b;
} shared_structure;
 
#endif

first_process.c

#include <sys/types.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


#include "shared_memory.h"

int main() {
    
    int mem_ID = shmget(KEY, sizeof(shared_structure), 0666 | IPC_CREAT);
    if (mem_ID < 0) {
        perror("shmget");
        return EXIT_FAILURE;
    }

    shared_structure *shared_memory = shmat(mem_ID, NULL, 0);
    if (shared_memory == (void *) -1) {
        perror("shmat");
        return EXIT_FAILURE;
    }

    shared_memory->a = 2;
    shared_memory->b = 2.6544;

    for (int i = 0; i < 20; i++) {
        shared_memory->a = i;
        printf("Read data from shared memory: data.a = %d, data.b = %lf\n", shared_memory->a, shared_memory->b);
        sleep(1);
    }
    shmdt(shared_memory);

    return 0;
}

second_process.c

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "shared_memory.h"

int main() {
    int mem_ID = shmget(KEY, sizeof(shared_structure), 0444);
    if (mem_ID < 0) {
        perror("shmget");
        return EXIT_FAILURE;
    }

    shared_structure *shared_memory = shmat(mem_ID, NULL, 0);
    if (shared_memory == (void *) -1) {
        perror("shmat");
        return EXIT_FAILURE;
    }

    for (int i = 0; i < 20; i++) {
        printf("Read data from shared memory: data.a = %d, data.b = %lf\n", shared_memory->a, shared_memory->b);
        sleep(1);
    }

    shmdt(shared_memory);

    return EXIT_SUCCESS;
}

Questions

  1. Compile and execute BOTH programs.
  2. Check that second program is outputting changed variables. Explain.
  3. What are the purposes of the following functions: shmget(), shmat(), shmdt()
  4. Use ipcs to display information on the shared memory. Why is the shared memory still present ?
  5. Create a program to delete the previously created shared memory (use the shmctl man pages).