Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

170 lines (138 sloc) 4.243 kB
/* copied from pp_sys.c */
#ifndef FLOCK
#ifdef HAS_FLOCK
# define FLOCK flock
#else /* no flock() */
/* fcntl.h might not have been included, even if it exists, because
the current Configure only sets I_FCNTL if it's needed to pick up
the *_OK constants. Make sure it has been included before testing
the fcntl() locking constants. */
# if defined(HAS_FCNTL) && !defined(I_FCNTL)
# include <fcntl.h>
# endif
# if defined(HAS_FCNTL) && defined(FCNTL_CAN_LOCK)
# define FLOCK fcntl_emulate_flock
# define FCNTL_EMULATE_FLOCK
# else /* no flock() or fcntl(F_SETLK,...) */
# ifdef HAS_LOCKF
# define FLOCK lockf_emulate_flock
# define LOCKF_EMULATE_FLOCK
# endif /* lockf */
# endif /* no flock() or fcntl(F_SETLK,...) */
# ifdef FLOCK
static int FLOCK (int, int);
/*
* These are the flock() constants. Since this sytems doesn't have
* flock(), the values of the constants are probably not available.
*/
# ifndef LOCK_SH
# define LOCK_SH 1
# endif
# ifndef LOCK_EX
# define LOCK_EX 2
# endif
# ifndef LOCK_NB
# define LOCK_NB 4
# endif
# ifndef LOCK_UN
# define LOCK_UN 8
# endif
# endif /* emulating flock() */
#endif /* no flock() */
#ifdef FCNTL_EMULATE_FLOCK
/* XXX Emulate flock() with fcntl().
What's really needed is a good file locking module.
*/
static int
fcntl_emulate_flock(int fd, int operation)
{
struct flock flock;
switch (operation & ~LOCK_NB) {
case LOCK_SH:
flock.l_type = F_RDLCK;
break;
case LOCK_EX:
flock.l_type = F_WRLCK;
break;
case LOCK_UN:
flock.l_type = F_UNLCK;
break;
default:
errno = EINVAL;
return -1;
}
flock.l_whence = SEEK_SET;
flock.l_start = flock.l_len = (Off_t)0;
return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &flock);
}
#endif /* FCNTL_EMULATE_FLOCK */
#ifdef LOCKF_EMULATE_FLOCK
/* XXX Emulate flock() with lockf(). This is just to increase
portability of scripts. The calls are not completely
interchangeable. What's really needed is a good file
locking module.
*/
/* The lockf() constants might have been defined in <unistd.h>.
Unfortunately, <unistd.h> causes troubles on some mixed
(BSD/POSIX) systems, such as SunOS 4.1.3.
Further, the lockf() constants aren't POSIX, so they might not be
visible if we're compiling with _POSIX_SOURCE defined. Thus, we'll
just stick in the SVID values and be done with it. Sigh.
*/
# ifndef F_ULOCK
# define F_ULOCK 0 /* Unlock a previously locked region */
# endif
# ifndef F_LOCK
# define F_LOCK 1 /* Lock a region for exclusive use */
# endif
# ifndef F_TLOCK
# define F_TLOCK 2 /* Test and lock a region for exclusive use */
# endif
# ifndef F_TEST
# define F_TEST 3 /* Test a region for other processes locks */
# endif
static int
lockf_emulate_flock(int fd, int operation)
{
int i;
const int save_errno = errno;
Off_t pos;
/* flock locks entire file so for lockf we need to do the same */
pos = PerlLIO_lseek(fd, (Off_t)0, SEEK_CUR); /* get pos to restore later */
if (pos > 0) /* is seekable and needs to be repositioned */
if (PerlLIO_lseek(fd, (Off_t)0, SEEK_SET) < 0)
pos = -1; /* seek failed, so don't seek back afterwards */
errno = save_errno;
switch (operation) {
/* LOCK_SH - get a shared lock */
case LOCK_SH:
/* LOCK_EX - get an exclusive lock */
case LOCK_EX:
i = lockf (fd, F_LOCK, 0);
break;
/* LOCK_SH|LOCK_NB - get a non-blocking shared lock */
case LOCK_SH|LOCK_NB:
/* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */
case LOCK_EX|LOCK_NB:
i = lockf (fd, F_TLOCK, 0);
if (i == -1)
if ((errno == EAGAIN) || (errno == EACCES))
errno = EWOULDBLOCK;
break;
/* LOCK_UN - unlock (non-blocking is a no-op) */
case LOCK_UN:
case LOCK_UN|LOCK_NB:
i = lockf (fd, F_ULOCK, 0);
break;
/* Default - can't decipher operation */
default:
i = -1;
errno = EINVAL;
break;
}
if (pos > 0) /* need to restore position of the handle */
PerlLIO_lseek(fd, pos, SEEK_SET); /* ignore error here */
return (i);
}
#endif /* LOCKF_EMULATE_FLOCK */
#endif /* perlflock.h */
Jump to Line
Something went wrong with that request. Please try again.