xref: /aosp_15_r20/external/cronet/base/files/scoped_file.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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