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
26namespace Poco {
27
28
29class TempFileCollector
30{
31public:
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
67private:
68 std::set<std::string> _files;
69 FastMutex _mutex;
70};
71
72
73TemporaryFile::TemporaryFile():
74 File(tempName()),
75 _keep(false)
76{
77}
78
79
80TemporaryFile::TemporaryFile(const std::string& tempDir):
81 File(tempName(tempDir)),
82 _keep(false)
83{
84}
85
86
87TemporaryFile::~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
110void TemporaryFile::keep()
111{
112 _keep = true;
113}
114
115
116void TemporaryFile::keepUntilExit()
117{
118 _keep = true;
119 registerForDeletion(path());
120}
121
122
123namespace
124{
125 static TempFileCollector fc;
126}
127
128
129void TemporaryFile::registerForDeletion(const std::string& path)
130{
131 fc.registerFile(path);
132}
133
134
135namespace
136{
137 static FastMutex mutex;
138}
139
140
141std::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