/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=2 ts=8 et tw=80 : */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef _RemoteOpenFileChild_h #define _RemoteOpenFileChild_h #include "mozilla/Attributes.h" #include "mozilla/dom/TabChild.h" #include "mozilla/net/PRemoteOpenFileChild.h" #include "nsICachedFileDescriptorListener.h" #include "nsILocalFile.h" #include "nsIRemoteOpenFileListener.h" class nsILoadContext; namespace mozilla { namespace ipc { class FileDescriptor; } // namespace ipc namespace net { /** * RemoteOpenFileChild: a thin wrapper around regular nsIFile classes that does * IPC to open a file handle on parent instead of child. Used when we can't * open file handle on child (don't have permission), but we don't want the * overhead of shipping all I/O traffic across IPDL. Example: JAR files. * * To open a file handle with this class, AsyncRemoteFileOpen() must be called * first. After the listener's OnRemoteFileOpenComplete() is called, if the * result is NS_OK, nsIFile.OpenNSPRFileDesc() may be called to get a * duplicated file descriptor. * * Note that the file descriptor returned by NSPRFileDesc() is duplicated from * the original, which shares its file offset with the original. If the file * offset is modified (ex: by lseek/read/write) on one of the shared * descriptors, the offset is also changed for the other. It can be safely * used only with operations that take absolute offsets, such as * mmap/pread/pwrite. * * This class should only be instantiated in a child process. * */ class RemoteOpenFileChild final : public PRemoteOpenFileChild , public nsIFile , public nsIHashable , public nsICachedFileDescriptorListener { typedef mozilla::dom::TabChild TabChild; typedef mozilla::ipc::FileDescriptor FileDescriptor; virtual ~RemoteOpenFileChild(); public: RemoteOpenFileChild() : mNSPRFileDesc(nullptr) , mAsyncOpenCalled(false) , mNSPROpenCalled(false) {} NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIFILE NS_DECL_NSIHASHABLE // aRemoteOpenUri must be scheme 'remoteopenfile://': otherwise looks like // a file:// uri. nsresult Init(nsIURI* aRemoteOpenUri, nsIURI* aAppUri); // Send message to parent to tell it to open file handle for file. // TabChild is required, for IPC security. // Note: currently only PR_RDONLY is supported for 'flags' nsresult AsyncRemoteFileOpen(int32_t aFlags, nsIRemoteOpenFileListener* aListener, nsITabChild* aTabChild, nsILoadContext *aLoadContext); nsresult SetNSPRFileDesc(PRFileDesc* aNSPRFileDesc); void ReleaseIPDLReference() { Release(); } private: RemoteOpenFileChild(const RemoteOpenFileChild& other); protected: void AddIPDLReference() { AddRef(); } virtual bool Recv__delete__(const FileDescriptor&) override; virtual void OnCachedFileDescriptor(const nsAString& aPath, const FileDescriptor& aFD) override; void HandleFileDescriptorAndNotifyListener(const FileDescriptor&, bool aFromRecvDelete); void NotifyListener(nsresult aResult); // regular nsIFile object, that we forward most calls to. nsCOMPtr mFile; nsCOMPtr mURI; nsCOMPtr mAppURI; nsCOMPtr mListener; RefPtr mTabChild; PRFileDesc* mNSPRFileDesc; bool mAsyncOpenCalled; bool mNSPROpenCalled; }; } // namespace net } // namespace mozilla #endif // _RemoteOpenFileChild_h