Skip to content

Instantly share code, notes, and snippets.

@alexlnkp
Last active November 19, 2024 17:48
Show Gist options
  • Save alexlnkp/d3094cc4c3089724ebb9c30631ad7b80 to your computer and use it in GitHub Desktop.
Save alexlnkp/d3094cc4c3089724ebb9c30631ad7b80 to your computer and use it in GitHub Desktop.
A (bad) way of making two programs communicate, without using sockets and whatnot
This is a simple showcase of how to make two different programs communicate in pure C without using sockets.
This is done using shared memory segments accessed using a unique key shared between two programs. No other program has access to this shared memory segment.
You can think of it as an arena allocated space for TWO programs at once! Isn't that cool???
Now, here are some concerns addressed:
- Is this secure? Not in the slightest!
- Is this fun to play with? Heck yeah!!
To build this example, run this command:
$ cc -o secwin second.c && cc -o mainwin main.c
Then, to test this thing out, run ./mainwin! It'll start incrementing the counter on its own, even without the other program running (which can be mitigated by
establishing a connection between two programs via a handshake of sorts, keeping eachother at a feedback loop, waiting for one another)
Then, open a separate terminal and run ./secwin! It'll echo the same counter values modified by the main.c!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include "shared_data.h"
/* yes those are global vars, fight me */
struct SharedData *data;
int shmid;
void cleanup() {
if (data) {
pthread_mutex_destroy(&data->mutex);
shmdt(data); /* detach from shared memory */
shmctl(shmid, IPC_RMID, NULL); /* remove shared memory */
}
}
void signal_handler(int signum) {
cleanup();
exit(signum);
}
int main() {
/* setup signal handling for mutex and shmdt */
signal(SIGINT, signal_handler);
/* create a unique key for the shared memory */
key_t key = ftok("shmfile", 65); /* create a unique key */
shmid = shmget(key, sizeof(struct SharedData), 0666 | IPC_CREAT); /* create shared memory */
/* attach to the shared memory */
data = shmat(shmid, NULL, 0);
/* init shared data */
data->counter = 0;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&data->mutex, &attr);
while (1) {
/* put a lock before modifying */
pthread_mutex_lock(&data->mutex); {
data->counter++;
printf("Counter: %d\n", data->counter);
} pthread_mutex_unlock(&data->mutex);
sleep(1);
}
/* unreachable */
cleanup();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include "shared_data.h"
int main() {
/* create a unique key for the shared memory */
key_t key = ftok("shmfile", 65); /* use same key as the main executable */
int shmid = shmget(key, sizeof(struct SharedData), 0666); /* get shared memory */
if (shmid == -1) {
perror("shmget failed");
exit(1);
}
/* attach to shared memory */
struct SharedData *data = shmat(shmid, NULL, 0);
if (data == (void *)-1) {
perror("shmat failed");
exit(1);
}
while (1) {
/* put a lock before reading */
pthread_mutex_lock(&data->mutex); {
printf("Counter from second process: %d\n", data->counter);
} pthread_mutex_unlock(&data->mutex);
sleep(1);
}
/* unreachable */
shmdt(data);
return 0;
}
/* shared_data.h */
#ifndef __SHDATA_H__
#define __SHDATA_H__
#include <pthread.h>
struct SharedData {
int counter; /* something that we'll share between programs */
pthread_mutex_t mutex; /* mutex for sync */
};
#endif /* __SHDATA_H__ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment