diff --git a/daemon/daemon.c b/daemon/daemon.c
index 73419df..90bb6f6 100644
--- a/daemon/daemon.c
+++ b/daemon/daemon.c
@@ -61,12 +61,10 @@
 #define SPEED_G_STR "GB/s"
 #define SPEED_T_STR "TB/s"
 
-#define LOGFILE_MODE_STR "a+"
-
 static bool paused = false;
 static bool seenHUP = false;
 static const char *logfileName = NULL;
-static FILE *logfile = NULL;
+static tr_sys_file_t logfile = TR_BAD_SYS_FILE;
 static tr_session * mySession = NULL;
 static tr_quark key_pidfile = 0;
 static struct event_base *ev_base = NULL;
@@ -144,6 +142,30 @@ showUsage (void)
     exit (0);
 }
 
+static bool
+reopen_log_file (const char *filename)
+{
+    tr_error * error = NULL;
+    const tr_sys_file_t old_log_file = logfile;
+    const tr_sys_file_t new_log_file = tr_sys_file_open (filename,
+                                                         TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_APPEND,
+                                                         0666, &error);
+
+    if (new_log_file == TR_BAD_SYS_FILE)
+    {
+        fprintf (stderr, "Couldn't (re)open log file \"%s\": %s\n", filename, error->message);
+        tr_error_free (error);
+        return false;
+    }
+
+    logfile = new_log_file;
+
+    if (old_log_file != TR_BAD_SYS_FILE)
+        tr_sys_file_close (old_log_file, NULL);
+
+    return true;
+}
+
 static void
 gotsig (int sig)
 {
@@ -162,10 +184,9 @@ gotsig (int sig)
                 const char * configDir;
 
                 /* reopen the logfile to allow for log rotation */
-                if (logfileName) {
-                    logfile = freopen (logfileName, LOGFILE_MODE_STR, logfile);
-                    if (!logfile)
-                        fprintf (stderr, "Couldn't reopen \"%s\": %s\n", logfileName, tr_strerror (errno));
+                if (logfileName != NULL)
+                {
+                    reopen_log_file (logfileName);
                 }
 
                 configDir = tr_sessionGetConfigDir (mySession);
@@ -306,16 +327,18 @@ onFileAdded (tr_session * session, const char * dir, const char * file)
 }
 
 static void
-printMessage (FILE * logfile, int level, const char * name, const char * message, const char * file, int line)
+printMessage (tr_sys_file_t logfile, int level, const char * name, const char * message, const char * file, int line)
 {
-    if (logfile != NULL)
+    if (logfile != TR_BAD_SYS_FILE)
     {
         char timestr[64];
         tr_logGetTimeStr (timestr, sizeof (timestr));
         if (name)
-            fprintf (logfile, "[%s] %s %s (%s:%d)\n", timestr, name, message, file, line);
+            tr_sys_file_write_fmt (logfile, "[%s] %s %s (%s:%d)" TR_NATIVE_EOL_STR,
+                                   NULL, timestr, name, message, file, line);
         else
-            fprintf (logfile, "[%s] %s (%s:%d)\n", timestr, message, file, line);
+            tr_sys_file_write_fmt (logfile, "[%s] %s (%s:%d)" TR_NATIVE_EOL_STR,
+                                   NULL, timestr, message, file, line);
     }
 #ifdef HAVE_SYSLOG
     else /* daemon... write to syslog */
@@ -338,7 +361,7 @@ printMessage (FILE * logfile, int level, const char * name, const char * message
 }
 
 static void
-pumpLogMessages (FILE * logfile)
+pumpLogMessages (tr_sys_file_t logfile)
 {
     const tr_log_message * l;
     tr_log_message * list = tr_logGetQueue ();
@@ -346,8 +369,8 @@ pumpLogMessages (FILE * logfile)
     for (l=list; l!=NULL; l=l->next)
         printMessage (logfile, l->level, l->name, l->message, l->file, l->line);
 
-    if (logfile != NULL)
-        fflush (logfile);
+    if (logfile != TR_BAD_SYS_FILE)
+        tr_sys_file_flush (logfile, NULL);
 
     tr_logFreeQueue (list);
 }
@@ -439,11 +462,8 @@ main (int argc, char ** argv)
                       break;
             case 'd': dumpSettings = true;
                       break;
-            case 'e': logfile = fopen (optarg, LOGFILE_MODE_STR);
-                      if (logfile)
+            case 'e': if (reopen_log_file (optarg))
                           logfileName = optarg;
-                      else
-                          fprintf (stderr, "Couldn't open \"%s\": %s\n", optarg, tr_strerror (errno));
                       break;
             case 'f': foreground = true;
                       break;
@@ -518,8 +538,8 @@ main (int argc, char ** argv)
         }
     }
 
-    if (foreground && !logfile)
-        logfile = stderr;
+    if (foreground && logfile == TR_BAD_SYS_FILE)
+        logfile = tr_sys_file_get_std (TR_STD_SYS_FILE_ERR, NULL);
 
     if (!loaded)
     {
@@ -568,16 +588,22 @@ main (int argc, char ** argv)
     tr_variantDictFindStr (&settings, key_pidfile, &pid_filename, NULL);
     if (pid_filename && *pid_filename)
     {
-        FILE * fp = fopen (pid_filename, "w+");
-        if (fp != NULL)
+        tr_error * error = NULL;
+        tr_sys_file_t fp = tr_sys_file_open (pid_filename,
+                                             TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE,
+                                             0666, &error);
+        if (fp != TR_BAD_SYS_FILE)
         {
-            fprintf (fp, "%d", (int)getpid ());
-            fclose (fp);
+            tr_sys_file_write_fmt (fp, "%d", NULL, (int)getpid ());
+            tr_sys_file_close (fp, NULL);
             tr_logAddInfo ("Saved pidfile \"%s\"", pid_filename);
             pidfile_created = true;
         }
         else
-            tr_logAddError ("Unable to save pidfile \"%s\": %s", pid_filename, tr_strerror (errno));
+        {
+            tr_logAddError ("Unable to save pidfile \"%s\": %s", pid_filename, error->message);
+            tr_error_free (error);
+        }
     }
 
     if (tr_variantDictFindBool (&settings, TR_KEY_rpc_authentication_required, &boolVal) && boolVal)
diff --git a/libtransmission/blocklist.c b/libtransmission/blocklist.c
index 987b205..729804e 100644
--- a/libtransmission/blocklist.c
+++ b/libtransmission/blocklist.c
@@ -302,14 +302,15 @@ compareAddressRangesByFirstAddress (const void * va, const void * vb)
 int
 tr_blocklistFileSetContent (tr_blocklistFile * b, const char * filename)
 {
-  FILE * in;
-  FILE * out;
+  tr_sys_file_t in;
+  tr_sys_file_t out;
   int inCount = 0;
   char line[2048];
   const char * err_fmt = _("Couldn't read \"%1$s\": %2$s");
   struct tr_ipv4_range * ranges = NULL;
   size_t ranges_alloc = 0;
   size_t ranges_count = 0;
+  tr_error * error = NULL;
 
   if (!filename)
     {
@@ -317,35 +318,34 @@ tr_blocklistFileSetContent (tr_blocklistFile * b, const char * filename)
       return 0;
     }
 
-  in = fopen (filename, "rb");
-  if (in == NULL)
+  in = tr_sys_file_open (filename, TR_SYS_FILE_READ, 0, &error);
+  if (in == TR_BAD_SYS_FILE)
     {
-      tr_logAddError (err_fmt, filename, tr_strerror (errno));
+      tr_logAddError (err_fmt, filename, error->message);
+      tr_error_free (error);
       return 0;
     }
 
   blocklistClose (b);
 
-  out = fopen (b->filename, "wb+");
-  if (out == NULL)
+  out = tr_sys_file_open (b->filename,
+                          TR_SYS_FILE_WRITE | TR_SYS_FILE_CREATE | TR_SYS_FILE_TRUNCATE,
+                          0666, &error);
+  if (out == TR_BAD_SYS_FILE)
     {
-      tr_logAddError (err_fmt, b->filename, tr_strerror (errno));
-      fclose (in);
+      tr_logAddError (err_fmt, b->filename, error->message);
+      tr_error_free (error);
+      tr_sys_file_close (in, NULL);
       return 0;
     }
 
   /* load the rules into memory */
-  while (fgets (line, sizeof (line), in) != NULL)
+  while (tr_sys_file_read_line (in, line, sizeof (line), NULL))
     {
-      char * walk;
       struct tr_ipv4_range range;
 
       ++inCount;
 
-      /* zap the linefeed */
-      if ((walk = strchr (line, '\r'))) *walk = '\0';
-      if ((walk = strchr (line, '\n'))) *walk = '\0';
-
       if (!parseLine (line, &range))
         {
           /* don't try to display the actual lines - it causes issues */
@@ -397,9 +397,10 @@ tr_blocklistFileSetContent (tr_blocklistFile * b, const char * filename)
 #endif
     }
 
-  if (fwrite (ranges, sizeof (struct tr_ipv4_range), ranges_count, out) != ranges_count)
+  if (!tr_sys_file_write (out, ranges, sizeof (struct tr_ipv4_range) * ranges_count, NULL, &error))
     {
-      tr_logAddError (_("Couldn't save file \"%1$s\": %2$s"), b->filename, tr_strerror (errno));
+      tr_logAddError (_("Couldn't save file \"%1$s\": %2$s"), b->filename, error->message);
+      tr_error_free (error);
     }
   else
     {
@@ -409,8 +410,8 @@ tr_blocklistFileSetContent (tr_blocklistFile * b, const char * filename)
     }
 
   tr_free (ranges);
-  fclose (out);
-  fclose (in);
+  tr_sys_file_close (out, NULL);
+  tr_sys_file_close (in, NULL);
 
   blocklistLoad (b);
 
diff --git a/libtransmission/log.c b/libtransmission/log.c
index 15db6c8..98c4517 100644
--- a/libtransmission/log.c
+++ b/libtransmission/log.c
@@ -58,11 +58,11 @@ getMessageLock (void)
   return l;
 }
 
-void*
+tr_sys_file_t
 tr_logGetFile (void)
 {
   static bool initialized = false;
-  static FILE * file = NULL;
+  static tr_sys_file_t file = TR_BAD_SYS_FILE;
 
   if (!initialized)
     {
@@ -75,15 +75,11 @@ tr_logGetFile (void)
       switch (fd)
         {
           case 1:
-            file = stdout;
+            file = tr_sys_file_get_std (TR_STD_SYS_FILE_OUT, NULL);
             break;
 
           case 2:
-            file = stderr;
-            break;
-
-          default:
-            file = NULL;
+            file = tr_sys_file_get_std (TR_STD_SYS_FILE_ERR, NULL);
             break;
         }
 
@@ -136,9 +132,9 @@ tr_logFreeQueue (tr_log_message * list)
   while (NULL != list)
     {
       next = list->next;
-      free (list->message);
-      free (list->name);
-      free (list);
+      tr_free (list->message);
+      tr_free (list->name);
+      tr_free (list);
       list = next;
     }
 }
@@ -173,7 +169,7 @@ tr_logGetDeepEnabled (void)
   static int8_t deepLoggingIsActive = -1;
 
   if (deepLoggingIsActive < 0)
-    deepLoggingIsActive = IsDebuggerPresent () || (tr_logGetFile ()!=NULL);
+    deepLoggingIsActive = IsDebuggerPresent () || (tr_logGetFile () != TR_BAD_SYS_FILE);
 
   return deepLoggingIsActive != 0;
 }
@@ -185,8 +181,8 @@ tr_logAddDeep (const char  * file,
                const char  * fmt,
                ...)
 {
-  FILE * fp = tr_logGetFile ();
-  if (fp || IsDebuggerPresent ())
+  const tr_sys_file_t fp = tr_logGetFile ();
+  if (fp != TR_BAD_SYS_FILE || IsDebuggerPresent ())
     {
       va_list args;
       char timestr[64];
@@ -201,12 +197,13 @@ tr_logAddDeep (const char  * file,
       va_start (args, fmt);
       evbuffer_add_vprintf (buf, fmt, args);
       va_end (args);
-      evbuffer_add_printf (buf, " (%s:%d)\n", base, line);
+      evbuffer_add_printf (buf, " (%s:%d)", base, line);
       /* FIXME (libevent2) ifdef this out for nonwindows platforms */
       message = evbuffer_free_to_str (buf);
       OutputDebugStringA (message);
-      if (fp)
-        fputs (message, fp);
+      OutputDebugStringA (TR_NATIVE_EOL_STR);
+      if (fp != TR_BAD_SYS_FILE)
+        tr_sys_file_write_line (fp, message, NULL);
 
       tr_free (message);
       tr_free (base);
@@ -267,20 +264,20 @@ tr_logAddMessage (const char * file,
         }
       else
         {
-          FILE * fp;
+          tr_sys_file_t fp;
           char timestr[64];
 
           fp = tr_logGetFile ();
-          if (fp == NULL)
-            fp = stderr;
+          if (fp == TR_BAD_SYS_FILE)
+            fp = tr_sys_file_get_std (TR_STD_SYS_FILE_ERR, NULL);
 
           tr_logGetTimeStr (timestr, sizeof (timestr));
 
           if (name)
-            fprintf (fp, "[%s] %s: %s\n", timestr, name, buf);
+            tr_sys_file_write_fmt (fp, "[%s] %s: %s" TR_NATIVE_EOL_STR, NULL, timestr, name, buf);
           else
-            fprintf (fp, "[%s] %s\n", timestr, buf);
-          fflush (fp);
+            tr_sys_file_write_fmt (fp, "[%s] %s" TR_NATIVE_EOL_STR, NULL, timestr, buf);
+          tr_sys_file_flush (fp, NULL);
         }
     }
 
diff --git a/libtransmission/log.h b/libtransmission/log.h
index 7413a3c..fc07bb5 100644
--- a/libtransmission/log.h
+++ b/libtransmission/log.h
@@ -11,6 +11,8 @@
 #define TR_LOG_H 1
 
 #include <stddef.h> /* size_t */
+
+#include "file.h" /* tr_sys_file_t */
 #include "utils.h" /* TR_GNUC_PRINTF, TR_GNUC_NONNULL */
 
 #ifdef __cplusplus
@@ -107,7 +109,7 @@ void tr_logAddMessage (const char   * file,
 
 
 
-void* tr_logGetFile (void);
+tr_sys_file_t tr_logGetFile (void);
 
 /** @brief return true if deep logging has been enabled by the user; false otherwise */
 bool tr_logGetDeepEnabled (void);
diff --git a/libtransmission/peer-msgs.c b/libtransmission/peer-msgs.c
index acac50b..22556c5 100644
--- a/libtransmission/peer-msgs.c
+++ b/libtransmission/peer-msgs.c
@@ -282,9 +282,9 @@ myDebug (const char * file, int line,
          const struct tr_peerMsgs * msgs,
          const char * fmt, ...)
 {
-  FILE * fp = tr_logGetFile ();
+  const tr_sys_file_t fp = tr_logGetFile ();
 
-  if (fp)
+  if (fp != TR_BAD_SYS_FILE)
     {
       va_list           args;
       char              timestr[64];
@@ -300,10 +300,10 @@ myDebug (const char * file, int line,
       va_start (args, fmt);
       evbuffer_add_vprintf (buf, fmt, args);
       va_end (args);
-      evbuffer_add_printf (buf, " (%s:%d)\n", base, line);
+      evbuffer_add_printf (buf, " (%s:%d)", base, line);
 
       message = evbuffer_free_to_str (buf);
-      fputs (message, fp);
+      tr_sys_file_write_line (fp, message, NULL);
 
       tr_free (base);
       tr_free (message);
diff --git a/libtransmission/tr-dht.c b/libtransmission/tr-dht.c
index 7f17302..2cbd7cb 100644
--- a/libtransmission/tr-dht.c
+++ b/libtransmission/tr-dht.c
@@ -32,7 +32,6 @@
 /* posix */
 #include <signal.h> /* sig_atomic_t */
 #include <sys/time.h>
-#include <unistd.h> /* close () */
 #ifdef _WIN32
   #include <inttypes.h>
   #define _WIN32_WINNT  0x0501	/* freeaddrinfo (),getaddrinfo (),getnameinfo () */
@@ -51,6 +50,7 @@
 /* libT */
 #include "transmission.h"
 #include "crypto.h"
+#include "file.h"
 #include "log.h"
 #include "net.h"
 #include "peer-mgr.h" /* tr_peerMgrCompactToPex () */
@@ -195,22 +195,21 @@ dht_bootstrap (void *closure)
 
     if (!bootstrap_done (cl->session, 0)) {
         char *bootstrap_file;
-        FILE *f = NULL;
+        tr_sys_file_t f = TR_BAD_SYS_FILE;
 
         bootstrap_file =
             tr_buildPath (cl->session->configDir, "dht.bootstrap", NULL);
 
         if (bootstrap_file)
-            f = fopen (bootstrap_file, "rb");
-        if (f != NULL) {
+            f = tr_sys_file_open (bootstrap_file, TR_SYS_FILE_READ, 0, NULL);
+        if (f != TR_BAD_SYS_FILE) {
             tr_logAddNamedInfo ("DHT", "Attempting manual bootstrap");
             for (;;) {
                 char buf[201];
                 char *p;
                 int port = 0;
 
-                p = fgets (buf, 200, f);
-                if (p == NULL)
+                if (!tr_sys_file_read_line (f, buf, 200, NULL))
                     break;
 
                 p = memchr (buf, ' ', strlen (buf));
@@ -228,7 +227,7 @@ dht_bootstrap (void *closure)
                 if (bootstrap_done (cl->session, 0))
                     break;
             }
-            fclose (f);
+            tr_sys_file_close (f, NULL);
         }
 
         tr_free (bootstrap_file);
