cprover
Toggle main menu visibility
Loading...
Searching...
No Matches
tempfile.cpp
Go to the documentation of this file.
1
/*******************************************************************\
2
3
Module:
4
5
Author: Daniel Kroening
6
7
\*******************************************************************/
8
9
#include "
tempfile.h
"
10
11
// clang-format off
12
// clang-format must not re-order includes here to avoid pragma_push/pragma_pop
13
#ifdef _WIN32
14
#include <util/pragma_push.def>
15
#ifdef _MSC_VER
16
#pragma warning(disable:4668)
17
// using #if/#elif on undefined macro
18
#pragma warning(disable : 5039)
19
// pointer or reference to potentially throwing function passed to extern C
20
#endif
21
#include <fcntl.h>
22
#include <process.h>
23
#include <sys/stat.h>
24
#include <windows.h>
25
#include <io.h>
26
#include <tchar.h>
27
#define getpid _getpid
28
#define open _open
29
#define close _close
30
#include <util/pragma_pop.def>
31
#endif
32
// clang-format on
33
34
#include <cstdlib>
35
#include <cstring>
36
#include <filesystem>
37
38
#include "
exception_utils.h
"
39
40
#if defined(__linux__) || \
41
defined(__FreeBSD_kernel__) || \
42
defined(__GNU__) || \
43
defined(__unix__) || \
44
defined(__CYGWIN__) || \
45
defined(__MACH__)
46
#include <unistd.h>
47
#endif
48
51
#ifdef _WIN32
52
#define mkstemps my_mkstemps
53
int
my_mkstemps(
char
*template_str,
int
suffix_len)
54
{
55
// The template should be of the form tmpXXXXXXsuffix
56
57
std::size_t template_length=strlen(template_str);
58
59
if
(suffix_len<0)
60
return
-1;
61
62
if
(
static_cast<
std::size_t
>
(suffix_len+6)>template_length)
63
return
-1;
// suffix too long
64
65
char
*XXXXXX_pos=
66
template_str+template_length-6-suffix_len;
67
68
if
(strncmp(XXXXXX_pos,
"XXXXXX"
, 6)!=0)
69
return
-1;
// XXXXXX missing
70
71
static
const
char
letters_and_numbers[]=
72
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
;
73
74
static
long
long
unsigned
int
random_state;
75
random_state+=getpid()+123;
76
77
for
(
unsigned
attempt = 0; attempt < 1000; ++attempt)
78
{
79
unsigned
long
long
number=random_state;
80
81
for
(
unsigned
i=0; i<6; i++)
82
{
83
XXXXXX_pos[i]=letters_and_numbers[number%62];
84
number/=62;
85
}
86
87
int
fd=open(template_str, O_RDWR|O_CREAT|O_EXCL, 0600);
88
if
(fd>=0)
89
return
fd;
// ok
90
91
random_state+=4321+getpid();
// avoid repeating
92
}
93
94
template_str[0]=0;
95
return
-1;
// error
96
}
97
#endif
98
99
std::string
get_temporary_file
(
100
const
std::string &prefix,
101
const
std::string &suffix)
102
{
103
#ifdef _WIN32
104
char
lpTempPathBuffer[MAX_PATH];
105
DWORD dwRetVal;
106
107
dwRetVal=
108
GetTempPathA(
109
MAX_PATH,
// length of the buffer
110
lpTempPathBuffer);
// buffer for path
111
112
if
(dwRetVal>MAX_PATH || (dwRetVal==0))
113
throw
system_exceptiont
(
"Failed to get temporary directory"
);
114
115
// the path returned by GetTempPath ends with a backslash
116
std::string t_template=
117
std::string(lpTempPathBuffer)+prefix+
118
std::to_string(getpid())+
".XXXXXX"
+suffix;
119
#else
120
std::string dir=
"/tmp/"
;
121
const
char
*TMPDIR_env=getenv(
"TMPDIR"
);
122
if
(TMPDIR_env!=
nullptr
)
123
dir=TMPDIR_env;
124
if
(*dir.rbegin()!=
'/'
)
125
dir+=
'/'
;
126
127
std::string t_template=
128
dir+prefix+std::to_string(getpid())+
".XXXXXX"
+suffix;
129
#endif
130
131
char
*t_ptr=strdup(t_template.c_str());
132
133
int
fd=mkstemps(t_ptr, suffix.size());
134
135
if
(fd<0)
136
throw
system_exceptiont
(
"Failed to open temporary file"
);
137
138
close(fd);
139
140
std::string result=std::string(t_ptr);
141
free(t_ptr);
142
return
result;
143
}
144
145
temporary_filet::~temporary_filet
()
146
{
147
if
(!
name
.empty())
148
std::filesystem::remove(
name
);
149
}
system_exceptiont
Thrown when some external system fails unexpectedly.
Definition
exception_utils.h:72
temporary_filet::name
std::string name
Definition
tempfile.h:51
temporary_filet::~temporary_filet
~temporary_filet()
Definition
tempfile.cpp:145
exception_utils.h
get_temporary_file
std::string get_temporary_file(const std::string &prefix, const std::string &suffix)
Substitute for mkstemps (OpenBSD standard) for Windows, where it is unavailable.
Definition
tempfile.cpp:99
tempfile.h
util
tempfile.cpp
Generated by
1.17.0