You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
2.5 KiB
C
130 lines
2.5 KiB
C
![]()
17 years ago
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <malloc.h>
|
||
|
|
||
|
#include <php.h>
|
||
|
#ifndef ZEND_WIN32
|
||
|
typedef int HANDLE;
|
||
|
#endif
|
||
|
#include "lock.h"
|
||
|
|
||
|
struct _xc_lock_t {
|
||
|
HANDLE fd;
|
||
|
char *pathname;
|
||
|
};
|
||
|
|
||
|
#ifndef ZEND_WIN32
|
||
|
# include <unistd.h>
|
||
|
# include <fcntl.h>
|
||
|
# include <errno.h>
|
||
|
static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
|
||
|
{
|
||
|
int ret;
|
||
|
struct flock lock;
|
||
|
|
||
|
lock.l_type = type;
|
||
|
lock.l_start = 0;
|
||
|
lock.l_whence = SEEK_SET;
|
||
|
lock.l_len = 1;
|
||
|
lock.l_pid = 0;
|
||
|
|
||
|
do {
|
||
|
ret = fcntl(lck->fd, F_SETLKW, &lock);
|
||
|
} while (ret < 0 && errno == EINTR);
|
||
|
return ret;
|
||
|
}
|
||
|
/* }}} */
|
||
|
#define LCK_WR F_WRLCK
|
||
|
#define LCK_RD F_RDLCK
|
||
|
#define LCK_UN F_UNLCK
|
||
|
#define LCK_NB 0
|
||
|
#else
|
||
|
|
||
|
# include <win32/flock.h>
|
||
|
# include <io.h>
|
||
|
# include <fcntl.h>
|
||
|
# include <sys/types.h>
|
||
|
# include <sys/stat.h>
|
||
|
# define errno GetLastError()
|
||
|
static inline int dolock(xc_lock_t *lck, int type) /* {{{ */
|
||
|
{
|
||
|
static OVERLAPPED offset = {0, 0, 0, 0, NULL};
|
||
|
|
||
|
if (type == LCK_UN) {
|
||
|
return UnlockFileEx((HANDLE)fd, 0, 1, 0, &offset);
|
||
|
}
|
||
|
else {
|
||
|
return LockFileEx((HANDLE)fd, type, 0, 1, 0, &offset);
|
||
|
}
|
||
|
}
|
||
|
/* }}} */
|
||
|
#define LCK_WR LOCKFILE_EXCLUSIVE_LOCK
|
||
|
#define LCK_RD 0
|
||
|
#define LCK_UN 0
|
||
|
#define LCK_NB LOCKFILE_FAIL_IMMEDIATELY
|
||
|
#endif
|
||
|
|
||
|
xc_lock_t *xc_fcntl_init(const char *pathname) /* {{{ */
|
||
|
{
|
||
|
HANDLE fd;
|
||
|
char myname[sizeof("/tmp/.xcache.lock") - 1 + 20];
|
||
|
|
||
|
if (pathname == NULL) {
|
||
|
static int i = 0;
|
||
|
snprintf(myname, sizeof(myname) - 1, "/tmp/.xcache.%d.%d.lock", (int) getuid(), i ++);
|
||
|
pathname = myname;
|
||
|
}
|
||
|
|
||
|
fd = open(pathname, O_RDWR|O_CREAT, 0666);
|
||
|
|
||
|
if (fd > 0) {
|
||
|
xc_lock_t *lck = malloc(sizeof(lck[0]));
|
||
|
int size;
|
||
|
|
||
|
#ifndef __CYGWIN__
|
||
|
unlink(pathname);
|
||
|
#endif
|
||
|
lck->fd = fd;
|
||
|
size = strlen(pathname) + 1;
|
||
|
lck->pathname = malloc(size);
|
||
|
memcpy(lck->pathname, pathname, size);
|
||
|
return lck;
|
||
|
}
|
||
|
else {
|
||
|
fprintf(stderr, "xc_fcntl_create: open(%s, O_RDWR|O_CREAT, 0666) failed:", pathname);
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
/* }}} */
|
||
|
void xc_fcntl_destroy(xc_lock_t *lck) /* {{{ */
|
||
|
{
|
||
|
close(lck->fd);
|
||
|
#ifdef __CYGWIN__
|
||
|
unlink(lck->pathname);
|
||
|
#endif
|
||
|
free(lck->pathname);
|
||
|
free(lck);
|
||
|
}
|
||
|
/* }}} */
|
||
|
void xc_fcntl_lock(xc_lock_t *lck) /* {{{ */
|
||
|
{
|
||
|
if (dolock(lck, LCK_WR) < 0) {
|
||
|
fprintf(stderr, "xc_fcntl_lock failed errno:%d", errno);
|
||
|
}
|
||
|
}
|
||
|
/* }}} */
|
||
|
void xc_fcntl_rdlock(xc_lock_t *lck) /* {{{ */
|
||
|
{
|
||
|
if (dolock(lck, LCK_RD) < 0) {
|
||
|
fprintf(stderr, "xc_fcntl_lock failed errno:%d", errno);
|
||
|
}
|
||
|
}
|
||
|
/* }}} */
|
||
|
void xc_fcntl_unlock(xc_lock_t *lck) /* {{{ */
|
||
|
{
|
||
|
if (dolock(lck, LCK_UN) < 0) {
|
||
|
fprintf(stderr, "xc_fcntl_unlock failed errno:%d", errno);
|
||
|
}
|
||
|
}
|
||
|
/* }}} */
|