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