diff --git a/src/ban.cpp b/src/ban.cpp
index 75bae746f9455131705a27763d382014ca6a7a7e..f9d32b605c2b6a20766f227791cb9ccb717bb10d 100644
--- a/src/ban.cpp
+++ b/src/ban.cpp
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <set>
 #include "strfnd.h"
 #include "log.h"
+#include "filesys.h"
 
 BanManager::BanManager(const std::string &banfilepath):
 		m_banfilepath(banfilepath),
@@ -76,20 +77,20 @@ void BanManager::save()
 {
 	JMutexAutoLock lock(m_mutex);
 	infostream<<"BanManager: saving to "<<m_banfilepath<<std::endl;
-	std::ofstream os(m_banfilepath.c_str(), std::ios::binary);
-	
-	if(os.good() == false)
-	{
-		infostream<<"BanManager: failed saving to "<<m_banfilepath<<std::endl;
-		throw SerializationError("BanManager::load(): Couldn't open file");
-	}
+	std::ostringstream ss(std::ios_base::binary);
 
 	for(std::map<std::string, std::string>::iterator
 			i = m_ips.begin();
 			i != m_ips.end(); i++)
 	{
-		os<<i->first<<"|"<<i->second<<"\n";
+		ss << i->first << "|" << i->second << "\n";
 	}
+
+	if(!fs::safeWriteToFile(m_banfilepath, ss.str())) {
+		infostream<<"BanManager: failed saving to "<<m_banfilepath<<std::endl;
+		throw SerializationError("BanManager::load(): Couldn't write file");
+	}
+
 	m_modified = false;
 }
 
diff --git a/src/environment.cpp b/src/environment.cpp
index 35983aaaf30b8e216fa5cc4383d6ff40b28b4be0..eacc2a008cad11e31b1766f9e3c15e8a8513a206 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -437,13 +437,13 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
 		if(player->checkModified())
 		{
 			// Open file and serialize
-			std::ofstream os(path.c_str(), std::ios_base::binary);
-			if(os.good() == false)
+			std::ostringstream ss(std::ios_base::binary);
+			player->serialize(ss);
+			if(!fs::safeWriteToFile(path, ss.str()))
 			{
-				infostream<<"Failed to overwrite "<<path<<std::endl;
+				infostream<<"Failed to write "<<path<<std::endl;
 				continue;
 			}
-			player->serialize(os);
 			saved_players.insert(player);
 		} else {
 			saved_players.insert(player);
@@ -493,13 +493,13 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
 			/*infostream<<"Saving player "<<player->getName()<<" to "
 					<<path<<std::endl;*/
 			// Open file and serialize
-			std::ofstream os(path.c_str(), std::ios_base::binary);
-			if(os.good() == false)
+			std::ostringstream ss(std::ios_base::binary);
+			player->serialize(ss);
+			if(!fs::safeWriteToFile(path, ss.str()))
 			{
-				infostream<<"Failed to overwrite "<<path<<std::endl;
+				infostream<<"Failed to write "<<path<<std::endl;
 				continue;
 			}
-			player->serialize(os);
 			saved_players.insert(player);
 		}
 	}
@@ -581,19 +581,20 @@ void ServerEnvironment::saveMeta(const std::string &savedir)
 	std::string path = savedir + "/env_meta.txt";
 
 	// Open file and serialize
-	std::ofstream os(path.c_str(), std::ios_base::binary);
-	if(os.good() == false)
-	{
-		infostream<<"ServerEnvironment::saveMeta(): Failed to open "
-				<<path<<std::endl;
-		throw SerializationError("Couldn't save env meta");
-	}
+	std::ostringstream ss(std::ios_base::binary);
 
 	Settings args;
 	args.setU64("game_time", m_game_time);
 	args.setU64("time_of_day", getTimeOfDay());
-	args.writeLines(os);
-	os<<"EnvArgsEnd\n";
+	args.writeLines(ss);
+	ss<<"EnvArgsEnd\n";
+
+	if(!fs::safeWriteToFile(path, ss.str()))
+	{
+		infostream<<"ServerEnvironment::saveMeta(): Failed to write "
+				<<path<<std::endl;
+		throw SerializationError("Couldn't save env meta");
+	}
 }
 
 void ServerEnvironment::loadMeta(const std::string &savedir)
diff --git a/src/filesys.cpp b/src/filesys.cpp
index 356d3018deff2843816f19a87e486479240efa85..a1795c8eadf9873ae77a41b9e3a7df5e88683c42 100644
--- a/src/filesys.cpp
+++ b/src/filesys.cpp
@@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
+#include <sstream>
+#include <fstream>
 #include "log.h"
 
 namespace fs
@@ -684,5 +686,28 @@ std::string RemoveRelativePathComponents(std::string path)
 	return path.substr(0, pos);
 }
 
+bool safeWriteToFile(const std::string &path, const std::string &content)
+{
+	std::string tmp_file = path + ".~mt";
+
+	// Write to a tmp file
+	std::ofstream os(tmp_file.c_str(), std::ios::binary);
+	if (!os.good())
+		return false;
+	os << content;
+	os.flush();
+	os.close();
+	if (os.fail())
+		return false;
+
+	// Copy file
+#ifdef _WIN32
+	remove(path.c_str());
+	return (rename(tmp_file.c_str(), path.c_str()) == 0);
+#else
+	return (rename(tmp_file.c_str(), path.c_str()) == 0);
+#endif
+}
+
 } // namespace fs
 
diff --git a/src/filesys.h b/src/filesys.h
index d0bf400c78921ca44d8891964a8d2e32dfd45c5d..1b3659afee947d8f2ecd3ff78a71fe36de5bdf86 100644
--- a/src/filesys.h
+++ b/src/filesys.h
@@ -98,6 +98,8 @@ std::string RemoveLastPathComponent(std::string path,
 // this does not resolve symlinks and check for existence of directories.
 std::string RemoveRelativePathComponents(std::string path);
 
+bool safeWriteToFile(const std::string &path, const std::string &content);
+
 }//fs
 
 #endif
diff --git a/src/map.cpp b/src/map.cpp
index da20b5b0e1e9993d85ca6002b0a4b4dc3e7f3aa4..331aa48d943541e5c2856ed05480387bfe134201 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -3490,20 +3490,21 @@ void ServerMap::saveMapMeta()
 	createDirs(m_savedir);
 
 	std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt";
-	std::ofstream os(fullpath.c_str(), std::ios_base::binary);
-	if(os.good() == false)
-	{
-		infostream<<"ERROR: ServerMap::saveMapMeta(): "
-				<<"could not open"<<fullpath<<std::endl;
-		throw FileNotGoodException("Cannot open chunk metadata");
-	}
+	std::ostringstream ss(std::ios_base::binary);
 
 	Settings params;
 
 	m_emerge->setParamsToSettings(&params);
-	params.writeLines(os);
+	params.writeLines(ss);
 
-	os<<"[end_of_params]\n";
+	ss<<"[end_of_params]\n";
+
+	if(!fs::safeWriteToFile(fullpath, ss.str()))
+	{
+		infostream<<"ERROR: ServerMap::saveMapMeta(): "
+				<<"could not write "<<fullpath<<std::endl;
+		throw FileNotGoodException("Cannot save chunk metadata");
+	}
 
 	m_map_metadata_changed = false;
 }
@@ -3574,11 +3575,12 @@ void ServerMap::saveSectorMeta(ServerMapSector *sector)
 	createDirs(dir);
 
 	std::string fullpath = dir + DIR_DELIM + "meta";
-	std::ofstream o(fullpath.c_str(), std::ios_base::binary);
-	if(o.good() == false)
-		throw FileNotGoodException("Cannot open sector metafile");
+	std::ostringstream ss(std::ios_base::binary);
+
+	sector->serialize(ss, version);
 
-	sector->serialize(o, version);
+	if(!fs::safeWriteToFile(fullpath, ss.str()))
+		throw FileNotGoodException("Cannot write sector metafile");
 
 	sector->differs_from_disk = false;
 }
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index 97d672b01df1478d371371eb725320ea3c23a90a..be65694aa27a28f6473e7b55507b8ed4e5d2fb33 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapgen_v6.h"
 #include "mapgen_v7.h"
 #include "util/serialize.h"
+#include "filesys.h"
 
 FlagDesc flagdesc_mapgen[] = {
 	{"trees",          MG_TREES},
@@ -756,24 +757,26 @@ bool DecoSchematic::loadSchematicFile() {
 	2 - Fixed messy never/always place; 0 probability is now never, 0xFF is always
 */
 void DecoSchematic::saveSchematicFile(INodeDefManager *ndef) {
-	std::ofstream os(filename.c_str(), std::ios_base::binary);
+	std::ostringstream ss(std::ios_base::binary);
 
-	writeU32(os, MTSCHEM_FILE_SIGNATURE); // signature
-	writeU16(os, 2);      // version
-	writeV3S16(os, size); // schematic size
+	writeU32(ss, MTSCHEM_FILE_SIGNATURE); // signature
+	writeU16(ss, 2);      // version
+	writeV3S16(ss, size); // schematic size
 	
 	std::vector<content_t> usednodes;
 	int nodecount = size.X * size.Y * size.Z;
 	build_nnlist_and_update_ids(schematic, nodecount, &usednodes);
 	
 	u16 numids = usednodes.size();
-	writeU16(os, numids); // name count
+	writeU16(ss, numids); // name count
 	for (int i = 0; i != numids; i++)
-		os << serializeString(ndef->get(usednodes[i]).name); // node names
+		ss << serializeString(ndef->get(usednodes[i]).name); // node names
 		
 	// compressed bulk node data
-	MapNode::serializeBulk(os, SER_FMT_VER_HIGHEST_WRITE, schematic,
+	MapNode::serializeBulk(ss, SER_FMT_VER_HIGHEST_WRITE, schematic,
 				nodecount, 2, 2, true);
+
+	fs::safeWriteToFile(filename, ss.str());
 }
 
 
diff --git a/src/serverlist.cpp b/src/serverlist.cpp
index bc09f6c0ad44f5b33cf40b6156c81de38316e5b5..4db5f3ecd5239d0a35fc546228f8ee14a08fbe03 100644
--- a/src/serverlist.cpp
+++ b/src/serverlist.cpp
@@ -105,13 +105,11 @@ bool deleteEntry (ServerListSpec server)
 	}
 
 	std::string path = ServerList::getFilePath();
-	std::ofstream stream (path.c_str());
-	if (stream.is_open())
-	{
-		stream<<ServerList::serialize(serverlist);
-		return true;
-	}
-	return false;
+	std::ostringstream ss(std::ios_base::binary);
+	ss << ServerList::serialize(serverlist);
+	if (!fs::safeWriteToFile(path, ss.str()))
+		return false;
+	return true;
 }
 
 /*
@@ -128,11 +126,9 @@ bool insert (ServerListSpec server)
 	serverlist.insert(serverlist.begin(), server);
 
 	std::string path = ServerList::getFilePath();
-	std::ofstream stream (path.c_str());
-	if (stream.is_open())
-	{
-		stream<<ServerList::serialize(serverlist);
-	}
+	std::ostringstream ss(std::ios_base::binary);
+	ss << ServerList::serialize(serverlist);
+	fs::safeWriteToFile(path, ss.str());
 
 	return false;
 }
diff --git a/src/settings.h b/src/settings.h
index e7b49b6d7798497cc3d25f8bda08a596abe4acf9..a9e0faa40a59898fc793f0c327bcf54ef75f8d5b 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <list>
 #include <map>
 #include <set>
+#include "filesys.h"
 
 enum ValueType
 {
@@ -308,14 +309,7 @@ class Settings
 
 		// Write stuff back
 		{
-			std::ofstream os(filename);
-			if(os.good() == false)
-			{
-				errorstream<<"Error opening configuration file"
-						" for writing: \""
-						<<filename<<"\""<<std::endl;
-				return false;
-			}
+			std::ostringstream ss(std::ios_base::binary);
 
 			/*
 				Write updated stuff
@@ -324,7 +318,7 @@ class Settings
 					i = objects.begin();
 					i != objects.end(); ++i)
 			{
-				os<<(*i);
+				ss<<(*i);
 			}
 
 			/*
@@ -340,7 +334,14 @@ class Settings
 				std::string value = i->second;
 				infostream<<"Adding \""<<name<<"\" = \""<<value<<"\""
 						<<std::endl;
-				os<<name<<" = "<<value<<"\n";
+				ss<<name<<" = "<<value<<"\n";
+			}
+
+			if(!fs::safeWriteToFile(filename, ss.str()))
+			{
+				errorstream<<"Error writing configuration file: \""
+						<<filename<<"\""<<std::endl;
+				return false;
 			}
 		}
 
diff --git a/src/subgame.cpp b/src/subgame.cpp
index 7fee3899d4ace353f7555735034f25390475c215..806d6593451adfd1629fd2602f661ba319d43b1f 100644
--- a/src/subgame.cpp
+++ b/src/subgame.cpp
@@ -241,8 +241,9 @@ bool initializeWorld(const std::string &path, const std::string &gameid)
 	if(!fs::PathExists(worldmt_path)){
 		infostream<<"Creating world.mt ("<<worldmt_path<<")"<<std::endl;
 		fs::CreateAllDirs(path);
-		std::ofstream of(worldmt_path.c_str(), std::ios::binary);
-		of<<"gameid = "<<gameid<<"\n";
+		std::ostringstream ss(std::ios_base::binary);
+		ss<<"gameid = "<<gameid<<"\n";
+		fs::safeWriteToFile(worldmt_path, ss.str());
 	}
 	return true;
 }