Bug 826846 - B2G: Crash in loop if reinstall existing packaged app. r=jdm
authorJason Duell <jduell.mcbugs@gmail.com>
Tue, 08 Jan 2013 10:15:02 +0100
changeset 124166 2c0352886e9570c85026b91558b79e2143ef475d
parent 124165 e30d0716bc359f85c2f554e6098217e7a4d53e22
child 124167 d62218c7449743ade43ff890a54457d363d3c9f1
push idunknown
push userunknown
push dateunknown
reviewersjdm
bugs826846
milestone21.0a1
Bug 826846 - B2G: Crash in loop if reinstall existing packaged app. r=jdm
netwerk/ipc/PRemoteOpenFile.ipdl
netwerk/ipc/RemoteOpenFileChild.cpp
netwerk/ipc/RemoteOpenFileChild.h
netwerk/ipc/RemoteOpenFileParent.cpp
--- a/netwerk/ipc/PRemoteOpenFile.ipdl
+++ b/netwerk/ipc/PRemoteOpenFile.ipdl
@@ -21,15 +21,17 @@ protocol PRemoteOpenFile
 parent:
   // Tell parent to open file. URI to open was passed and vetted for security in
   // IPDL constructor: see NeckoParent::AllocPRemoteOpenFile()
   AsyncOpenFile();
 
   __delete__();
 
 child:
-  // success/failure code, and if NS_SUCCEEDED(rv), an open file descriptor
-  FileOpened(FileDescriptor fd, nsresult rv);
+  // Your file handle is ready, Sir...
+  FileOpened(FileDescriptor fd);
+  // Trying to send invalid fd crashes, so we need separate method for failure
+  FileDidNotOpen();
 };
 
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/ipc/RemoteOpenFileChild.cpp
+++ b/netwerk/ipc/RemoteOpenFileChild.cpp
@@ -133,36 +133,49 @@ RemoteOpenFileChild::AsyncRemoteFileOpen
 }
 
 
 //-----------------------------------------------------------------------------
 // RemoteOpenFileChild::PRemoteOpenFileChild
 //-----------------------------------------------------------------------------
 
 bool
-RemoteOpenFileChild::RecvFileOpened(const FileDescriptor& aFD,
-                                    const nsresult& aRV)
+RemoteOpenFileChild::RecvFileOpened(const FileDescriptor& aFD)
 {
 #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
   NS_NOTREACHED("osX and Windows shouldn't be doing IPDL here");
 #else
-  if (NS_SUCCEEDED(aRV)) {
-    mNSPRFileDesc = PR_AllocFileDesc(aFD.PlatformHandle(), PR_GetFileMethods());
-  }
+  mNSPRFileDesc = PR_AllocFileDesc(aFD.PlatformHandle(), PR_GetFileMethods());
 
   MOZ_ASSERT(mListener);
-
-  mListener->OnRemoteFileOpenComplete(aRV);
-
+  mListener->OnRemoteFileOpenComplete(NS_OK);
   mListener = nullptr;     // release ref to listener
 
   // This calls NeckoChild::DeallocPRemoteOpenFile(), which deletes |this| if
   // IPDL holds the last reference.  Don't rely on |this| existing after here!
   Send__delete__(this);
+#endif
 
+  return true;
+}
+
+bool
+RemoteOpenFileChild::RecvFileDidNotOpen()
+{
+#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
+  NS_NOTREACHED("osX and Windows shouldn't be doing IPDL here");
+#else
+  MOZ_ASSERT(mListener);
+  printf_stderr("RemoteOpenFileChild: file was not opened!\n");
+  mListener->OnRemoteFileOpenComplete(NS_ERROR_FILE_NOT_FOUND);
+  mListener = nullptr;     // release ref to listener
+
+  // This calls NeckoChild::DeallocPRemoteOpenFile(), which deletes |this| if
+  // IPDL holds the last reference.  Don't rely on |this| existing after here!
+  Send__delete__(this);
 #endif
 
   return true;
 }
 
 void
 RemoteOpenFileChild::AddIPDLReference()
 {
--- a/netwerk/ipc/RemoteOpenFileChild.h
+++ b/netwerk/ipc/RemoteOpenFileChild.h
@@ -63,17 +63,18 @@ public:
   // Note: currently only PR_RDONLY is supported for 'flags'
   nsresult AsyncRemoteFileOpen(int32_t aFlags,
                                nsIRemoteOpenFileListener* aListener,
                                nsITabChild* aTabChild);
 private:
   RemoteOpenFileChild(const RemoteOpenFileChild& other);
 
 protected:
-  virtual bool RecvFileOpened(const FileDescriptor&, const nsresult&);
+  virtual bool RecvFileOpened(const FileDescriptor&);
+  virtual bool RecvFileDidNotOpen();
 
   // regular nsIFile object, that we forward most calls to.
   nsCOMPtr<nsIFile> mFile;
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIRemoteOpenFileListener> mListener;
   PRFileDesc* mNSPRFileDesc;
   bool mAsyncOpenCalled;
   bool mNSPROpenCalled;
--- a/netwerk/ipc/RemoteOpenFileParent.cpp
+++ b/netwerk/ipc/RemoteOpenFileParent.cpp
@@ -45,26 +45,27 @@ RemoteOpenFileParent::RecvAsyncOpenFile(
   // TODO: make this async!
 
   nsAutoCString path;
   nsresult rv = mURI->GetFilePath(path);
   NS_UnescapeURL(path);
   if (NS_SUCCEEDED(rv)) {
     int fd = open(path.get(), O_RDONLY);
     if (fd != -1) {
-      unused << SendFileOpened(FileDescriptor(fd), NS_OK);
+      unused << SendFileOpened(FileDescriptor(fd));
       // file handle needs to stay open until it's shared with child (and IPDL
       // is async, so hasn't happened yet). Close in destructor.
       mFd = fd;
       return true;
     }
   }
 
   // Note: sending an invalid file descriptor currently kills the child process:
   // but that's ok for our use case (failing to open application.jar).
-  unused << SendFileOpened(FileDescriptor(mFd), NS_ERROR_NOT_AVAILABLE);
+  printf_stderr("RemoteOpenFileParent: file '%s' was not found!\n", path.get());
+  unused << SendFileDidNotOpen();
 #endif // OS_TYPE
 
   return true;
 }
 
 } // namespace net
 } // namespace mozilla