#include <errno.h>
 #include <fcntl.h>
 #include <glib.h>
+#include <glib/gstdio.h>
 #include <JavaScriptCore/JavaScript.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/file.h>
+#include <unistd.h>
 
 #include "ascii.h"
 #include "completion.h"
 gboolean util_create_dir_if_not_exists(const char *dirpath)
 {
     if (g_mkdir_with_parents(dirpath, 0755) == -1) {
-        g_critical("Could not create directory '%s': %s", dirpath, strerror(errno));
+        g_critical("Could not create directory '%s': %s", dirpath, g_strerror(errno));
 
         return FALSE;
     }
  * @line:       Line to be written as new first line into the file.
  *              The line ending is inserted automatic.
  * @max_lines   Maximum number of lines in file after the operation.
+ * @mode        Mode (file permission as chmod(2)) used for the file when
+ *              creating it.
  */
 void util_file_prepend_line(const char *file, const char *line,
-        unsigned int max_lines)
+        unsigned int max_lines, int mode)
 {
     char **lines;
     GString *new_content;
         }
         g_strfreev(lines);
     }
-    g_file_set_contents(file, new_content->str, -1, NULL);
+    util_file_set_content(file, new_content->str, mode);
     g_string_free(new_content, TRUE);
 }
 
  * @file:       file to read from
  * @item_count: will be filled with the number of remaining lines in file if it
  *              is not NULL.
+ * @mode        Mode (file permission as chmod(2)) used for the file when
+ *              creating it.
  *
  * Returned string must be freed with g_free.
  */
-char *util_file_pop_line(const char *file, int *item_count)
+char *util_file_pop_line(const char *file, int *item_count, int mode)
 {
     char **lines;
     char *new,
             /* minus one for last empty item and one for popped item */
             count = len - 2;
             new   = g_strjoinv("\n", lines + 1);
-            g_file_set_contents(file, new, -1, NULL);
+            util_file_set_content(file, new, mode);
             g_free(new);
         }
         g_strfreev(lines);
     return content;
 }
 
+/**
+ * Atomicly writes contents to given file.
+ * Returns TRUE on success, FALSE otherwise.
+ */
+char *util_file_set_content(const char *file, const char *contents, int mode)
+{
+    gboolean retval = FALSE;
+    char *tmp_name;
+    int fd;
+    gsize length;
+
+    /* Create a temporary file. */
+    tmp_name = g_strconcat(file, ".XXXXXX", NULL);
+    errno    = 0;
+    fd       = g_mkstemp_full(tmp_name, O_RDWR, mode);
+    length   = strlen(contents);
+
+    if (fd == -1) {
+        g_error("Failed to create file %s: %s", tmp_name, g_strerror(errno));
+
+        goto out;
+    }
+
+    /* Write the contents to the temporary file. */
+    while (length > 0) {
+        gssize s;
+        s = write(fd, contents, length);
+        if (s < 0) {
+            if (errno == EINTR) {
+                continue;
+            }
+            g_error("Failed to write to file %s: write() failed: %s",
+                    tmp_name, g_strerror(errno));
+            close(fd);
+            g_unlink(tmp_name);
+
+            goto out;
+        }
+
+        g_assert (s <= length);
+
+        contents += s;
+        length   -= s;
+    }
+
+    if (!g_close(fd, NULL)) {
+        g_unlink(tmp_name);
+        goto out;
+    }
+
+    /* Atomic rename the temporary file into the destination file. */
+    if (g_rename(tmp_name, file) == -1) {
+        g_error("Failed to rename file %s to %s: g_rename() failed: %s",
+                tmp_name, file, g_strerror(errno));
+        g_unlink(tmp_name);
+        goto out;
+    }
+
+    retval = TRUE;
+
+out:
+    g_free(tmp_name);
+
+    return retval;
+}
+
 /**
  * Buil the path from given directory and filename and checks if the file
  * exists. If the file does not exists and the create option is not set, this
 
 gboolean util_file_append(const char *file, const char *format, ...);
 gboolean util_file_prepend(const char *file, const char *format, ...);
 void util_file_prepend_line(const char *file, const char *line,
-        unsigned int max_lines);
-char *util_file_pop_line(const char *file, int *item_count);
+        unsigned int max_lines, int mode);
+char *util_file_pop_line(const char *file, int *item_count, int mode);
 char *util_get_config_dir(void);
 char *util_get_file_contents(const char *filename, gsize *length);
+char *util_file_set_content(const char *file, const char *contents, int mode);
 char *util_get_filepath(const char *dir, const char *filename, gboolean create, int mode);
 char **util_get_lines(const char *filename);
 GList *util_file_to_unique_list(const char *filename, Util_Content_Func func,