1 // Copyright 2018 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 PARTITION_ALLOC_PARTITION_ALLOC_BASE_SCOPED_CLEAR_LAST_ERROR_H_
6 #define PARTITION_ALLOC_PARTITION_ALLOC_BASE_SCOPED_CLEAR_LAST_ERROR_H_
7 
8 #include <cerrno>
9 
10 #include "build/build_config.h"
11 #include "partition_alloc/partition_alloc_base/component_export.h"
12 
13 namespace partition_alloc::internal::base {
14 
15 // ScopedClearLastError stores and resets the value of thread local error codes
16 // (errno, GetLastError()), and restores them in the destructor. This is useful
17 // to avoid side effects on these values in instrumentation functions that
18 // interact with the OS.
19 
20 // Common implementation of ScopedClearLastError for all platforms. Use
21 // ScopedClearLastError instead.
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE)22 class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ScopedClearLastErrorBase {
23  public:
24   ScopedClearLastErrorBase() : last_errno_(errno) { errno = 0; }
25   ScopedClearLastErrorBase(const ScopedClearLastErrorBase&) = delete;
26   ScopedClearLastErrorBase& operator=(const ScopedClearLastErrorBase&) = delete;
27   ~ScopedClearLastErrorBase() { errno = last_errno_; }
28 
29  private:
30   const int last_errno_;
31 };
32 
33 #if BUILDFLAG(IS_WIN)
34 
35 // Windows specific implementation of ScopedClearLastError.
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE)36 class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) ScopedClearLastError
37     : public ScopedClearLastErrorBase {
38  public:
39   ScopedClearLastError();
40   ScopedClearLastError(const ScopedClearLastError&) = delete;
41   ScopedClearLastError& operator=(const ScopedClearLastError&) = delete;
42   ~ScopedClearLastError();
43 
44  private:
45   const unsigned long last_system_error_;
46 };
47 
48 #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
49 
50 using ScopedClearLastError = ScopedClearLastErrorBase;
51 
52 #endif  // BUILDFLAG(IS_WIN)
53 
54 }  // namespace partition_alloc::internal::base
55 
56 #endif  // PARTITION_ALLOC_PARTITION_ALLOC_BASE_SCOPED_CLEAR_LAST_ERROR_H_
57