[vlc-commits] timeshift: try to create the TS directory always before use
Rémi Denis-Courmont
git at videolan.org
Mon Aug 24 20:14:06 CEST 2015
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Aug 24 20:27:56 2015 +0300| [0e7efd20df4fd9355a13bf29f0eecf56eacf783c] | committer: Rémi Denis-Courmont
timeshift: try to create the TS directory always before use
The vlc_stat() call did not really ensure that the directory was usable
(space and permission), nor that it would still exist when needed.
Now instead, try to create the temporary file and fall back to the
default path if that fails.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=0e7efd20df4fd9355a13bf29f0eecf56eacf783c
---
src/input/es_out_timeshift.c | 195 +++++++++++++++++++++---------------------
1 file changed, 99 insertions(+), 96 deletions(-)
diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c
index d95a3aa..d9bd3dc 100644
--- a/src/input/es_out_timeshift.c
+++ b/src/input/es_out_timeshift.c
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
+#include <errno.h>
#if defined (_WIN32)
# include <direct.h>
#endif
@@ -281,8 +282,7 @@ static void CmdExecuteDel ( es_out_t *, ts_cmd_t * );
static int CmdExecuteControl( es_out_t *, ts_cmd_t * );
/* File helpers */
-static char *GetTmpPath( char *psz_path );
-static FILE *GetTmpFile( char **ppsz_file, const char *psz_path );
+static int GetTmpFile( char **ppsz_file, const char *psz_path );
/*****************************************************************************
* input_EsOutTimeshiftNew:
@@ -329,12 +329,52 @@ es_out_t *input_EsOutTimeshiftNew( input_thread_t *p_input, es_out_t *p_next_out
p_sys->i_tmp_size_max = 50*1024*1024;
else
p_sys->i_tmp_size_max = __MAX( i_tmp_size_max, 1*1024*1024 );
+ msg_Dbg( p_input, "using timeshift granularity of %d MiB",
+ (int)p_sys->i_tmp_size_max/(1024*1024) );
- char *psz_tmp_path = var_CreateGetNonEmptyString( p_input, "input-timeshift-path" );
- p_sys->psz_tmp_path = GetTmpPath( psz_tmp_path );
+ p_sys->psz_tmp_path = var_InheritString( p_input, "input-timeshift-path" );
+#if defined (_WIN32) && !VLC_WINSTORE_APP
+ if( p_sys->psz_tmp_path == NULL )
+ {
+ const DWORD count = GetTempPath( 0, NULL );
+ if( count > 0 )
+ {
+ TCHAR *path = malloc( (count + 1) * sizeof(TCHAR) );
+ if( path != NULL )
+ {
+ DWORD ret = GetTempPath( count + 1, path );
+ if( ret != 0 && ret <= count )
+ p_sys->psz_tmp_path = FromT( path );
+ free( path );
+ }
+ }
+ }
+ if( p_sys->psz_tmp_path == NULL )
+ {
+ wchar_t *wpath = _wgetcwd( NULL, 0 );
+ if( wpath != NULL )
+ {
+ p_sys->psz_tmp_path = FromWide( wpath );
+ free( wpath );
+ }
+ }
+ if( p_sys->psz_tmp_path == NULL )
+ p_sys->psz_tmp_path = strdup( "C:" );
- msg_Dbg( p_input, "using timeshift granularity of %d MiB, in path '%s'",
- (int)p_sys->i_tmp_size_max/(1024*1024), p_sys->psz_tmp_path );
+ if( p_sys->psz_tmp_path != NULL )
+ {
+ size_t len = strlen( p_sys->psz_tmp_path );
+
+ while( len > 0 && p_sys->psz_tmp_path[len - 1] == DIR_SEP_CHAR )
+ len--;
+
+ p_sys->psz_tmp_path[len] = '\0';
+ }
+#endif
+ if( p_sys->psz_tmp_path != NULL )
+ msg_Dbg( p_input, "using timeshift path: %s", p_sys->psz_tmp_path );
+ else
+ msg_Dbg( p_input, "using default timeshift path" );
#if 0
#define S(t) msg_Err( p_input, "SIZEOF("#t")=%d", sizeof(t) )
@@ -1053,19 +1093,38 @@ static void *TsRun( void *p_data )
*****************************************************************************/
static ts_storage_t *TsStorageNew( const char *psz_tmp_path, int64_t i_tmp_size_max )
{
- ts_storage_t *p_storage = calloc( 1, sizeof(ts_storage_t) );
- if( !p_storage )
+ ts_storage_t *p_storage = malloc( sizeof (*p_storage) );
+ if( unlikely(p_storage == NULL) )
return NULL;
- /* */
+ int fd = GetTmpFile( &p_storage->psz_file, psz_tmp_path );
+ if( fd == -1 )
+ {
+ free( p_storage );
+ return NULL;
+ }
+
+ p_storage->p_filew = fdopen( fd, "w+b" );
+ if( p_storage->p_filew == NULL )
+ {
+ close( fd );
+ vlc_unlink( p_storage->psz_file );
+ goto error;
+ }
+
+ p_storage->p_filer = vlc_fopen( p_storage->psz_file, "rb" );
+ if( p_storage->p_filer == NULL )
+ {
+ fclose( p_storage->p_filew );
+ vlc_unlink( p_storage->psz_file );
+ goto error;
+ }
+
p_storage->p_next = NULL;
/* */
p_storage->i_file_max = i_tmp_size_max;
p_storage->i_file_size = 0;
- p_storage->p_filew = GetTmpFile( &p_storage->psz_file, psz_tmp_path );
- if( p_storage->psz_file )
- p_storage->p_filer = vlc_fopen( p_storage->psz_file, "rb" );
/* */
p_storage->i_cmd_w = 0;
@@ -1074,13 +1133,18 @@ static ts_storage_t *TsStorageNew( const char *psz_tmp_path, int64_t i_tmp_size_
p_storage->p_cmd = malloc( p_storage->i_cmd_max * sizeof(*p_storage->p_cmd) );
//fprintf( stderr, "\nSTORAGE name=%s size=%d KiB\n", p_storage->psz_file, p_storage->i_cmd_max * sizeof(*p_storage->p_cmd) /1024 );
- if( !p_storage->p_cmd || !p_storage->p_filew || !p_storage->p_filer )
+ if( !p_storage->p_cmd )
{
TsStorageDelete( p_storage );
return NULL;
}
return p_storage;
+error:
+ free( p_storage->psz_file );
+ free( p_storage );
+ return NULL;
}
+
static void TsStorageDelete( ts_storage_t *p_storage )
{
while( p_storage->i_cmd_r < p_storage->i_cmd_w )
@@ -1093,19 +1157,13 @@ static void TsStorageDelete( ts_storage_t *p_storage )
}
free( p_storage->p_cmd );
- if( p_storage->p_filer )
- fclose( p_storage->p_filer );
- if( p_storage->p_filew )
- fclose( p_storage->p_filew );
-
- if( p_storage->psz_file )
- {
- vlc_unlink( p_storage->psz_file );
- free( p_storage->psz_file );
- }
-
+ fclose( p_storage->p_filer );
+ fclose( p_storage->p_filew );
+ vlc_unlink( p_storage->psz_file );
+ free( p_storage->psz_file );
free( p_storage );
}
+
static void TsStoragePack( ts_storage_t *p_storage )
{
/* Try to release a bit of memory */
@@ -1533,84 +1591,29 @@ static void CmdCleanControl( ts_cmd_t *p_cmd )
}
}
-
-/*****************************************************************************
- * GetTmpFile/Path:
- *****************************************************************************/
-static char *GetTmpPath( char *psz_path )
+static int GetTmpFile( char **filename, const char *dirname )
{
- if( psz_path && *psz_path )
- {
- /* Make sure that the path exists and is a directory */
- struct stat s;
- const int i_ret = vlc_stat( psz_path, &s );
-
- if( i_ret < 0 && !vlc_mkdir( psz_path, 0600 ) )
- return psz_path;
- else if( i_ret == 0 && ( s.st_mode & S_IFDIR ) )
- return psz_path;
- }
- free( psz_path );
-
- /* Create a suitable path */
-#if defined (_WIN32) && !VLC_WINSTORE_APP
- const DWORD dwCount = GetTempPathW( 0, NULL );
- wchar_t *psw_path = calloc( dwCount + 1, sizeof(wchar_t) );
- if( psw_path )
- {
- if( GetTempPathW( dwCount + 1, psw_path ) <= 0 )
- {
- free( psw_path );
-
- psw_path = _wgetcwd( NULL, 0 );
- }
- }
-
- psz_path = NULL;
- if( psw_path )
+ if( dirname != NULL
+ && asprintf( filename, "%s"DIR_SEP PACKAGE_NAME"-timeshift.XXXXXX",
+ dirname ) >= 0 )
{
- psz_path = FromWide( psw_path );
- while( psz_path && *psz_path && psz_path[strlen( psz_path ) - 1] == '\\' )
- psz_path[strlen( psz_path ) - 1] = '\0';
+ vlc_mkdir( dirname, 0700 );
- free( psw_path );
- }
+ int fd = vlc_mkstemp( *filename );
+ if( fd != -1 )
+ return fd;
- if( !psz_path || *psz_path == '\0' )
- {
- free( psz_path );
- return strdup( "C:" );
+ free( *filename );
}
-#else
- psz_path = strdup( DIR_SEP"tmp" );
-#endif
-
- return psz_path;
-}
-
-static FILE *GetTmpFile( char **ppsz_file, const char *psz_path )
-{
- char *psz_name;
- int fd;
- FILE *f;
- /* */
- *ppsz_file = NULL;
- if( asprintf( &psz_name, "%s"DIR_SEP"vlc-timeshift.XXXXXX", psz_path ) < 0 )
- return NULL;
+ *filename = strdup( DIR_SEP"tmp"DIR_SEP PACKAGE_NAME"-timeshift.XXXXXX" );
+ if( unlikely(*filename == NULL) )
+ return -1;
- /* */
- fd = vlc_mkstemp( psz_name );
- *ppsz_file = psz_name;
-
- if( fd < 0 )
- return NULL;
+ int fd = vlc_mkstemp( *filename );
+ if( fd != -1 )
+ return fd;
- /* */
- f = fdopen( fd, "w+b" );
- if( !f )
- close( fd );
-
- return f;
+ free( *filename );
+ return -1;
}
-
More information about the vlc-commits
mailing list