Iniziato a lavorare sulla Shared Memory POSIX. Risistemate un po' di cose
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 2 Feb 2003 20:35:34 +0000 (20:35 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 2 Feb 2003 20:35:34 +0000 (20:35 +0000)
e scritte routine e programma di prova.

14 files changed:
ipc.tex
simpltcp.tex
socket.tex
sources/ElemEchoTCPClient.c
sources/ElemEchoTCPServer.c
sources/FullRead.c [new file with mode: 0644]
sources/FullWrite.c [new file with mode: 0644]
sources/Gapil.h
sources/Makefile
sources/SharedMem.c
sources/SimpleEchoTCPClient.c
sources/SimpleEchoTCPServer.c
sources/SockRead.c [deleted file]
sources/SockWrite.c [deleted file]

diff --git a/ipc.tex b/ipc.tex
index 8428b47c73fccd51d2caf22778b38bb74d463d9a..78d612f91270dfb2a6e799ec7fd49f9d6df66c44 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -3779,15 +3779,39 @@ meccanismi di comunicazione, che vanno sotto il nome di POSIX IPC, definendo
 una interfaccia completamente nuova, che tratteremo in questa sezione.
 
 
 una interfaccia completamente nuova, che tratteremo in questa sezione.
 
 
-
 \subsection{Considerazioni generali}
 \label{sec:ipc_posix_generic}
 
 \subsection{Considerazioni generali}
 \label{sec:ipc_posix_generic}
 
-Il Linux non tutti gli oggetti del POSIX IPC sono supportati nel kernel
-ufficiale; solo la memoria condivisa è presente, ma solo a partire dal kernel
-2.4.x, per gli altri oggetti esistono patch e librerie non ufficiali.
-Nonostante questo è importante esaminare questa interfaccia per la sua netta
-superiorità nei confronti di quella del \textit{SysV IPC}.
+In Linux non tutti gli oggetti del POSIX IPC sono pienamente supportati nel
+kernel ufficiale; solo la memoria condivisa è presente con l'interfaccia
+completa, ma solo a partire dal kernel 2.4.x, i semafori sono forniti dalle
+\acr{glibc} nella sezione che implementa i thread POSIX, e sono utilizzabili
+solo all'interno dei thread generati dallo stesso processo,\footnote{sono cioè
+  oggetti che non possono, al contrario dei semafori del SysV IPC, essere
+  utilizzati per sincronizzare processi diversi.} le code di messaggi non
+hanno alcun tipo di supporto ufficiale.  Esistono tuttavia dei patch e delle
+librerie aggiuntive che supportano alcune di queste interfacce, anche se
+sperimentali e di uso limitato.
+
+La caratteristica fondamentale dell'interfaccia POSIX è l'abbandono dell'uso
+degli identificatori e delle chiavi visti nel SysV IPC, per passare ai
+\textit{Posix IPC names}\index{Posix IPC names}, che sono sostanzialmente
+equivalenti ai nomi dei file. Tutte le funzioni che creano un oggetto di IPC
+Posix prendono come primo argomento una stringa che indica uno di questi nomi;
+lo standard è molto generico riguardo l'implementazione, ed i nomi stessi
+possono avere o meno una corrispondenza sul filesystem. 
+
+
+ le caratteristiche di questi nomi,
+per i quali richiede che:
+\begin{itemize}
+\item debbano essere conformi alle regole che caratterizzano i
+  \textit{pathname}, in particolare non essere più lunghi di \const{PATH\_MAX}
+  byte e terminati da un carattere nullo.
+\item se il nome inizia per una \texttt{/} 
+\end{itemize}
+
+
 
 
 \subsection{Code di messaggi}
 
 
 \subsection{Code di messaggi}
@@ -3797,11 +3821,11 @@ Le code di messaggi non sono ancora supportate nel kernel
 ufficiale;\footnote{esiste però una proposta di implementazione di Krzysztof
   Benedyczak, a partire dal kernel 2.5.50.}  inoltre esse possono essere
 implementate, usando la memoria condivisa ed i mutex, con funzioni di
 ufficiale;\footnote{esiste però una proposta di implementazione di Krzysztof
   Benedyczak, a partire dal kernel 2.5.50.}  inoltre esse possono essere
 implementate, usando la memoria condivisa ed i mutex, con funzioni di
-libreria. In generale, come le corrispettive del SysV IPC, sono poco usate,
+libreria.  In generale, come le corrispettive del SysV IPC, sono poco usate,
 dato che i socket\index{socket}, nei casi in cui sono sufficienti, sono più
 comodi, e negli altri casi la comunicazione può essere gestita direttamente
 dato che i socket\index{socket}, nei casi in cui sono sufficienti, sono più
 comodi, e negli altri casi la comunicazione può essere gestita direttamente
-con mutex e memoria condivisa. Per questo ci limiteremo ad una descrizione
-essenziale.
+con mutex e memoria condivisa. Per questo, in assenza di una implementazione
+uffiale, ne tralasciamo la descrizione.
 
 
 
 
 
 
@@ -3812,7 +3836,9 @@ Dei semafori POSIX esistono sostanzialmente due implementazioni; una 
 livello di libreria ed è fornita dalla libreria dei thread; questa però li
 implementa solo a livello di thread e non di processi. Esiste un'altra
 versione, realizzata da Konstantin Knizhnik, che reimplementa l'interfaccia
 livello di libreria ed è fornita dalla libreria dei thread; questa però li
 implementa solo a livello di thread e non di processi. Esiste un'altra
 versione, realizzata da Konstantin Knizhnik, che reimplementa l'interfaccia
-POSIX usando i semafori di SysV IPC. 
+POSIX usando i semafori di SysV IPC.
+
+
 
 
 \subsection{Memoria condivisa}
 
 
 \subsection{Memoria condivisa}
index 4d46b1a2deecb3eea0b9d6cae8566d270ed7cd2f..b4b9931413d9a08703352b2b39c54ed6c5b90b5b 100644 (file)
@@ -136,7 +136,7 @@ Il codice della funzione \code{ServEcho} 
 all'interno del ciclo (linee \texttt{\small 6--8}).  I dati inviati dal client
 vengono letti dal socket con una semplice \func{read} (che ritorna solo in
 presenza di dati in arrivo), la riscrittura viene invece gestita dalla
 all'interno del ciclo (linee \texttt{\small 6--8}).  I dati inviati dal client
 vengono letti dal socket con una semplice \func{read} (che ritorna solo in
 presenza di dati in arrivo), la riscrittura viene invece gestita dalla
-funzione \func{SockWrite} (descritta in \figref{fig:sock_SockWrite_code}) che
+funzione \func{FullWrite} (descritta in \figref{fig:sock_FullWrite_code}) che
 si incarica di tenere conto automaticamente della possibilità che non tutti i
 dati di cui è richiesta la scrittura vengano trasmessi con una singola
 \func{write}.
 si incarica di tenere conto automaticamente della possibilità che non tutti i
 dati di cui è richiesta la scrittura vengano trasmessi con una singola
 \func{write}.
@@ -150,7 +150,7 @@ void ServEcho(int sockfd) {
     
     /* main loop, reading 0 char means client close connection */
     while ( (nread = read(sockfd, buffer, MAXLINE)) != 0) {
     
     /* main loop, reading 0 char means client close connection */
     while ( (nread = read(sockfd, buffer, MAXLINE)) != 0) {
-        nwrite = SockWrite(sockfd, buffer, nread);
+        nwrite = FullWrite(sockfd, buffer, nread);
     }
     return;
 }
     }
     return;
 }
@@ -234,8 +234,8 @@ void ClientEcho(FILE * filein, int socket)
     char sendbuff[MAXLINE], recvbuff[MAXLINE];
     int nread; 
     while (fgets(sendbuff, MAXLINE, filein) != NULL) {
     char sendbuff[MAXLINE], recvbuff[MAXLINE];
     int nread; 
     while (fgets(sendbuff, MAXLINE, filein) != NULL) {
-        SockWrite(socket, sendbuff, strlen(sendbuff)); 
-        nread = SockRead(socket, recvbuff, strlen(sendbuff));        
+        FullWrite(socket, sendbuff, strlen(sendbuff)); 
+        nread = FullRead(socket, recvbuff, strlen(sendbuff));        
         recvbuff[nread] = 0;
         fputs(recvbuff, stdout);
     }
         recvbuff[nread] = 0;
         fputs(recvbuff, stdout);
     }
@@ -253,11 +253,11 @@ La funzione utilizza due buffer per gestire i dati inviati e letti sul socket
 presi dallo \file{stdin} usando la funzione \func{fgets} che legge una
 linea di testo (terminata da un \texttt{CR} e fino al massimo di
 \const{MAXLINE} caratteri) e la salva sul buffer di invio, la funzione
 presi dallo \file{stdin} usando la funzione \func{fgets} che legge una
 linea di testo (terminata da un \texttt{CR} e fino al massimo di
 \const{MAXLINE} caratteri) e la salva sul buffer di invio, la funzione
-\func{SockWrite} (\texttt{\small 3}) scrive detti dati sul socket (gestendo
+\func{FullWrite} (\texttt{\small 3}) scrive detti dati sul socket (gestendo
 l'invio multiplo qualora una singola \func{write} non basti, come spiegato
 in \secref{sec:sock_io_behav}).
 
 l'invio multiplo qualora una singola \func{write} non basti, come spiegato
 in \secref{sec:sock_io_behav}).
 
-I dati che vengono riletti indietro con una \func{SockRead} sul buffer di
+I dati che vengono riletti indietro con una \func{FullRead} sul buffer di
 ricezione e viene inserita la terminazione della stringa (\texttt{\small
   7--8}) e per poter usare la funzione \func{fputs} per scriverli su
 \file{stdout}. 
 ricezione e viene inserita la terminazione della stringa (\texttt{\small
   7--8}) e per poter usare la funzione \func{fputs} per scriverli su
 \file{stdout}. 
index fa70b6d800a1094109394212b3c1d2ef866ad107..2e34e78d3bdeaaa3bab7428c8740310ecc3b36ec 100644 (file)
@@ -817,7 +817,7 @@ riveda quanto detto in \secref{sec:ipc_pipes}).
   \begin{lstlisting}{}
 #include <unistd.h>
 
   \begin{lstlisting}{}
 #include <unistd.h>
 
-ssize_t SockRead(int fd, void *buf, size_t count) 
+ssize_t FullRead(int fd, void *buf, size_t count) 
 {
     size_t nleft;
     ssize_t nread;
 {
     size_t nleft;
     ssize_t nread;
@@ -839,17 +839,17 @@ ssize_t SockRead(int fd, void *buf, size_t count)
     return (count - nleft);
 }  
   \end{lstlisting}
     return (count - nleft);
 }  
   \end{lstlisting}
-  \caption{Funzione \func{SockRead}, legge \var{count} byte da un socket }
-  \label{fig:sock_SockRead_code}
+  \caption{Funzione \func{FullRead}, legge \var{count} byte da un socket }
+  \label{fig:sock_FullRead_code}
 \end{figure}
 
 Per questo motivo, seguendo l'esempio di W. R. Stevens in \cite{UNP1}, si sono
 \end{figure}
 
 Per questo motivo, seguendo l'esempio di W. R. Stevens in \cite{UNP1}, si sono
-definite due funzioni \func{SockRead} e \func{SockWrite} che eseguono la
+definite due funzioni \func{FullRead} e \func{FullWrite} che eseguono la
 lettura da un socket tenendo conto di questa caratteristica, ed in grado di
 ritornare dopo avere letto o scritto esattamente il numero di byte
 lettura da un socket tenendo conto di questa caratteristica, ed in grado di
 ritornare dopo avere letto o scritto esattamente il numero di byte
-specificato; il sorgente è riportato in \figref{fig:sock_SockRead_code} e
-\figref{fig:sock_SockWrite_code} ed è disponibile fra i sorgenti allegati alla
-guida nei files \file{SockRead.c} e \file{SockWrite.c}.
+specificato; il sorgente è riportato in \figref{fig:sock_FullRead_code} e
+\figref{fig:sock_FullWrite_code} ed è disponibile fra i sorgenti allegati alla
+guida nei files \file{FullRead.c} e \file{FullWrite.c}.
 
 \begin{figure}[htb]
   \centering
 
 \begin{figure}[htb]
   \centering
@@ -857,7 +857,7 @@ guida nei files \file{SockRead.c} e \file{SockWrite.c}.
   \begin{lstlisting}{}
 #include <unistd.h>
 
   \begin{lstlisting}{}
 #include <unistd.h>
 
-ssize_t SockWrite(int fd, const void *buf, size_t count) 
+ssize_t FullWrite(int fd, const void *buf, size_t count) 
 {
     size_t nleft;
     ssize_t nwritten;
 {
     size_t nleft;
     ssize_t nwritten;
@@ -877,8 +877,8 @@ ssize_t SockWrite(int fd, const void *buf, size_t count)
     return (count);
 }  
   \end{lstlisting}
     return (count);
 }  
   \end{lstlisting}
-  \caption{Funzione \func{SockWrite}, scrive \var{count} byte su un socket.}
-  \label{fig:sock_SockWrite_code}
+  \caption{Funzione \func{FullWrite}, scrive \var{count} byte su un socket.}
+  \label{fig:sock_FullWrite_code}
 \end{figure}
 
 Come si può notare le funzioni ripetono la lettura/scrittura in un ciclo fino
 \end{figure}
 
 Come si può notare le funzioni ripetono la lettura/scrittura in un ciclo fino
index ac1d9910a4a89ca62e8dd3da8c7b701838853934..3529cd792203a3d5348bab470a79f6c50cd4926c 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: echo -h give all info's
  *
  *
  * Usage: echo -h give all info's
  *
- * $Id: ElemEchoTCPClient.c,v 1.4 2002/12/03 11:06:05 piccardi Exp $
+ * $Id: ElemEchoTCPClient.c,v 1.5 2003/02/02 20:35:33 piccardi Exp $
  *
  ****************************************************************/
 /* 
  *
  ****************************************************************/
 /* 
@@ -120,8 +120,8 @@ void ClientEcho(FILE * filein, int socket)
     char sendbuff[MAXLINE], recvbuff[MAXLINE];
     int nread; 
     while (fgets(sendbuff, MAXLINE, filein) != NULL) {
     char sendbuff[MAXLINE], recvbuff[MAXLINE];
     int nread; 
     while (fgets(sendbuff, MAXLINE, filein) != NULL) {
-       SockWrite(socket, sendbuff, strlen(sendbuff)); 
-       nread = SockRead(socket, recvbuff, strlen(sendbuff));
+       FullWrite(socket, sendbuff, strlen(sendbuff)); 
+       nread = FullRead(socket, recvbuff, strlen(sendbuff));
        recvbuff[nread] = 0;
        fputs(recvbuff, stdout);
     }
        recvbuff[nread] = 0;
        fputs(recvbuff, stdout);
     }
index f02ac5c846a19851102a8ac9bc5ce02b8e88258b..1793d3fe8c6110132d28406f903ae4f2c832d74b 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: echod -h give all info
  *
  *
  * Usage: echod -h give all info
  *
- * $Id: ElemEchoTCPServer.c,v 1.4 2002/12/03 11:06:05 piccardi Exp $ 
+ * $Id: ElemEchoTCPServer.c,v 1.5 2003/02/02 20:35:33 piccardi Exp $ 
  *
  ****************************************************************/
 /* 
  *
  ****************************************************************/
 /* 
@@ -148,7 +148,7 @@ void ServEcho(int sockfd) {
     /* main loop, reading 0 char means client close connection */
     while ( (nread = read(sockfd, buffer, MAXLINE)) != 0) {
        printf("Letti %d bytes, %s ", nread, buffer);
     /* main loop, reading 0 char means client close connection */
     while ( (nread = read(sockfd, buffer, MAXLINE)) != 0) {
        printf("Letti %d bytes, %s ", nread, buffer);
-       nwrite = SockWrite(sockfd, buffer, nread);
+       nwrite = FullWrite(sockfd, buffer, nread);
     }
     return;
 }
     }
     return;
 }
diff --git a/sources/FullRead.c b/sources/FullRead.c
new file mode 100644 (file)
index 0000000..b7be61f
--- /dev/null
@@ -0,0 +1,54 @@
+/* FullRead.c
+ * 
+ * Copyright (C) 2001 Simone Piccardi
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/****************************************************************
+ *
+ * Routine FullRead
+ * Routine to read an exact number of bytes from a socket
+ *
+ * Author: Simone Piccardi
+ * Jun. 2001
+ *
+ * $Id: FullRead.c,v 1.1 2003/02/02 20:35:33 piccardi Exp $ 
+ *
+ ****************************************************************/
+#include <unistd.h>
+#include <errno.h>
+
+ssize_t FullRead(int fd, void *buf, size_t count) 
+{
+    size_t nleft;
+    ssize_t nread;
+    nleft = count;
+    while (nleft > 0) {             /* repeat until no left */
+       if ( (nread = read(fd, buf, nleft)) < 0) {
+           if (errno == EINTR) {   /* if interrupted by system call */
+               continue;           /* repeat the loop */
+           } else {
+               return(nread);      /* otherwise exit */
+           }
+       } else if (nread == 0) {    /* EOF */
+           break;                  /* break loop here */ 
+       }
+       nleft -= nread;             /* set left to read */
+       buf +=nread;                /* set pointer */
+    }
+    return (count - nleft);
+}
+
diff --git a/sources/FullWrite.c b/sources/FullWrite.c
new file mode 100644 (file)
index 0000000..dbddf1a
--- /dev/null
@@ -0,0 +1,52 @@
+/* FullWrite.c
+ * 
+ * Copyright (C) 2001 Simone Piccardi
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/****************************************************************
+ *
+ * Routine FullWrite
+ * Routine to write an exact number of bytes into a socket
+ *
+ * Author: Simone Piccardi
+ * Jun. 2001
+ *
+ * $Id: FullWrite.c,v 1.1 2003/02/02 20:35:33 piccardi Exp $ 
+ *
+ ****************************************************************/
+#include <unistd.h>
+#include <errno.h>
+
+ssize_t FullWrite(int fd, const void *buf, size_t count) 
+{
+    size_t nleft;
+    ssize_t nwritten;
+
+    nleft = count;
+    while (nleft > 0) {             /* repeat until no left */
+       if ( (nwritten = write(fd, buf, nleft)) < 0) {
+           if (errno == EINTR) {   /* if interrupted by system call */
+               continue;           /* repeat the loop */
+           } else {
+               return(nwritten);   /* otherwise exit with error */
+           }
+       }
+       nleft -= nwritten;          /* set left to write */
+       buf +=nwritten;             /* set pointer */
+    }
+    return (count);
+}
+
index a8e786f49a37448cf9fa72fd79be8d41dad2dfbf..401871c611792106fc9922a6405fb7a0bf642966 100644 (file)
@@ -23,7 +23,7 @@
  *
  * Author: S. Piccardi
  *
  *
  * Author: S. Piccardi
  *
- * $Id: Gapil.h,v 1.5 2003/01/07 23:00:34 piccardi Exp $
+ * $Id: Gapil.h,v 1.6 2003/02/02 20:35:33 piccardi Exp $
  *
  *****************************************************************************/
 #include <sys/sem.h>                           /* IPC semaphore declarations */
  *
  *****************************************************************************/
 #include <sys/sem.h>                           /* IPC semaphore declarations */
@@ -96,12 +96,27 @@ void HandSigCHLD(int sig);
 /* 
  * Socket service functions
  */
 /* 
  * Socket service functions
  */
-/* Function SockRead: to read from a socket. See SockRead.c */
-ssize_t SockRead(int fd, void *buf, size_t count);
-/* Function SockWrite: to read from a socket. See SockWrite.c */
-ssize_t SockWrite(int fd, const void *buf, size_t count);
+/* Function FullRead: to read from a socket. See FullRead.c */
+ssize_t FullRead(int fd, void *buf, size_t count);
+/* Function FullWrite: to read from a socket. See FullWrite.c */
+ssize_t FullWrite(int fd, const void *buf, size_t count);
 /*
  * File miscellaneous
  */
 /*
  * File miscellaneous
  */
-/* Function DirScan: simple scan for a directory */
+/* Function DirScan: simple scan for a directory. See DirScan.c */
 int DirScan(char * dirname, int(*compute)(struct dirent *));
 int DirScan(char * dirname, int(*compute)(struct dirent *));
+/*
+ * Shared memory handling functions. See SharedMem.c
+ */
+/* Function ShmCreate: create a SysV shared memory */
+void * ShmCreate(key_t ipc_key, int shm_size, int perm, char fill);
+/* Function ShmFind: find an existing SysV shared memory */
+void * ShmFind(key_t ipc_key, int shm_size);
+/* Function ShmRemove: remove a SysV shared memory */
+int ShmRemove(key_t ipc_key, void * shm_ptr);
+/* Function CreateShm: create a POSIX shared memory */
+void * CreateShm(char * shm_name, int shm_size, int perm, char fill);
+/* Function FindShm: find an existing POSIX shared memory */
+void * FindShm(char * shm_name, int shm_size);
+/* Function RemoveShm: remove a POSIX shared memory */
+int RemoveShm(char * shm_name);
index 2b6240eb6c58afcc537a70717dc2f0f1a8068fe8..32e5d20ce4f582fa1f1ca9a3f2ab1bd5591e040a 100644 (file)
@@ -8,14 +8,14 @@ CFLAGJ= -L./ -lgapil
 
 LIB = libgapil.so
 
 
 LIB = libgapil.so
 
-OBJ = SockRead.o SockWrite.o SigHand.o Mutex.o SharedMem.o LockFile.o DirScan.o
+OBJ = FullRead.o FullWrite.o SigHand.o Mutex.o SharedMem.o LockFile.o DirScan.o
 
 FINAL = forktest errcode echo echod daytimed iterdaytimed daytime testfopen \
        testren fortune fortuned mqfortune mqfortuned flock myls dirmonitor \
 
 FINAL = forktest errcode echo echod daytimed iterdaytimed daytime testfopen \
        testren fortune fortuned mqfortune mqfortuned flock myls dirmonitor \
-       readmon ipctestid
+       readmon ipctestid writeshm readshm
 
 $(LIB): $(OBJ)
 
 $(LIB): $(OBJ)
-       gcc -shared $^ -o $@
+       gcc -shared -lrt $^ -o $@
 
 $(OBJ): Gapil.h
 
 
 $(OBJ): Gapil.h
 
@@ -84,6 +84,12 @@ daytime: ElemDaytimeTCPClient.c
 ipctestid: IPCTestId.c
        $(CC)  $^ -o $@
 
 ipctestid: IPCTestId.c
        $(CC)  $^ -o $@
 
+writeshm: WriteShm.c
+       $(CC) $(CFLAGJ) $^ -o $@
+
+#readshm: ReadShm.c
+#      $(CC) $(CFLAGJ) $^ -o $@
+
 
 # Macro per la generazione della tarball dei sorgenti
 package: clean gapil_source.tgz
 
 # Macro per la generazione della tarball dei sorgenti
 package: clean gapil_source.tgz
index 23f9c097d30cec89a4953586a25bd73f60550729..eab28f471368364e0ce34b950f81edd22712858f 100644 (file)
 /***************************************************************
  *
  * File SharedMem.c 
 /***************************************************************
  *
  * File SharedMem.c 
- * Routine for Shared Memory use
+ * Routines for Shared Memory use. 
+ *
+ * Define two interfaces, the first one use SysV shared memory, the
+ * second POSIX shared memory.
  *
  * Author: S. Piccardi
  *
  *
  * Author: S. Piccardi
  *
- * $Id: SharedMem.c,v 1.2 2002/12/03 22:30:11 piccardi Exp $
+ * $Id: SharedMem.c,v 1.3 2003/02/02 20:35:33 piccardi Exp $
  *
  ***************************************************************/
 #include <sys/shm.h>                  /* SysV IPC shared memory declarations */
  *
  ***************************************************************/
 #include <sys/shm.h>                  /* SysV IPC shared memory declarations */
 #include <stdio.h>                                 /* standard I/O functions */
 #include <fcntl.h>
 #include <signal.h>                          /* signal handling declarations */
 #include <stdio.h>                                 /* standard I/O functions */
 #include <fcntl.h>
 #include <signal.h>                          /* signal handling declarations */
+#include <unistd.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <errno.h>
+/* *************************************************************************
+ *
+ *  Functions for SysV shared memory
+ *
+ * ************************************************************************* */
 /*
  * Function ShmCreate:
  * Create and attach a SysV shared memory segment to the current process.
 /*
  * Function ShmCreate:
  * Create and attach a SysV shared memory segment to the current process.
  *
  * Input:  an IPC key value
  *         the shared memory segment size
  *
  * Input:  an IPC key value
  *         the shared memory segment size
- * Return: the address of the segment
+ *         the permissions
+ *         the fill value
+ * Return: the address of the shared memory segment (NULL on error)
  */
  */
-void * ShmCreate(key_t ipc_key, int shm_size, char fill) 
+void * ShmCreate(key_t ipc_key, int shm_size, int perm, char fill) 
 {
 {
-    void * shptr;
-    int shmid;                        /* ID of the IPC shared memory segment */
-    shmid = shmget(ipc_key,shm_size,IPC_CREAT|0666);           /* get shm ID */
-    if (shmid < 0) { 
-       return (void *) shmid;
+    void * shm_ptr;
+    int shm_id;                       /* ID of the IPC shared memory segment */
+    shm_id = shmget(ipc_key, shm_size, IPC_CREAT|perm);        /* get shm ID */
+    if (shm_id < 0) { 
+       return NULL;
     }
     }
-    shptr = shmat(shmid,0,0);                      /* take the pointer to it */
-    if ( shptr == 0 ){    
-        perror("cannot attach shared memory");
-       exit(1);
+    shm_ptr = shmat(shm_id, NULL, 0);                  /* map it into memory */
+    if (shm_ptr < 0) {
+       return NULL;
     }
     }
-    memset((void *)shptr, fill, shm_size); /* second counter starts from "0" */
-    return shptr;
+    memset((void *)shm_ptr, fill, shm_size);                 /* fill segment */
+    return shm_ptr;
 }
 /*
  * Function ShmFind:
 }
 /*
  * Function ShmFind:
- * Find a shared memory segment 
+ * Find a SysV shared memory segment 
  * Input:  an IPC key value
  *         the shared memory segment size
  * Input:  an IPC key value
  *         the shared memory segment size
- * Return: the address of the segment
+ * Return: the address of the segment (NULL on error)
  */
 void * ShmFind(key_t ipc_key, int shm_size) 
 {
  */
 void * ShmFind(key_t ipc_key, int shm_size) 
 {
-    void * shptr;
-    int shmid;               /* ID of the IPC shared memory segment */
-    if ( (shmid=shmget(ipc_key,shm_size,0))<0 ){  /* find shared memory ID */
-        perror("cannot find shared memory");
-        exit(1);
+    void * shm_ptr;
+    int shm_id;                      /* ID of the SysV shared memory segment */
+    shm_id = shmget(ipc_key, shm_size, 0);          /* find shared memory ID */
+    if (shm_id < 0) {
+       return NULL;
+    }
+    shm_ptr = shmat(shm_id, NULL, 0);                  /* map it into memory */
+    if (shm_ptr < 0) {
+       return NULL;
+    }
+    return shm_ptr;
+}
+/*
+ * Function ShmRemove:
+ * Scheudle removal for a SysV shared memory segment 
+ * Input:  an IPC key value
+ *         the shared memory segment size
+ * Return: 0 on success, -1 on error
+ */
+int ShmRemove(key_t ipc_key, void * shm_ptr) 
+{
+    int shm_id;                      /* ID of the SysV shared memory segment */
+    /* first detach segment */
+    if (shmdt(shm_ptr) < 0) {
+       return -1;
+    }
+    /* schedule segment removal */
+    shm_id = shmget(ipc_key, 0, 0);                 /* find shared memory ID */
+    if (shm_id < 0) {
+       if (errno == EIDRM) return 0;
+       return -1;
     }
     }
-    if ( (shptr=shmat(shmid,0,0)) < 0 ){    /* take the pointer to it */
-        perror("cannot attach shared memory");
-        exit(1);
+    if (shmctl(shm_id, IPC_RMID, NULL) < 0) {             /* ask for removal */
+       if (errno == EIDRM) return 0;
+       return -1;
     }
     }
-    return shptr;
+    return 0;
+}
+/* *************************************************************************
+ *
+ *  Functions for POSIX shared memory
+ *
+ * ************************************************************************* */
+/*
+ * Function CreateShm:
+ * Create a POSIX shared memory segment and map it to the current process.
+ *
+ *
+ * Input:  a pathname
+ *         the shared memory segment size
+ *         the permissions
+ *         the fill value
+ * Return: the address of the shared memory segment (NULL on error)
+ */
+void * CreateShm(char * shm_name, int shm_size, int perm, char fill) 
+{
+    void * shm_ptr;
+    int fd;
+    int flag;
+    /* first open the object, creating it if not existent */
+    flag = O_RDWR|O_TRUNC|O_CREAT|O_EXCL;
+    fd = shm_open(shm_name, flag, perm);    /* get object file descriptor */
+    if (fd < 0) { 
+       return NULL;
+    }
+    /* set the object size */
+    if (ftruncate(fd, shm_size)) {
+       return NULL;
+    }
+    /* map it in the process address space */
+    shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
+    if (shm_ptr == MAP_FAILED) {
+       return NULL;
+    }
+    memset((void *) shm_ptr, fill, shm_size);                /* fill segment */
+    return shm_ptr;
+}
+/*
+ * Function FindShm:
+ * Find a POSIX shared memory segment 
+ * Input:  a name
+ *         the shared memory segment size
+ * Return: the address of the segment (NULL on error)
+ */
+void * FindShm(char * shm_name, int shm_size) 
+{
+    void * shm_ptr;
+    int fd;                           /* ID of the IPC shared memory segment */
+    /* find shared memory ID */
+    if ((fd = shm_open(shm_name, O_RDWR|O_EXCL, 0)) < 0) {
+       return NULL;
+    }
+    /* take the pointer to it */
+    shm_ptr = mmap(NULL, shm_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
+    if (shm_ptr == MAP_FAILED) {
+       return NULL;
+    }
+    return shm_ptr;
+}
+/*
+ * Function RemoveShm:
+ * Remove a POSIX shared memory segment 
+ * Input:  the object name
+ * Return: 0 on success, -1 on error
+ */
+int RemoveShm(char * shm_name)
+{
+    shm_unlink(shm_name);
+    return 0;
 }
 }
index f6941635986b0151f309ecb6daa462f7cdf6e3ea..70855ad5e8a6c8d7340c341cb83fb22691c78d02 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: echo -h give all info's
  *
  *
  * Usage: echo -h give all info's
  *
- * $Id: SimpleEchoTCPClient.c,v 1.5 2002/12/03 11:06:05 piccardi Exp $
+ * $Id: SimpleEchoTCPClient.c,v 1.6 2003/02/02 20:35:33 piccardi Exp $
  *
  ****************************************************************/
 /* 
  *
  ****************************************************************/
 /* 
@@ -120,8 +120,8 @@ void EchoClient(FILE * filein, int socket)
     char sendbuff[MAXLINE], recvbuff[MAXLINE];
     int nread; 
     while (fgets(sendbuff, MAXLINE, filein) != NULL) {
     char sendbuff[MAXLINE], recvbuff[MAXLINE];
     int nread; 
     while (fgets(sendbuff, MAXLINE, filein) != NULL) {
-       SockWrite(socket, sendbuff, strlen(sendbuff)); 
-       nread = SockRead(socket, recvbuff, strlen(sendbuff));
+       FullWrite(socket, sendbuff, strlen(sendbuff)); 
+       nread = FullRead(socket, recvbuff, strlen(sendbuff));
        recvbuff[nread] = 0;
        fputs(recvbuff, stdout);
     }
        recvbuff[nread] = 0;
        fputs(recvbuff, stdout);
     }
index d4ba728fcb0ab2d65109ef41db4690a68be54b00..890954d5915655f0526139a9ce1499101c217d79 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: echod
  *
  *
  * Usage: echod
  *
- * $Id: SimpleEchoTCPServer.c,v 1.5 2002/12/03 11:06:05 piccardi Exp $ 
+ * $Id: SimpleEchoTCPServer.c,v 1.6 2003/02/02 20:35:34 piccardi Exp $ 
  *
  ****************************************************************/
 /* 
  *
  ****************************************************************/
 /* 
@@ -147,7 +147,7 @@ void SockEcho(int sockfd) {
     /* main loop, reading 0 char means client close connection */
     while ( (nread = read(sockfd, buffer, MAXLINE)) != 0) {
        printf("Letti %d bytes, %s ", nread, buffer);
     /* main loop, reading 0 char means client close connection */
     while ( (nread = read(sockfd, buffer, MAXLINE)) != 0) {
        printf("Letti %d bytes, %s ", nread, buffer);
-       nwrite = SockWrite(sockfd, buffer, nread);
+       nwrite = FullWrite(sockfd, buffer, nread);
     }
     return;
 }
     }
     return;
 }
diff --git a/sources/SockRead.c b/sources/SockRead.c
deleted file mode 100644 (file)
index a018f33..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* SockRead.c
- * 
- * Copyright (C) 2001 Simone Piccardi
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/****************************************************************
- *
- * Routine SockRead
- * Routine to read an exact number of bytes from a socket
- *
- * Author: Simone Piccardi
- * Jun. 2001
- *
- * $Id: SockRead.c,v 1.3 2001/09/09 22:45:34 piccardi Exp $ 
- *
- ****************************************************************/
-#include <unistd.h>
-#include <errno.h>
-
-ssize_t SockRead(int fd, void *buf, size_t count) 
-{
-    size_t nleft;
-    ssize_t nread;
-    nleft = count;
-    while (nleft > 0) {             /* repeat until no left */
-       if ( (nread = read(fd, buf, nleft)) < 0) {
-           if (errno == EINTR) {   /* if interrupted by system call */
-               continue;           /* repeat the loop */
-           } else {
-               return(nread);      /* otherwise exit */
-           }
-       } else if (nread == 0) {    /* EOF */
-           break;                  /* break loop here */ 
-       }
-       nleft -= nread;             /* set left to read */
-       buf +=nread;                /* set pointer */
-    }
-    return (count - nleft);
-}
-
diff --git a/sources/SockWrite.c b/sources/SockWrite.c
deleted file mode 100644 (file)
index c0a41d9..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SockWrite.c
- * 
- * Copyright (C) 2001 Simone Piccardi
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/****************************************************************
- *
- * Routine SockWrite
- * Routine to write an exact number of bytes into a socket
- *
- * Author: Simone Piccardi
- * Jun. 2001
- *
- * $Id: SockWrite.c,v 1.3 2001/09/09 22:45:34 piccardi Exp $ 
- *
- ****************************************************************/
-#include <unistd.h>
-#include <errno.h>
-
-ssize_t SockWrite(int fd, const void *buf, size_t count) 
-{
-    size_t nleft;
-    ssize_t nwritten;
-
-    nleft = count;
-    while (nleft > 0) {             /* repeat until no left */
-       if ( (nwritten = write(fd, buf, nleft)) < 0) {
-           if (errno == EINTR) {   /* if interrupted by system call */
-               continue;           /* repeat the loop */
-           } else {
-               return(nwritten);   /* otherwise exit with error */
-           }
-       }
-       nleft -= nwritten;          /* set left to write */
-       buf +=nwritten;             /* set pointer */
-    }
-    return (count);
-}
-