Fixed bugs: 155, 156, 157 and 158; rework pclFileOpen function
authorIngo Huerner <ingo.huerner@xse.de>
Wed, 12 Feb 2014 13:19:13 +0000 (14:19 +0100)
committerIngo Huerner <ingo.huerner@xse.de>
Wed, 12 Feb 2014 13:19:13 +0000 (14:19 +0100)
src/persistence_client_library.c
src/persistence_client_library_backup_filelist.c
src/persistence_client_library_backup_filelist.h
src/persistence_client_library_db_access.c
src/persistence_client_library_file.c
src/persistence_client_library_handle.c
src/persistence_client_library_handle.h
src/persistence_client_library_key.c
test/persistence_client_library_test.c

index 38da6c8..612b50c 100644 (file)
@@ -218,6 +218,10 @@ int pclDeinitLibrary(void)
 
       // close opend database
       pers_db_close_all();
+
+      // close persistence handles
+      close_all_persistence_handle();
+
       // end dbus library
       bContinue = 0;
 
@@ -242,7 +246,7 @@ int pclDeinitLibrary(void)
    }
    else
    {
-      rval = PCLnotInitialized;
+      rval = EPERS_NOT_INITIALIZED;
    }
    return rval;
 }
index c72b739..f87942d 100644 (file)
@@ -333,9 +333,11 @@ int pclCreateFile(const char* path)
 {
    const char* delimiters = "/\n";   // search for blank and end of line
    char* tokenArray[24];
-   char* thePath = (char*)path;
+   char thePath[DbPathMaxLen] = {0};
    int numTokens = 0, i = 0, validPath = 1;
-   int handle = 0;
+   int handle = -1;
+
+   strncpy(thePath, path, DbPathMaxLen);
 
    tokenArray[numTokens++] = strtok(thePath, delimiters);
    while(tokenArray[numTokens-1] != NULL )
@@ -371,18 +373,6 @@ int pclCreateFile(const char* path)
       strncat(createPath, "/", DbPathMaxLen-1);
       strncat(createPath, tokenArray[i], DbPathMaxLen-1);
       handle = open(createPath, O_CREAT|O_RDWR |O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
-      if(handle != -1)
-      {
-         if(handle < MaxPersHandle)
-         {
-            __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag
-         }
-         else
-         {
-            close(handle);
-            handle = EPERS_MAXHANDLE;
-         }
-      }
    }
    else
    {
@@ -590,9 +580,12 @@ int pclCreateBackup(const char* dstPath, int srcfd, const char* csumPath, const
 
    if(access(dstPath, F_OK) != 0)
    {
+      int handle = -1;
       char pathToCreate[DbPathMaxLen] = {0};
       strncpy(pathToCreate, dstPath, DbPathMaxLen);
-      pclCreateFileAndPath(pathToCreate);
+
+      handle = pclCreateFile(pathToCreate);
+      close(handle); // don't need the open file
    }
 
    // create checksum file and and write checksum
@@ -693,60 +686,6 @@ int pclBackupNeeded(const char* path)
 
 
 
-int pclCreateFileAndPath(const char* path)
-{
-   const char* delimiters = "/\n";   // search for blank and end of line
-   char* tokenArray[24];
-   char* thePath = (char*)path;
-   char createPath[DbPathMaxLen] = {0};
-   int numTokens = 0, i = 0, validPath = 1;
-   int rval = -1;
-
-   tokenArray[numTokens++] = strtok(thePath, delimiters);
-   while(tokenArray[numTokens-1] != NULL )
-   {
-     tokenArray[numTokens] = strtok(NULL, delimiters);
-     if(tokenArray[numTokens] != NULL)
-     {
-        numTokens++;
-        if(numTokens >= 24)
-        {
-           validPath = 0;
-           break;
-        }
-     }
-     else
-     {
-        break;
-     }
-   }
-
-   if(validPath == 1)
-   {
-      snprintf(createPath, DbPathMaxLen, "/%s",tokenArray[0] );
-      for(i=1; i<numTokens-1; i++)
-      {
-         // create folders
-         strncat(createPath, "/", DbPathMaxLen-1);
-         strncat(createPath, tokenArray[i], DbPathMaxLen-1);
-         mkdir(createPath, 0744);
-      }
-      // finally create the file
-      strncat(createPath, "/", DbPathMaxLen-1);
-      strncat(createPath, tokenArray[i], DbPathMaxLen-1);
-      rval = open(createPath, O_CREAT|O_RDWR |O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
-      close(rval);
-   }
-   else
-   {
-      DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclCreateFileAndPath ==> no valid path to create:"), DLT_STRING(path));
-   }
-
-   return rval;
-}
-
-
-
 int pclGetPosixPermission(PersistencePermission_e permission)
 {
    int posixPerm = 0;
index 896981b..0771ae4 100644 (file)
@@ -47,7 +47,7 @@ int need_backup_key(unsigned int key);
  *
  * @param
  *
- * @return
+ * @return the handle to his file
  */
 int pclCreateFile(const char* path);
 
@@ -112,16 +112,4 @@ inline int pclBackupNeeded(const char* path);
 int pclGetPosixPermission(PersistencePermission_e permission);
 
 
-
-/**
- * @brief create the file and the given path
- *
- * @param
- *
- * @return
- */
-int pclCreateFileAndPath(const char* path);
-
-
-
 #endif /* PERS_BACKUP_BLACKLIST_H */
index 443aab4..3818218 100644 (file)
@@ -63,7 +63,7 @@ int gFreeCursorHandleArray[MaxPersHandle];
 int gFreeCursorHandleIdxHead = 0;
 
 // mutex to controll access to the cursor array
-pthread_mutex_t gMtx = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t gCursorMtx = PTHREAD_MUTEX_INITIALIZER;
 
 
 /// btree array
@@ -714,7 +714,7 @@ int get_cursor_handle()
 {
    int handle = 0;
 
-   if(pthread_mutex_lock(&gMtx) == 0)
+   if(pthread_mutex_lock(&gCursorMtx) == 0)
    {
       if(gFreeCursorHandleIdxHead > 0)   // check if we have a free spot in the array before the current max
       {
@@ -732,7 +732,7 @@ int get_cursor_handle()
             handle = -1;
          }
       }
-      pthread_mutex_unlock(&gMtx);
+      pthread_mutex_unlock(&gCursorMtx);
    }
    return handle;
 }
@@ -740,13 +740,13 @@ int get_cursor_handle()
 
 void close_cursor_handle(int handlerDB)
 {
-   if(pthread_mutex_lock(&gMtx) == 0)
+   if(pthread_mutex_lock(&gCursorMtx) == 0)
    {
       if(gFreeCursorHandleIdxHead < MaxPersHandle)
       {
          gFreeCursorHandleArray[gFreeCursorHandleIdxHead++] = handlerDB;
       }
-      pthread_mutex_unlock(&gMtx);
+      pthread_mutex_unlock(&gCursorMtx);
    }
 }
 
index 85e0753..180ace4 100644 (file)
@@ -183,29 +183,30 @@ int pclFileOpen(unsigned int ldbid, const char* resource_id, unsigned int user_n
                handle = open(dbPath, flags);
             }
 
-            if(handle != -1)
+            if(handle == -1)
             {
-               if(handle < MaxPersHandle)
+               if( (handle = pclCreateFile(dbPath)) == -1)
                {
-                  __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag
-
-                  if(dbContext.configKey.permission != PersistencePermission_ReadOnly)
-                  {
-                     strcpy(gFileHandleArray[handle].backupPath, backupPath);
-                     strcpy(gFileHandleArray[handle].csumPath,   csumPath);
-                     gFileHandleArray[handle].backupCreated = 0;
-                     gFileHandleArray[handle].permission = dbContext.configKey.permission;
-                  }
+                  DLT_LOG(gDLTContext, DLT_LOG_ERROR, DLT_STRING("pclFileOpen: error => failed to create file: "), DLT_STRING(dbPath));
                }
-               else
+            }
+
+            if(handle < MaxPersHandle)
+            {
+               __sync_fetch_and_add(&gOpenFdArray[handle], FileOpen); // set open flag
+
+               if(dbContext.configKey.permission != PersistencePermission_ReadOnly)
                {
-                  close(handle);
-                  handle = EPERS_MAXHANDLE;
+                  strcpy(gFileHandleArray[handle].backupPath, backupPath);
+                  strcpy(gFileHandleArray[handle].csumPath,   csumPath);
+                  gFileHandleArray[handle].backupCreated = 0;
+                  gFileHandleArray[handle].permission = dbContext.configKey.permission;
                }
             }
-            else  // file does not exist, create file and folder
+            else
             {
-               handle = pclCreateFile(dbPath);
+               close(handle);
+               handle = EPERS_MAXHANDLE;
             }
          }
          else  // requested resource is not in the RCT, so create resource as local/cached.
@@ -238,7 +239,6 @@ int pclFileOpen(unsigned int ldbid, const char* resource_id, unsigned int user_n
          handle = EPERS_RESOURCE_NO_FILE;
       }
    }
-
    return handle;
 }
 
@@ -462,15 +462,16 @@ int pclFileCreatePath(unsigned int ldbid, const char* resource_id, unsigned int
                   }
 
                   *size = strlen(dbPath);
-                  *path = malloc(*size);
-                  memcpy(*path, dbPath, *size);
-                  (*path)[*size] = '\0';
+                  *path = malloc((*size)+1);    // allocate 1 byte for the string termination
+                  memcpy(*path, dbPath, (*size)+1);
+                  (*path)[(*size)+1] = '\0';   // terminate string
                   gOssHandleArray[handle].filePath = *path;
 
                   if(access(*path, F_OK) == -1)
                   {
                      // file does not exist, create it.
-                     pclCreateFileAndPath(*path);
+                     int handle = pclCreateFile(*path);
+                     close(handle);    // don't need the open file
                   }
                }
                else
index f83178e..704d715 100644 (file)
@@ -26,8 +26,6 @@
 /// handle index
 static int gHandleIdx = 1;
 
-static int gInitialized = 0;
-
 /// open file descriptor handle array
 int gOpenFdArray[MaxPersHandle] = {0};
 
@@ -47,7 +45,7 @@ PersistenceFileHandle_s gOssHandleArray[MaxPersHandle];
 /// free handle array
 int gFreeHandleArray[MaxPersHandle] = {0};
 int gFreeHandleIdxHead = 0;
-pthread_mutex_t gMtx;
+pthread_mutex_t gMtx = PTHREAD_MUTEX_INITIALIZER;
 
 
 
@@ -56,12 +54,6 @@ int get_persistence_handle_idx()
 {
    int handle = 0;
 
-   if(gInitialized == 0)
-   {
-      gInitialized = 1;
-      pthread_mutex_init(&gMtx, 0);
-   }
-
    if(pthread_mutex_lock(&gMtx) == 0)
    {
       if(gFreeHandleIdxHead > 0)   // check if we have a free spot in the array before the current max
@@ -100,3 +92,21 @@ void set_persistence_handle_close_idx(int handle)
    }
 }
 
+
+
+void close_all_persistence_handle()
+{
+   if(pthread_mutex_lock(&gMtx) == 0)
+   {
+      // "free" all handles
+      memset(gFreeHandleArray, 0, MaxPersHandle);
+      memset(gOpenFdArray, 0, MaxPersHandle);
+      memset(gOpenFdArray, 0, MaxPersHandle);
+
+      // reset variables
+      gHandleIdx = 1;
+      gFreeHandleIdxHead = 0;
+
+      pthread_mutex_unlock(&gMtx);
+   }
+}
index 583fd80..2a1c200 100644 (file)
@@ -81,6 +81,12 @@ void set_persistence_handle_close_idx(int handle);
 
 
 
+/**
+ * @brief close open file handles
+ *
+ */
+void close_all_persistence_handle();
+
 
 #endif /* PERSISTENCY_CLIENT_LIBRARY_HANDLE_H */
 
index 2c212e0..9d65619 100644 (file)
@@ -121,7 +121,7 @@ int pclKeyHandleClose(int key_handle)
 
    if(gPclInitialized >= PCLinitialized)
    {
-      if(key_handle < MaxPersHandle)
+      if(key_handle < MaxPersHandle && key_handle > 0)
       {
          if(PersistenceStorage_custom == gKeyHandleArray[key_handle].info.configKey.storage )
          {
@@ -167,7 +167,7 @@ int pclKeyHandleGetSize(int key_handle)
 
    if(gPclInitialized >= PCLinitialized)
    {
-      if(key_handle < MaxPersHandle)
+      if(key_handle < MaxPersHandle && key_handle > 0)
       {
          if(PersistenceStorage_custom ==  gKeyHandleArray[key_handle].info.configKey.storage)
          {
@@ -208,7 +208,7 @@ int pclKeyHandleReadData(int key_handle, unsigned char* buffer, int buffer_size)
 
    if(gPclInitialized >= PCLinitialized)
    {
-      if(key_handle < MaxPersHandle)
+      if(key_handle < MaxPersHandle && key_handle > 0)
       {
          if(PersistenceStorage_custom ==  gKeyHandleArray[key_handle].info.configKey.storage)
          {
@@ -264,7 +264,7 @@ int handleRegNotifyOnChange(int key_handle, pclChangeNotifyCallback_t callback,
 
    if(gPclInitialized >= PCLinitialized)
    {
-      if(key_handle < MaxPersHandle)
+      if(key_handle < MaxPersHandle && key_handle > 0)
       {
          rval = regNotifyOnChange(gKeyHandleArray[key_handle].info.context.ldbid,
                                   gKeyHandleArray[key_handle].resourceID,
@@ -296,7 +296,7 @@ int pclKeyHandleWriteData(int key_handle, unsigned char* buffer, int buffer_size
       {
          if(buffer_size <= gMaxKeyValDataSize)  // check data size
          {
-            if(key_handle < MaxPersHandle)
+            if(key_handle < MaxPersHandle && key_handle > 0)
             {
                if(gKeyHandleArray[key_handle].info.configKey.permission != PersistencePermission_ReadOnly)  // don't write to a read only resource
                {
index 6cf1da1..4667d55 100644 (file)
@@ -52,7 +52,12 @@ char gTheAppId[MaxAppNameLen] = {0};
 char* dayOfWeek[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
 
 
+int myChangeCallback(pclNotification_s * notifyStruct)
+{
+   printf(" ==> * - * myChangeCallback * - *\n");
 
+   return 1;
+}
 /**
  * Test the key value interface using different logicalDB id's, users and seats.
  * Each resource below has an entry in the resource configuration table where the
@@ -1069,6 +1074,7 @@ START_TEST(test_GetPath)
    x_fail_unless(ret <= 1, "Failed to init PCL");
 #if 1
    ret = pclFileCreatePath(0xFF, "media/mediaDB_create.db", 1, 1, &path, &pathSize);
+
    x_fail_unless(strncmp((char*)path, thePath, strlen((char*)path)) == 0, "Path not correct");
    x_fail_unless(pathSize == strlen((char*)path), "Path size not correct");
 
@@ -1106,6 +1112,91 @@ END_TEST
 
 
 
+START_TEST(test_NegHandle)
+{
+   int handle = -1, ret = 0;;
+   int negativeHandle = -17;
+   unsigned int shutdownReg = PCL_SHUTDOWN_TYPE_FAST | PCL_SHUTDOWN_TYPE_NORMAL;
+
+   unsigned char buffer[128] = {0};
+
+   (void)pclInitLibrary(gTheAppId, shutdownReg);
+
+   handle = pclKeyHandleOpen(0xFF, "posHandle/last_position", 0, 0);
+   x_fail_unless(handle >= 0, "Failed to open handle ==> /posHandle/last_position");
+
+
+
+   ret = pclKeyHandleReadData(negativeHandle, buffer, READ_SIZE);
+   x_fail_unless(ret == EPERS_MAXHANDLE, "pclKeyHandleReadData => negative handle not detected");
+
+   ret = pclKeyHandleClose(negativeHandle);
+   x_fail_unless(ret == EPERS_MAXHANDLE, "pclKeyHandleClose => negative handle not detected");
+
+   ret = pclKeyHandleGetSize(negativeHandle);
+   x_fail_unless(ret == EPERS_MAXHANDLE, "pclKeyHandleGetSize => negative handle not detected");
+
+   ret = pclKeyHandleReadData(negativeHandle, buffer, 128);
+   x_fail_unless(ret == EPERS_MAXHANDLE, "pclKeyHandleReadData => negative handle not detected");
+
+   ret = pclKeyHandleRegisterNotifyOnChange(negativeHandle, &myChangeCallback);
+   x_fail_unless(ret == EPERS_MAXHANDLE, "pclKeyHandleRegisterNotifyOnChange => negative handle not detected");
+
+   ret = pclKeyHandleWriteData(negativeHandle, (unsigned char*)"Whatever", strlen("Whatever"));
+   x_fail_unless(ret == EPERS_MAXHANDLE, "pclKeyHandleWriteData => negative handle not detected");
+
+
+   // close handle
+   ret = pclKeyHandleClose(handle);
+
+   pclDeinitLibrary();
+}
+END_TEST
+
+
+
+
+
+START_TEST(test_FileOpenCreate)
+{
+   int handle = -1, ret = 0;
+   unsigned int shutdownReg = PCL_SHUTDOWN_TYPE_FAST | PCL_SHUTDOWN_TYPE_NORMAL;
+   char buffer[128] = {0};
+   char* writeBuffer = "test_FileOpenCreate: write some data to the file!";
+
+   (void)pclInitLibrary(gTheAppId, shutdownReg);
+
+   // remove file
+   remove("/Data/mnt-wt/lt-persistence_client_library_test/user/1/seat/1/media/mediaDBWrite.db");
+
+   handle = pclFileOpen(0xFF, "media/mediaDBWrite.db", 1, 1);
+   x_fail_unless(handle != -1, "Could not open file ==> /media/mediaDBWrite.db");
+
+
+   ret = pclFileWriteData(handle, writeBuffer, strlen(writeBuffer));
+   x_fail_unless(ret == strlen(writeBuffer), "pclKeyHandleWriteData => error writing data");
+
+
+   ret = pclFileSeek(handle, 0, SEEK_SET);
+   x_fail_unless(ret <= 0, "pclFileSeek => failed to position fd");
+
+
+   ret = pclFileReadData(handle, buffer, 128);
+   x_fail_unless(ret == strlen(writeBuffer), "pclKeyHandleReadData => error read data");
+   x_fail_unless(strncmp(buffer, writeBuffer, strlen(writeBuffer)) == 0, "pclKeyHandleReadData => Buffer not correctly read");
+
+   ret = pclFileClose(handle);
+   x_fail_unless(ret <= 0, "pclKeyHandleClose => failed to close");
+
+   // remove file
+   remove("/Data/mnt-wt/lt-persistence_client_library_test/user/1/seat/1/media/mediaDBWrite.db");
+
+   pclDeinitLibrary();
+}
+END_TEST
+
+
+
 static Suite * persistencyClientLib_suite()
 {
    Suite * s  = suite_create("Persistency client library");
@@ -1158,6 +1249,12 @@ static Suite * persistencyClientLib_suite()
    TCase * tc_InitDeinit = tcase_create("InitDeinit");
    tcase_add_test(tc_InitDeinit, test_InitDeinit);
 
+   TCase * tc_NegHandle = tcase_create("NegHandle");
+   tcase_add_test(tc_NegHandle, test_NegHandle);
+
+   TCase * tc_FileOpenCreate = tcase_create("FileOpenCreate");
+   tcase_add_test(tc_FileOpenCreate, test_FileOpenCreate);
+
    suite_add_tcase(s, tc_persSetData);
    suite_add_tcase(s, tc_persGetData);
    suite_add_tcase(s, tc_persSetDataNoPRCT);
@@ -1173,6 +1270,9 @@ static Suite * persistencyClientLib_suite()
    suite_add_tcase(s, tc_ReadConfDefault);
    suite_add_tcase(s, tc_GetPath);
    suite_add_tcase(s, tc_InitDeinit);
+   suite_add_tcase(s, tc_NegHandle);
+   suite_add_tcase(s, tc_FileOpenCreate);
+
    //suite_add_tcase(s, tc_Plugin); // activate only if the plugins are available
    return s;
 }