Gli esempi mostrati di seguito sono tratti dal libro UNIX: PROGRAMMAZIONE AVANZATA disponibile presso la biblioteca dell'istituto.
Per gli approfondimenti ed i commenti si rimanda a tale testo.

La libreria che segue viene utilizzata dal client. Prepara il messaggio da inviare al server, e si mette in attesa della risposta.

 

/*********************************/
/*          dblib.c              */
/*********************************/

#include 
#include 
#include 
#include "dbms.h"

extern int errno;
static MESSAGE m;

static STATUS dbmscall(r)
RCD *r;
{
   char *dbmsval, *getenv();
   static long dbmskey;
   long atol();

   if (dbmskey == 0) {
     if((dbmsval = getenv("DBMSKEY")) == NULL)
       fatal("manca la variabile di environment DMSKEY");
     dbmskey=atol(dbmsval);
     }
     if (m.clientkey == 0)
      m.clientkey=getpid();
     if(!send(dbmskey,&m,sizeof(m)))
      return(ERROR);
     if(!receive(m.clientkey,&m,sizeof(m)))
      return(ERROR);
     if(r!= NULL)
      *r=m.rcd;
     if(m.status == ERROR)
      errno=m.errno;
     else 
      errno=0;
     return(m.status);
  }

  STATUS Dopen(file)
  char *file;
  {
    m.cmd = 'o';
    strcpy(m.file,file);
    return(dbmscall(NULL));
  }

  STATUS Dcreate(file)
  char *file;
  {
   m.cmd='c';
   strcpy(m.file,file);
   return(dbmscall(NULL));
  }

  STATUS Dclose()
  {
   STATUS status;

   m.cmd='q';
   status=dbmscall(NULL);
   rmqueue(m.clientkey);
   return(status);
  }

  STATUS Dtop()
  {
    m.cmd='t';
    return(dbmscall(NULL));
  }

STATUS Dget(name,r)
char *name;
RCD *r;
{
  m.cmd='g';
  strcpy(m.rcd.name,name);
  return(dbmscall(r));
}

La seguente librerie viene utilizzata dal server. In base all'analisi del comando giunto dal client viene eseguita l'operazione corretta e viene inviato l'esito dell'operazione al client.

/********************************/
/*        dbms.c                */
/********************************/

#include 
#include 
#include "dbms.h"

static int fd=-1;

static STATUS Dopen(file) 
char *file;
{
 if ((fd=open(file,O_RDWR,0))==-1)
  return(ERROR);
 return(OK);
}

static STATUS Dcreate(file)
char *file;
{
  if ((fd=open(file,O_RDWR | O_CREAT | O_TRUNC,0666))==-1)
    return(ERROR);
  return(OK);
}

static STATUS Dclose()
{
 if(close(fd)==-1)
   return(ERROR);
 return(OK);
}

long lseek();
extern int errno;

static STATUS Dtop()
{
 if (lseek(fd,0L,0)==-1)
  return(ERROR);
 return(OK);
}

static STATUS Dget(name,r)

char *name;
RCD *r;
{
 int nread;

 if(Dtop()!=OK)
  return(ERROR);
 while((nread=read(fd,r,sizeof(RCD)))==sizeof(RCD))
  if (strcmp(r->name,name)==0){
   if(lseek(fd,-(long)sizeof(RCD),1)==-1)
    return(ERROR);
   return(OK);
  }
 switch(nread){
 case 0:
    return(NOTFOUND);
 case -1:
    return(ERROR);
 default:
     errno=0;
     return(ERROR);
 }
}


static STATUS Dgetnext(r)

RCD *r;
{
	while(1)
		switch(read(fd,r,sizeof(RCD))) {
		case sizeof(RCD):
			if (r->name[0]=='\0')
				continue;
			return(OK);
		case 0:
			return(NOTFOUND);
		case -1:
			return(ERROR);
		default:
			errno=0;
			return(ERROR);
		}
}

static STATUS Dput(r)
RCD *r;
{
	RCD rcd;

	switch(Dget(r->name,&rcd)) {
	case NOTFOUND:
		if (lseek(fd,0l,2)==-1)
			return(ERROR);
		break;
	case ERROR:
		return(ERROR);
	}
	switch (write(fd,r,sizeof(RCD))) {
	case sizeof(RCD):
		return(OK);
	case -1:
		return(ERROR);
	default:
		errno=0;
		return(ERROR);
	}
}

static STATUS Ddelete(name)
char *name;
{
	RCD rcd;
	switch(Dget(name,&rcd)) {
	case NOTFOUND:
		return(OK);
	case ERROR:
		return(ERROR);
	}
	rcd.name[0]='\0';
	switch (write(fd,&rcd,sizeof(RCD))) {
	case sizeof(RCD):
		return(OK);
	case -1:
		return(ERROR);
	default:
		errno=0;
		return(ERROR);
	}
}


/********************************/
/*     demodbms.c               */
/********************************/
#include 
#include 
#include 
#include "dbms.h"
#include "defs.h"

static void rcdprint(r)
RCD *r;
{
   printf("Nome\t%s\n",r->name);
   printf("Indirizzo\t%s\n",r->street);
   printf("Citta'\t%s\n",r->city);
   printf("Stato\t%s\n",r->state);
   printf("Cap\t%s\n",r->zip);
   printf("Telefono\t%s\n",r->tel);
}

static void prompt(msg,result,max,required)
char *msg, *result;
int max;
BOOLEAN required;
{
   char s[200];
   int len;

   while(1) {
     printf("\n%s?",msg);
     if(gets(s) == NULL)
      exit(0);
     len=strlen(s);
     if(len >=max) {
      printf("Risposta troppo lunga\n");
      continue;
     }
     if(len == 0 && required) {
       printf("Valore obbligatorio\n");
       continue;
     }
     strcpy(result,s);
     return;
   }
}

main()
{
 char cmd[5], file[50], name[30];
 RCD rcd;
 extern int errno;

 while(1) {
   prompt("Comando (? per aiuto)",cmd,sizeof(cmd), TRUE);
   if(strlen(cmd) != 1) {
    printf("Una sola lettera\n");
    continue;
   }
   switch(cmd[0]) {
   case '?':
     printf("o apre un database\n");
     printf("c crea un database\n");
     printf("p inserisce un record\n");
     printf("d cancella un record\n");
     printf("g trova un record per key\n");
     printf("n trova il record successivo\n");
     printf("t si posiziona all'inizio del database\n");
     printf("q termina l'esecuzione\n");
     continue;
   case 'o':
     prompt("File da aprire",file,sizeof(file),TRUE);
     if(Dopen(file) == OK)
      printf("OK\n");
     else
      printf("Non riesco; errno=%d\n",errno);
     continue;
   case 'c' :
     prompt("File da creare",file,sizeof(file), TRUE);
     if(Dcreate(file) == OK)
      printf("OK\n");
     else
      printf("Non riesco; errno=%d\n",errno);
     continue;
   case 'q' :
     if (Dclose() == OK)
      printf("OK\n");
     else
      printf("Non riesco; errno=%d\n",errno);
     exit(0);
   case 'g' :
    prompt("Nome",name,sizeof(name), TRUE);
    switch(Dget(name,&rcd)) {
    case OK:
     rcdprint(&rcd);
     continue;
    case NOTFOUND:
     printf("Non trovato\n");
     continue;
    case ERROR:
     printf("Non riesco; errno=%d\n",errno);
     continue;
    }
   case 'n':
     switch(Dgetnext(&rcd)) {
     case OK:
      rcdprint(&rcd);
      continue;
     case NOTFOUND:
      printf("Non trovato\n");
      continue;
     case ERROR:
      printf("Non riesco; errno=%d", errno);
      continue;
     }
   case 'p' :
     prompt("Nome",rcd.name,sizeof(rcd.name),TRUE);
     prompt("Indirizzo",rcd.street,sizeof(rcd.street), FALSE);
     prompt("Citta'",rcd.city,sizeof(rcd.city),FALSE);
     prompt("Stato",rcd.state,sizeof(rcd.state),FALSE);
     prompt("Cap",rcd.zip,sizeof(rcd.zip), FALSE);
     prompt("Telefono",rcd.tel,sizeof(rcd.tel), FALSE);
     if(Dput(&rcd) == OK)
      printf("OK\n");
     else
      printf("Non riesco; errno=%d\n",errno);
     continue;
   case 'd':
     prompt("Nome",name,sizeof(rcd.name), TRUE);
     if(Ddelete(name) == OK)
      printf("OK\n");
     else
      printf("Non riesco; errno=%d\n",errno);
     continue;
   case 't' :
     if(Dtop() == OK)
      printf("OK\n");
     else
      printf("Non riesco; errno=%d\n",errno);
     continue;
   default:
     printf("Comando sconosciuto - usare ? per aiuto\n");
   }
  }
 }

#include 
 
void fatal(msg)
 
char *msg;
{
        fprintf(stderr, "ERROR: %s\n", msg);
        exit(1);
}
 
/********************************/
/*         main.c               */
/********************************/
#include 
#include 
#include 
#include "dbms.h"

main()
{
	MESSAGE m;
	char *dbmsval,name[30],*getenv();
	long dbmskey,atol();

	if ((dbmsval=getenv("DBMSKEY"))==NULL)
		fatal("manca la variabile di enviorment  DBMSKEY");
	dbmskey=atol(dbmsval);
	while(receive(dbmskey,&m,sizeof(m))) {
		switch(m.cmd) {
		case 'o':
			m.status=Dopen(m.file);
			break;
		case 'c':
			m.status=Dcreate(m.file);
			break;
		case'q':
			m.status=Dclose();
			rmqueue(dbmskey);
			break;
		case 'g':
			strcpy(name,m.rcd.name);
			m.status=Dget(name,&m.rcd);
			break;
		case 'n':
			m.status=Dgetnext(&m.rcd);
			break;
		case 'p':
			m.status=Dput(&m.rcd);
			break;
		case 'd':
			m.status=Ddelete(m.rcd.name);
			break;
		case 't':
			m.status=Dtop();
			break;
		default:
			errno=EINVAL;
			m.status=ERROR;
		}
		m.errno=errno;
		if (!send(m.clientkey,&m,sizeof(m)))
			printf("non posso inviare a %ld;errno=%ld\n",m.clientkey,errno);
		if (m.cmd=='q')
			exit(0);
	}
	syserr("receive");
}

#include 
#include 
#include 
#include "defs.h"

#define MAXMSG 4096
#define MAXOPEN 20
#define BADADDR (char *) (-1)

static BOOLEAN findinfo(key,sndsidp,rcvsidp,addrp,segidp)
int key;
int *sndsidp,*rcvsidp,*segidp;
char **addrp;
{
	static struct {
		int key;
		int sndsid;
		int rcvsid;
		char *addr;
		int segid;
	} sems[MAXOPEN];
	int i,avail;
	extern int errno;
	char *shmat();
avail=-1;
	for (i=0;iMAXMSG)
		nbytes=MAXMSG;
	P(sndsid);
	memcpy(addr,buf,nbytes);
	V(rcvsid);
	return(TRUE);
}

BOOLEAN receive(srckey,uf,nbytes)
int srckey;
char *uf;
int nbytes;
{
	int sndsid,rcvsid,segid;
	char *addr;

	if (!findinfo(srckey,&sndsid,&rcvsid,&addr,&segid))
		return(FALSE);
	if (nbytes>MAXMSG)
		nbytes=MAXMSG;
	P(rcvsid);
	memcpy(uf,addr,nbytes);
	V(sndsid);
	return(TRUE);
}

void rmqueue(key)
int key;
{
	int sndsid,rcvsid,segid;
	char *addr;

	if (!findinfo(key,&sndsid,&rcvsid,&addr,&segid))
		syserr("findinfo");
	(void)semctl(sndsid,0,IPC_RMID,0);
	(void)semctl(rcvsid,0,IPC_RMID,0);
	(void)shmdt(addr);
	(void)shmctl(segid,IPC_RMID,0);
}







#include 
#include 
#include 

int semtran(key)
int key;
{
 int sid;

 if ((sid=semget((key_t)key, 1,0666 | IPC_CREAT)) == -1)
    syserr("semget");
 return(sid);
}

static void semcall(sid,op)
int sid;
int op;
{
  struct sembuf sb;

  sb.sem_num=0;
  sb.sem_op=op;
  sb.sem_flg=0;
  if (semop(sid,&sb,1) == -1)
   syserr("semop");
}

void P(sid)
int sid;
{
    semcall(sid,-1);
}

void V(sid)
int sid;
{
     semcall(sid,1);
}



#include 
 
void syserr(msg)        /* stampa un messaggio di errore di una  */
                        /* chiamata di sistema e termina         */
char    *msg;
{
        extern int errno, sys_nerr;
        extern char *sys_errlist[];
 
        fprintf(stderr,"ERROR: %s ( %d",msg, errno);
        if (errno > 0 && errno < sys_nerr)
                fprintf(stderr,": %s)\n",sys_errlist[errno]);
        else
                fprintf(stderr,")\n");
        exit(1);
}
 
 
/************************************/
/*             dbms.h               */
/************************************/

typedef enum {OK, NOTFOUND, ERROR} STATUS;

typedef struct {
 char name[20];
 char street[15];
 char city[10];
 char state[3];
 char zip[6];
 char tel[15];
}RCD;

typedef struct {
 long mtype;
 long clientkey;
 char cmd;
 char file[20];
 RCD rcd;
 STATUS status;
 int errno;
} MESSAGE;



/**********************/
/*       defs.h       */
/**********************/

typedef enum {TRUE, FALSE} BOOLEAN;

#define lowbyte(w) ((w) & 0377)
#define highbyte(w) lowbyte((w)>> 8)