Permalink
Cannot retrieve contributors at this time
Fetching contributors…

/* 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 */ |