1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_FILES_SCOPED_FILE_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_FILES_SCOPED_FILE_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stdio.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <memory> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/scoped_generic.h" 14*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h" 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker namespace base { 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker namespace internal { 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID) 21*6777b538SAndroid Build Coastguard Worker // Use fdsan on android. 22*6777b538SAndroid Build Coastguard Worker struct BASE_EXPORT ScopedFDCloseTraits : public ScopedGenericOwnershipTracking { InvalidValueScopedFDCloseTraits23*6777b538SAndroid Build Coastguard Worker static int InvalidValue() { return -1; } 24*6777b538SAndroid Build Coastguard Worker static void Free(int); 25*6777b538SAndroid Build Coastguard Worker static void Acquire(const ScopedGeneric<int, ScopedFDCloseTraits>&, int); 26*6777b538SAndroid Build Coastguard Worker static void Release(const ScopedGeneric<int, ScopedFDCloseTraits>&, int); 27*6777b538SAndroid Build Coastguard Worker }; 28*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) 29*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) 30*6777b538SAndroid Build Coastguard Worker // On ChromeOS and Linux we guard FD lifetime with a global table and hook into 31*6777b538SAndroid Build Coastguard Worker // libc close() to perform checks. 32*6777b538SAndroid Build Coastguard Worker struct BASE_EXPORT ScopedFDCloseTraits : public ScopedGenericOwnershipTracking { 33*6777b538SAndroid Build Coastguard Worker #else 34*6777b538SAndroid Build Coastguard Worker struct BASE_EXPORT ScopedFDCloseTraits { 35*6777b538SAndroid Build Coastguard Worker #endif 36*6777b538SAndroid Build Coastguard Worker static int InvalidValue() { 37*6777b538SAndroid Build Coastguard Worker return -1; 38*6777b538SAndroid Build Coastguard Worker } 39*6777b538SAndroid Build Coastguard Worker static void Free(int fd); 40*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) 41*6777b538SAndroid Build Coastguard Worker static void Acquire(const ScopedGeneric<int, ScopedFDCloseTraits>&, int); 42*6777b538SAndroid Build Coastguard Worker static void Release(const ScopedGeneric<int, ScopedFDCloseTraits>&, int); 43*6777b538SAndroid Build Coastguard Worker #endif 44*6777b538SAndroid Build Coastguard Worker }; 45*6777b538SAndroid Build Coastguard Worker #endif 46*6777b538SAndroid Build Coastguard Worker 47*6777b538SAndroid Build Coastguard Worker // Functor for |ScopedFILE| (below). 48*6777b538SAndroid Build Coastguard Worker struct ScopedFILECloser { operatorScopedFILECloser49*6777b538SAndroid Build Coastguard Worker inline void operator()(FILE* x) const { 50*6777b538SAndroid Build Coastguard Worker if (x) 51*6777b538SAndroid Build Coastguard Worker fclose(x); 52*6777b538SAndroid Build Coastguard Worker } 53*6777b538SAndroid Build Coastguard Worker }; 54*6777b538SAndroid Build Coastguard Worker 55*6777b538SAndroid Build Coastguard Worker } // namespace internal 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) 58*6777b538SAndroid Build Coastguard Worker namespace subtle { 59*6777b538SAndroid Build Coastguard Worker 60*6777b538SAndroid Build Coastguard Worker // Enables or disables enforcement of FD ownership as tracked by ScopedFD 61*6777b538SAndroid Build Coastguard Worker // objects. Enforcement is disabled by default since it proves unwieldy in some 62*6777b538SAndroid Build Coastguard Worker // test environments, but tracking is always done. It's best to enable this as 63*6777b538SAndroid Build Coastguard Worker // early as possible in a process's lifetime. 64*6777b538SAndroid Build Coastguard Worker void BASE_EXPORT EnableFDOwnershipEnforcement(bool enabled); 65*6777b538SAndroid Build Coastguard Worker 66*6777b538SAndroid Build Coastguard Worker // Resets ownership state of all FDs. The only permissible use of this API is 67*6777b538SAndroid Build Coastguard Worker // in a forked child process between the fork() and a subsequent exec() call. 68*6777b538SAndroid Build Coastguard Worker // 69*6777b538SAndroid Build Coastguard Worker // For one issue, it is common to mass-close most open FDs before calling 70*6777b538SAndroid Build Coastguard Worker // exec(), to avoid leaking FDs into the new executable's environment. For 71*6777b538SAndroid Build Coastguard Worker // processes which have enabled FD ownership enforcement, this reset operation 72*6777b538SAndroid Build Coastguard Worker // is necessary before performing such closures. 73*6777b538SAndroid Build Coastguard Worker // 74*6777b538SAndroid Build Coastguard Worker // Furthermore, fork()+exec() may be used in a multithreaded context, and 75*6777b538SAndroid Build Coastguard Worker // because fork() is not atomic, the FD ownership state in the child process may 76*6777b538SAndroid Build Coastguard Worker // be inconsistent with the actual set of opened file descriptors once fork() 77*6777b538SAndroid Build Coastguard Worker // returns in the child process. 78*6777b538SAndroid Build Coastguard Worker // 79*6777b538SAndroid Build Coastguard Worker // It is therefore especially important to call this ASAP after fork() in the 80*6777b538SAndroid Build Coastguard Worker // child process if any FD manipulation will be done prior to the subsequent 81*6777b538SAndroid Build Coastguard Worker // exec call. 82*6777b538SAndroid Build Coastguard Worker void BASE_EXPORT ResetFDOwnership(); 83*6777b538SAndroid Build Coastguard Worker 84*6777b538SAndroid Build Coastguard Worker } // namespace subtle 85*6777b538SAndroid Build Coastguard Worker #endif 86*6777b538SAndroid Build Coastguard Worker 87*6777b538SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------- 88*6777b538SAndroid Build Coastguard Worker 89*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) 90*6777b538SAndroid Build Coastguard Worker // A low-level Posix file descriptor closer class. Use this when writing 91*6777b538SAndroid Build Coastguard Worker // platform-specific code, especially that does non-file-like things with the 92*6777b538SAndroid Build Coastguard Worker // FD (like sockets). 93*6777b538SAndroid Build Coastguard Worker // 94*6777b538SAndroid Build Coastguard Worker // If you're writing low-level Windows code, see base/win/scoped_handle.h 95*6777b538SAndroid Build Coastguard Worker // which provides some additional functionality. 96*6777b538SAndroid Build Coastguard Worker // 97*6777b538SAndroid Build Coastguard Worker // If you're writing cross-platform code that deals with actual files, you 98*6777b538SAndroid Build Coastguard Worker // should generally use base::File instead which can be constructed with a 99*6777b538SAndroid Build Coastguard Worker // handle, and in addition to handling ownership, has convenient cross-platform 100*6777b538SAndroid Build Coastguard Worker // file manipulation functions on it. 101*6777b538SAndroid Build Coastguard Worker typedef ScopedGeneric<int, internal::ScopedFDCloseTraits> ScopedFD; 102*6777b538SAndroid Build Coastguard Worker #endif 103*6777b538SAndroid Build Coastguard Worker 104*6777b538SAndroid Build Coastguard Worker // Automatically closes |FILE*|s. 105*6777b538SAndroid Build Coastguard Worker typedef std::unique_ptr<FILE, internal::ScopedFILECloser> ScopedFILE; 106*6777b538SAndroid Build Coastguard Worker 107*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) 108*6777b538SAndroid Build Coastguard Worker // Queries the ownership status of an FD, i.e. whether it is currently owned by 109*6777b538SAndroid Build Coastguard Worker // a ScopedFD in the calling process. 110*6777b538SAndroid Build Coastguard Worker bool BASE_EXPORT IsFDOwned(int fd); 111*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) 112*6777b538SAndroid Build Coastguard Worker 113*6777b538SAndroid Build Coastguard Worker } // namespace base 114*6777b538SAndroid Build Coastguard Worker 115*6777b538SAndroid Build Coastguard Worker #endif // BASE_FILES_SCOPED_FILE_H_ 116