From 6483a787322c614bc6282a0bf0ee001f1bf54b44 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Tue, 3 Dec 2002 11:06:05 +0000 Subject: [PATCH] Revisione completa (e relativa razionalizzazione) dei sorgenti degli esempi. Si e` provveduto anche a mettere il tutto in una bella libreria ... --- ipc.tex | 30 ++--- signal.tex | 25 ++-- sources/ElemEchoTCPClient.c | 4 +- sources/ElemEchoTCPServer.c | 3 +- sources/ErrCode.c | 3 +- sources/ForkTest.c | 6 +- sources/FortuneServer.c | 4 +- sources/Gapil.h | 67 +++++++++++ sources/HandSIGCHLD.c | 27 ----- sources/LockFile.c | 37 ++++++ sources/MQFortuneClient.c | 3 +- sources/MQFortuneServer.c | 4 +- sources/Makefile | 73 ++++++------ sources/Mutex.c | 93 +++++++++++++++ sources/SharedMem.c | 69 +++++++++++ sources/SigHand.c | 74 ++++++++++++ sources/SimpleEchoTCPClient.c | 4 +- sources/SimpleEchoTCPServer.c | 4 +- sources/wrappers.h | 214 ---------------------------------- 19 files changed, 420 insertions(+), 324 deletions(-) create mode 100644 sources/Gapil.h delete mode 100644 sources/HandSIGCHLD.c create mode 100644 sources/LockFile.c create mode 100644 sources/Mutex.c create mode 100644 sources/SharedMem.c create mode 100644 sources/SigHand.c delete mode 100644 sources/wrappers.h diff --git a/ipc.tex b/ipc.tex index 7bf4186..63b1557 100644 --- a/ipc.tex +++ b/ipc.tex @@ -2441,7 +2441,7 @@ ripristino non Come esempio di uso dell'interfaccia dei semafori vediamo come implementare con essa dei semplici \textit{mutex} (cioè semafori binari), tutto il codice -in questione, contenuto nel file \file{wrappers.h} allegato ai sorgenti, è +in questione, contenuto nel file \file{Mutex.c} allegato ai sorgenti, è riportato in \figref{fig:ipc_mutex_create}. Utilizzeremo l'interfaccia per creare un insieme contenente un singolo semaforo, per il quale poi useremo un valore unitario per segnalare la disponibilità della risorsa, ed un valore @@ -2887,18 +2887,18 @@ memoria condivisa; questo viene identificato con l'indirizzo \param{shmaddr} restituito dalla precedente chiamata a \func{shmat} con il quale era stato agganciato al processo. -Per capire meglio il funzionamento delle funzioni facciamo ancora una volta -riferimento alle strutture con cui il kernel implementa i segmenti di memoria -condivisa; uno schema semplificato della struttura è illustrato in -\figref{fig:ipc_shm_struct}. +%% Per capire meglio il funzionamento delle funzioni facciamo ancora una volta +%% riferimento alle strutture con cui il kernel implementa i segmenti di memoria +%% condivisa; uno schema semplificato della struttura è illustrato in +%% \figref{fig:ipc_shm_struct}. -\begin{figure}[htb] - \centering - \includegraphics[width=10cm]{img/shmstruct} - \caption{Schema dell'implementazione dei segmenti di memoria condivisa in - Linux.} - \label{fig:ipc_shm_struct} -\end{figure} +%% \begin{figure}[htb] +%% \centering +%% \includegraphics[width=10cm]{img/shmstruct} +%% \caption{Schema dell'implementazione dei segmenti di memoria condivisa in +%% Linux.} +%% \label{fig:ipc_shm_struct} +%% \end{figure} @@ -2980,9 +2980,9 @@ quella di segnalare l'occupazione di una risorsa, senza necessit che questa si liberi; ad esempio la si usa spesso per evitare interferenze sull'uso delle porte seriali da parte di più programmi: qualora si trovi un file di lock il programma che cerca di accedere alla seriale si limita a -segnalare che la risorsa non è disponibile; sempre in \file{wrapper.h} si sono -predisposte due funzioni, \func{LockFile} e \func{UnlockFile}, da utilizzare -allo scopo. +segnalare che la risorsa non è disponibile; in \file{LockFile.c} (un'altro dei +sorgenti allegati alla guida) si sono predisposte due funzioni, +\func{LockFile} e \func{UnlockFile}, da utilizzare allo scopo. Dato che i file di lock presentano gli inconvenienti illustrati in precedenza, la tecnica alternativa più comune è quella di fare ricorso al \textit{file diff --git a/signal.tex b/signal.tex index 7cbda4f..4d748d9 100644 --- a/signal.tex +++ b/signal.tex @@ -1984,25 +1984,24 @@ inline SigFunc * Signal(int signo, SigFunc *func) Per questo motivo si è provveduto, per mantenere un'interfaccia semplificata che abbia le stesse caratteristiche di \func{signal}, a definire una funzione equivalente attraverso \func{sigaction}; la funzione è \code{Signal}, e si -trova definita come \code{inline} nel file \file{wrapper.h} (nei sorgenti -allegati), riportata in \figref{fig:sig_Signal_code}. La riutilizzeremo spesso -in seguito. +trova definita nel file \file{SigHand.c} (nei sorgenti allegati), e riportata +in \figref{fig:sig_Signal_code}. La riutilizzeremo spesso in seguito. \subsection{La gestione della \textsl{maschera dei segnali} o \textit{signal mask}} \label{sec:sig_sigmask} Come spiegato in \secref{sec:sig_semantics} tutti i moderni sistemi unix-like -permettono si bloccare temporaneamente (o di eliminare completamente, impostando -\macro{SIG\_IGN} come azione) la consegna dei segnali ad un processo. Questo è -fatto specificando la cosiddetta \textsl{maschera dei segnali} (o -\textit{signal mask}) del processo\footnote{nel caso di Linux essa è mantenuta - dal campo \var{blocked} della \var{task\_struct} del processo.} cioè -l'insieme dei segnali la cui consegna è bloccata. Abbiamo accennato in -\secref{sec:proc_fork} che la \textit{signal mask} viene ereditata dal padre -alla creazione di un processo figlio, e abbiamo visto al paragrafo precedente -che essa può essere modificata, durante l'esecuzione di un gestore, -attraverso l'uso dal campo \var{sa\_mask} di \var{sigaction}. +permettono si bloccare temporaneamente (o di eliminare completamente, +impostando \macro{SIG\_IGN} come azione) la consegna dei segnali ad un +processo. Questo è fatto specificando la cosiddetta \textsl{maschera dei + segnali} (o \textit{signal mask}) del processo\footnote{nel caso di Linux + essa è mantenuta dal campo \var{blocked} della \var{task\_struct} del + processo.} cioè l'insieme dei segnali la cui consegna è bloccata. Abbiamo +accennato in \secref{sec:proc_fork} che la \textit{signal mask} viene +ereditata dal padre alla creazione di un processo figlio, e abbiamo visto al +paragrafo precedente che essa può essere modificata, durante l'esecuzione di +un gestore, attraverso l'uso dal campo \var{sa\_mask} di \var{sigaction}. Uno dei problemi evidenziatisi con l'esempio di \secref{fig:sig_event_wrong} è che in molti casi è necessario proteggere delle sezioni di codice (nel caso in diff --git a/sources/ElemEchoTCPClient.c b/sources/ElemEchoTCPClient.c index 57b8fa1..ac1d991 100644 --- a/sources/ElemEchoTCPClient.c +++ b/sources/ElemEchoTCPClient.c @@ -26,7 +26,7 @@ * * Usage: echo -h give all info's * - * $Id: ElemEchoTCPClient.c,v 1.3 2001/09/09 22:45:34 piccardi Exp $ + * $Id: ElemEchoTCPClient.c,v 1.4 2002/12/03 11:06:05 piccardi Exp $ * ****************************************************************/ /* @@ -38,8 +38,6 @@ #include /* socket library */ #include /* include standard I/O library */ -#include "wrappers.h" - #define MAXLINE 256 void usage(void); void ClientEcho(FILE * filein, int socket); diff --git a/sources/ElemEchoTCPServer.c b/sources/ElemEchoTCPServer.c index ba36b95..f02ac5c 100644 --- a/sources/ElemEchoTCPServer.c +++ b/sources/ElemEchoTCPServer.c @@ -26,7 +26,7 @@ * * Usage: echod -h give all info * - * $Id: ElemEchoTCPServer.c,v 1.3 2001/09/09 17:39:15 piccardi Exp $ + * $Id: ElemEchoTCPServer.c,v 1.4 2002/12/03 11:06:05 piccardi Exp $ * ****************************************************************/ /* @@ -39,7 +39,6 @@ #include /* include standard I/O library */ #include -#include "wrappers.h" #define BACKLOG 10 #define MAXLINE 256 diff --git a/sources/ErrCode.c b/sources/ErrCode.c index aaec2cc..b59da7f 100644 --- a/sources/ErrCode.c +++ b/sources/ErrCode.c @@ -26,7 +26,7 @@ * * Usage: errcode -h give all info's * - * $Id: ErrCode.c,v 1.4 2001/10/14 15:05:33 piccardi Exp $ + * $Id: ErrCode.c,v 1.5 2002/12/03 11:06:05 piccardi Exp $ * ****************************************************************/ /* @@ -37,6 +37,7 @@ #include /* unix standard library */ #include /* standard I/O library */ #include /* string functions */ +#include /* system limits values */ /* Help printing routine */ void usage(void); diff --git a/sources/ForkTest.c b/sources/ForkTest.c index a4f0296..edec00e 100644 --- a/sources/ForkTest.c +++ b/sources/ForkTest.c @@ -26,7 +26,7 @@ * * Usage: forktest -h give all info's * - * $Id: ForkTest.c,v 1.7 2002/08/18 23:24:44 piccardi Exp $ + * $Id: ForkTest.c,v 1.8 2002/12/03 11:06:05 piccardi Exp $ * ****************************************************************/ /* @@ -38,7 +38,7 @@ #include /* standard I/O library */ #include /* string functions */ -#include "wrappers.h" +#include "Gapil.h" #include "macros.h" /* Help printing routine */ @@ -79,7 +79,7 @@ int main(int argc, char *argv[]) wait_end = strtol(optarg, NULL, 10); /* convert input */ break; case 's': - Signal(SIGCHLD, HandSIGCHLD); + Signal(SIGCHLD, HandSigCHLD); break; case '?': /* unrecognized options */ printf("Unrecognized options -%c\n",optopt); diff --git a/sources/FortuneServer.c b/sources/FortuneServer.c index 69e3b34..7e3dfb6 100644 --- a/sources/FortuneServer.c +++ b/sources/FortuneServer.c @@ -26,7 +26,7 @@ * * Usage: fortuned -h give all info * - * $Id: FortuneServer.c,v 1.4 2002/08/19 17:34:23 piccardi Exp $ + * $Id: FortuneServer.c,v 1.5 2002/12/03 11:06:05 piccardi Exp $ * ****************************************************************/ /* @@ -43,7 +43,7 @@ #include /* */ #include "macros.h" -#include "wrappers.h" +#include "Gapil.h" /* Subroutines declaration */ void usage(void); diff --git a/sources/Gapil.h b/sources/Gapil.h new file mode 100644 index 0000000..00dc3a6 --- /dev/null +++ b/sources/Gapil.h @@ -0,0 +1,67 @@ +/***************************************************************************** + * + * File Gapil.h: + * Set of definition for service routines + * + * Author: S. Piccardi + * + * $Id: Gapil.h,v 1.1 2002/12/03 11:06:05 piccardi Exp $ + * + *****************************************************************************/ +#include /* IPC semaphore declarations */ +#include /* IPC shared memory declarations */ +#include +#include +#include /* unix standard functions */ +#include /* file control (lock) functions */ +#include /* signal handling declarations */ +/* + * Definition of semun struct; used to implement a MutexXXXX API To + * create a Mutex use an underlaying semaphore and init it; we put + * here all the needed data structures + */ +/* use this definition, get from the man pages */ +#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) +/* union semun is defined by including */ +#else +/* according to X/OPEN we have to define it ourselves */ +union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ + unsigned short int *array; /* array for GETALL, SETALL */ + struct seminfo *__buf; /* buffer for IPC_INFO */ +}; +#endif +/* + * Mutex handling Functions + */ +/* Function MutexCreate: create a mutex. See Mutex.c */ +inline int MutexCreate(key_t ipc_key); +/* Function MutexFind: get the mutex ID given fomr IPC key. See Mutex.c */ +inline int MutexFind(key_t ipc_key); +/* Function MutexRead: read the current value of the mutex. See Mutex.c */ +inline int MutexRead(int sem_id); +/* Function MutexLock: to lock a mutex/semaphore. See Mutex.c */ +inline int MutexLock(int sem_id); +/* Function MutexUnlock: to unlock a mutex/semaphore. See Mutex.c */ +inline int MutexUnlock(int sem_id); + +/* Function LockFile: create a lock file. See FileLock.c*/ +inline int LockFile(const char* path_name); +/* Function UnLockFile: remove a lock file. See FileLock.c*/ +inline int UnlockFile(const char* path_name); +/* + * Signal Handling Functions + */ +typedef void SigFunc(int); +/* Function Signal: Initialize a signal handler. See SigHand.c */ +SigFunc * Signal(int signo, SigFunc *func); +/* Function HandSigCHLD: to handle SIGCHILD. See SigHand.c */ +void HandSigCHLD(int sig); +/* + * 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); diff --git a/sources/HandSIGCHLD.c b/sources/HandSIGCHLD.c deleted file mode 100644 index 04f9753..0000000 --- a/sources/HandSIGCHLD.c +++ /dev/null @@ -1,27 +0,0 @@ -#include /* error simbol definitions */ -#include /* signal handling declarations */ -#include -#include - -#include "macros.h" - -void HandSIGCHLD(int sig) -{ - int errno_save; - int status; - pid_t pid; - /* save errno current value */ - errno_save = errno; - /* loop until no */ - do { - errno = 0; - pid = waitpid(WAIT_ANY, &status, WNOHANG); - if (pid > 0) { - debug("child %d terminated with status %x\n", pid, status); - } - } while ((pid > 0) && (errno == EINTR)); - /* restore errno value*/ - errno = errno_save; - /* return */ - return; -} diff --git a/sources/LockFile.c b/sources/LockFile.c new file mode 100644 index 0000000..492c23c --- /dev/null +++ b/sources/LockFile.c @@ -0,0 +1,37 @@ +/***************************************************************************** + * + * File LockFile.h: + * Function to manipulate lock files. + * + * Author: S. Piccardi, Dec 2002 + * + * $Id: LockFile.c,v 1.1 2002/12/03 11:06:05 piccardi Exp $ + * + *****************************************************************************/ +#include +#include +#include /* unix standard functions */ +#include /* file control (lock) functions */ +/* + * Function LockFile: + * + * Create a lockfile of the given pathname. Fail and exit in case of + * error or existence of the same lock file, using unlink do not need + * to remove the file. + * + * Author: Simone Piccardi, Dec. 2002 + */ +int LockFile(const char* path_name) +{ + return open(path_name, O_EXCL|O_CREAT); +} +/* + * Function UnlockFile: + * Remove a lockfile of the given pathname. + * + * Author: Simone Piccardi, Dec. 2002 + */ +int UnlockFile(const char* path_name) +{ + return unlink(path_name); +} diff --git a/sources/MQFortuneClient.c b/sources/MQFortuneClient.c index c001ea3..a26f672 100644 --- a/sources/MQFortuneClient.c +++ b/sources/MQFortuneClient.c @@ -26,7 +26,7 @@ * * Usage: fortune -h give all info * - * $Id: MQFortuneClient.c,v 1.1 2002/10/20 22:42:48 piccardi Exp $ + * $Id: MQFortuneClient.c,v 1.2 2002/12/03 11:06:05 piccardi Exp $ * ****************************************************************/ /* @@ -44,7 +44,6 @@ #include #include "macros.h" -#include "wrappers.h" /* Maximum message size */ #define MSGMAX 8192 diff --git a/sources/MQFortuneServer.c b/sources/MQFortuneServer.c index 4d4ec74..cae21ea 100644 --- a/sources/MQFortuneServer.c +++ b/sources/MQFortuneServer.c @@ -26,7 +26,7 @@ * * Usage: fortuned -h give all info * - * $Id: MQFortuneServer.c,v 1.2 2002/10/20 22:40:34 piccardi Exp $ + * $Id: MQFortuneServer.c,v 1.3 2002/12/03 11:06:05 piccardi Exp $ * ****************************************************************/ /* @@ -44,7 +44,7 @@ #include #include "macros.h" -#include "wrappers.h" +#include "Gapil.h" /* Maximum message size */ #define MSGMAX 8192 diff --git a/sources/Makefile b/sources/Makefile index e2c9331..64f7648 100644 --- a/sources/Makefile +++ b/sources/Makefile @@ -2,72 +2,76 @@ # Simple Makefile to build examples # # C flags -CC=gcc -DDEBUG -CFLAGS= -Wall -g -CFLADJ=-c +CC=gcc +CFLAGS= -Wall -g -DDEBUG -fPIC +CFLAGJ= -L./ -lgapil -OBJ = SockRead.o SockWrite.o +LIB = libgapil.so + +OBJ = SockRead.o SockWrite.o SigHand.o Mutex.o SharedMem.o LockFile.o FINAL = forktest errcode echo echod daytimed iterdaytimed daytime testfopen \ - testren fortune fortuned + testren fortune fortuned mqfortune mqfortuned flock + +$(LIB): $(OBJ) + gcc -shared $^ -o $@ + + +$(OBJ): Gapil.h + +all: $(FINAL) $(LIB) + flock: Flock.c - $(CC) $^ -o $@ + $(CC) $(CFLAGJ) $^ -o $@ mqfortune: MQFortuneClient.c - $(CC) $^ -o $@ + $(CC) $(CFLAGJ) $^ -o $@ mqfortuned: MQFortuneServer.c FortuneParse.c - $(CC) $^ -o $@ + $(CC) $(CFLAGJ) $^ -o $@ fortune: FortuneClient.c - $(CC) $^ -o $@ + $(CC) $(CFLAGJ) $^ -o $@ fortuned: FortuneServer.c FortuneParse.c - $(CC) $^ -o $@ + $(CC) $(CFLAGJ) $^ -o $@ barcode: BarCode.c - $(CC) $(CFLAGS) $^ -o $@ - + $(CC) $(CFLAGJ) $^ -o $@ barcodepage: BarCodePage.c - $(CC) $(CFLAGS) $^ -o $@ - + $(CC) $(CFLAGJ) $^ -o $@ getparam: getparam.c - $(CC) $(CFLAGS) $^ -o $@ - -all: $(FINAL) - + $(CC) $(CFLAGJ) $^ -o $@ testfopen: test_fopen.c - $(CC) $(CFLAGS) $^ -o $@ + $(CC) $(CFLAGJ) $^ -o $@ testren: TestRen.c - $(CC) $(CFLAGS) $^ -o $@ + $(CC) $(CFLAGJ) $^ -o $@ -forktest: ForkTest.c HandSIGCHLD.c - $(CC) $(CFLAGS) $^ -o $@ +forktest: ForkTest.c + $(CC) $(CFLAGJ) $^ -o $@ errcode: ErrCode.c - $(CC) $(CFLAGS) $^ -o $@ + $(CC) $(CFLAGJ) $^ -o $@ -echo: SimpleEchoTCPClient.c $(OBJ) - $(CC) $(CFLAGS) $^ -o $@ +echo: SimpleEchoTCPClient.c + $(CC) $(CFLAGJ) $^ -o $@ -echod: SimpleEchoTCPServer.c $(OBJ) - $(CC) $(CFLAGS) $^ -o $@ +echod: SimpleEchoTCPServer.c + $(CC) $(CFLAGJ) $^ -o $@ daytimed: ElemDaytimeTCPCuncServ.c - $(CC) $(CFLAGS) $^ -o $@ - -iterdaytimed: SimpleDaytimeTCPServer.c - $(CC) $(CFLAGS) $^ -o $@ + $(CC) $(CFLAGJ) $^ -o $@ -daytime: SimpleDaytimeTCPClient.c - $(CC) $(CFLAGS) $^ -o $@ +iterdaytimed: ElemDaytimeTCPServer.c + $(CC) $(CFLAGJ) $^ -o $@ -$(OBJ): wrappers.h +daytime: ElemDaytimeTCPClient.c + $(CC) $(CFLAGJ) $^ -o $@ # Macro per la generazione della tarball dei sorgenti @@ -84,5 +88,6 @@ clean: rm -f $(FINAL) rm -f *~ rm -f *.o + rm -f *.so rm -f prova* rm -f output* diff --git a/sources/Mutex.c b/sources/Mutex.c new file mode 100644 index 0000000..78b4fca --- /dev/null +++ b/sources/Mutex.c @@ -0,0 +1,93 @@ +/***************************************************************************** + * + * File Mutex.c: define a set of functions for mutex manipulation + * + * Author: S. Piccardi Dec. 2002 + * + * $Id: Mutex.c,v 1.1 2002/12/03 11:06:05 piccardi Exp $ + * + *****************************************************************************/ +#include /* IPC semaphore declarations */ +#include +#include +#include +#include /* signal handling declarations */ + +#include "Gapil.h" +/* + * Function MutexCreate: create a mutex/semaphore + * + * First call create a semaphore, using the given key. + * We want only one semaphore so we set second argument to 1; third + * parameter is the flag argument, and is set to create a semaphore + * with R/W privilege for the user. + * Second call initialize the semaphore to 1 (unlocked) + * + * Input: an IPC key value (to create an unique semaphore) + * Return: the semaphore id# or -1 on error + */ +int MutexCreate(key_t ipc_key) +{ + const union semun semunion={1}; /* semaphore union structure */ + int sem_id, ret; + sem_id = semget(ipc_key, 1, IPC_CREAT|0666); /* get semaphore ID */ + if (sem_id == -1) { /* if error return code */ + return sem_id; + } + ret = semctl(sem_id, 0, SETVAL, semunion); /* init semaphore */ + if (ret == -1) { + return ret; + } + return sem_id; +} +/* + * Function MutexFind: get the semaphore/mutex Id given the IPC key value + * + * Input: an IPC key value + */ +int MutexFind(key_t ipc_key) +{ + return semget(ipc_key,1,0); +} +/* + * Function MutexRead: read the current value of the mutex/semaphore + * + * Input: a semaphore id # + * Return: the semaphore value + */ +int MutexRead(int sem_id) +{ + return semctl(sem_id, 0, GETVAL); +} +/* + * Define sembuf structures to lock and unlock the semaphore + * (used to implement a mutex) + */ +struct sembuf sem_lock={ /* to lock semaphore */ + 0, /* semaphore number (only one so 0) */ + -1, /* operation (-1 to use resource) */ + SEM_UNDO}; /* flag (set for undo at exit) */ +struct sembuf sem_ulock={ /* to unlock semaphore */ + 0, /* semaphore number (only one so 0) */ + 1, /* operation (1 to release resource) */ + SEM_UNDO}; /* flag (in this case 0) */ +/* + * Function MutexLock: to lock a mutex/semaphore + * + * Input: a semaphore id # + * Output: semop return code (0 OK, -1 KO) + */ +int MutexLock(int sem_id) +{ + return semop(sem_id, &sem_lock, 1); +} +/* + * Function MutexUnlock: to unlock a mutex/semaphore + * + * Input: a semaphore id # + * Return: semop return code (0 OK, -1 KO) + */ +int MutexUnlock(int sem_id) +{ + return semop(sem_id, &sem_ulock, 1); +} diff --git a/sources/SharedMem.c b/sources/SharedMem.c new file mode 100644 index 0000000..2715ca1 --- /dev/null +++ b/sources/SharedMem.c @@ -0,0 +1,69 @@ +/*************************************************************** + * + * File SharedMem.c + * Routine for Shared Memory use + * + * Author: S. Piccardi + * + * $Id: SharedMem.c,v 1.1 2002/12/03 11:06:05 piccardi Exp $ + * + ***************************************************************/ +#include /* SysV IPC shared memory declarations */ +#include +#include +#include /* standard I/O functions */ +#include +#include /* signal handling declarations */ +/* + * Function ShmCreate: + * Create and attach a SysV shared memory segment to the current process. + * + * First call get a shared memory segment with KEY key access and size SIZE, + * by creating it with R/W privilege for the user (this is the meaning of + * the ored flags). The function return an identifier shmid used for any + * further reference to the shared memory segment. + * Second call attach the shared memory segment to this process and return a + * pointer to it (of void * type). + * Then initialize shared memory to the given value + * + * Input: an IPC key value + * the shared memory segment size + * Return: the address of the segment + */ +void * ShmCreate(key_t ipc_key, int shm_size, 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; + } + shptr = shmat(shmid,0,0); /* take the pointer to it */ + if ( shptr == 0 ){ + perror("cannot attach shared memory"); + exit(1); + } + memset((void *)shptr, fill, shm_size); /* second counter starts from "0" */ + return shptr; +} +/* + * Function ShmFind: + * Find a shared memory segment + * Input: an IPC key value + * the shared memory segment size + * Return: the address of the segment + */ +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); + } + if ( (shptr=shmat(shmid,0,0)) < 0 ){ /* take the pointer to it */ + perror("cannot attach shared memory"); + exit(1); + } + return shptr; +} diff --git a/sources/SigHand.c b/sources/SigHand.c new file mode 100644 index 0000000..12a7c5b --- /dev/null +++ b/sources/SigHand.c @@ -0,0 +1,74 @@ +/***************************************************************************** + * + * File SigHand.c: define a set of functions for signal manipulation + * + * Author: S. Piccardi Dec. 2002 + * + * $Id: SigHand.c,v 1.1 2002/12/03 11:06:05 piccardi Exp $ + * + *****************************************************************************/ +#include /* error simbol definitions */ +#include /* standard I/O functions */ +#include /* signal handling declarations */ +#include +#include + +#include "Gapil.h" +#include "macros.h" + +/* + * Function Signal + * Initialize a signal handler. + * To enable the signal handling a process we need to tell it to + * kernel; this is done writing all needed info to a sigaction structure + * named sigact, and then callind sigaction() system call passing the + * information stored in the sigact structure variable. + * + * Input: the signal to handle + * the signal handler function + * Return: the previous sigaction structure + */ +inline SigFunc * Signal(int signo, SigFunc *func) +{ + struct sigaction new_handl, old_handl; + new_handl.sa_handler=func; + /* clear signal mask: no signal blocked during execution of func */ + if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */ + perror("cannot initializes the signal set to empty"); /* see mess. */ + exit(1); + } + new_handl.sa_flags=0; /* init to 0 all flags */ + /* change action for signo signal */ + if (sigaction(signo,&new_handl,&old_handl)){ + perror("sigaction failed on signal action setting"); + exit(1); + } + return (old_handl.sa_handler); +} +/* + * Functions: HandSigCHLD + * Generic handler for SIGCHLD signal + * + * Simone Piccardi Dec. 2002 + * $Id: SigHand.c,v 1.1 2002/12/03 11:06:05 piccardi Exp $ + */ +void HandSigCHLD(int sig) +{ + int errno_save; + int status; + pid_t pid; + /* save errno current value */ + errno_save = errno; + /* loop until no */ + do { + errno = 0; + pid = waitpid(WAIT_ANY, &status, WNOHANG); + if (pid > 0) { + debug("child %d terminated with status %x\n", pid, status); + } + } while ((pid > 0) && (errno == EINTR)); + /* restore errno value*/ + errno = errno_save; + /* return */ + return; +} diff --git a/sources/SimpleEchoTCPClient.c b/sources/SimpleEchoTCPClient.c index 5661f87..f694163 100644 --- a/sources/SimpleEchoTCPClient.c +++ b/sources/SimpleEchoTCPClient.c @@ -26,7 +26,7 @@ * * Usage: echo -h give all info's * - * $Id: SimpleEchoTCPClient.c,v 1.4 2001/09/09 22:45:34 piccardi Exp $ + * $Id: SimpleEchoTCPClient.c,v 1.5 2002/12/03 11:06:05 piccardi Exp $ * ****************************************************************/ /* @@ -38,8 +38,6 @@ #include /* socket library */ #include /* include standard I/O library */ -#include "wrappers.h" - #define MAXLINE 256 void usage(void); void EchoClient(FILE * filein, int socket); diff --git a/sources/SimpleEchoTCPServer.c b/sources/SimpleEchoTCPServer.c index beda574..d4ba728 100644 --- a/sources/SimpleEchoTCPServer.c +++ b/sources/SimpleEchoTCPServer.c @@ -26,7 +26,7 @@ * * Usage: echod * - * $Id: SimpleEchoTCPServer.c,v 1.4 2001/09/09 22:45:34 piccardi Exp $ + * $Id: SimpleEchoTCPServer.c,v 1.5 2002/12/03 11:06:05 piccardi Exp $ * ****************************************************************/ /* @@ -39,8 +39,6 @@ #include /* include standard I/O library */ #include -#include "wrappers.h" - #define BACKLOG 10 #define MAXLINE 256 diff --git a/sources/wrappers.h b/sources/wrappers.h deleted file mode 100644 index ed4a19b..0000000 --- a/sources/wrappers.h +++ /dev/null @@ -1,214 +0,0 @@ -/*************************************************************** - * - * File wrappers.h: define a set of macro and inlined - * functions for signal, shared memory and semaphore handling - * - * Author: S. Piccardi - * - * $Id: wrappers.h,v 1.5 2002/12/02 23:06:59 piccardi Exp $ - * - ***************************************************************/ -#include /* IPC semaphore declarations */ -#include /* IPC shared memory declarations */ -#include -#include -#include -#include /* signal handling declarations */ -/** - ** Semaphore definition; used to implement a MutexXXXX API - ** To create a Mutex use an underlaying semaphore and init it; - ** we put here all the needed data structires - **/ -/* put this definition, get from the man pages */ -#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) -/* union semun is defined by including */ -#else -/* according to X/OPEN we have to define it ourselves */ -union semun { - int val; /* value for SETVAL */ - struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ - unsigned short int *array; /* array for GETALL, SETALL */ - struct seminfo *__buf; /* buffer for IPC_INFO */ -}; -#endif -/* - * Function MutexCreate: create a mutex/semaphore - * - * First call create a semaphore, using the given key. - * We want only one semaphore so we set second argument to 1; third - * parameter is the flag argument, and is set to create a semaphore - * with R/W privilege for the user. - * Second call initialize the semaphore to 1 (unlocked) - * - * Input: an IPC key value (to create an unique semaphore) - * Return: the semaphore id# or -1 on error - */ -inline int MutexCreate(key_t ipc_key) -{ - const union semun semunion={1}; /* semaphore union structure */ - int sem_id, ret; - sem_id = semget(ipc_key, 1, IPC_CREAT|0666); /* get semaphore ID */ - if (sem_id == -1) { /* if error return code */ - return sem_id; - } - ret = semctl(sem_id, 0, SETVAL, semunion); /* init semaphore */ - if (ret == -1) { - return ret; - } - return sem_id; -} -/* - * Function MutexFind: get the semaphore/mutex Id given the IPC key value - * - * Input: an IPC key value - */ -inline int MutexFind(key_t ipc_key) -{ - return semget(ipc_key,1,0); -} -/* - * Function MutexRead: read the current value of the mutex/semaphore - * - * Input: a semaphore id # - * Return: the semaphore value - */ -inline int MutexRead(int sem_id) -{ - return semctl(sem_id, 0, GETVAL); -} -/* - * Define sembuf structures to lock and unlock the semaphore - * (used to implement a mutex) - */ -struct sembuf sem_lock={ /* to lock semaphore */ - 0, /* semaphore number (only one so 0) */ - -1, /* operation (-1 to use resource) */ - SEM_UNDO}; /* flag (set for undo at exit) */ -struct sembuf sem_ulock={ /* to unlock semaphore */ - 0, /* semaphore number (only one so 0) */ - 1, /* operation (1 to release resource) */ - SEM_UNO}; /* flag (in this case 0) */ -/* - * Function MutexLock: to lock a mutex/semaphore - * - * Input: a semaphore id # - * Output: semop return code (0 OK, -1 KO) - */ -inline int MutexLock(int sem_id) -{ - return semop(sem_id, &sem_lock, 1); -} -/* - * Function MutexUnlock: to unlock a mutex/semaphore - * - * Input: a semaphore id # - * Return: semop return code (0 OK, -1 KO) - */ -inline int MutexUnlock(int sem_id) -{ - return semop(sem_id, &sem_ulock, 1); -} -/* - * Function ShmCreate: - * Allocate a shared memory segment. - * First call get a shared memory segment with KEY key access and size SIZE, - * by creating it with R/W privilege for the user (this is the meaning of - * the ored flags). The function return an identifier shmid used for any - * further reference to the shared memory segment. - * Second call attach the shared memory segment to this process and return a - * pointer to it (of char * type). - * Then initialize shared memory: - * Set all to 0x55 (means 0101 un binary notation - * - * Input: an IPC key value - * the shared memory segment size - * Return: the address of the segment - */ -inline char * ShmCreate(key_t ipc_key, int shm_size) -{ - char * shptr; - int shmid; /* ID of the IPC shared memory segment */ - if ((shmid=shmget(ipc_key,shm_size,IPC_CREAT|0666))<0){ /* get shm ID */ - perror("cannot find shared memory"); - exit(1); - } - if ( (shptr=shmat(shmid,0,0)) < 0 ){ /* take the pointer to it */ - perror("cannot attach shared memory"); - exit(1); - } - memset((void *)shptr,0x55,shm_size); /* second couter starts from "0" */ - return shptr; -} -/* - * Function ShmFind: - * Find a shared memory segment - * Input: an IPC key value - * the shared memory segment size - * Return: the address of the segment - */ -inline char * ShmFind(key_t ipc_key, int shm_size) -{ - char * 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); - } - if ( (shptr=shmat(shmid,0,0)) < 0 ){ /* take the pointer to it */ - perror("cannot attach shared memory"); - exit(1); - } - return shptr; -} -/* - * Function LockFile & UnlockFile: - * Create and remove a lockfile of the given pathname. - * Fail and exit in case of error or existence of the same lock - * file, using unlink do not need to remove the file, - */ -inline int LockFile(const char* path_name) -{ - return open(path_name, O_EXCL|O_CREAT); -} -inline int UnlockFile(const char* path_name) -{ - return unlink(path_name); -} -/* - * Function Signal - * Initialize a signal handler. - * To enable the signal handling a process we need to tell it to - * kernel; this is done writing all needed info to a sigaction structure - * named sigact, and then callind sigaction() system call passing the - * information stored in the sigact structure variable. - * - * Input: the signal to handle - * the signal handler function - * Return: the previous sigaction structure - */ -typedef void SigFunc(int); -inline SigFunc * Signal(int signo, SigFunc *func) -{ - struct sigaction new_handl, old_handl; - new_handl.sa_handler=func; - /* clear signal mask: no signal blocked during execution of func */ - if (sigemptyset(&new_handl.sa_mask)!=0){ /* initialize signal set */ - perror("cannot initializes the signal set to empty"); /* see mess. */ - exit(1); - } - new_handl.sa_flags=0; /* init to 0 all flags */ - /* change action for signo signal */ - if (sigaction(signo,&new_handl,&old_handl)){ - perror("sigaction failed on signal action setting"); - exit(1); - } - return (old_handl.sa_handler); -} - -/** - ** Defining prototypes for the all other functions - **/ -ssize_t SockRead(int fd, void *buf, size_t count); -ssize_t SockWrite(int fd, const void *buf, size_t count); - -void HandSIGCHLD(int sig); -- 2.30.2