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 #include "FileDescriptorFile.h"
8 
9 #include "mozilla/ipc/FileDescriptorUtils.h"
10 #include "mozilla/ipc/URIUtils.h"
11 #include "mozilla/net/NeckoChild.h"
12 #include "nsNetUtil.h"
13 #include "nsProxyRelease.h"
14 #include "nsThreadUtils.h"
15 #include "private/pprio.h"
16 #include "SerializedLoadContext.h"
17 
18 namespace mozilla {
19 namespace net {
20 
21 NS_IMPL_ISUPPORTS(FileDescriptorFile, nsIFile)
22 
23 LazyLogModule gFDFileLog("FDFile");
24 #undef DBG
25 #define DBG(...) MOZ_LOG(gFDFileLog, LogLevel::Debug, (__VA_ARGS__))
26 
FileDescriptorFile(const FileDescriptor & aFD,nsIFile * aFile)27 FileDescriptorFile::FileDescriptorFile(const FileDescriptor& aFD,
28                                        nsIFile* aFile) {
29   MOZ_ASSERT(aFD.IsValid());
30   auto platformHandle = aFD.ClonePlatformHandle();
31   mFD = FileDescriptor(platformHandle.get());
32   mFile = aFile;
33 }
34 
FileDescriptorFile(const FileDescriptorFile & aOther)35 FileDescriptorFile::FileDescriptorFile(const FileDescriptorFile& aOther) {
36   auto platformHandle = aOther.mFD.ClonePlatformHandle();
37   mFD = FileDescriptor(platformHandle.get());
38   aOther.mFile->Clone(getter_AddRefs(mFile));
39 }
40 
41 //-----------------------------------------------------------------------------
42 // FileDescriptorFile::nsIFile functions that we override logic for
43 //-----------------------------------------------------------------------------
44 
45 NS_IMETHODIMP
Clone(nsIFile ** aFileOut)46 FileDescriptorFile::Clone(nsIFile** aFileOut) {
47   RefPtr<FileDescriptorFile> fdFile = new FileDescriptorFile(*this);
48   fdFile.forget(aFileOut);
49   return NS_OK;
50 }
51 
52 NS_IMETHODIMP
OpenNSPRFileDesc(int32_t aFlags,int32_t aMode,PRFileDesc ** aRetval)53 FileDescriptorFile::OpenNSPRFileDesc(int32_t aFlags, int32_t aMode,
54                                      PRFileDesc** aRetval) {
55   // Remove optional OS_READAHEAD flag so we test against PR_RDONLY
56   aFlags &= ~nsIFile::OS_READAHEAD;
57 
58   // Remove optional/deprecated DELETE_ON_CLOSE flag
59   aFlags &= ~nsIFile::DELETE_ON_CLOSE;
60 
61   // All other flags require write access to the file and
62   // this implementation only provides read access.
63   if (aFlags != PR_RDONLY) {
64     DBG("OpenNSPRFileDesc flags error (%" PRIu32 ")\n", aFlags);
65     return NS_ERROR_NOT_AVAILABLE;
66   }
67 
68   if (!mFD.IsValid()) {
69     DBG("OpenNSPRFileDesc error: no file descriptor\n");
70     return NS_ERROR_NOT_AVAILABLE;
71   }
72 
73   auto platformHandle = mFD.ClonePlatformHandle();
74   *aRetval = PR_ImportFile(PROsfd(platformHandle.release()));
75 
76   if (!*aRetval) {
77     DBG("OpenNSPRFileDesc Clone failure\n");
78     return NS_ERROR_NOT_AVAILABLE;
79   }
80 
81   return NS_OK;
82 }
83 
84 //-----------------------------------------------------------------------------
85 // FileDescriptorFile::nsIFile functions that we delegate to underlying nsIFile
86 //-----------------------------------------------------------------------------
87 
GetLeafName(nsAString & aLeafName)88 nsresult FileDescriptorFile::GetLeafName(nsAString& aLeafName) {
89   return mFile->GetLeafName(aLeafName);
90 }
91 
92 NS_IMETHODIMP
GetNativeLeafName(nsACString & aLeafName)93 FileDescriptorFile::GetNativeLeafName(nsACString& aLeafName) {
94   return mFile->GetNativeLeafName(aLeafName);
95 }
96 
GetTarget(nsAString & aRetVal)97 nsresult FileDescriptorFile::GetTarget(nsAString& aRetVal) {
98   return mFile->GetTarget(aRetVal);
99 }
100 
101 NS_IMETHODIMP
GetNativeTarget(nsACString & aRetVal)102 FileDescriptorFile::GetNativeTarget(nsACString& aRetVal) {
103   return mFile->GetNativeTarget(aRetVal);
104 }
105 
GetPath(nsAString & aRetVal)106 nsresult FileDescriptorFile::GetPath(nsAString& aRetVal) {
107   return mFile->GetPath(aRetVal);
108 }
109 
NativePath()110 PathString FileDescriptorFile::NativePath() { return mFile->NativePath(); }
111 
112 NS_IMETHODIMP
Equals(nsIFile * aOther,bool * aRetVal)113 FileDescriptorFile::Equals(nsIFile* aOther, bool* aRetVal) {
114   return mFile->Equals(aOther, aRetVal);
115 }
116 
117 NS_IMETHODIMP
Contains(nsIFile * aOther,bool * aRetVal)118 FileDescriptorFile::Contains(nsIFile* aOther, bool* aRetVal) {
119   return mFile->Contains(aOther, aRetVal);
120 }
121 
122 NS_IMETHODIMP
GetParent(nsIFile ** aParent)123 FileDescriptorFile::GetParent(nsIFile** aParent) {
124   return mFile->GetParent(aParent);
125 }
126 
127 NS_IMETHODIMP
GetPersistentDescriptor(nsACString & aPersistentDescriptor)128 FileDescriptorFile::GetPersistentDescriptor(nsACString& aPersistentDescriptor) {
129   return mFile->GetPersistentDescriptor(aPersistentDescriptor);
130 }
131 
132 //-----------------------------------------------------------------------------
133 // FileDescriptorFile::nsIFile functions that are not currently supported
134 //-----------------------------------------------------------------------------
135 
Append(const nsAString & aNode)136 nsresult FileDescriptorFile::Append(const nsAString& aNode) {
137   return NS_ERROR_NOT_IMPLEMENTED;
138 }
139 
140 NS_IMETHODIMP
AppendNative(const nsACString & aFragment)141 FileDescriptorFile::AppendNative(const nsACString& aFragment) {
142   return NS_ERROR_NOT_IMPLEMENTED;
143 }
144 
145 NS_IMETHODIMP
Normalize()146 FileDescriptorFile::Normalize() { return NS_ERROR_NOT_IMPLEMENTED; }
147 
148 NS_IMETHODIMP
Create(uint32_t aType,uint32_t aPermissions,bool aSkipAncestors)149 FileDescriptorFile::Create(uint32_t aType, uint32_t aPermissions,
150                            bool aSkipAncestors) {
151   return NS_ERROR_NOT_IMPLEMENTED;
152 }
153 
SetLeafName(const nsAString & aLeafName)154 nsresult FileDescriptorFile::SetLeafName(const nsAString& aLeafName) {
155   return NS_ERROR_NOT_IMPLEMENTED;
156 }
157 
158 NS_IMETHODIMP
SetNativeLeafName(const nsACString & aLeafName)159 FileDescriptorFile::SetNativeLeafName(const nsACString& aLeafName) {
160   return NS_ERROR_NOT_IMPLEMENTED;
161 }
162 
InitWithPath(const nsAString & aPath)163 nsresult FileDescriptorFile::InitWithPath(const nsAString& aPath) {
164   return NS_ERROR_NOT_IMPLEMENTED;
165 }
166 
167 NS_IMETHODIMP
InitWithNativePath(const nsACString & aPath)168 FileDescriptorFile::InitWithNativePath(const nsACString& aPath) {
169   return NS_ERROR_NOT_IMPLEMENTED;
170 }
171 
172 NS_IMETHODIMP
InitWithFile(nsIFile * aFile)173 FileDescriptorFile::InitWithFile(nsIFile* aFile) {
174   return NS_ERROR_NOT_IMPLEMENTED;
175 }
176 
AppendRelativePath(const nsAString & aNode)177 nsresult FileDescriptorFile::AppendRelativePath(const nsAString& aNode) {
178   return NS_ERROR_NOT_IMPLEMENTED;
179 }
180 
181 NS_IMETHODIMP
AppendRelativeNativePath(const nsACString & aFragment)182 FileDescriptorFile::AppendRelativeNativePath(const nsACString& aFragment) {
183   return NS_ERROR_NOT_IMPLEMENTED;
184 }
185 
186 NS_IMETHODIMP
SetPersistentDescriptor(const nsACString & aPersistentDescriptor)187 FileDescriptorFile::SetPersistentDescriptor(
188     const nsACString& aPersistentDescriptor) {
189   return NS_ERROR_NOT_IMPLEMENTED;
190 }
191 
192 NS_IMETHODIMP
GetRelativeDescriptor(nsIFile * aFromFile,nsACString & aRetVal)193 FileDescriptorFile::GetRelativeDescriptor(nsIFile* aFromFile,
194                                           nsACString& aRetVal) {
195   return NS_ERROR_NOT_IMPLEMENTED;
196 }
197 
198 NS_IMETHODIMP
SetRelativeDescriptor(nsIFile * aFromFile,const nsACString & aRelativeDesc)199 FileDescriptorFile::SetRelativeDescriptor(nsIFile* aFromFile,
200                                           const nsACString& aRelativeDesc) {
201   return NS_ERROR_NOT_IMPLEMENTED;
202 }
203 
204 NS_IMETHODIMP
GetRelativePath(nsIFile * aFromFile,nsACString & aRetVal)205 FileDescriptorFile::GetRelativePath(nsIFile* aFromFile, nsACString& aRetVal) {
206   return NS_ERROR_NOT_IMPLEMENTED;
207 }
208 
209 NS_IMETHODIMP
SetRelativePath(nsIFile * aFromFile,const nsACString & aRelativePath)210 FileDescriptorFile::SetRelativePath(nsIFile* aFromFile,
211                                     const nsACString& aRelativePath) {
212   return NS_ERROR_NOT_IMPLEMENTED;
213 }
214 
CopyTo(nsIFile * aNewParentDir,const nsAString & aNewName)215 nsresult FileDescriptorFile::CopyTo(nsIFile* aNewParentDir,
216                                     const nsAString& aNewName) {
217   return NS_ERROR_NOT_IMPLEMENTED;
218 }
219 
220 NS_IMETHODIMP
CopyToNative(nsIFile * aNewParent,const nsACString & aNewName)221 FileDescriptorFile::CopyToNative(nsIFile* aNewParent,
222                                  const nsACString& aNewName) {
223   return NS_ERROR_NOT_IMPLEMENTED;
224 }
225 
CopyToFollowingLinks(nsIFile * aNewParentDir,const nsAString & aNewName)226 nsresult FileDescriptorFile::CopyToFollowingLinks(nsIFile* aNewParentDir,
227                                                   const nsAString& aNewName) {
228   return NS_ERROR_NOT_IMPLEMENTED;
229 }
230 
231 NS_IMETHODIMP
CopyToFollowingLinksNative(nsIFile * aNewParent,const nsACString & aNewName)232 FileDescriptorFile::CopyToFollowingLinksNative(nsIFile* aNewParent,
233                                                const nsACString& aNewName) {
234   return NS_ERROR_NOT_IMPLEMENTED;
235 }
236 
MoveTo(nsIFile * aNewParentDir,const nsAString & aNewName)237 nsresult FileDescriptorFile::MoveTo(nsIFile* aNewParentDir,
238                                     const nsAString& aNewName) {
239   return NS_ERROR_NOT_IMPLEMENTED;
240 }
241 
242 NS_IMETHODIMP
MoveToNative(nsIFile * aNewParent,const nsACString & aNewName)243 FileDescriptorFile::MoveToNative(nsIFile* aNewParent,
244                                  const nsACString& aNewName) {
245   return NS_ERROR_NOT_IMPLEMENTED;
246 }
247 
248 NS_IMETHODIMP
MoveToFollowingLinks(nsIFile * aNewParent,const nsAString & aNewName)249 FileDescriptorFile::MoveToFollowingLinks(nsIFile* aNewParent,
250                                          const nsAString& aNewName) {
251   return NS_ERROR_NOT_IMPLEMENTED;
252 }
253 
254 NS_IMETHODIMP
MoveToFollowingLinksNative(nsIFile * aNewParent,const nsACString & aNewName)255 FileDescriptorFile::MoveToFollowingLinksNative(nsIFile* aNewParent,
256                                                const nsACString& aNewName) {
257   return NS_ERROR_NOT_IMPLEMENTED;
258 }
259 
260 NS_IMETHODIMP
RenameTo(nsIFile * aNewParentDir,const nsAString & aNewName)261 FileDescriptorFile::RenameTo(nsIFile* aNewParentDir,
262                              const nsAString& aNewName) {
263   return NS_ERROR_NOT_IMPLEMENTED;
264 }
265 
266 NS_IMETHODIMP
RenameToNative(nsIFile * aNewParentDir,const nsACString & aNewName)267 FileDescriptorFile::RenameToNative(nsIFile* aNewParentDir,
268                                    const nsACString& aNewName) {
269   return NS_ERROR_NOT_IMPLEMENTED;
270 }
271 
272 NS_IMETHODIMP
Remove(bool aRecursive)273 FileDescriptorFile::Remove(bool aRecursive) { return NS_ERROR_NOT_IMPLEMENTED; }
274 
275 NS_IMETHODIMP
GetPermissions(uint32_t * aPermissions)276 FileDescriptorFile::GetPermissions(uint32_t* aPermissions) {
277   return NS_ERROR_NOT_IMPLEMENTED;
278 }
279 
280 NS_IMETHODIMP
SetPermissions(uint32_t aPermissions)281 FileDescriptorFile::SetPermissions(uint32_t aPermissions) {
282   return NS_ERROR_NOT_IMPLEMENTED;
283 }
284 
285 NS_IMETHODIMP
GetPermissionsOfLink(uint32_t * aPermissionsOfLink)286 FileDescriptorFile::GetPermissionsOfLink(uint32_t* aPermissionsOfLink) {
287   return NS_ERROR_NOT_IMPLEMENTED;
288 }
289 
290 NS_IMETHODIMP
SetPermissionsOfLink(uint32_t aPermissions)291 FileDescriptorFile::SetPermissionsOfLink(uint32_t aPermissions) {
292   return NS_ERROR_NOT_IMPLEMENTED;
293 }
294 
295 NS_IMETHODIMP
GetLastModifiedTime(PRTime * aLastModTime)296 FileDescriptorFile::GetLastModifiedTime(PRTime* aLastModTime) {
297   return NS_ERROR_NOT_IMPLEMENTED;
298 }
299 
300 NS_IMETHODIMP
SetLastModifiedTime(PRTime aLastModTime)301 FileDescriptorFile::SetLastModifiedTime(PRTime aLastModTime) {
302   return NS_ERROR_NOT_IMPLEMENTED;
303 }
304 
305 NS_IMETHODIMP
GetLastModifiedTimeOfLink(PRTime * aLastModTimeOfLink)306 FileDescriptorFile::GetLastModifiedTimeOfLink(PRTime* aLastModTimeOfLink) {
307   return NS_ERROR_NOT_IMPLEMENTED;
308 }
309 
310 NS_IMETHODIMP
SetLastModifiedTimeOfLink(PRTime aLastModTimeOfLink)311 FileDescriptorFile::SetLastModifiedTimeOfLink(PRTime aLastModTimeOfLink) {
312   return NS_ERROR_NOT_IMPLEMENTED;
313 }
314 
315 NS_IMETHODIMP
GetCreationTime(PRTime * aCreationTime)316 FileDescriptorFile::GetCreationTime(PRTime* aCreationTime) {
317   return NS_ERROR_NOT_IMPLEMENTED;
318 }
319 
320 NS_IMETHODIMP
GetCreationTimeOfLink(PRTime * aCreationTime)321 FileDescriptorFile::GetCreationTimeOfLink(PRTime* aCreationTime) {
322   return NS_ERROR_NOT_IMPLEMENTED;
323 }
324 
325 NS_IMETHODIMP
GetFileSize(int64_t * aFileSize)326 FileDescriptorFile::GetFileSize(int64_t* aFileSize) {
327   return NS_ERROR_NOT_IMPLEMENTED;
328 }
329 
330 NS_IMETHODIMP
SetFileSize(int64_t aFileSize)331 FileDescriptorFile::SetFileSize(int64_t aFileSize) {
332   return NS_ERROR_NOT_IMPLEMENTED;
333 }
334 
335 NS_IMETHODIMP
GetFileSizeOfLink(int64_t * aFileSize)336 FileDescriptorFile::GetFileSizeOfLink(int64_t* aFileSize) {
337   return NS_ERROR_NOT_IMPLEMENTED;
338 }
339 
340 NS_IMETHODIMP
Exists(bool * aRetVal)341 FileDescriptorFile::Exists(bool* aRetVal) { return NS_ERROR_NOT_IMPLEMENTED; }
342 
343 NS_IMETHODIMP
IsWritable(bool * aRetVal)344 FileDescriptorFile::IsWritable(bool* aRetVal) {
345   return NS_ERROR_NOT_IMPLEMENTED;
346 }
347 
348 NS_IMETHODIMP
IsReadable(bool * aRetVal)349 FileDescriptorFile::IsReadable(bool* aRetVal) {
350   return NS_ERROR_NOT_IMPLEMENTED;
351 }
352 
353 NS_IMETHODIMP
IsExecutable(bool * aRetVal)354 FileDescriptorFile::IsExecutable(bool* aRetVal) {
355   return NS_ERROR_NOT_IMPLEMENTED;
356 }
357 
358 NS_IMETHODIMP
IsHidden(bool * aRetVal)359 FileDescriptorFile::IsHidden(bool* aRetVal) { return NS_ERROR_NOT_IMPLEMENTED; }
360 
361 NS_IMETHODIMP
IsDirectory(bool * aRetVal)362 FileDescriptorFile::IsDirectory(bool* aRetVal) {
363   return NS_ERROR_NOT_IMPLEMENTED;
364 }
365 
366 NS_IMETHODIMP
IsFile(bool * aRetVal)367 FileDescriptorFile::IsFile(bool* aRetVal) { return NS_ERROR_NOT_IMPLEMENTED; }
368 
369 NS_IMETHODIMP
IsSymlink(bool * aRetVal)370 FileDescriptorFile::IsSymlink(bool* aRetVal) {
371   return NS_ERROR_NOT_IMPLEMENTED;
372 }
373 
374 NS_IMETHODIMP
IsSpecial(bool * aRetVal)375 FileDescriptorFile::IsSpecial(bool* aRetVal) {
376   return NS_ERROR_NOT_IMPLEMENTED;
377 }
378 
379 NS_IMETHODIMP
CreateUnique(uint32_t aType,uint32_t aAttributes)380 FileDescriptorFile::CreateUnique(uint32_t aType, uint32_t aAttributes) {
381   return NS_ERROR_NOT_IMPLEMENTED;
382 }
383 
384 NS_IMETHODIMP
GetDirectoryEntriesImpl(nsIDirectoryEnumerator ** aEntries)385 FileDescriptorFile::GetDirectoryEntriesImpl(nsIDirectoryEnumerator** aEntries) {
386   return NS_ERROR_NOT_IMPLEMENTED;
387 }
388 
389 NS_IMETHODIMP
OpenANSIFileDesc(const char * aMode,FILE ** aRetVal)390 FileDescriptorFile::OpenANSIFileDesc(const char* aMode, FILE** aRetVal) {
391   return NS_ERROR_NOT_IMPLEMENTED;
392 }
393 
394 NS_IMETHODIMP
Load(PRLibrary ** aRetVal)395 FileDescriptorFile::Load(PRLibrary** aRetVal) {
396   return NS_ERROR_NOT_IMPLEMENTED;
397 }
398 
399 NS_IMETHODIMP
GetDiskSpaceAvailable(int64_t * aDiskSpaceAvailable)400 FileDescriptorFile::GetDiskSpaceAvailable(int64_t* aDiskSpaceAvailable) {
401   return NS_ERROR_NOT_IMPLEMENTED;
402 }
403 
404 NS_IMETHODIMP
GetDiskCapacity(int64_t * aDiskCapacity)405 FileDescriptorFile::GetDiskCapacity(int64_t* aDiskCapacity) {
406   return NS_ERROR_NOT_IMPLEMENTED;
407 }
408 
409 NS_IMETHODIMP
Reveal()410 FileDescriptorFile::Reveal() { return NS_ERROR_NOT_IMPLEMENTED; }
411 
412 NS_IMETHODIMP
Launch()413 FileDescriptorFile::Launch() { return NS_ERROR_NOT_IMPLEMENTED; }
414 
415 }  // namespace net
416 }  // namespace mozilla
417