1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_POSIX_GLOBAL_DESCRIPTORS_H_ 6 #define BASE_POSIX_GLOBAL_DESCRIPTORS_H_ 7 8 #include "build/build_config.h" 9 10 #include <vector> 11 #include <utility> 12 13 #include <stdint.h> 14 15 #include "base/files/memory_mapped_file.h" 16 #include "base/files/scoped_file.h" 17 #include "base/memory/singleton.h" 18 19 namespace base { 20 21 // It's common practice to install file descriptors into well known slot 22 // numbers before execing a child; stdin, stdout and stderr are ubiqutous 23 // examples. 24 // 25 // However, when using a zygote model, this becomes troublesome. Since the 26 // descriptors which need to be in these slots generally aren't known, any code 27 // could open a resource and take one of the reserved descriptors. Simply 28 // overwriting the slot isn't a viable solution. 29 // 30 // We could try to fill the reserved slots as soon as possible, but this is a 31 // fragile solution since global constructors etc are able to open files. 32 // 33 // Instead, we retreat from the idea of installing descriptors in specific 34 // slots and add a layer of indirection in the form of this singleton object. 35 // It maps from an abstract key to a descriptor. If independent modules each 36 // need to define keys, then values should be chosen randomly so as not to 37 // collide. 38 // 39 // Note that this class is deprecated and passing file descriptor should ideally 40 // be done through the command line and using FileDescriptorStore. 41 // See https://crbugs.com/detail?id=692619 42 class BASE_EXPORT GlobalDescriptors { 43 public: 44 typedef uint32_t Key; 45 struct Descriptor { 46 Descriptor(Key key, int fd); 47 Descriptor(Key key, int fd, base::MemoryMappedFile::Region region); 48 49 // Globally unique key. 50 Key key; 51 // Actual FD. 52 int fd; 53 // Optional region, defaults to kWholeFile. 54 base::MemoryMappedFile::Region region; 55 }; 56 typedef std::vector<Descriptor> Mapping; 57 58 // Often we want a canonical descriptor for a given Key. In this case, we add 59 // the following constant to the key value: 60 static const int kBaseDescriptor = 3; // 0, 1, 2 are already taken. 61 62 // Return the singleton instance of GlobalDescriptors. 63 static GlobalDescriptors* GetInstance(); 64 65 // Get a descriptor given a key. It is a fatal error if the key is not known. 66 int Get(Key key) const; 67 68 // Get a descriptor given a key. Returns -1 on error. 69 int MaybeGet(Key key) const; 70 71 // Returns a descriptor given a key and removes it from this class mappings. 72 // Also populates |region|. 73 // It is a fatal error if the key is not known. 74 base::ScopedFD TakeFD(Key key, base::MemoryMappedFile::Region* region); 75 76 // Get a region given a key. It is a fatal error if the key is not known. 77 base::MemoryMappedFile::Region GetRegion(Key key) const; 78 79 // Set the descriptor for the given |key|. This sets the region associated 80 // with |key| to kWholeFile. 81 void Set(Key key, int fd); 82 83 // Set the descriptor and |region| for the given |key|. 84 void Set(Key key, int fd, base::MemoryMappedFile::Region region); 85 86 void Reset(const Mapping& mapping); 87 88 private: 89 friend struct DefaultSingletonTraits<GlobalDescriptors>; 90 GlobalDescriptors(); 91 ~GlobalDescriptors(); 92 93 Mapping descriptors_; 94 }; 95 96 } // namespace base 97 98 #endif // BASE_POSIX_GLOBAL_DESCRIPTORS_H_ 99