}
#ifdef WIN32
-/* in windows, renaming to an existing file is verboten */
- unlink(outfilename);
-#endif
+/* In Windows, renaming to an existing file is not allowed. Even, if the file
+ * is deleted before, using _unlink() here. Furthermore the FILE_SHARE_DELETE
+ * flag is required, which is used in CreateFileA in rrd_open.c
+ * Check first, if the file exists. Use ReplaceFileA if the file exists.
+ * Otherwise rename as usual */
+ if (_access_s(outfilename, 0) == 0) {
+ if (ReplaceFileA(outfilename, tmpfilename, NULL, 0, 0, 0) ==
+ 0) {
+ rrd_set_error("Cannot replace %s!", outfilename);
+ goto done;
+ }
+ } else {
+ if (rename(tmpfilename, outfilename) != 0) {
+ rrd_set_error
+ ("Cannot rename temporary file to final file!");
+ goto done;
+ }
+ }
+#else
if (rename(tmpfilename, outfilename) != 0) {
rrd_set_error("Cannot rename temporary file to final file!");
goto done;
}
+#endif
// after the rename: forget the file again, just to be sure...
if (rrdc_is_any_connected()) {
flags |= O_BINARY;
#endif
+#if defined(_WIN32)
+ /* In Windows we need FILE_SHARE_DELETE, so that the file can be
+ * renamed/replaced later on in rrd_create.c
+ * This is only possible using CreateFileA() first and not using open() alone */
+ HANDLE handle;
+
+ handle =
+ CreateFileA(file_name, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if ((rrd_simple_file->fd = _open_osfhandle((intptr_t) handle, flags)) < 0) {
+ rrd_set_error("opening '%s': %s", file_name, rrd_strerror(errno));
+ goto out_free;
+ }
+#else
if ((rrd_simple_file->fd = open(file_name, flags, 0666)) < 0) {
rrd_set_error("opening '%s': %s", file_name, rrd_strerror(errno));
goto out_free;
}
+#endif
#ifdef HAVE_MMAP
#ifdef HAVE_BROKEN_MS_ASYNC