cprover
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
37
#include "
exception_utils.h
"
38
#include "
file_util.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
file_remove
(
name
);
149
}
ait
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition
ai.h:564
system_exceptiont
Thrown when some external system fails unexpectedly.
Definition
exception_utils.h:61
temporary_filet::name
std::string name
Definition
tempfile.h:51
temporary_filet::~temporary_filet
~temporary_filet()
Definition
tempfile.cpp:145
exception_utils.h
file_remove
bool file_remove(const std::string &path)
C++17 will allow us to use std::filesystem::remove.
Definition
file_util.cpp:231
file_util.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.9.8