From 4c364dc07ed7d2726bf95101e6d14b2bd95939c3 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Fri, 20 Jan 2023 00:15:42 +0200
Subject: [PATCH] SL-14318 MacOS __write_nocancel crash

Multiple instances of viewer could write to the same uuid.inv file at the same time.
---
 indra/newview/llappviewer.cpp      |  3 ++-
 indra/newview/llinventorymodel.cpp | 17 ++++++++++-------
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 8af5fdfc93e..d9d89efee70 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -5474,7 +5474,8 @@ void LLAppViewer::disconnectViewer()
     {
         gInventory.cache(gInventory.getRootFolderID(), gAgent.getID());
         if (gInventory.getLibraryRootFolderID().notNull()
-            && gInventory.getLibraryOwnerID().notNull())
+            && gInventory.getLibraryOwnerID().notNull()
+            && !mSecondInstance) // agent is unique, library isn't
         {
             gInventory.cache(
                 gInventory.getLibraryRootFolderID(),
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 13a83c8527e..1ebb18be1bd 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1953,18 +1953,20 @@ void LLInventoryModel::cache(
 		items,
 		INCLUDE_TRASH,
 		can_cache);
-	std::string inventory_filename = getInvCacheAddres(agent_id);
-	saveToFile(inventory_filename, categories, items);
-	std::string gzip_filename(inventory_filename);
+    // Use temporary file to avoid potential conflicts with other
+    // instances (even a 'read only' instance unzips into a file)
+    std::string temp_file = gDirUtilp->getTempFilename();
+	saveToFile(temp_file, categories, items);
+    std::string gzip_filename = getInvCacheAddres(agent_id);
 	gzip_filename.append(".gz");
-	if(gzip_file(inventory_filename, gzip_filename))
+	if(gzip_file(temp_file, gzip_filename))
 	{
-		LL_DEBUGS(LOG_INV) << "Successfully compressed " << inventory_filename << LL_ENDL;
-		LLFile::remove(inventory_filename);
+		LL_DEBUGS(LOG_INV) << "Successfully compressed " << temp_file << " to " << gzip_filename << LL_ENDL;
+		LLFile::remove(temp_file);
 	}
 	else
 	{
-		LL_WARNS(LOG_INV) << "Unable to compress " << inventory_filename << LL_ENDL;
+		LL_WARNS(LOG_INV) << "Unable to compress " << temp_file << " into " << gzip_filename << LL_ENDL;
 	}
 }
 
@@ -3038,6 +3040,7 @@ bool LLInventoryModel::saveToFile(const std::string& filename,
                 return false;
             }
         }
+        fileXML.flush();
 
         fileXML.close();
 
-- 
GitLab