/disk1/p.uno. git-svn-id: svn://10.65.10.50/trunk@1811 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			905 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			905 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| #include "ccustio.h"         
 | |
| #include "checks.h"
 | |
| #ifdef DOS
 | |
| #include <sys/types.h>
 | |
| #endif
 | |
| #include <sys/stat.h>
 | |
| #ifndef DOS
 | |
| #include <sys/ipc.h>
 | |
| #include <sys/sem.h>
 | |
| #include <unistd.h>
 | |
| #else
 | |
| #include <io.h>
 | |
| #include <share.h>
 | |
| #include <sys/locking.h>           
 | |
| #include <dos.h>
 | |
| #include "modaut.h"
 | |
| #endif
 | |
| 
 | |
| #define         CalcPos(Rec, Len, Base) (((Rec) - 1) * ((RecNoType) (Len)) + ((RecNoType) (Base)))
 | |
| #define LOCK_OFF 1200000000L
 | |
| 
 | |
| #ifndef DOS
 | |
| #define         LOCKSEM "locksem"
 | |
| 
 | |
| /* extern long lseek(int, long, int);*/
 | |
| extern int chsize(int, long);
 | |
| extern int lockf(int, int, long);
 | |
| #endif
 | |
| 
 | |
| unsigned        setlock(unsigned);
 | |
| int                             seeklk(SecDef *, long, unsigned, unsigned, long);
 | |
| #ifndef DOS
 | |
| int     semtran(char *);
 | |
| static void semcall(int, int);
 | |
| void    PS(int); 
 | |
| void    VS(int);
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|    BOOLEAN test_share()
 | |
|    {
 | |
|    #ifdef DOS
 | |
|    static BOOLEAN share_active = 2;
 | |
|    
 | |
|    if (share_active == 2)
 | |
|    {
 | |
|    share_active = CGetAut(MUAUT);
 | |
|    if (share_active)
 | |
|    {
 | |
|    int f = open("net.ini", O_RDONLY, SH_DENYNO, S_IREAD);
 | |
|    
 | |
|    share_active = f != -1;
 | |
|    if (f != -1) close(f);    
 | |
|    }
 | |
|    }
 | |
|    return share_active; 
 | |
|    #else
 | |
|    return TRUE; 
 | |
|    #endif
 | |
|    }
 | |
|    */
 | |
| 
 | |
| 
 | |
| /*
 | |
|    @($) setlock  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Trasforma il modo di lock utente in modo lock XENIX.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    Nella versione XENIX :
 | |
| 
 | |
|    lm = numero lock xenix.
 | |
|    @(FSV)
 | |
| 
 | |
|    @(IN)
 | |
|    Restituisce il comando XENIX.
 | |
|    @(FN)
 | |
|    */
 | |
| 
 | |
| unsigned        setlock(LockMode)
 | |
|   unsigned      LockMode; /* Tipo di lock */
 | |
| 
 | |
| {
 | |
| 
 | |
|   int           lm;
 | |
| 
 | |
|   LockMode &= RecLockTypes ;
 | |
| #ifdef DOS
 | |
|   if (LockMode == ShareLock) lm = _LK_NBRLCK ;
 | |
|   else
 | |
|     if (LockMode == Lock) lm = _LK_NBRLCK ;
 | |
|     else lm = _LK_UNLCK ;
 | |
| #else
 | |
|   if (LockMode == ShareLock) lm = F_TLOCK ;
 | |
|   else
 | |
|     if (LockMode == Lock) lm = F_TLOCK ;
 | |
|     else lm = F_ULOCK ;
 | |
| #endif
 | |
|   return(lm) ;
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @($) seeklk  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Effettua una seek.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    junk = variabile di lavoro.
 | |
| 
 | |
|    lock = variabile per eseguire comandi di lock.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| int seeklk(S, pos, lm, LockMode, rec) 
 | |
|   SecDef                        *S ;      /* Descrittore file               */
 | |
|   long                          pos ;     /* posizione all'interno del file */
 | |
|   unsigned              lm ;      /* comando di lock per XENIX      */
 | |
|   unsigned              LockMode; /* comando di lock utente         */ 
 | |
|   long                    rec;      /* n.ro di record                 */
 | |
| 
 | |
| {
 | |
|   if (LockMode != NoLock && S->LockMode != ExclLock) 
 | |
|   {               
 | |
| #ifdef DOS
 | |
|     /*    if (test_share())  */
 | |
|   { 
 | |
|     if (_lseek(S->F, LOCK_OFF + rec, SEEK_SET) == -1L)
 | |
|       if ((S->IOR = CIOResult()) != NoErr) return(-1);
 | |
|     
 | |
|     if ( _locking(S->F,lm, 1L) == -1)
 | |
|     { 
 | |
|       S->IOR = CIOResult();
 | |
|       
 | |
|       if (S->IOR == EACCES) S->IOR = EAGAIN;   
 | |
|       if (LockMode == UnLock || LockMode == NoLock) S->IOR = NoErr;
 | |
|       if (S->IOR != NoErr) return(-1);
 | |
|     }  
 | |
|   }
 | |
| #else
 | |
|   if (lseek(S->F, LOCK_OFF + rec, SEEK_SET) == -1L)
 | |
|     if ((S->IOR = CIOResult()) != NoErr) return(-1) ;
 | |
|   if (lockf(S->F,lm, 1L) == -1)
 | |
|     if ((S->IOR = CIOResult()) != NoErr) return(-1) ;
 | |
| #endif
 | |
| }
 | |
| #ifdef DOS
 | |
|   if (_lseek(S->F, pos, SEEK_SET) == -1L)
 | |
| #else
 | |
|     if (lseek(S->F, pos, SEEK_SET) == -1L)
 | |
| #endif
 | |
|       if ((S->IOR = CIOResult()) != NoErr) return(-1) ;
 | |
|   return(0) ;
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) CLockRec  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Esegue un comando lock sul record nro. "rec" del file descritto da "s".
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    Solo versione XENIX.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| void CLockRec(s, rec, lockmode) 
 | |
|   SecDef                        *s ; /* descrittore del file */
 | |
|   RecNoType     rec ; /* numero record su cui effettuare il lock */
 | |
|   unsigned              lockmode;/* operazione lock da effettuare  */
 | |
| 
 | |
| {
 | |
|   seeklk(s, CalcPos(rec, s->LenRec, s->BaseFil), setlock(lockmode), lockmode, rec);
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) CVerify  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Verifica che il file "name" esista.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    junk = variabile di lavoro.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| void                             CVerify(S, Name)
 | |
|   SecDef                                *S;   /* descrittore File */
 | |
|   FileName                      Name; /* nome file        */
 | |
| 
 | |
| {
 | |
|   int   junk ;
 | |
| 
 | |
|   S->IOR = NoErr;
 | |
| #ifdef DOS
 | |
|   if ((S->F = sopen(Name, O_RDONLY | O_BINARY, SH_DENYNO, S_IREAD | S_IWRITE)) == -1)
 | |
| #else
 | |
|     if ((S->F = open(Name, O_RDONLY, 0666)) == -1)
 | |
| #endif
 | |
|       S->IOR = CIOResult();
 | |
|     else
 | |
|       if (close(S->F) == -1)
 | |
|       {
 | |
|         junk = CIOResult();
 | |
|         if (!S->IOR) S->IOR = junk;
 | |
|       }
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) COpen  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Apre un file di record.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    junk = variabile di lavoro.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| void                             COpen(S, Name, Len, Base, LockMode)
 | |
|   SecDef        *S;            /* descrittore file */
 | |
|   FileName                      Name;    /* nome del file    */
 | |
|   unsigned                      Len;     /* lunghezza record */
 | |
|   unsigned                      Base;    /* offset dall'inizio del file fisico; e' sempre 0 per i file dati */
 | |
|   unsigned                      LockMode;/* lock di apertura del file    */
 | |
| 
 | |
| {
 | |
|   int   junk;
 | |
| 
 | |
|   S->IOR = NoErr;
 | |
| #ifdef DOS
 | |
|   if ((S->F = sopen(Name, O_RDWR|O_BINARY,
 | |
|                     /*  test_share() && */ LockMode == ExclLock ? SH_DENYRW : 
 | |
|                     SH_DENYNO, S_IREAD|S_IWRITE)) == -1)
 | |
| #else
 | |
|     if ((S->F = open(Name, O_RDWR , 0666)) == -1)
 | |
| #endif
 | |
|       if ((S->IOR = CIOResult()) != NoErr) return ;
 | |
|   S->LenRec = Len;
 | |
|   S->BaseFil = Base * BlockLenIO ;
 | |
|   S->LockMode = LockMode ;
 | |
|   S->lpos = -1;
 | |
|   strcpy(S->name, Name);
 | |
|   if (lseek(S->F, 0L, SEEK_SET) == -1L)
 | |
|     if ((S->IOR = CIOResult()) != NoErr) return ;
 | |
|   if (excllock(Name, (S->LockMode == ExclLock)) == -1)
 | |
|   {
 | |
|     S->IOR = CIOResult();
 | |
|     if (close(S->F) == -1) junk = CIOResult();
 | |
|   }
 | |
| }
 | |
| /*
 | |
|    @(#) CCreate  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Crea un nuovo file di record.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    junk = variabile di lavoro.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| void                            CCreate(S, Name, Len, Base, MaxSec)
 | |
|   SecDef                                *S;     /* descrittore del file */
 | |
|   FileName                      Name;   /* nome del file        */
 | |
|   unsigned                      Len;    /* lunghezza del record */
 | |
|   unsigned                      Base;   /* offset dall'inizio del file fisico  */
 | |
|   RecNoType                     MaxSec; /* Numero di blocchi di disco da allocare */
 | |
| 
 | |
| {
 | |
|   int                           junk;
 | |
| 
 | |
|   S->IOR = NoErr;
 | |
| #ifdef DOS
 | |
|   if ((S->F = sopen(Name, O_RDWR | O_CREAT, SH_DENYNO, S_IREAD | S_IWRITE)) == -1)
 | |
| #else
 | |
|     if ((S->F = open(Name, O_RDWR | O_CREAT, 0666)) == -1)
 | |
| #endif
 | |
|       if ((S->IOR = CIOResult()) != NoErr) return ;
 | |
|   if (chsize(S->F, ((RecNoType) MaxSec)*BlockLenIO) == -1)
 | |
|     S->IOR = CIOResult();
 | |
|   if (close(S->F) == -1)
 | |
|   {
 | |
|     junk = CIOResult();
 | |
|     if (!S->IOR) S->IOR = junk;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) CChsize  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Cambia la dimensione di un file di record.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    junk = variabile di lavoro.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| void                            CChsize(S, Name, Len, Base, MaxSec)
 | |
|   SecDef                                *S;     /* descrittore del file */
 | |
|   FileName                      Name;   /* nome del file        */
 | |
|   unsigned                      Len;    /* lunghezza del record */
 | |
|   unsigned                      Base;   /* offset dall'inizio del file fisico */ 
 | |
|   RecNoType                     MaxSec; /* numero di blocchi del file modificati */
 | |
| 
 | |
| {
 | |
|   int                           junk;
 | |
| 
 | |
|   S->IOR = NoErr;
 | |
| #ifdef DOS
 | |
|   if ((S->F = sopen(Name, O_RDWR | O_BINARY, SH_DENYNO, S_IREAD | S_IWRITE)) == -1)
 | |
| #else
 | |
|     if ((S->F = open(Name, O_RDWR, 0666)) == -1)
 | |
| #endif
 | |
|       if ((S->IOR = CIOResult()) != NoErr) return ;
 | |
|   if (chsize(S->F, ((RecNoType) MaxSec)*BlockLenIO) == -1)
 | |
|     S->IOR = CIOResult();
 | |
|   if (close(S->F) == -1)
 | |
|   {
 | |
|     junk = CIOResult();
 | |
|     if (!S->IOR) S->IOR = junk;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) CClose  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Chiude un file di record. 
 | |
|    @(FD)
 | |
| 
 | |
|    */
 | |
| 
 | |
| void                             CClose(S)
 | |
|   SecDef        *S; /* descrittore del file da chiudere */
 | |
| 
 | |
| {
 | |
|   S->IOR = NoErr;
 | |
| #ifdef DOS
 | |
|   if (close(S->F) == -1) S->IOR = CIOResult();
 | |
| #else
 | |
|   if (S->LockMode == AutoLock)
 | |
|   {
 | |
|     if (S->lpos != -1)
 | |
|     {
 | |
|       if (lseek(S->F, S->lpos, SEEK_SET) == -1L)
 | |
|         if ((S->IOR = CIOResult()) != NoErr) return ;
 | |
|       if (lockf(S->F,F_ULOCK,(long) S->LenRec) == -1)
 | |
|         if ((S->IOR = CIOResult()) != NoErr) return ;
 | |
|     }
 | |
|   }
 | |
|   if (close(S->F) == -1) S->IOR = CIOResult();
 | |
|   if (exclunlock(S->name, (S->LockMode == ExclLock)) == -1)
 | |
|     S->IOR = CIOResult();
 | |
| #endif
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) CDelete  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Cancella un file di record.
 | |
|    @(FD)
 | |
|    */
 | |
| 
 | |
| 
 | |
| void                             CDelete(S, Name)
 | |
|   SecDef        *S;         /* descrittore del file */
 | |
|   FileName                      Name; /* Nome del file        */
 | |
| 
 | |
| {
 | |
|   if (unlink(Name) == -1)
 | |
|     S->IOR = CIOResult();
 | |
|   else
 | |
|     S->IOR = NoErr;
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) CRead  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Legge un record del file.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    junk = variabile di lavoro.
 | |
| 
 | |
|    fpos = contiene la posizione del record all'interno del file.
 | |
|    @(FSV)
 | |
| 
 | |
|    @(IN)
 | |
|    Lo spazio necessario a contenere il record letto deve essere stato allocato in precedenza.
 | |
|    @(FN)
 | |
|    */
 | |
| 
 | |
| void                             CRead(S, RecBuf, Rec, LockMode)
 | |
|   SecDef        *S;             /* descrittore del file           */
 | |
|   RecType                               RecBuf;   /* spazio per contenere il record */
 | |
|   RecNoType                     Rec;      /* Record da leggere              */
 | |
|   unsigned                      LockMode; /* lock sul record                */
 | |
| 
 | |
| {
 | |
|   int                           junk;
 | |
|   register      RecNoType       fpos;
 | |
| 
 | |
|   if (Rec)
 | |
|   {
 | |
|     S->IOR = NoErr;
 | |
|     fpos = CalcPos(Rec, S->LenRec, S->BaseFil);
 | |
| #ifndef DOS
 | |
|     if (S->LockMode == AutoLock)
 | |
|     {
 | |
|       if (S->lpos != -1)
 | |
|         if (seeklk(S, S->lpos, F_ULOCK, LockMode, (S->lpos - S->BaseFil) / S->LenRec) == -1) return ;
 | |
|       if (seeklk(S, fpos, F_TLOCK, LockMode, Rec) == -1) return ;
 | |
|       S->lpos = fpos ;
 | |
|     }
 | |
|     else
 | |
| #endif
 | |
|       if (seeklk(S, fpos, setlock(LockMode), LockMode, Rec) == -1) return ;
 | |
|     if (read(S->F, RecBuf, (unsigned) S->LenRec) == -1)
 | |
|     {
 | |
|       S->IOR = CIOResult();
 | |
|       junk = seeklk(S, fpos, setlock(UnLock), LockMode, Rec) == -1;
 | |
|     }
 | |
|   }
 | |
|   else S->IOR = 3;
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) CWrite  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Scrive un record nel file.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    junk = variabile di lavoro.
 | |
| 
 | |
|    fpos = contiene la posizione del record all'interno del file.
 | |
|    @(FSV)
 | |
| 
 | |
|    @(IN)
 | |
|    Lo spazio necessario a contenere il record letto deve essere stato allocato in precedenza.
 | |
|    @(FN)
 | |
|    */
 | |
| 
 | |
| void                             CWrite(S, RecBuf, Rec, LockMode)
 | |
|   SecDef        *S;             /* descrittore del file                      */
 | |
|   RecType                               RecBuf;   /* spazio che contiene il record da scrivere */
 | |
|   RecNoType                     Rec;      /* numero del record da scrivere             */
 | |
|   unsigned                      LockMode; /* lock sul record                           */
 | |
| 
 | |
| {
 | |
|   int                           junk;
 | |
|   register      RecNoType       fpos;
 | |
| 
 | |
|   if (Rec)
 | |
|   {
 | |
|     S->IOR = NoErr;
 | |
|     fpos = CalcPos(Rec, S->LenRec, S->BaseFil);
 | |
| #ifndef DOS
 | |
|     if (S->LockMode == AutoLock)
 | |
|     {
 | |
|       if (S->lpos != -1)
 | |
|         if (seeklk(S, S->lpos, F_ULOCK, LockMode, (S->lpos - S->BaseFil) / S->LenRec) == -1) return ;
 | |
|       if (seeklk(S, fpos, F_TLOCK, LockMode, Rec) == -1) return ;
 | |
|       S->lpos = fpos ;
 | |
|     }
 | |
|     else
 | |
| #endif
 | |
|       if (seeklk(S, fpos, setlock(LockMode), LockMode, Rec) == -1) return ;
 | |
|     if (write(S->F, RecBuf, (unsigned) S->LenRec) == -1)
 | |
|     {
 | |
|       S->IOR = CIOResult();
 | |
|       junk = seeklk(S, fpos, setlock(UnLock), LockMode, Rec) == -1;
 | |
|     }
 | |
|   }
 | |
|   else S->IOR = 3;
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) IDeleteRec  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Cancellazione logica di un record.
 | |
|    @(FD)
 | |
|    */
 | |
| 
 | |
| void                             IDeleteRec(RecBuf)
 | |
|   RecType                        RecBuf; /* record da cancellare */
 | |
| 
 | |
| {
 | |
|   RecBuf[0] = Deleted;
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) IRecallRec  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Recupero logico di un record.
 | |
|    @(FD)
 | |
|    */
 | |
| 
 | |
| void                             IRecallRec(RecBuf)
 | |
|   RecType                        RecBuf; /* record da recuperare logicamente */
 | |
| 
 | |
| {
 | |
|   RecBuf[0] = Valid;
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) IRecIsDeleted  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Controlla se il record in "RecBuf" e' cancellato oppure no.
 | |
|    @(FD)
 | |
|    */
 | |
| 
 | |
| BOOLEAN         IRecIsDeleted(RecBuf)
 | |
|   RecType               RecBuf; /* record da controllare */
 | |
| 
 | |
| {
 | |
|   return (RecBuf[0] == Deleted);
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) ITestLock  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Controlla se l'errore "err" e' dovuto ad un lock.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    Versione DOS e XENIX.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| 
 | |
| BOOLEAN         ITestLock(err)
 | |
|   int           err;  /* codice di errore */
 | |
| 
 | |
| {
 | |
|   return(TESTLOCK(err)) ;
 | |
| }
 | |
| 
 | |
| #ifndef DOS
 | |
| struct lockdata
 | |
| {
 | |
|   int users;
 | |
|   int excl;
 | |
| } ld;
 | |
| 
 | |
| int sizeld = sizeof(struct lockdata);
 | |
| 
 | |
| /*
 | |
|    @($) lockpath  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Restituisce il nome del file di lock per il file "name".
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    path = percorso per il file (/usr/tmp/....).
 | |
| 
 | |
|    s1,s,s2   = stringhe di lavoro (nomi file).
 | |
| 
 | |
|    Solo versione XENIX.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| char            *lockpath(name)
 | |
|   char  *name; /* stringa nome file */
 | |
| 
 | |
| {
 | |
|   static char   path[200];
 | |
|   char *s1 = name, *s = name, *s2 = name;
 | |
| 
 | |
|   while ((s1 = strchr(s, DIRSEP)) != NULL)
 | |
|   {
 | |
|     s2 = s;
 | |
|     s = s1 + 1;
 | |
|   }
 | |
|   sprintf(path, "/usr/tmp/%s", s2);
 | |
|   return(path);
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @($) dirname  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Estrae dal path il nome del direttorio.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    path = percorso per il file .
 | |
| 
 | |
|    s   = stringa di lavoro.
 | |
| 
 | |
|    Solo versione XENIX.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| char            *dirname(name)
 | |
|   char  *name; /* stringa contenente il path */
 | |
| 
 | |
| {
 | |
|   static char   path[200];
 | |
|   char                                  *s;
 | |
| 
 | |
|   strcpy(path,name);
 | |
|   if ((s = strrchr(path, DIRSEP)) == NULL) strcpy(path, ".");
 | |
|   else *s = '\0';
 | |
|   return(path);
 | |
| }
 | |
| 
 | |
| static int      semres = 0;
 | |
| 
 | |
| /*
 | |
|    @($) semtran  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Trasforma il nome di un semaforo in un identificatore poi lo crea o lo apre.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    key = chiave corrispondente al nome semaforo.
 | |
| 
 | |
|    id  = identificatore del semaforo.
 | |
| 
 | |
|    Solo versione XENIX.
 | |
|    La semget fa una open sul semaforo; se non lo trova lo crea e poi lo libera.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| int     semtran(s)
 | |
|   char  *s; /* stringa nome del semaforo */
 | |
| 
 | |
| {
 | |
|   register      int key = 0, sid;
 | |
| 
 | |
|   semres = 0 ;
 | |
|   while (*s) key += *s++;
 | |
|   if ((sid = semget((key_t) key, 1, 0666)) == -1)
 | |
|   {
 | |
|     if ((sid = semget((key_t) key, 1, 0666 | IPC_CREAT)) == -1)
 | |
|       semres = -1;
 | |
|     VS(sid);
 | |
|   }
 | |
|   return(sid);
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @($) semcall  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Chiama il semaforo "sid" e su di esso svolge "op".
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    sb = struttura necessaria per la chiamata a "semop".
 | |
| 
 | |
|    Solo versione XENIX.
 | |
|    @(FSV)
 | |
| 
 | |
|    @(IN)
 | |
|    se op = -1 il semaforo viene occupato.
 | |
| 
 | |
|    se op = +1 il semaforo viene liberato.
 | |
|    @(FN)
 | |
|    */
 | |
| 
 | |
| static void semcall(sid, op)
 | |
|   int           sid; /* identificatore semaforo */
 | |
|   int           op;  /* operazione da effettuare sul semaforo: libero/occupato */
 | |
| 
 | |
| {
 | |
|   struct sembuf sb;
 | |
| 
 | |
|   semres = 0 ;
 | |
|   sb.sem_num = 0;
 | |
|   sb.sem_op = op;
 | |
|   sb.sem_flg = 0;
 | |
|   if (semop(sid, &sb, 1) == -1)
 | |
|     semres = -1;
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @($) PS  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Acquisisce il semaforo "sid".
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    Solo versione XENIX.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| void    PS(sid)
 | |
|   int   sid; /* identificatore semaforo */
 | |
| 
 | |
| {
 | |
|   semcall(sid, -1);
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @($) VS  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Rilascia il semaforo "sid".
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    Solo versione XENIX.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| void    VS(sid)
 | |
|   int   sid;
 | |
| 
 | |
| {
 | |
|   semcall(sid, 1);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|    @(#) excllock  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Funzione per la gestione di un lock esclusivo su tutto il file.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    Nella versione XENIX:
 | |
| 
 | |
|    path = contiene il file di lock.
 | |
| 
 | |
|    dir  = contiene la directory.
 | |
| 
 | |
|    fd        = identificatore restituito dalla "open".
 | |
| 
 | |
|    junk = variabile di lavoro.
 | |
| 
 | |
|    sid       = identificatore del semaforo su locksem.
 | |
| 
 | |
|    errno     = numero errore.
 | |
| 
 | |
|    sb        = struttura che contiene informazioni sullo stato del file (vedi "stat").
 | |
| 
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| int excllock(name,excl)
 | |
|   char  *name;  /* nome del file                               */
 | |
|   BOOLEAN excl; /* se true deve fare il lock ex. altrimenti no */
 | |
| 
 | |
| {
 | |
| #ifndef DOS
 | |
|   char  path[200], dir[200];
 | |
|   int           fd, junk, sid;
 | |
|   extern int errno;
 | |
|   struct stat   sb;
 | |
| 
 | |
|   strcpy(path, lockpath(name));
 | |
|   strcpy(dir, dirname(path));
 | |
|   sid = semtran(LOCKSEM);
 | |
|   if (semres == -1) return(-1);
 | |
|   PS(sid);
 | |
|   if (semres == -1) return(-1);
 | |
|   if ((stat(dir, &sb) == -1) && (errno == ENOENT)) CMkDir(dir);
 | |
|   if (((fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666)) == -1) && 
 | |
|       errno == EEXIST)
 | |
|   {
 | |
|     errno = 0;
 | |
|     if ((fd = open(path, O_RDWR, 0666)) == -1)
 | |
|     {
 | |
|       VS(sid);
 | |
|       return(-1);
 | |
|     }
 | |
|     if ((read(fd, &ld, sizeld) <= 0) ||
 | |
|         (lseek(fd, 0L, SEEK_SET) == -1L))
 | |
|     {
 | |
|       junk = close(fd);
 | |
|       VS(sid);
 | |
|       return(-1) ;
 | |
|     }
 | |
|     if (((ld.excl) && (ld.excl != getpid())) || excl)
 | |
|     {
 | |
|       junk = close(fd);
 | |
|       errno = EACCES ;
 | |
|       VS(sid);
 | |
|       return(-1);
 | |
|     }
 | |
|     ld.users++;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     if (fd == -1)
 | |
|     {
 | |
|       VS(sid);
 | |
|       return(-1);
 | |
|     }
 | |
|     errno = 0;
 | |
|     ld.users = 1;
 | |
|     if (excl) ld.excl = getpid();
 | |
|     else ld.excl = 0;
 | |
|   }
 | |
|   if (write(fd, &ld, sizeld) == -1) 
 | |
|   {
 | |
|     junk = close(fd);
 | |
|     VS(sid);
 | |
|     return(-1);
 | |
|   }
 | |
|   if (close(fd) == -1)
 | |
|   {
 | |
|     VS(sid);
 | |
|     return(-1);
 | |
|   }
 | |
|   VS(sid);
 | |
|   if (semres == -1) return(-1);
 | |
| #endif
 | |
|   return(0);
 | |
| }
 | |
| 
 | |
| /*
 | |
|    @(#) exclunlock  CUSTIO
 | |
| 
 | |
|    @(ID)
 | |
|    Gestisce un unlock esclusivo su tutto il file.
 | |
|    @(FD)
 | |
| 
 | |
|    @(ISV)
 | |
|    Nella versione XENIX:
 | |
| 
 | |
|    path = contiene il file di lock.
 | |
| 
 | |
|    fd        = identificatore restituito dalla "open".
 | |
| 
 | |
|    junk = variabile di lavoro.
 | |
| 
 | |
|    sid       = identificatore del semaforo su locksem.
 | |
|    @(FSV)
 | |
|    */
 | |
| 
 | |
| int     exclunlock(name,excl)
 | |
|   char  *name;  /* nome file */
 | |
|   BOOLEAN excl; /* se true esegue un unlock sul file */
 | |
| 
 | |
| {
 | |
| #ifndef DOS
 | |
|   int                           fd, junk, sid;
 | |
|   char                  path[200];
 | |
| 
 | |
|   strcpy(path, lockpath(name));
 | |
|   sid = semtran(LOCKSEM);
 | |
|   if (semres == -1) return(-1);
 | |
|   PS(sid);
 | |
|   if (semres == -1) return(-1);
 | |
|   if (((fd = open(path, O_RDWR , 0666)) == -1) ||
 | |
|       (read(fd, &ld, sizeld) <= 0) ||
 | |
|       (lseek(fd, 0L, SEEK_SET) == -1L))
 | |
|   {
 | |
|     junk = close(fd);
 | |
|     VS(sid);
 | |
|     return(-1);
 | |
|   }
 | |
|   if (excl) ld.excl = 0;
 | |
|   if (--ld.users == 0)
 | |
|   {
 | |
|     if ((close(fd) == -1) || (unlink(path) == -1))
 | |
|     {
 | |
|       VS(sid);
 | |
|       return(-1);
 | |
|     }
 | |
|     VS(sid);
 | |
|     if (semres == -1) return(-1);
 | |
|     return(0);
 | |
|   }
 | |
|   if (write(fd, &ld, sizeld) == -1)
 | |
|   {
 | |
|     junk = close(fd);
 | |
|     VS(sid);
 | |
|     return(-1);
 | |
|   }
 | |
|   if (close(fd) == -1)
 | |
|   {
 | |
|     VS(sid);
 | |
|     return(-1);
 | |
|   }
 | |
|   VS(sid);
 | |
|   if (semres == -1) return(-1);
 | |
| #endif
 | |
|   return(0);
 | |
| }
 |