I want to create shared memory from a child process that can be used from other processes. However when I create shared memory with in the child the parent crashes when trying to use a pointer in the shared memory.
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
struct list_node
{
char *data;
};
static int create_shared(void **pointer, int size)
{
*pointer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
if(*pointer == MAP_FAILED)
{
perror("mmap:");
return -1;
}
return 0;
}
int main(void)
{
int rtrn;
pid_t pid;
struct list_node *node;
pid = fork();
if(pid == 0)
{
rtrn = create_shared((void **)&node, sizeof(struct list_node));
if(rtrn < 0)
{
printf("Can't create shared node\n");
return -1;
}
rtrn = asprintf(&node->data, "Test\n");
if(rtrn < 0)
{
perror("asprintf:");
return -1;
}
printf("data_child: %s\n", node->data);
}
else if(pid > 0)
{
/* Parent. */
sleep(1); // Make sure child runs first.
printf("data_parent: %s\n", node->data);
}
else
{
perror("fork");
return -1;
}
return 0;
}
But when I create the shared memory in the parent process it can be used from the child process and it's not just a copy from fork()
because the child can change the pointer and the parent see's it. In the example below the child changes the value of node->data
from test to best.
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
struct list_node
{
char *data;
};
static int create_shared(void **pointer, int size)
{
*pointer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
if(*pointer == MAP_FAILED)
{
perror("mmap:");
return -1;
}
return 0;
}
int main(void)
{
int rtrn;
struct list_node *node;
rtrn = create_shared((void **)&node, sizeof(struct list_node));
if(rtrn < 0)
{
printf("Can't create shared node\n");
return -1;
}
rtrn = asprintf(&node->data, "Test\n");
if(rtrn < 0)
{
perror("asprintf:");
return -1;
}
pid_t pid;
pid = fork();
if(pid == 0)
{
printf("data_child: %s\n", node->data);
node->data = "Best";
}
else if(pid > 0)
{
/* Parent. */
sleep(1); // Make sure child runs first.
printf("data_parent: %s\n", node->data);
}
else
{
perror("fork");
return -1;
}
return 0;
}
So how can I create shared memory from a child so that the parent or other child process can access it?
Edit
I tried marking the memory that char *data
points to as shared memory with create_shared() aka mmap but I still get segfaults when trying to print the string pointed to by char *data
. Below is how I tried setting data
as shared memory. I also tried memcpy thinking that just setting char *data
to test was just setting the pointer to non shared memory but that does not work either.
rtrn = create_shared((void **)&node->data, 5);
if(rtrn < 0)
{
printf("Can't create shared data\n");
return -1;
}
node->data = "Test";
//memcpy(node->data, "Test", 4);