mirror of
https://github.com/samba-team/samba.git
synced 2025-03-11 16:58:40 +03:00
Moved fcntl locking code into util.c to allow it to be
called from nmbd code. jra@cygnus.com
This commit is contained in:
parent
09aa77766c
commit
d718f4fd30
@ -32,137 +32,6 @@ extern files_struct Files[];
|
||||
pstring share_del_pending="";
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
routine to do file locking
|
||||
****************************************************************************/
|
||||
BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
|
||||
{
|
||||
#if HAVE_FCNTL_LOCK
|
||||
struct flock lock;
|
||||
int ret;
|
||||
|
||||
#if 1
|
||||
uint32 mask = 0xC0000000;
|
||||
|
||||
/* make sure the count is reasonable, we might kill the lockd otherwise */
|
||||
count &= ~mask;
|
||||
|
||||
/* the offset is often strange - remove 2 of its bits if either of
|
||||
the top two bits are set. Shift the top ones by two bits. This
|
||||
still allows OLE2 apps to operate, but should stop lockd from
|
||||
dieing */
|
||||
if ((offset & mask) != 0)
|
||||
offset = (offset & ~mask) | ((offset & mask) >> 2);
|
||||
#else
|
||||
uint32 mask = ((unsigned)1<<31);
|
||||
|
||||
/* interpret negative counts as large numbers */
|
||||
if (count < 0)
|
||||
count &= ~mask;
|
||||
|
||||
/* no negative offsets */
|
||||
offset &= ~mask;
|
||||
|
||||
/* count + offset must be in range */
|
||||
while ((offset < 0 || (offset + count < 0)) && mask)
|
||||
{
|
||||
offset &= ~mask;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
|
||||
|
||||
lock.l_type = type;
|
||||
lock.l_whence = SEEK_SET;
|
||||
lock.l_start = (int)offset;
|
||||
lock.l_len = (int)count;
|
||||
lock.l_pid = 0;
|
||||
|
||||
errno = 0;
|
||||
|
||||
ret = fcntl(fd,op,&lock);
|
||||
|
||||
if (errno != 0)
|
||||
DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
|
||||
|
||||
/* a lock query */
|
||||
if (op == F_GETLK)
|
||||
{
|
||||
if ((ret != -1) &&
|
||||
(lock.l_type != F_UNLCK) &&
|
||||
(lock.l_pid != 0) &&
|
||||
(lock.l_pid != getpid()))
|
||||
{
|
||||
DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
|
||||
return(True);
|
||||
}
|
||||
|
||||
/* it must be not locked or locked by me */
|
||||
return(False);
|
||||
}
|
||||
|
||||
/* a lock set or unset */
|
||||
if (ret == -1)
|
||||
{
|
||||
DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
|
||||
offset,count,op,type,strerror(errno)));
|
||||
|
||||
/* perhaps it doesn't support this sort of locking?? */
|
||||
if (errno == EINVAL)
|
||||
{
|
||||
DEBUG(3,("locking not supported? returning True\n"));
|
||||
return(True);
|
||||
}
|
||||
|
||||
return(False);
|
||||
}
|
||||
|
||||
/* everything went OK */
|
||||
DEBUG(5,("Lock call successful\n"));
|
||||
|
||||
return(True);
|
||||
#else
|
||||
return(False);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
lock a file - returning a open file descriptor or -1 on failure
|
||||
The timeout is in seconds. 0 means no timeout
|
||||
********************************************************************/
|
||||
int file_lock(char *name,int timeout)
|
||||
{
|
||||
int fd = open(name,O_RDWR|O_CREAT,0666);
|
||||
time_t t=0;
|
||||
if (fd < 0) return(-1);
|
||||
|
||||
#if HAVE_FCNTL_LOCK
|
||||
if (timeout) t = time(NULL);
|
||||
while (!timeout || (time(NULL)-t < timeout)) {
|
||||
if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
|
||||
msleep(LOCK_RETRY_TIMEOUT);
|
||||
}
|
||||
return(-1);
|
||||
#else
|
||||
return(fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
unlock a file locked by file_lock
|
||||
********************************************************************/
|
||||
void file_unlock(int fd)
|
||||
{
|
||||
if (fd<0) return;
|
||||
#if HAVE_FCNTL_LOCK
|
||||
fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
|
||||
#endif
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
utility function called to see if a file region is locked
|
||||
****************************************************************************/
|
||||
|
Loading…
x
Reference in New Issue
Block a user