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