Unix: Shared Memory

Header

#ifndef _MYDATUM_ /* don't repeat this header */

#define _MYDATUM_

#define MAXDATUM 4080
typedef struct {
          int type;
          int length;
           char datum[MAXDATUM]; 
} MyDatum;

#endif

Server

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include "MySharedMemory.h"

int shmid, client_sema, server_sema;
MyDatum * msg_ptr;

void main(void)
{

shmid = shmget(SHMKEY, sizeof(MyDatum), PERMS | IPC_CREAT);
if (shmid<0) 
err_sys("Server cannot get shared memory ID\n");

msg_ptr = (msg_ptr *) shmat(shmid, (char *) 0, 0);
if (msg_ptr == (msg_ptr *) -1 ) 
           err_sys("Server cannot attach to shared memory \n");

client_sema = sem_create(SEMKEY1, 1);
if (client_sema <0 ) 
           err_sys("Server cannot create Client semaphore\n");

server_sema = sem_create(SEMKEY2, 0);
if (server_sema <0 ) 
          err_sys("Server cannot create Server semaphore\n");

server(); /* caller the actual server function */

result = shmdt( msg_ptr ); // try to detach
if ( result < 0 )
          err_sys("Server cannot detach\n");

sem_close(client_sema);
sem_close(server_sema);

return 0;
}

                                     /* simple file server */
void server(void) 
{

int count, hFile;
char errmsg[255], *sys_err_str();

sema_wait(server_sema); /* wait for client's signal */

msg_ptr->length = 0;
msg_ptr->datum[msg_ptr->length] = '\0';

hFile = open(msg_ptr->datum, 0);
if (hFile < 0 ) 
{
           sprintf(errmsg, ":cannot open, %s\n", sys_err_str() );
           strcat( msg_ptr->datum, errmsg);
           msg_ptr->length = strlen(msg_ptr->datum);
           sem_signal(client_sema); /* wakeup client */
           sem_wait(server_sema); /* wait for client */

else /* file was found, let's send it to client */
{
count = read(hFile, msg_ptr->datum, MAXDATUM-1);
while (count > 0) 
{
           msg_ptr->length = count;
           sem_signal(client_sema);
           sem_wait(server_sema);
           count = read(hFile, msg_ptr->datum, MAXDATUM-1);
}
close (hFile);
msg_ptr->length = 0; /* use zero to signal end of file */
sem_signal(client_sema);
}
}

Client 
 
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include "MySharedMemory.h"

int result, shmid, client_sema, server_sema;

MyDatum * msg_ptr;

void main(void)
{

shmid = shmget(SHMKEY, sizeof(MyDatum), 0);
if (shmid<0) 
err_sys("Client cannot get shared memory ID\n");

msg_ptr = (msg_ptr *) shmat(shmid, (char *) 0, 0);
if (msg_ptr == (msg_ptr *) -1 ) 
err_sys("Client cannot attach to shared memory \n");

client_sema = sem_create(SEMKEY1, 1);
if (client_sema <0 ) 
err_sys("Client attach to Client semaphore\n");

server_sema = sem_create(SEMKEY2, 0);
if (server_sema <0 ) 
err_sys("Client attach to Server semaphore\n");

client(); /* caller the actual server function */

result = shmdt( msg_ptr ); // try to detach
if ( result < 0 )
err_sys("Client cannot detach\n");

result = shmctl( shmid, IPC_RMID, (struct shmid_ds *) 0);
if ( result < 0 )
err_sys("Client cannot delete sharememory\n");

sem_close(client_sema);
sem_close(server_sema);

return 0;
}

/* simple file server */
void client(void) 
{

int count, hFile;
char errmsg[255], *sys_err_str();

sema_wait(server_sema); /* wait for client's signal */

msg_ptr->length = 0;
msg_ptr->datum[msg_ptr->length] = '\0';

hFile = open(msg_ptr->datum, 0);
if (hFile < 0 ) 
{
sprintf(errmsg, ":cannot open, %s\n", sys_err_str() );
strcat( msg_ptr->datum, errmsg);
msg_ptr->length = strlen(msg_ptr->datum);
sem_signal(client_sema); /* wakeup client */
sem_wait(server_sema); /* wait for client */

else /* file was found, let's send it to client */
{
count = read(hFile, msg_ptr->datum, MAXDATUM-1);
while (count > 0) 
{
msg_ptr->length = count;
sem_signal(client_sema);
sem_wait(server_sema);
count = read(hFile, msg_ptr->datum, MAXDATUM-1);
}
close (hFile);
msg_ptr->length = 0; /* use zero to signal end of file */
sem_signal(client_sema);
}
}