]> git.sesse.net Git - vlc/blobdiff - src/config/file.c
SaveConfigFile: correctly an error on I/O failure
[vlc] / src / config / file.c
index 0126d608ee773654f15102a53e1415e50ca030e8..0d3f6b6afb06553ca3bea140be53db47127c36f3 100644 (file)
@@ -38,7 +38,8 @@
 
 #include <vlc_common.h>
 #include "../libvlc.h"
-#include "vlc_charset.h"
+#include <vlc_charset.h>
+#include <vlc_fs.h>
 #include "vlc_keys.h"
 
 #include "configuration.h"
@@ -75,7 +76,7 @@ static FILE *config_OpenConfigFile( vlc_object_t *p_obj )
 
     msg_Dbg( p_obj, "opening config file (%s)", psz_filename );
 
-    FILE *p_stream = utf8_fopen( psz_filename, "rt" );
+    FILE *p_stream = vlc_fopen( psz_filename, "rt" );
     if( p_stream == NULL && errno != ENOENT )
     {
         msg_Err( p_obj, "cannot open config file (%s): %m",
@@ -94,7 +95,7 @@ static FILE *config_OpenConfigFile( vlc_object_t *p_obj )
          && asprintf( &psz_old, "%s/.vlc/" CONFIG_FILE,
                       home ) != -1 )
         {
-            p_stream = utf8_fopen( psz_old, "rt" );
+            p_stream = vlc_fopen( psz_old, "rt" );
             if( p_stream )
             {
                 /* Old config file found. We want to write it at the
@@ -105,7 +106,7 @@ static FILE *config_OpenConfigFile( vlc_object_t *p_obj )
                 if( asprintf(&psz_readme,"%s/.vlc/README",
                              home ) != -1 )
                 {
-                    FILE *p_readme = utf8_fopen( psz_readme, "wt" );
+                    FILE *p_readme = vlc_fopen( psz_readme, "wt" );
                     if( p_readme )
                     {
                         fprintf( p_readme, "The VLC media player "
@@ -134,22 +135,25 @@ static FILE *config_OpenConfigFile( vlc_object_t *p_obj )
 }
 
 
-static int strtoi (const char *str)
+static int64_t strtoi (const char *str)
 {
     char *end;
-    long l;
+    long long l;
 
     errno = 0;
-    l = strtol (str, &end, 0);
+    l = strtoll (str, &end, 0);
 
     if (!errno)
     {
-        if ((l > INT_MAX) || (l < INT_MIN))
+#if (LLONG_MAX > 0x7fffffffffffffffLL)
+        if (l > 0x7fffffffffffffffLL
+         || l < -0x8000000000000000LL)
             errno = ERANGE;
+#endif
         if (*end)
             errno = EINVAL;
     }
-    return (int)l;
+    return l;
 }
 
 #undef config_LoadConfigFile
@@ -269,12 +273,14 @@ int config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
                 case CONFIG_ITEM_BOOL:
                 case CONFIG_ITEM_INTEGER:
                 {
-                    long l = strtoi (psz_option_value);
+                    int64_t l = strtoi (psz_option_value);
+                    if ((l > p_item->max.i) || (l < p_item->min.i))
+                        errno = ERANGE;
                     if (errno)
                         msg_Warn (p_this, "Integer value (%s) for %s: %m",
                                   psz_option_value, psz_option_name);
                     else
-                        p_item->saved.i = p_item->value.i = (int)l;
+                        p_item->saved.i = p_item->value.i = l;
                     break;
                 }
 
@@ -329,7 +335,7 @@ int config_CreateDir( vlc_object_t *p_this, const char *psz_dirname )
 {
     if( !psz_dirname || !*psz_dirname ) return -1;
 
-    if( utf8_mkdir( psz_dirname, 0700 ) == 0 )
+    if( vlc_mkdir( psz_dirname, 0700 ) == 0 )
         return 0;
 
     switch( errno )
@@ -349,7 +355,7 @@ int config_CreateDir( vlc_object_t *p_this, const char *psz_dirname )
                 *psz_end = '\0';
                 if( config_CreateDir( p_this, psz_parent ) == 0 )
                 {
-                    if( !utf8_mkdir( psz_dirname, 0700 ) )
+                    if( !vlc_mkdir( psz_dirname, 0700 ) )
                         return 0;
                 }
             }
@@ -431,7 +437,7 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
     if( config_PrepareDir( p_this ) )
     {
         msg_Err( p_this, "no configuration directory" );
-        goto error;
+        return -1;
     }
 
     file = config_OpenConfigFile( p_this );
@@ -540,7 +546,7 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
     static vlc_mutex_t lock = VLC_STATIC_MUTEX;
     vlc_mutex_lock (&lock);
 
-    int fd = utf8_open (temporary, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
+    int fd = vlc_open (temporary, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
     if (fd == -1)
     {
         vlc_rwlock_unlock (&config_lock);
@@ -551,6 +557,7 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
     file = fdopen (fd, "wt");
     if (file == NULL)
     {
+        msg_Err (p_this, "cannot create configuration file: %m");
         vlc_rwlock_unlock (&config_lock);
         close (fd);
         vlc_mutex_unlock (&lock);
@@ -558,8 +565,15 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
         goto error;
     }
 
-    fprintf( file, "\xEF\xBB\xBF###\n###  " COPYRIGHT_MESSAGE "\n###\n\n"
-       "###\n### lines beginning with a '#' character are comments\n###\n\n" );
+    fprintf( file,
+        "\xEF\xBB\xBF###\n"
+        "###  "PACKAGE_NAME" "PACKAGE_VERSION"\n"
+        "###\n"
+        "\n"
+        "###\n"
+        "### lines beginning with a '#' character are comments\n"
+        "###\n"
+        "\n" );
 
     /* Ensure consistent number formatting... */
     locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
@@ -606,7 +620,7 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
 
             if (IsConfigIntegerType (p_item->i_type))
             {
-                int val = b_retain ? p_item->saved.i : p_item->value.i;
+                int64_t val = b_retain ? p_item->saved.i : p_item->value.i;
                 if (p_item->i_type == CONFIG_ITEM_KEY)
                 {
                     char *psz_key = ConfigKeyToString (val);
@@ -621,7 +635,7 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
                                   (p_item->i_type == CONFIG_ITEM_BOOL)
                                       ? N_("boolean") : N_("integer"),
                                   val == p_item->orig.i,
-                                  p_item->psz_name, "%d", val);
+                                  p_item->psz_name, "%"PRId64, val);
                 p_item->saved.i = val;
             }
             else
@@ -691,6 +705,14 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
      * Flush to disk and replace atomically
      */
     fflush (file); /* Flush from run-time */
+    if (ferror (file))
+    {
+        vlc_unlink (temporary);
+        vlc_mutex_unlock (&lock);
+        msg_Err (p_this, "cannot write configuration file");
+        clearerr (file);
+        goto error;
+    }
 #ifndef WIN32
 #ifdef __APPLE__
     fsync (fd); /* Flush from OS */
@@ -698,8 +720,8 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
     fdatasync (fd); /* Flush from OS */
 #endif
     /* Atomically replace the file... */
-    if (utf8_rename (temporary, permanent))
-        utf8_unlink (temporary);
+    if (vlc_rename (temporary, permanent))
+        vlc_unlink (temporary);
     /* (...then synchronize the directory, err, TODO...) */
     /* ...and finally close the file */
     vlc_mutex_unlock (&lock);
@@ -707,9 +729,9 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
     fclose (file);
 #ifdef WIN32
     /* Windows cannot remove open files nor overwrite existing ones */
-    utf8_unlink (permanent);
-    if (utf8_rename (temporary, permanent))
-        utf8_unlink (temporary);
+    vlc_unlink (permanent);
+    if (vlc_rename (temporary, permanent))
+        vlc_unlink (temporary);
     vlc_mutex_unlock (&lock);
 #endif