Commit Diff


commit - f63b8f7342aefba6b3dac50d6790981987c8faa8
commit + de6a6a402e45970c4b6d65778efc2e990c4a78a4
blob - 2309904c0b78c1bf3d1042531cd40b17c2442cbd
blob + 055d8061449bdc4efeae2d66f59b07941e8e7941
--- fs.c
+++ fs.c
@@ -71,8 +71,8 @@ char		lockfile_path[PATH_MAX];
 char		bookmark_file[PATH_MAX];
 char		known_hosts_file[PATH_MAX], known_hosts_tmp[PATH_MAX];
 char		crashed_file[PATH_MAX];
-char		session_file[PATH_MAX];
-char		history_file[PATH_MAX];
+char		session_file[PATH_MAX], session_file_tmp[PATH_MAX];
+char		history_file[PATH_MAX], history_file_tmp[PATH_MAX];
 
 static void __attribute__((__noreturn__))
 die(void)
@@ -445,8 +445,12 @@ fs_init(void)
 	join_path(known_hosts_tmp, cache_path_base,
 	    "/known_hosts.tmp.XXXXXXXXXX", sizeof(known_hosts_tmp));
 	join_path(session_file, cache_path_base, "/session",
+	    sizeof(session_file));
+	join_path(session_file_tmp, cache_path_base, "/session.XXXXXXXXXX",
 	    sizeof(session_file));
 	join_path(history_file, cache_path_base, "/history",
+	    sizeof(history_file));
+	join_path(history_file_tmp, cache_path_base, "/history.XXXXXXXXXX",
 	    sizeof(history_file));
 	join_path(crashed_file, cache_path_base, "/crashed",
 	    sizeof(crashed_file));
blob - da0257e65eb443f4bdfca3f75baa41cce5e60076
blob + 984e9d4e4252b6a78b374f1536b06960bf7624e5
--- include/fs.h
+++ include/fs.h
@@ -30,8 +30,8 @@ extern char	lockfile_path[PATH_MAX];
 extern char	bookmark_file[PATH_MAX];
 extern char	known_hosts_file[PATH_MAX], known_hosts_tmp[PATH_MAX];
 extern char	crashed_file[PATH_MAX];
-extern char	session_file[PATH_MAX];
-extern char	history_file[PATH_MAX];
+extern char	session_file[PATH_MAX], session_file_tmp[PATH_MAX];
+extern char	history_file[PATH_MAX], history_file_tmp[PATH_MAX];
 
 int		 fs_init(void);
 int		 lock_session(void);
blob - b5bd2aaf1318f0aded094a8b90bd8a7519ff04d4
blob + 49f267c9fb03d61e18a50c8e530f12bb1893dde6
--- session.c
+++ session.c
@@ -193,26 +193,51 @@ savetab(FILE *fp, struct tab *tab, int killed)
 void
 save_session(void)
 {
-	FILE			*session, *hist;
-	struct tab		*tab;
-	size_t			 i;
+	FILE		*tmp;
+	struct tab	*tab;
+	size_t		 i;
+	int		 fd, err=  0;
+	char		 sfn[PATH_MAX];
 
 	if (safe_mode)
 		return;
 
-	if ((session = fopen(session_file, "w")) == NULL)
+	strlcpy(sfn, session_file_tmp, sizeof(sfn));
+	if ((fd = mkstemp(sfn)) == -1 ||
+	    (tmp = fdopen(fd, "w")) == NULL) {
+		if (fd != -1) {
+			unlink(sfn);
+			close(fd);
+		}
 		return;
+	}
 
 	TAILQ_FOREACH(tab, &tabshead, tabs)
-		savetab(session, tab, 0);
+		savetab(tmp, tab, 0);
 	TAILQ_FOREACH(tab, &ktabshead, tabs)
-		savetab(session, tab, 1);
+		savetab(tmp, tab, 1);
 
-	fclose(session);
+	err = ferror(tmp);
+	fclose(tmp);
 
-	if ((hist = fopen(history_file, "a")) == NULL)
+	if (err) {
+		unlink(sfn);
 		return;
+	}
 
+	if (rename(sfn, session_file))
+		return;
+
+	strlcpy(sfn, history_file_tmp, sizeof(sfn));
+	if ((fd = mkstemp(sfn)) == -1 ||
+	    (tmp = fdopen(fd, "w")) == NULL) {
+		if (fd != -1) {
+			unlink(sfn);
+			close(fd);
+		}
+		return;
+	}
+
 	if (history.dirty) {
 		for (i = 0; i < history.len && history.dirty > 0; ++i) {
 			if (!history.items[i].dirty)
@@ -220,14 +245,22 @@ save_session(void)
 			history.dirty--;
 			history.items[i].dirty = 0;
 
-			fprintf(hist, "%lld %s\n",
+			fprintf(tmp, "%lld %s\n",
 			    (long long)history.items[i].ts,
 			    history.items[i].uri);
 		}
 		history.dirty = 0;
 	}
 
-	fclose(hist);
+	err = ferror(tmp);
+	fclose(tmp);
+
+	if (err) {
+		unlink(sfn);
+		return;
+	}
+
+	rename(sfn, history_file);
 }
 
 void