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