1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_nsDumpUtils_h 8 #define mozilla_nsDumpUtils_h 9 10 #include "nsIObserver.h" 11 #include "base/message_loop.h" 12 #include "nsXULAppAPI.h" 13 #include "nsThreadUtils.h" 14 #include "mozilla/Mutex.h" 15 #include "mozilla/StaticPtr.h" 16 #include "nsTArray.h" 17 18 #ifdef LOG 19 # undef LOG 20 #endif 21 22 #ifdef ANDROID 23 # include "android/log.h" 24 # define LOG(...) \ 25 __android_log_print(ANDROID_LOG_INFO, "Gecko:DumpUtils", ##__VA_ARGS__) 26 #else 27 # define LOG(...) 28 #endif 29 30 #ifdef XP_UNIX // { 31 32 /** 33 * Abstract base class for something which watches an fd and takes action when 34 * we can read from it without blocking. 35 */ 36 class FdWatcher : public MessageLoopForIO::Watcher, public nsIObserver { 37 protected: 38 MessageLoopForIO::FileDescriptorWatcher mReadWatcher; 39 int mFd; 40 ~FdWatcher()41 virtual ~FdWatcher() { 42 // StopWatching should have run. 43 MOZ_ASSERT(mFd == -1); 44 } 45 46 public: FdWatcher()47 FdWatcher() : mFd(-1) { MOZ_ASSERT(NS_IsMainThread()); } 48 49 /** 50 * Open the fd to watch. If we encounter an error, return -1. 51 */ 52 virtual int OpenFd() = 0; 53 54 /** 55 * Called when you can read() from the fd without blocking. Note that this 56 * function is also called when you're at eof (read() returns 0 in this case). 57 */ 58 virtual void OnFileCanReadWithoutBlocking(int aFd) override = 0; OnFileCanWriteWithoutBlocking(int aFd)59 virtual void OnFileCanWriteWithoutBlocking(int aFd) override{}; 60 61 NS_DECL_THREADSAFE_ISUPPORTS 62 63 /** 64 * Initialize this object. This should be called right after the object is 65 * constructed. (This would go in the constructor, except we interact with 66 * XPCOM, which we can't do from a constructor because our refcount is 0 at 67 * that point.) 68 */ 69 void Init(); 70 71 // Implementations may call this function multiple times if they ensure that 72 73 virtual void StartWatching(); 74 75 // Since implementations can call StartWatching() multiple times, they can of 76 // course call StopWatching() multiple times. 77 virtual void StopWatching(); 78 Observe(nsISupports * aSubject,const char * aTopic,const char16_t * aData)79 NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic, 80 const char16_t* aData) override { 81 MOZ_ASSERT(NS_IsMainThread()); 82 MOZ_ASSERT(!strcmp(aTopic, "xpcom-shutdown")); 83 84 XRE_GetIOMessageLoop()->PostTask(mozilla::NewRunnableMethod( 85 "FdWatcher::StopWatching", this, &FdWatcher::StopWatching)); 86 87 return NS_OK; 88 } 89 }; 90 91 typedef void (*FifoCallback)(const nsCString& aInputStr); 92 struct FifoInfo { 93 nsCString mCommand; 94 FifoCallback mCallback; 95 }; 96 typedef nsTArray<FifoInfo> FifoInfoArray; 97 98 class FifoWatcher : public FdWatcher { 99 public: 100 /** 101 * The name of the preference used to enable/disable the FifoWatcher. 102 */ 103 // The length of this array must match the size of the string constant in 104 // the definition in nsDumpUtils.cpp. A mismatch will result in a compile-time 105 // error. 106 static const char kPrefName[38]; 107 108 static FifoWatcher* GetSingleton(); 109 110 static bool MaybeCreate(); 111 112 void RegisterCallback(const nsCString& aCommand, FifoCallback aCallback); 113 114 virtual ~FifoWatcher(); 115 116 virtual int OpenFd() override; 117 118 virtual void OnFileCanReadWithoutBlocking(int aFd) override; 119 120 private: 121 nsAutoCString mDirPath; 122 123 static mozilla::StaticRefPtr<FifoWatcher> sSingleton; 124 FifoWatcher(nsCString aPath)125 explicit FifoWatcher(nsCString aPath) 126 : mDirPath(aPath), mFifoInfoLock("FifoWatcher.mFifoInfoLock") {} 127 128 mozilla::Mutex mFifoInfoLock; // protects mFifoInfo 129 FifoInfoArray mFifoInfo; 130 }; 131 132 typedef void (*PipeCallback)(const uint8_t aRecvSig); 133 struct SignalInfo { 134 uint8_t mSignal; 135 PipeCallback mCallback; 136 }; 137 typedef nsTArray<SignalInfo> SignalInfoArray; 138 139 class SignalPipeWatcher : public FdWatcher { 140 public: 141 static SignalPipeWatcher* GetSingleton(); 142 143 void RegisterCallback(uint8_t aSignal, PipeCallback aCallback); 144 145 void RegisterSignalHandler(uint8_t aSignal = 0); 146 147 virtual ~SignalPipeWatcher(); 148 149 virtual int OpenFd() override; 150 151 virtual void StopWatching() override; 152 153 virtual void OnFileCanReadWithoutBlocking(int aFd) override; 154 155 private: 156 static mozilla::StaticRefPtr<SignalPipeWatcher> sSingleton; 157 SignalPipeWatcher()158 SignalPipeWatcher() : mSignalInfoLock("SignalPipeWatcher.mSignalInfoLock") { 159 MOZ_ASSERT(NS_IsMainThread()); 160 } 161 162 mozilla::Mutex mSignalInfoLock; // protects mSignalInfo 163 SignalInfoArray mSignalInfo; 164 }; 165 166 #endif // XP_UNIX } 167 168 class nsDumpUtils { 169 public: 170 enum Mode { CREATE, CREATE_UNIQUE }; 171 172 /** 173 * This function creates a new unique file based on |aFilename| in a 174 * world-readable temp directory. This is the system temp directory 175 * or, in the case of Android, the downloads directory. If |aFile| is 176 * non-null, it is assumed to point to a folder, and that folder is used 177 * instead. 178 */ 179 static nsresult OpenTempFile(const nsACString& aFilename, nsIFile** aFile, 180 const nsACString& aFoldername = ""_ns, 181 Mode aMode = CREATE_UNIQUE); 182 }; 183 184 #endif 185