ftok does not need to be called by the children. All ftok does is return an integer based on values from the a file's inode and its second argument. ftok provides a simple way for unrelated processes to find the same IPC resource. Here's the implementation from musl-1.1.12 ftok.c (it's easier to read than the glibc version).
#include <sys/ipc.h>
#include <sys/stat.h>
key_t ftok(const char *path, int id)
{
struct stat st;
if (stat(path, &st) < 0) return -1;
return ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ((id & 0xff) << 24));
}
IPC_PRIVATE supplied to msgget(2), semget(2), or shmget(2) means that a new IPC resource should be created. The resource isn't "private", only newly created.
The Linux man pages say as much in the BUGS section:
The name choice IPC_PRIVATE was perhaps unfortunate, IPC_NEW would
more clearly show its function.
Have a look at the POSIX IPC interfaces: mq_overview(7), sem_overview(7), and shm_overview(7). To quote the man pages:
POSIX [...] provides a simpler, and better designed interface