src/util/smart_ptr.h \
src/util/static_assert.h \
src/util/string_utils.h \
+ src/util/temp_file.h \
src/util/u32lim.h \
src/util/uniq_vector.h \
src/util/wrap_iter.h
src/parse/validate.cc \
src/util/get_dir.cc \
src/util/s_to_n32_unsafe.cc \
+ src/util/temp_file.cc \
src/util/range.cc
re2c_SOURCES = \
src/main.cc \
#include "src/options/opt.h"
#include "src/encoding/enc.h"
#include "src/util/string_utils.h"
+#include "src/util/temp_file.h"
#include "src/util/uniq_vector.h"
namespace re2c
const std::set<std::string> &global_mtags)
{
FILE *file = NULL;
- std::string filename = fname;
+ bool temp = false;
+ std::string filename = fname, tempname = fname;
+
if (filename.empty()) {
filename = "<stdout>";
file = stdout;
}
- else {
- file = fopen(filename.c_str(), "w");
- if (!file) {
- error("cannot open output file: %s", filename.c_str());
- return false;
- }
+ else if ((file = temp_file(tempname))) {
+ temp = true;
+ }
+ else if (!(file = fopen(filename.c_str(), "w"))) {
+ error("cannot open output file %s", filename.c_str());
+ return false;
}
fix_first_block_opts(blocks);
}
fclose(file);
+ if (temp && rename(tempname.c_str(), fname.c_str()) != 0) {
+ error("cannot rename temporary file %s to output file %s"
+ , tempname.c_str(), fname.c_str());
+ return false;
+ }
+
return true;
}
--- /dev/null
+#include <time.h>
+#include "src/msg/msg.h"
+#include "src/util/temp_file.h"
+
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+
+// MSVC
+#include <io.h>
+#define OPEN _open
+#define FDOPEN _fdopen
+#define FLAGS _O_CREAT | _O_EXCL | _O_RDWR
+#define MODE _S_IREAD | _S_IWRITE
+
+#else
+
+// POSIX
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#define OPEN open
+#define FDOPEN fdopen
+#define FLAGS O_CREAT | O_EXCL | O_RDWR
+#define MODE S_IRUSR | S_IWUSR
+
+#endif
+
+namespace re2c {
+
+FILE *temp_file(std::string &fname)
+{
+ // append "random enough" suffix to filename
+ const time_t t = time(NULL);
+ char buffer[20];
+ strftime(buffer, sizeof(buffer), ".tmp.%Y%m%d%H%M%S", localtime(&t));
+ fname += buffer;
+
+ // open file for writing, unless it exists already
+ FILE *f = NULL;
+ int fd = OPEN(fname.c_str(), FLAGS, MODE);
+ if (fd != -1) {
+ f = FDOPEN(fd, "w");
+ }
+
+ // we don't try too hard
+ if (!f) {
+ error("cannot open temporary file %s", fname.c_str());
+ }
+ return f;
+}
+
+} // namespace re2c
+
+#undef OPEN
+#undef FDOPEN
+#undef FLAGS
--- /dev/null
+#ifndef _RE2C_UTIL_TEMP_FILE_
+#define _RE2C_UTIL_TEMP_FILE_
+
+#include <stdio.h>
+#include <string>
+
+
+namespace re2c {
+
+FILE *temp_file(std::string &fname);
+
+} // namespace re2c
+
+#endif // _RE2C_UTIL_TEMP_FILE_