DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T l

⟦37ffab44f⟧ TextFile

    Length: 3349 (0xd15)
    Types: TextFile
    Names: »lock.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« 
        └─⟦e5a54fb17⟧ 
            └─⟦this⟧ »pp-5.0/Lib/util/lock.c« 

TextFile

/* lock.c: file locking subroutines  */

# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Lib/util/RCS/lock.c,v 5.0 90/09/20 16:17:25 pp Exp Locker: pp $";
# endif

/*
 * $Header: /cs/research/pp/hubris/pp-beta/Lib/util/RCS/lock.c,v 5.0 90/09/20 16:17:25 pp Exp Locker: pp $
 *
 * $Log:	lock.c,v $
 * Revision 5.0  90/09/20  16:17:25  pp
 * rcsforce : 5.0 public release
 * 
 */



#include "util.h"
#include <sys/file.h>
#if defined(SUNOS4) || defined(SYS5)
#include <sys/fcntl.h>
#endif
#if defined(sun) || defined(SYS5)
#include <unistd.h>
#endif
#include <sys/stat.h>


static int lk_file ();
static int lk_unlck ();

static char *lockfd[FD_SETSIZE];

extern char	*lockdir;
extern int	lockstyle;
extern int	lock_break_time;	/* 30 minutes grace ? */
extern time_t time ();

FILE	*flckopen (name, mode)
char	*name;
char	*mode;
{
	FILE	*fp;

	if ((fp = fopen (name, mode)) == NULL)
		return NULL;

	switch (lockstyle) {
	    case LOCK_FLOCK:
#ifdef LOCK_EX
		if (flock (fileno (fp), LOCK_EX | LOCK_NB) == NOTOK) {
			(void) fclose (fp);
			return NULL;
		}
		return fp;
#else
		break;
#endif
		
	    case LOCK_FCNTL:
#ifdef F_RDLCK
		{
			struct flock l;

			l.l_len = 0;
			l.l_start = 0;
			l.l_whence = 0;

			if (*mode == 'r' && mode[1] != '+')
				l.l_type = F_RDLCK;
			else
				l.l_type = F_WRLCK;
				
			if (fcntl (fileno(fp), F_SETLK, &l) < 0) {
				(void) fclose (fp);
				return NULL;
			}
		}
		return fp;
#else
		break;
#endif
	    case LOCK_LOCKF:
#ifdef F_TLOCK
		if (lockf (fileno (fp), F_TLOCK, 0L) == NOTOK) {
			(void) fclose (fp);
			return NULL;
		}
		return fp;
#else
		break;
#endif	
	    default:
	    case LOCK_FILE:
		if (lk_file (name, fileno (fp)) == NOTOK) {
			(void) fclose (fp);
			return NULL;
		}
		break;
	}
	PP_OPER (NULLCP, ("Specified styple of locking (%d) not supported",
			  lockstyle));
	return NULL;
}

static int lk_file (name, n)
char	*name;
int	n;
{
	char	locktmp[FILNSIZE];
	char	lockname[FILNSIZE];
	struct stat st;
	int	fd;
	time_t	now;

	if (n < 0 || n >= FD_SETSIZE)
		return NOTOK;

	if (fstat (n, &st) == NOTOK) {
		PP_SLOG (LLOG_EXCEPTIONS, name, ("Can't fstat %d file", n));
		return NOTOK;
	}

	(void) sprintf (locktmp, "%s/LCK%05.5o+%o.t", lockdir,
			st.st_dev, st.st_ino);
	(void) sprintf (lockname, "%s/LCK%05.5o+%o",
			lockdir, st.st_dev, st.st_ino);

	if ((fd = open (locktmp, O_RDWR|O_CREAT, 0)) < 0) {
		PP_SLOG (LLOG_EXCEPTIONS, locktmp,
			 ("Can't create lock temp file"));
		return NOTOK;
	}
	(void) close (fd);

	if (stat (lockname, &st) != NOTOK) {
		(void) time (&now);
		if (st.st_mtime + lock_break_time < now) {
			PP_NOTICE (("Forcing lock for %s", lockname));
			(void) unlink (lockname);
		}
	}
	if (link (locktmp, lockname) == NOTOK) {
		PP_SLOG (LLOG_EXCEPTIONS, lockname,
			 ("Can't lock by linking %s to ", locktmp));
		(void) unlink (locktmp);
		return NOTOK;
	}
	(void) unlink (locktmp);
	lockfd[n] = strdup (lockname);
	return OK;
}

int	flckclose (fp)
FILE	*fp;
{
	switch (lockstyle) {
	    case LOCK_FCNTL:
	    case LOCK_FLOCK:
		return fclose (fp);

	    default:
	    case LOCK_FILE:
		return lk_unlck (fp);
	}
}

static int lk_unlck (fp)
FILE	*fp;
{
	int	n = fileno (fp);

	if (n >= 0 && n < FD_SETSIZE && lockfd[n] && *lockfd[n]) {
		(void) unlink (lockfd[n]);
		lockfd[n] = NULLCP;
		return OK;
	}
	return NOTOK;
}