1 | // |
---|---|
2 | // TemporaryFile.cpp |
3 | // |
4 | // Library: Foundation |
5 | // Package: Filesystem |
6 | // Module: TemporaryFile |
7 | // |
8 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/TemporaryFile.h" |
16 | #include "Poco/Path.h" |
17 | #include "Poco/Exception.h" |
18 | #if !defined(POCO_VXWORKS) |
19 | #include "Poco/Process.h" |
20 | #endif |
21 | #include "Poco/Mutex.h" |
22 | #include <set> |
23 | #include <sstream> |
24 | |
25 | |
26 | namespace Poco { |
27 | |
28 | |
29 | class TempFileCollector |
30 | { |
31 | public: |
32 | TempFileCollector() |
33 | { |
34 | } |
35 | |
36 | ~TempFileCollector() |
37 | { |
38 | try |
39 | { |
40 | for (std::set<std::string>::iterator it = _files.begin(); it != _files.end(); ++it) |
41 | { |
42 | try |
43 | { |
44 | File f(*it); |
45 | if (f.exists()) |
46 | f.remove(true); |
47 | } |
48 | catch (Exception&) |
49 | { |
50 | } |
51 | } |
52 | } |
53 | catch (...) |
54 | { |
55 | poco_unexpected(); |
56 | } |
57 | } |
58 | |
59 | void registerFile(const std::string& path) |
60 | { |
61 | FastMutex::ScopedLock lock(_mutex); |
62 | |
63 | Path p(path); |
64 | _files.insert(p.absolute().toString()); |
65 | } |
66 | |
67 | private: |
68 | std::set<std::string> _files; |
69 | FastMutex _mutex; |
70 | }; |
71 | |
72 | |
73 | TemporaryFile::TemporaryFile(): |
74 | File(tempName()), |
75 | _keep(false) |
76 | { |
77 | } |
78 | |
79 | |
80 | TemporaryFile::TemporaryFile(const std::string& tempDir): |
81 | File(tempName(tempDir)), |
82 | _keep(false) |
83 | { |
84 | } |
85 | |
86 | |
87 | TemporaryFile::~TemporaryFile() |
88 | { |
89 | try |
90 | { |
91 | if (!_keep) |
92 | { |
93 | try |
94 | { |
95 | if (exists()) |
96 | remove(true); |
97 | } |
98 | catch (Exception&) |
99 | { |
100 | } |
101 | } |
102 | } |
103 | catch (...) |
104 | { |
105 | poco_unexpected(); |
106 | } |
107 | } |
108 | |
109 | |
110 | void TemporaryFile::keep() |
111 | { |
112 | _keep = true; |
113 | } |
114 | |
115 | |
116 | void TemporaryFile::keepUntilExit() |
117 | { |
118 | _keep = true; |
119 | registerForDeletion(path()); |
120 | } |
121 | |
122 | |
123 | namespace |
124 | { |
125 | static TempFileCollector fc; |
126 | } |
127 | |
128 | |
129 | void TemporaryFile::registerForDeletion(const std::string& path) |
130 | { |
131 | fc.registerFile(path); |
132 | } |
133 | |
134 | |
135 | namespace |
136 | { |
137 | static FastMutex mutex; |
138 | } |
139 | |
140 | |
141 | std::string TemporaryFile::tempName(const std::string& tempDir) |
142 | { |
143 | std::ostringstream name; |
144 | static unsigned long count = 0; |
145 | mutex.lock(); |
146 | unsigned long n = count++; |
147 | mutex.unlock(); |
148 | name << (tempDir.empty() ? Path::temp() : tempDir); |
149 | if (name.str().at(name.str().size() - 1) != Path::separator()) |
150 | { |
151 | name << Path::separator(); |
152 | } |
153 | #if defined(POCO_VXWORKS) |
154 | name << "tmp"; |
155 | #else |
156 | name << "tmp"<< Process::id(); |
157 | #endif |
158 | for (int i = 0; i < 6; ++i) |
159 | { |
160 | name << char('a' + (n % 26)); |
161 | n /= 26; |
162 | } |
163 | return name.str(); |
164 | } |
165 | |
166 | |
167 | } // namespace Poco |
168 |