#include <sys/stat.h>
#ifdef __APPLE__
# include <xlocale.h>
-#else
+#elif defined(HAVE_USELOCALE)
#include <locale.h>
#endif
#include "configuration.h"
#include "modules/modules.h"
-static char *ConfigKeyToString( int );
-
static inline char *strdupnull (const char *src)
{
return src ? strdup (src) : NULL;
*/
static char *config_GetConfigFile( vlc_object_t *obj )
{
- char *psz_file = config_GetPsz( obj, "config" );
+ char *psz_file = var_CreateGetNonEmptyString( obj, "config" );
+ var_Destroy( obj, "config" );
if( psz_file == NULL )
{
- char *psz_dir = config_GetUserConfDir();
+ char *psz_dir = config_GetUserDir( VLC_CONFIG_DIR );
if( asprintf( &psz_file, "%s" DIR_SEP CONFIG_FILE, psz_dir ) == -1 )
psz_file = NULL;
{
/* This is the fallback for pre XDG Base Directory
* Specification configs */
+ char *home = config_GetUserDir(VLC_HOME_DIR);
char *psz_old;
- if( asprintf( &psz_old, "%s" DIR_SEP CONFIG_DIR DIR_SEP CONFIG_FILE,
- config_GetHomeDir() ) != -1 )
+
+ if( home != NULL
+ && asprintf( &psz_old, "%s/.vlc/" CONFIG_FILE,
+ home ) != -1 )
{
p_stream = utf8_fopen( psz_old, "rt" );
if( p_stream )
msg_Info( p_obj->p_libvlc, "Found old config file at %s. "
"VLC will now use %s.", psz_old, psz_filename );
char *psz_readme;
- if( asprintf(&psz_readme,"%s"DIR_SEP CONFIG_DIR DIR_SEP"README",
- config_GetHomeDir() ) != -1 )
+ if( asprintf(&psz_readme,"%s/.vlc/README",
+ home ) != -1 )
{
FILE *p_readme = utf8_fopen( psz_readme, "wt" );
if( p_readme )
}
free( psz_readme );
}
+ /* Remove the old configuration file so that --reset-config
+ * can work properly. Fortunately, Linux allows removing
+ * open files - with most filesystems. */
+ unlink( psz_old );
}
free( psz_old );
}
+ free( home );
}
#endif
free( psz_filename );
locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
locale_t baseloc = uselocale (loc);
+ vlc_rwlock_wrlock (&config_lock);
while (fgets (line, 1024, file) != NULL)
{
/* Ignore comments and empty lines */
/* We found it */
errno = 0;
- vlc_mutex_lock( p_item->p_lock );
switch( p_item->i_type )
{
case CONFIG_ITEM_BOOL:
p_item->saved.psz = strdupnull (p_item->value.psz);
break;
}
- vlc_mutex_unlock( p_item->p_lock );
break;
}
}
+ vlc_rwlock_unlock (&config_lock);
if (ferror (file))
{
}
}
- msg_Err( p_this, "could not create %s: %m", psz_dirname );
+ msg_Warn( p_this, "could not create %s: %m", psz_dirname );
return -1;
}
static int
-config_Write (FILE *file, const char *type, const char *desc,
+config_Write (FILE *file, const char *desc, const char *type,
bool comment, const char *name, const char *fmt, ...)
{
va_list ap;
static int config_PrepareDir (vlc_object_t *obj)
{
- char *psz_configdir = config_GetUserConfDir ();
- if (psz_configdir == NULL) /* XXX: This should never happen */
+ char *psz_configdir = config_GetUserDir (VLC_CONFIG_DIR);
+ if (psz_configdir == NULL)
return -1;
int ret = config_CreateDir (obj, psz_configdir);
goto error;
}
- if (asprintf (&temporary, "%s.%u", permanent,
-#ifdef UNDER_CE
- GetCurrentProcessId ()
-#else
- getpid ()
-#endif
- ) == -1)
+ if (asprintf (&temporary, "%s.%u", permanent, getpid ()) == -1)
{
temporary = NULL;
module_list_free (list);
goto error;
}
+ /* Configuration lock must be taken before vlcrc serializer below. */
+ vlc_rwlock_rdlock (&config_lock);
+
/* The temporary configuration file is per-PID. Therefore SaveConfigFile()
* should be serialized against itself within a given process. */
static vlc_mutex_t lock = VLC_STATIC_MUTEX;
int fd = utf8_open (temporary, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
if (fd == -1)
{
+ vlc_rwlock_unlock (&config_lock);
vlc_mutex_unlock (&lock);
module_list_free (list);
goto error;
file = fdopen (fd, "wt");
if (file == NULL)
{
+ vlc_rwlock_unlock (&config_lock);
close (fd);
vlc_mutex_unlock (&lock);
module_list_free (list);
locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
locale_t baseloc = uselocale (loc);
+ /* We would take the config lock here. But this would cause a lock
+ * inversion with the serializer above and config_AutoSaveConfigFile().
+ vlc_rwlock_rdlock (&config_lock);*/
+
/* Look for the selected module, if NULL then save everything */
for( i_index = 0; (p_parser = list[i_index]) != NULL; i_index++ )
{
|| p_item->b_unsaveable) /* ignore volatile option */
continue;
- vlc_mutex_lock (p_item->p_lock);
-
/* Do not save the new value in the configuration file
* if doing an autosave, and the item is not an "autosaved" one. */
bool b_retain = b_autosave && !p_item->b_autosave;
if (!b_retain)
p_item->b_dirty = false;
- vlc_mutex_unlock (p_item->p_lock);
}
}
+ vlc_rwlock_unlock (&config_lock);
module_list_free (list);
if (loc != (locale_t)0)
*/
fflush (file); /* Flush from run-time */
#ifndef WIN32
+#ifdef __APPLE__
+ fsync (fd); /* Flush from OS */
+#else
fdatasync (fd); /* Flush from OS */
+#endif
/* Atomically replace the file... */
if (utf8_rename (temporary, permanent))
utf8_unlink (temporary);
int config_AutoSaveConfigFile( vlc_object_t *p_this )
{
- size_t i_index;
+ int ret = VLC_SUCCESS;
bool save = false;
assert( p_this );
/* Check if there's anything to save */
module_t **list = module_list_get (NULL);
- for( i_index = 0; list[i_index] && !save; i_index++ )
+ vlc_rwlock_rdlock (&config_lock);
+ for (size_t i_index = 0; list[i_index] && !save; i_index++)
{
module_t *p_parser = list[i_index];
module_config_t *p_item, *p_end;
p_item < p_end && !save;
p_item++ )
{
- vlc_mutex_lock (p_item->p_lock);
save = p_item->b_autosave && p_item->b_dirty;
- vlc_mutex_unlock (p_item->p_lock);
}
}
- module_list_free (list);
- return save ? VLC_SUCCESS : SaveConfigFile( p_this, NULL, true );
+ if (save)
+ /* Note: this will get the read lock recursively. Ok. */
+ ret = SaveConfigFile (p_this, NULL, true);
+ vlc_rwlock_unlock (&config_lock);
+
+ module_list_free (list);
+ return ret;
}
int __config_SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name )
{
return SaveConfigFile( p_this, psz_module_name, false );
}
-
-int ConfigStringToKey( const char *psz_key )
-{
- int i_key = 0;
- size_t i;
- const char *psz_parser = strchr( psz_key, '-' );
- while( psz_parser && psz_parser != psz_key )
- {
- for( i = 0; i < vlc_num_modifiers; ++i )
- {
- if( !strncasecmp( vlc_modifiers[i].psz_key_string, psz_key,
- strlen( vlc_modifiers[i].psz_key_string ) ) )
- {
- i_key |= vlc_modifiers[i].i_key_code;
- }
- }
- psz_key = psz_parser + 1;
- psz_parser = strchr( psz_key, '-' );
- }
- for( i = 0; i < vlc_num_keys; ++i )
- {
- if( !strcasecmp( vlc_keys[i].psz_key_string, psz_key ) )
- {
- i_key |= vlc_keys[i].i_key_code;
- break;
- }
- }
- return i_key;
-}
-
-char *ConfigKeyToString( int i_key )
-{
- // Worst case appears to be 45 characters:
- // "Command-Meta-Ctrl-Shift-Alt-Browser Favorites"
- enum { keylen=64 };
- char *psz_key = malloc( keylen );
- char *p;
- size_t index;
-
- if ( !psz_key )
- {
- return NULL;
- }
- *psz_key = '\0';
- p = psz_key;
-
- for( index = 0; index < vlc_num_modifiers; ++index )
- {
- if( i_key & vlc_modifiers[index].i_key_code )
- {
- p += snprintf( p, keylen-(psz_key-p), "%s-",
- vlc_modifiers[index].psz_key_string );
- }
- }
- for( index = 0; index < vlc_num_keys; ++index )
- {
- if( (int)( i_key & ~KEY_MODIFIER ) == vlc_keys[index].i_key_code )
- {
- p += snprintf( p, keylen-(psz_key-p), "%s",
- vlc_keys[index].psz_key_string );
- break;
- }
- }
- return psz_key;
-}
-