ed742ea403
git-svn-id: svn://10.65.10.50/trunk@3 c028cbd2-c16b-5b4b-a496-9718f37d4682
922 lines
17 KiB
C
Executable File
922 lines
17 KiB
C
Executable File
/*
|
|
@(SH) Funzioni per la gestione dei file a record.
|
|
|
|
@(M$) PRIVATE
|
|
|
|
CalcPos(Rec,Len,Base) : Calcola la posizione del record nel file
|
|
|
|
@(C$) PRIVATE
|
|
|
|
LOCKSEM : 'locksem' ; nome del semaforo utilizzato per il lock
|
|
|
|
@(VG$) PRIVATE
|
|
|
|
ld : struttura su disco che contien i dati per i lock sui file
|
|
sizeld : numero di byte occupati dalla struttura ld
|
|
semres : flag per l'ok delle operazioni sui semafori
|
|
-------------------------------------------------------------------------------
|
|
-------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#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) 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);
|
|
}
|