I am currently working on a part where a linked list, one linked list node has multiple variable data, is to be saved in a shared memory segment so that another program can read that list and do operations accordingly.
I have previously worked on socket programming, but sending a stream of data does not fulfill my purpose, as I have to do validation based on reading one node/element at a time. So, of all the IPC's, I think shared memory would be the best as it also has good performance than others(in this case, not generally).
The following is the struct that I have made:
struct DNode {
char *polname;
char *devname;
char *status;
char *srczone;
char *dstzone;
char *srcaddr;
char *dstaddr;
char *srcuser;
char *app;
char *service;
char *urlcategory;
char *action;
char *vulnerability;
char *value;
struct DNode *next;
};
struct DNode *head = NULL;
struct DList {
DNode pool[MAX_DNODE]; // fixed-size space for nodes
size_t npool; // used space in pool
size_t pfree; // pointer to re-use freed nodes
size_t head; // global list head
};
DList *dlist;
DNode *dnode_alloc(void)
{
if (dlist->pfree != DNULL) {
DNode *node = dlist->pool + dlist->pfree;
dlist->pfree = dlist->pool[dlist->pfree].next;
return node;
} else {
if (dlist->npool < MAX_DNODE) return &dlist->pool[dlist->npool++];
}
return NULL;
}
void dnode_free(DNode *node)
{
if (node) {
node->next = dlist->pfree;
dlist->pfree = node - dlist->pool;
}
}
DNode *dnode(size_t index)
{
return (index == DNULL) ? NULL : dlist->pool + index;
}
DNode *dnode_next(const DNode *node)
{
return dnode(node->next);
}
DNode *dnode_push(size_t *head, const char *str)
{
DNode *node = dnode_alloc();
if (node) {
strncpy(node->polname, str, sizeof(node->polname));
node->next = *head;
*head = node - dlist->pool;
}
return node;
}
void dnode_pop(size_t *head)
{
if (*head != DNULL) {
size_t next = dlist->pool[*head].next;
dnode_free(&dlist->pool[*head]);
*head = next;
}
}
int list_insert_front(struct node* new_node) {
struct node *temp;
temp = malloc(sizeof *temp);
if (temp && new_node) {
memcpy(temp, new_node, sizeof(struct node));
temp->next = head;
head = temp;
return 1;
}
return 0;
}
int main(int argc, char **argv)
{
struct Dnode *iter = head;
int shmid;
xmlDocPtr doc;
xmlNode *root_element = NULL;
if (argc != 2)
{
printf("\nInvalid argument\n");
return(1);
}
doc = xmlReadFile(argv[1], NULL, XML_PARSE_NOBLANKS | XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NONET);
if (doc == NULL)
{
fprintf(stderr, "Document not parsed successfully.\n");
return 0;
}
root_element = xmlDocGetRootElement(doc);
if (root_element == NULL)
{
fprintf(stderr, "empty document\n");
xmlFreeDoc(doc);
return 0;
}
printf("Root Node is %s\n", root_element->name);
traverse_dom_trees(root_element);
shmid = shmget(IPC_PRIVATE, sizeof(DList), IPC_CREAT | 0660);
if (shmid < 0) exit (1);
dlist = shmat(shmid, NULL, 0);
if (dlist == (void *) (-1)) exit(1);
dlist->head = DNULL;
dlist->pfree = DNULL;
dlist->npool = 0;
while(iter != NULL){
dnode_push(&dlist->head, head->polname);
dnode_pop(&dlist->head);
iter = head->next;
}
shmdt(dlist);
xmlFreeDoc(doc); // free document
xmlCleanupParser(); // Free globals
return 0;
}
As you can see, I have also included an XML parser part in the main function so as to give you an idea of what I am taking as an input. But the part where I am stuck is how to save/use this struct inside a shared memory, and making it easy for the other program to access it.
Please can somebody provide me with some pseudo-code for the same as I have never used such C functionalities before and am absolutely clueless on how to approach this. Any and all suggestions are welcome and am thankful in advance.
Edit 1
Using Centos7 on a virtual machine since somebody pointed out that mentioning the platform would be fruitful.
Edit 2 Just added some code to implement shared memory segments, and it does not give me any such errors. What my concern is:
- Is it doing what I intended?
- Is the approach correct?
- I know I am currently just pushing one element but this sure is right, right?
- Am I wasting time and efforts trying to work it out using shared memory?