Changes to test in configure if capabilities are enabled on a system.
[samba.git] / source3 / locking / shmem.c
index 63d7ebd3d41db94966f1c0ecbf6f5975fcc38f0f..b63db1f168dc7fa0b422a2f57de4b1233bc5cec7 100644 (file)
@@ -23,7 +23,7 @@
 #include "includes.h"
 
 
-#ifdef FAST_SHARE_MODES
+#ifdef HAVE_SHARED_MMAP
 
 
 extern int DEBUGLEVEL;
@@ -41,7 +41,7 @@ extern int DEBUGLEVEL;
 #define SHM_FILE_MODE 0644
 #endif
 
-#define SHMEM_HASH_SIZE 113
+#define SHMEM_HASH_SIZE 13
 
 
 /* WARNING : offsets are used because mmap() does not guarantee that all processes have the 
@@ -107,7 +107,7 @@ static BOOL smb_shm_global_lock(void)
           return True;
    
    /* Do an exclusive wait lock on the first byte of the file */
-   if (fcntl_lock(smb_shm_fd, F_SETLKW, 0, 1, F_WRLCK) == False)
+   if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False)
    {
       DEBUG(0,("ERROR smb_shm_global_lock : fcntl_lock failed with code %s\n",strerror(errno)));
       smb_shm_times_locked--;
@@ -128,7 +128,7 @@ static BOOL smb_shm_global_unlock(void)
    
    if(smb_shm_times_locked == 0)
    {
-      DEBUG(0,("ERROR smb_shm_global_unlock : shmem not locked\n",smb_shm_fd));
+      DEBUG(0,("ERROR smb_shm_global_unlock : shmem not locked\n"));
       return False;
    }
    
@@ -144,7 +144,7 @@ static BOOL smb_shm_global_unlock(void)
           return True;
    
    /* Do a wait unlock on the first byte of the file */
-   if (fcntl_lock(smb_shm_fd, F_SETLKW, 0, 1, F_UNLCK) == False)
+   if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, 0, 1, F_UNLCK) == False)
    {
       DEBUG(0,("ERROR smb_shm_global_unlock : fcntl_lock failed with code %s\n",strerror(errno)));
       smb_shm_times_locked++;
@@ -314,9 +314,9 @@ static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *oth
    int smb_shm_processes_fd = -1;
    int nb_read;
    pid_t other_pid;
-   int seek_back = -((int)sizeof(other_pid));
-   int free_slot = -1;
-   int erased_slot;   
+   SMB_OFF_T seek_back = -((SMB_OFF_T)sizeof(other_pid));
+   SMB_OFF_T free_slot = -1;
+   SMB_OFF_T erased_slot;   
    
    smb_shm_processes_fd = open(processreg_file, 
                               read_only?O_RDONLY:(O_RDWR|O_CREAT), 
@@ -339,10 +339,10 @@ static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *oth
         else
         {
            /* erase old pid */
-            DEBUG(5,("smb_shm_register_process : erasing stale record for pid %d (seek_back = %d)\n",
-                      other_pid, seek_back));
+            DEBUG(5,("smb_shm_register_process : erasing stale record for pid %d (seek_back = %.0f)\n",
+                      (int)other_pid, (double)seek_back));
            other_pid = (pid_t)0;
-           erased_slot = lseek(smb_shm_processes_fd, seek_back, SEEK_CUR);
+           erased_slot = sys_lseek(smb_shm_processes_fd, seek_back, SEEK_CUR);
            write(smb_shm_processes_fd, &other_pid, sizeof(other_pid));
            if(free_slot < 0)
               free_slot = erased_slot;
@@ -350,7 +350,7 @@ static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *oth
       }
       else 
         if(free_slot < 0)
-           free_slot = lseek(smb_shm_processes_fd, seek_back, SEEK_CUR);
+           free_slot = sys_lseek(smb_shm_processes_fd, seek_back, SEEK_CUR);
    }
    if (nb_read < 0)
    {
@@ -360,10 +360,12 @@ static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *oth
    }
    
    if(free_slot < 0)
-      free_slot = lseek(smb_shm_processes_fd, 0, SEEK_END);
+      free_slot = sys_lseek(smb_shm_processes_fd, 0, SEEK_END);
 
-   DEBUG(5,("smb_shm_register_process : writing record for pid %d at offset %d\n",pid,free_slot));
-   lseek(smb_shm_processes_fd, free_slot, SEEK_SET);
+   DEBUG(5,("smb_shm_register_process : writing record for pid %d at offset %.0f\n",
+         (int)pid, (double)free_slot));
+
+   sys_lseek(smb_shm_processes_fd, free_slot, SEEK_SET);
    if(write(smb_shm_processes_fd, &pid, sizeof(pid)) < 0)
    {
       DEBUG(0,("ERROR smb_shm_register_process : processreg_file write failed with code %s\n",strerror(errno)));
@@ -381,8 +383,7 @@ static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid)
    int smb_shm_processes_fd = -1;
    int nb_read;
    pid_t other_pid;
-   int seek_back = -((int)sizeof(other_pid));
-   int erased_slot;
+   SMB_OFF_T seek_back = -((SMB_OFF_T)sizeof(other_pid));
    BOOL found = False;
    
    
@@ -395,23 +396,28 @@ static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid)
    
    while ((nb_read = read(smb_shm_processes_fd, &other_pid, sizeof(other_pid))) > 0)
    {
-      DEBUG(5,("smb_shm_unregister_process : read record for pid %d\n",other_pid));
+      DEBUG(5,("smb_shm_unregister_process : read record for pid %d\n",(int)other_pid));
       if(other_pid == pid)
       {
-        /* erase pid */
-         DEBUG(5,("smb_shm_unregister_process : erasing record for pid %d (seek_val = %d)\n",
-                     other_pid, seek_back));
-        other_pid = (pid_t)0;
-        erased_slot = lseek(smb_shm_processes_fd, seek_back, SEEK_CUR);
-        if(write(smb_shm_processes_fd, &other_pid, sizeof(other_pid)) < 0)
-        {
-           DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file write failed with code %s\n",strerror(errno)));
-           close(smb_shm_processes_fd);
-           return False;
-        }
+        /* erase pid */
+        DEBUG(5,("smb_shm_unregister_process : erasing record for pid %d (seek_val = %.0f)\n",
+                     (int)other_pid, (double)seek_back));
+        other_pid = (pid_t)0;
+        if(sys_lseek(smb_shm_processes_fd, seek_back, SEEK_CUR) == -1)
+        {
+          DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file sys_lseek failed with code %s\n",strerror(errno)));
+          close(smb_shm_processes_fd);
+          return False;
+        }
+        if(write(smb_shm_processes_fd, &other_pid, sizeof(other_pid)) < 0)
+        {
+          DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file write failed with code %s\n",strerror(errno)));
+          close(smb_shm_processes_fd);
+          return False;
+        }
         
-        found = True;
-        break;
+        found = True;
+        break;
       }
    }
    if (nb_read < 0)
@@ -423,7 +429,8 @@ static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid)
    
    if(!found)
    {
-      DEBUG(0,("ERROR smb_shm_unregister_process : couldn't find pid %d in file %s\n",pid,processreg_file));
+      DEBUG(0,("ERROR smb_shm_unregister_process : couldn't find pid %d in file %s\n",
+            (int)pid,processreg_file));
       close(smb_shm_processes_fd);
       return False;
    }
@@ -540,7 +547,8 @@ static BOOL smb_shm_close( void )
    }
 
    smb_shm_global_lock();
-   DEBUG(5,("calling smb_shm_unregister_process(%s, %d)\n", smb_shm_processreg_name, getpid()));
+   DEBUG(5,("calling smb_shm_unregister_process(%s, %d)\n", 
+         smb_shm_processreg_name, (int)getpid()));
    smb_shm_unregister_process(smb_shm_processreg_name, getpid());
    smb_shm_global_unlock();
    
@@ -603,6 +611,9 @@ static BOOL smb_shm_free(int offset)
    
    DEBUG(6,("smb_shm_free : freeing %d bytes at offset %d\n",header_p->size*CellSize,offset));
 
+   /* zero the area being freed - this allows us to find bugs faster */
+   memset(smb_shm_offset2addr(offset), 0, header_p->size*CellSize);
+
    if ( scanner_p == prev_p )
    {
       smb_shm_header_p->statistics.cells_free += header_p->size;
@@ -656,8 +667,11 @@ static BOOL smb_shm_lock_hash_entry( unsigned int entry)
       return False;
     }
 
+  if (read_only)
+         return True;
+
   /* Do an exclusive wait lock on the 4 byte region mapping into this entry  */
-  if (fcntl_lock(smb_shm_fd, F_SETLKW, start, sizeof(int), F_WRLCK) == False)
+  if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, start, sizeof(int), F_WRLCK) == False)
     {
       DEBUG(0,("ERROR smb_shm_lock_hash_entry : fcntl_lock failed with code %s\n",strerror(errno)));
       return False;
@@ -679,9 +693,12 @@ static BOOL smb_shm_unlock_hash_entry( unsigned int entry )
       DEBUG(0,("ERROR smb_shm_unlock_hash_entry : bad smb_shm_fd (%d)\n",smb_shm_fd));
       return False;
     }
+
+  if (read_only)
+         return True;
    
   /* Do a wait lock on the 4 byte region mapping into this entry  */
-  if (fcntl_lock(smb_shm_fd, F_SETLKW, start, sizeof(int), F_UNLCK) == False)
+  if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, start, sizeof(int), F_UNLCK) == False)
     {
       DEBUG(0,("ERROR smb_shm_unlock_hash_entry : fcntl_lock failed with code %s\n",strerror(errno)));
       return False;
@@ -738,10 +755,10 @@ static struct shmem_ops shmops = {
 struct shmem_ops *smb_shm_open(int ronly)
 {
        pstring file_name;
-       int filesize;
+       SMB_OFF_T filesize;
        BOOL created_new = False;
        BOOL other_processes = True;
-       int size = lp_shmem_size();
+       SMB_OFF_T size = (SMB_OFF_T)lp_shmem_size();
 
        read_only = ronly;
 
@@ -752,9 +769,9 @@ struct shmem_ops *smb_shm_open(int ronly)
        }
        trim_string(file_name,"","/");
        if (!*file_name) return(False);
-       strcat(file_name, "/SHARE_MEM_FILE");
+       pstrcat(file_name, "/SHARE_MEM_FILE");
    
-   DEBUG(5,("smb_shm_open : using shmem file %s to be of size %d\n",file_name,size));
+   DEBUG(5,("smb_shm_open : using shmem file %s to be of size %.0f\n",file_name,(double)size));
 
    smb_shm_fd = open(file_name, read_only?O_RDONLY:(O_RDWR|O_CREAT),
                     SHM_FILE_MODE);
@@ -771,7 +788,7 @@ struct shmem_ops *smb_shm_open(int ronly)
       return NULL;
    }
    
-   if( (filesize = lseek(smb_shm_fd, 0, SEEK_END)) < 0)
+   if( (filesize = sys_lseek(smb_shm_fd, 0, SEEK_END)) < 0)
    {
       DEBUG(0,("ERROR smb_shm_open : lseek failed with code %s\n",strerror(errno)));
       smb_shm_global_unlock();
@@ -780,7 +797,7 @@ struct shmem_ops *smb_shm_open(int ronly)
    }
 
    /* return the file offset to 0 to save on later seeks */
-   lseek(smb_shm_fd,0,SEEK_SET);
+   sys_lseek(smb_shm_fd,0,SEEK_SET);
 
    if (filesize == 0)
    {
@@ -793,8 +810,8 @@ struct shmem_ops *smb_shm_open(int ronly)
       */
 
    /* construct processreg file name */
-   strcpy(smb_shm_processreg_name, file_name);
-   strcat(smb_shm_processreg_name, ".processes");
+   pstrcpy(smb_shm_processreg_name, file_name);
+   pstrcat(smb_shm_processreg_name, ".processes");
 
    if (!read_only && 
        !smb_shm_register_process(smb_shm_processreg_name, getpid(), &other_processes))
@@ -807,17 +824,17 @@ struct shmem_ops *smb_shm_open(int ronly)
    if (!read_only && (created_new || !other_processes))
    {
       /* we just created a new one, or are the first opener, lets set it size */
-      if( ftruncate(smb_shm_fd, size) <0)
+      if( sys_ftruncate(smb_shm_fd, size) <0)
       {
-         DEBUG(0,("ERROR smb_shm_open : ftruncate failed with code %s\n",strerror(errno)));
-        smb_shm_unregister_process(smb_shm_processreg_name, getpid());
-        smb_shm_global_unlock();
-        close(smb_shm_fd);
-        return NULL;
+        DEBUG(0,("ERROR smb_shm_open : ftruncate failed with code %s\n",strerror(errno)));
+        smb_shm_unregister_process(smb_shm_processreg_name, getpid());
+        smb_shm_global_unlock();
+        close(smb_shm_fd);
+        return NULL;
       }
 
       /* paranoia */
-      lseek(smb_shm_fd,0,SEEK_SET);
+      sys_lseek(smb_shm_fd,0,SEEK_SET);
 
       filesize = size;
    }
@@ -826,7 +843,9 @@ struct shmem_ops *smb_shm_open(int ronly)
    {
       /* the existing file has a different size and we are not the first opener.
         Since another process is still using it, we will use the file size */
-      DEBUG(0,("WARNING smb_shm_open : filesize (%d) != expected size (%d), using filesize\n",filesize,size));
+      DEBUG(0,("WARNING smb_shm_open : filesize (%.0f) != expected size (%.0f), using filesize\n",
+            (double)filesize, (double)size));
+
       size = filesize;
    }
    
@@ -868,7 +887,7 @@ struct shmem_ops *smb_shm_open(int ronly)
 }
 
 
-#else /* FAST_SHARE_MODES */
+#else /* HAVE_SHARED_MMAP */
  int shmem_dummy_procedure(void)
 {return 0;}
-#endif /* FAST_SHARE_MODES */
+#endif /* HAVE_SHARED_MMAP */