For a uni assignment I need to create a circular list of up to 10 file names, and then store these in a shared memory area, so that 2 child processes can read/write to the list (using a semaphore to control access). Trouble is, that I am a total C novice and I feel loss and despair because its totally out of my depth. I need some help in “filling in the holes” of my knowledge.
Right now, I am simply focussing on it one problem at a time, and presently, I am only trying to get my circular list into the shared memory area.
So far I have:
typedef struct FILE
{
struct FILE *f_link; /* forward link for linked list */
char name[255]; /* name of the file */
} FILE_entry;
As my struct which will hold the reference to the file that comes next (f_link). this way I can just call ->f_link to get the next item in the list, and where the 10th element will simply have its f_link directed back to the 1st. My reason for doing this is so that I can simply traverse the list without an iterator (and never have to check for the end of the list as I would with an array).
I also know that I need to use shmget to get the memory area, and I understand it, I pass shmget a key, a size and a flag (which i dont get) and it returns an identifier in the type of an int.
So my question is 2 fold. How do I store my linked list INTO the shared memory area – and how do I access it FROM the shared memory area?
shmgetjust reserves some amount of shared memory – like creating a fixed-size file on disk. The flags are a permission mask (like themodeparameter foropen) in the low 9 bits plus some extra flags,IPC_CREATandIPC_EXCL, corresponding toO_CREATandO_EXCLforopen. To actually access that memory, you need to map it into the address space of your process (“attach” it – analogous tommapfor files). This is done usingshmat(which returns a pointer). You then need to allocate yourFILEstructures from that pointer. The whole process looks something like this:After mapping, you can work with it like regular memory – since it is regular memory. That’s the whole point!
EDIT: One important caveat I forgot to mention. Putting a linked list into a shared memory segment like this will only work if all involved processes map it to the same address! So you either need to do that (using the second argument of
shmat) or switch from pointers to offsets relative to the base address of the shared memory range. That means turning yournextfield from a pointer to aptrdiff_tand adding the base address of the mapped memory range whenever you load it (and subtracting it whenever you store it).