summaryrefslogtreecommitdiff
path: root/source3/lib/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/util.c')
-rw-r--r--source3/lib/util.c112
1 files changed, 61 insertions, 51 deletions
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 891b11facc..260435d9e8 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -4533,20 +4533,18 @@ void free_namearray(name_compare_entry *name_array)
/****************************************************************************
routine to do file locking
****************************************************************************/
-BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
+BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
#if HAVE_FCNTL_LOCK
- struct flock lock;
+ SMB_STRUCT_FLOCK lock;
int ret;
- /*
- * FIXME.
- * NB - this code will need re-writing to cope with large (64bit)
- * lock requests. JRA.
- */
-
if(lp_ole_locking_compat()) {
- uint32 mask = 0xC0000000;
+#ifdef LARGE_SMB_OFF_T
+ SMB_OFF_T mask = 0xC000000000000000LL;
+#else
+ SMB_OFF_T mask = 0xC0000000;
+#endif
/* make sure the count is reasonable, we might kill the lockd otherwise */
count &= ~mask;
@@ -4556,38 +4554,45 @@ BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
still allows OLE2 apps to operate, but should stop lockd from
dieing */
if ((offset & mask) != 0)
- offset = (offset & ~mask) | ((offset & mask) >> 2);
+#ifdef LARGE_SMB_OFF_T
+ offset = (offset & ~mask) | (((offset & mask) >> 2) & 0x3000000000000000LL);
+#else
+ offset = (offset & ~mask) | (((offset & mask) >> 2) & 0x30000000);
+#endif
} else {
- uint32 mask = ((unsigned)1<<31);
- int32 s_count = (int32) count; /* Signed count. */
- int32 s_offset = (int32)offset; /* Signed offset. */
+#ifdef LARGE_SMB_OFF_T
+ SMB_OFF_T mask = 0x8000000000000000LL;
+#else
+ SMB_OFF_T mask = 0x80000000;
+#endif
+ SMB_OFF_T neg_mask = ~mask;
/* interpret negative counts as large numbers */
- if (s_count < 0)
- s_count &= ~mask;
+ if (count < 0)
+ count &= ~mask;
/* no negative offsets */
- if(s_offset < 0)
- s_offset &= ~mask;
+ if(offset < 0)
+ offset &= ~mask;
/* count + offset must be in range */
- while ((s_offset < 0 || (s_offset + s_count < 0)) && mask)
+ while ((offset < 0 || (offset + count < 0)) && mask)
{
- s_offset &= ~mask;
- mask = mask >> 1;
+ offset &= ~mask;
+ mask = ((mask >> 1) & neg_mask);
}
-
- offset = (uint32)s_offset;
- count = (uint32)s_count;
}
-
+#ifdef LARGE_SMB_OFF_T
+ DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
+#else
DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
+#endif
lock.l_type = type;
lock.l_whence = SEEK_SET;
- lock.l_start = (int)offset;
- lock.l_len = (int)count;
+ lock.l_start = offset;
+ lock.l_len = count;
lock.l_pid = 0;
errno = 0;
@@ -4598,37 +4603,42 @@ BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
/* a lock query */
- if (op == F_GETLK)
+ if (op == SMB_F_GETLK)
+ {
+ if ((ret != -1) &&
+ (lock.l_type != F_UNLCK) &&
+ (lock.l_pid != 0) &&
+ (lock.l_pid != getpid()))
{
- 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,(int)lock.l_pid));
- return(True);
- }
-
- /* it must be not locked or locked by me */
- return(False);
+ DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)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);
- }
+ {
+#ifdef LARGE_SMB_OFF_T
+ DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
+ (double)offset,(double)count,op,type,strerror(errno)));
+#else
+ DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
+ offset,count,op,type,strerror(errno)));
+#endif
- return(False);
+ /* 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(8,("Lock call successful\n"));
@@ -4651,7 +4661,7 @@ int file_lock(char *name,int timeout)
#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);
+ if (fcntl_lock(fd,SMB_F_SETLK,0,1,F_WRLCK)) return(fd);
msleep(LOCK_RETRY_TIMEOUT);
}
return(-1);
@@ -4667,7 +4677,7 @@ void file_unlock(int fd)
{
if (fd<0) return;
#if HAVE_FCNTL_LOCK
- fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
+ fcntl_lock(fd,SMB_F_SETLK,0,1,F_UNLCK);
#endif
close(fd);
}