0027901: Resource_Manager creates directory with insufficient permissions
authorabv <abv@opencascade.com>
Sun, 25 Sep 2016 20:05:00 +0000 (23:05 +0300)
committerkgv <kgv@opencascade.com>
Fri, 30 Sep 2016 08:17:16 +0000 (11:17 +0300)
Resource_Manager now sets RWXD permissions for the created directories to allow their removal.
Method OSD_Directory::Build() will create intermediate directories if they do not exist yet.
OSD_FileNode is corrected to clean error status in method Exists().

Tests bugs fclasses bug181_1 and bug181_2 are corrected to check existence of generated resource files; TODO is removed in bug181_2.

src/OSD/OSD_Directory.cxx
src/OSD/OSD_FileNode.cxx
src/Resource/Resource_Manager.cxx
tests/bugs/fclasses/bug181_1
tests/bugs/fclasses/bug181_2

index 0439f28..7db3ac2 100644 (file)
@@ -43,18 +43,26 @@ TCollection_AsciiString aBuffer;
  myPath.SystemName(aBuffer);
  umask ( 0 );
  status = mkdir (aBuffer.ToCString(), (mode_t)internal_prot);
- if (status == -1) 
-  if (errno != EEXIST) {
-   Standard_PCharacter err_message;
-
-   err_message = new Standard_Character [255];
-   sprintf (err_message,
-           "OSD_Directory::Build Directory \"%s\"",
+ if (status == -1 && errno == ENOENT)
+ {
+   OSD_Path aSupPath = myPath;
+   aSupPath.UpTrek();
+   aSupPath.SetName (myPath.TrekValue (myPath.TrekLength())); // incredible, but required!
+   OSD_Directory aSupDir (aSupPath);
+   aSupDir.Build (Protect);
+   if (aSupDir.Failed())
+   {
+     myError = aSupDir.myError;
+     return;
+   }
+   status = mkdir (aBuffer.ToCString(), (mode_t)internal_prot);
+ }
+ if (status == -1 && errno != EEXIST) {
+   Standard_Character err_message[2048];
+   Sprintf (err_message, "OSD_Directory::Build Directory \"%.2000s\"",
            aBuffer.ToCString());
-   
-   myError.SetValue(errno, Iam, err_message);
-   delete err_message;
-  }
+   myError.SetValue (errno, Iam, err_message);
+ }
 }
 
 OSD_Directory OSD_Directory::BuildTemporary(){
@@ -120,18 +128,48 @@ void OSD_Directory :: Build (const OSD_Protection& Protect) {
  if (  dirName.IsEmpty ()  )
 
   Standard_ProgramError :: Raise ( "OSD_Directory :: Build (): incorrect call - no directory name");
- TCollection_ExtendedString dirNameW(dirName);
- if (Exists() || CreateDirectoryW (dirNameW.ToWideString(), NULL))
- {
+
+  Standard_Boolean isOK = Exists();
+  if (! isOK)
+  {
+    // myError will be set to fail by Exists() if intermediate dirs do not exist
+    myError.Reset();
+
+    // create directory if it does not exist;
+    TCollection_ExtendedString dirNameW(dirName);
+    if (CreateDirectoryW (dirNameW.ToWideString(), NULL))
+    {
+      isOK = Standard_True;
+    }
+    // if failed due to absence of intermediate directories, create them recursively
+    else if (GetLastError() == ERROR_PATH_NOT_FOUND)
+    {
+      OSD_Path aSupPath = myPath;
+      aSupPath.UpTrek();
+      aSupPath.SetName (myPath.TrekValue (myPath.TrekLength())); // incredible, but required!
+      OSD_Directory aSupDir (aSupPath);
+      aSupDir.Build (Protect);
+      if (aSupDir.Failed())
+      {
+        myError = aSupDir.myError;
+        return;
+      }
+      isOK = (CreateDirectoryW (dirNameW.ToWideString(), NULL) != 0);
+    }
+  }
+
+  if (isOK)
+  {
 #ifndef OCCT_UWP
-   SetProtection(Protect);
+    SetProtection(Protect);
 #else
-   (void)Protect;
+    (void)Protect;
 #endif
- } else
-
-  _osd_wnt_set_error ( myError, OSD_WDirectory );
-
+  }
+  else
+  {
+    _osd_wnt_set_error ( myError, OSD_WDirectory );
+  }
 }  // end OSD_Directory :: Build
 
 OSD_Directory OSD_Directory :: BuildTemporary () {
index 5933a26..8354eee 100644 (file)
@@ -445,7 +445,9 @@ void OSD_FileNode::SetPath ( const OSD_Path& Name ) {
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean OSD_FileNode::Exists () {
+Standard_Boolean OSD_FileNode::Exists ()
+{
+  myError.Reset();
 
  Standard_Boolean        retVal = Standard_False;;
  TCollection_AsciiString fName;
index f6752db..21c0404 100644 (file)
@@ -252,7 +252,7 @@ Standard_Boolean Resource_Manager::Save() const
     {
       try {
         OCC_CATCH_SIGNALS
-        Dir.Build(OSD_Protection(OSD_RX, OSD_RWX, OSD_RX, OSD_RX));
+        Dir.Build(OSD_Protection(OSD_RX, OSD_RWXD, OSD_RX, OSD_RX));
       }
       catch (Standard_Failure) {
         Status = Standard_False;
index b7c4341..c208cbf 100644 (file)
@@ -27,4 +27,8 @@ if { ${status} == "TRUE"} then {
    puts "OCC181: Error"
 }
 
+if { ! [file exists ${tmp}/1/OCC181] } {
+  puts "Error: user resource file is not found!"
+}
+
 file delete -force ${tmp}/1
index c07ff4f..3c84e39 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC12345 ALL: OCC181: Error"
-
 puts "========"
 puts "OCC181"
 puts "OCC701"
@@ -29,4 +27,8 @@ if { ${status} == "TRUE"} then {
     puts "OCC181: Error"
 }
 
+if { ! [file exists ${tmp}/2/2/3/OCC181] } {
+  puts "Error: user resource file is not found!"
+}
+
 file delete -force ${tmp}/2