Program goes into a deadlock when invoking fork()
===

I've implemented a pipe that's based on a shared memory , and I have a problem when I 
try to invoke `fork` with a `main` program . 


The following main : 

    # include "my_shm_piper.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <sys/shm.h>
    #include <semaphore.h>
    #include <sys/mman.h>
    int main()
    {
    	int spd[2], pid, rb;
    	char buff[4096];
    
    	fork();  // that fork is okay , but if we put it after initPipe() , there's a deadlock
    
    	initPipe();
    
    	if (my_pipe(spd) < 0)
    	{
    		perror("my_pipe");
    		exit(1);
    	}
    
    	if (fork()) 
    	{
    		rb = my_read(spd[0], buff, sizeof(buff));
    		if (rb > 0)
    			write(1, buff, rb);
    	}
    
    	else
    	{
    		my_write(spd[1], "hello world!\n", sizeof("hello world!\n"));
    	}
    
    	my_close(spd[0]);
    	my_close(spd[1]);
    	removePipe();
    	return 0;
    }



Is using on an **Anonymous-pipe** that's implemented using shared memory library. 

When I put the `1st` command of `fork()` , as above , then my program is working as expected , all the `hello-world`-s are presented . 

But when I put the `fork` after `initPipe()` , there's deadlock , and the program hangs : 


    int main()
    
    {
    	int spd[2], pid, rb;
    	char buff[4096];
    
        initPipe();
        fork();   // now the fork() is after the initialization ,and we have a deadlock
    	
    	if (my_pipe(spd) < 0)
    	{
    		perror("my_pipe");
    		exit(1);
    	}
    
            // from here the same as above 
    }

I think that the initialization stage for the `fork()` is happening only once , and not 
twice , as in the first `main()` . 

I guess that there's something wrong with the writing/reading stage , but I can't seem 
to find the exact source . 

I'd appreciate for your help with the matter


The implementations for the methods are here : 

the struct in the H. file : 

    struct PipeShm
    {
    	int init;
    	int flag;
    	sem_t *mutex;
    	char * ptr1;
    	char * ptr2;
    	int status1;
    	int status2;
    	int semaphoreFlag;
    };


This is initPipe:

    int initPipe()
    {
        if (!myPipe.init)
        {
        	myPipe.mutex = mmap (NULL, sizeof *myPipe.mutex, PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, -1, 0);
    		if (!sem_init (myPipe.mutex, 1, 1))
    		{
    			myPipe.init = TRUE;
    		}
    		else
    			perror ("initPipe");
        }
        return 1;	// always successful
    }



this is my_pipe():


    int my_pipe(int spd[2])
    {
    	spd[0] = shmget(2009, SHMSIZE, 0);		// for reading
    	spd[1] = shmget(2009, SHMSIZE, 0666 | IPC_CREAT);  // for writing
    
    	 if (spd[0] == -1 || spd[1] == -1)
    	 {
    		     perror("shmget");
    		     exit(EXIT_FAILURE);
    		     return -1;
    	 }
    
    	 return 1;
    
    }




This is the reading : 

    ssize_t my_read(int spd, void *buf, size_t count)
    {
        
        char array[4096];
        memset (array, '\0', 4096);
        ssize_t returnVal = 0;
    
        sem_wait (myPipe.mutex);
    
        int sval;
        sem_getvalue (myPipe.mutex, &sval);
    
        printf ("my_read - wait %d\n", sval);
        if (sem_wait (myPipe.mutex))
    	perror ("sem_wait");
    
        printf ("my_read - proceed\n");
    
        if (myPipe.flag == FALSE)
        {
        	myPipe.ptr1 = shmat (spd, NULL, 0);	// attaching the segment
    		if (myPipe.ptr1 == (void *) -1)
    			error_out ("shmat");
    
    		strncpy (array, myPipe.ptr1, count);
    		array[count] = '\0';
    
    		returnVal = strlen (array);
    		buf = (void *) array;
    
    		printf ("Output:%s", array);
    
        }
    
        else if (myPipe.flag == TRUE)
        {
    		const size_t region_size = sysconf (_SC_PAGE_SIZE);
    		myPipe.ptr1 = mmap (0, region_size, PROT_READ | PROT_WRITE, MAP_SHARED, spd, 0);
    		if (myPipe.ptr1 == (void *) -1)
    			error_out ("mmap");
    
    		strncpy (array, myPipe.ptr1, count);
    		array[count] = '\0';
    
    		returnVal = strlen (array);
    		buf = (void *) array;
    
    		printf ("Output:%s", array);
    
        }
    
        return returnVal;
    
    }


and this is the writing : 

    ssize_t my_write(int spd, const void *buf, size_t count)
    {
    
    	   ssize_t returnVal = 0;
    	   sleep(1); // debug to ensure that read goes first for testing.
    	    if (myPipe.flag == FALSE)
    	    {
    	    	myPipe.ptr2 = shmat (spd, NULL, 0);	// attaching the segment
    			if (myPipe.ptr2 == (void *) -1)
    				error_out ("shmat");
    
    			char *d = (char *) buf;
    
    			returnVal = snprintf (myPipe.ptr2, count, "%s", d);
    	    }
    	    else
    	    {
    			const size_t region_size = sysconf (_SC_PAGE_SIZE);
    
    			// Map the region into memory.
    			myPipe.ptr2 = mmap (0, region_size, PROT_READ | PROT_WRITE, MAP_SHARED, spd, 0);
    			if (myPipe.ptr2 == MAP_FAILED)
    				error_out ("mmap");
    			char *d = (char *) buf;
    
    			returnVal = snprintf (myPipe.ptr2, count, "%s", d);
    	    }
    
    	    sem_post (myPipe.mutex);
    	    return returnVal;
    
    }

Best regards 