SHARED MEMORY – STRING CONCATENATION & CASE FLIPPING
1. AIM
To demonstrate interprocess communication using System V Shared Memory, where:

The first process writes three strings to shared memory.

The second process concatenates the strings with spaces and writes the result back.

The first process then reads the concatenated string and prints it in flipped case.

2. THEORY
Shared memory is the fastest IPC mechanism in UNIX/Linux because multiple processes can access the same memory segment directly.
System calls used:

System Call	Purpose
shmget()	Create/get shared memory segment
shmat()	Attach shared memory to process
shmdt()	Detach shared memory
shmctl()	Control operations (remove segment)
Shared memory requires synchronization, but for simple sequential read/write, explicit synchronization is often omitted for simplicity in lab experiments.

3. ALGORITHM
Process 1 (Sender & Receiver)
Create shared memory using shmget().

Attach it using shmat().

Read three strings from user.

Write them into shared memory.

Wait for Process 2 to update the concatenated string.

Read the concatenated string.

Flip the case of each alphabet.

Print the flipped-case output.

Remove the shared memory segment.

Process 2 (Concatenator)
Access the same shared memory using shmget().

Attach it using shmat().

Read the three strings from shared memory.

Concatenate strings with spaces.

Write the concatenated string back to shared memory.

4. PROGRAMS
File 1: process1.c (Process 1)
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SHMKEY 9999

struct data {
    char s1[50];
    char s2[50];
    char s3[50];
    char result[200];
};

void flipCase(char *str) {
    for (int i = 0; str[i] != '\0'; i++) {
        if (isupper(str[i]))
            str[i] = tolower(str[i]);
        else if (islower(str[i]))
            str[i] = toupper(str[i]);
    }
}

int main() {
    int shmid;
    struct data *d;

    shmid = shmget(SHMKEY, sizeof(struct data), IPC_CREAT | 0666);
    d = (struct data *) shmat(shmid, NULL, 0);

    printf("Enter first string: ");
    scanf("%s", d->s1);

    printf("Enter second string: ");
    scanf("%s", d->s2);

    printf("Enter third string: ");
    scanf("%s", d->s3);

    printf("\nWaiting for Process 2 to concatenate...\n");

    // Wait until process2 writes result (simple wait)
    sleep(20);

    flipCase(d->result);

    printf("\nFinal Output (Flipped Case): %s\n", d->result);

    shmdt(d);
    shmctl(shmid, IPC_RMID, NULL);

    return 0;
}
File 2: process2.c (Process 2)
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SHMKEY 9999

struct data {
    char s1[50];
    char s2[50];
    char s3[50];
    char result[200];
};

int main() {
    int shmid;
    struct data *d;

    shmid = shmget(SHMKEY, sizeof(struct data), IPC_CREAT | 0666);
    d = (struct data *) shmat(shmid, NULL, 0);

    sprintf(d->result, "%s %s %s", d->s1, d->s2, d->s3);

    printf("Process 2: Concatenated string written to shared memory.\n");

    shmdt(d);
    return 0;
}
5. COMPILATION & EXECUTION
Terminal 1 (Run Process 1 first):
gcc process1.c -o p1
./p1
Terminal 2 (Run Process 2):
gcc process2.c -o p2
./p2
6. SAMPLE OUTPUT
Process 1
Enter first string: Hello
Enter second string: S4
Enter third string: Students

Waiting for Process 2 to concatenate...

Final Output (Flipped Case): hELLO s4 sTUDENTS
Process 2
Process 2: Concatenated string written to shared memory.
7. RESULT
Thus, interprocess communication using Shared Memory was successfully implemented.
The first process passed strings to the second, which concatenated them, and the first process printed the concatenated string in flipped case.
