@ -88,7 +88,12 @@ struct cache_file_mtime {
AST_LIST_ENTRY ( cache_file_mtime ) list ;
AST_LIST_HEAD_NOLOCK ( includes , cache_file_include ) includes ;
unsigned int has_exec : 1 ;
time_t mtime ;
/*! stat() file size */
unsigned long stat_size ;
/*! stat() file modtime nanoseconds */
unsigned long stat_mtime_nsec ;
/*! stat() file modtime seconds since epoc */
time_t stat_mtime ;
/*! String stuffed in filename[] after the filename string. */
const char * who_asked ;
@ -1180,6 +1185,61 @@ enum config_cache_attribute_enum {
ATTRIBUTE_EXEC = 1 ,
} ;
/*!
* \ internal
* \ brief Clear the stat ( ) data in the cached file modtime struct .
*
* \ param cfmtime Cached file modtime .
*
* \ return Nothing
*/
static void cfmstat_clear ( struct cache_file_mtime * cfmtime )
{
cfmtime - > stat_size = 0 ;
cfmtime - > stat_mtime_nsec = 0 ;
cfmtime - > stat_mtime = 0 ;
}
/*!
* \ internal
* \ brief Save the stat ( ) data to the cached file modtime struct .
*
* \ param cfmtime Cached file modtime .
* \ param statbuf Buffer filled in by stat ( ) .
*
* \ return Nothing
*/
static void cfmstat_save ( struct cache_file_mtime * cfmtime , struct stat * statbuf )
{
cfmtime - > stat_size = statbuf - > st_size ;
# if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || (defined(_POSIX_C_SOURCE) && 200809L <= _POSIX_C_SOURCE) || (defined(_XOPEN_SOURCE) && 700 <= _XOPEN_SOURCE)
cfmtime - > stat_mtime_nsec = statbuf - > st_mtim . tv_nsec ;
# else
cfmtime - > stat_mtime_nsec = statbuf - > st_mtimensec ;
# endif
cfmtime - > stat_mtime = statbuf - > st_mtime ;
}
/*!
* \ internal
* \ brief Compare the stat ( ) data with the cached file modtime struct .
*
* \ param cfmtime Cached file modtime .
* \ param statbuf Buffer filled in by stat ( ) .
*
* \ retval non - zero if different .
*/
static int cfmstat_cmp ( struct cache_file_mtime * cfmtime , struct stat * statbuf )
{
struct cache_file_mtime cfm_buf ;
cfmstat_save ( & cfm_buf , statbuf ) ;
return cfmtime - > stat_size ! = cfm_buf . stat_size
| | cfmtime - > stat_mtime ! = cfm_buf . stat_mtime
| | cfmtime - > stat_mtime_nsec ! = cfm_buf . stat_mtime_nsec ;
}
static void config_cache_attribute ( const char * configfile , enum config_cache_attribute_enum attrtype , const char * filename , const char * who_asked )
{
struct cache_file_mtime * cfmtime ;
@ -1202,10 +1262,11 @@ static void config_cache_attribute(const char *configfile, enum config_cache_att
AST_LIST_INSERT_SORTALPHA ( & cfmtime_head , cfmtime , list , filename ) ;
}
if ( ! stat ( configfile , & statbuf ) )
cfmtime - > mtime = 0 ;
else
cfmtime - > mtime = statbuf . st_mtime ;
if ( ! stat ( configfile , & statbuf ) ) {
cfmstat_clear ( cfmtime ) ;
} else {
cfmstat_save ( cfmtime , & statbuf ) ;
}
switch ( attrtype ) {
case ATTRIBUTE_INCLUDE :
@ -1587,14 +1648,19 @@ static struct ast_config *config_text_file_load(const char *database, const char
}
if ( ! cfmtime ) {
cfmtime = cfmtime_new ( fn , who_asked ) ;
if ( ! cfmtime )
if ( ! cfmtime ) {
AST_LIST_UNLOCK ( & cfmtime_head ) ;
continue ;
}
/* Note that the file mtime is initialized to 0, i.e. 1970 */
AST_LIST_INSERT_SORTALPHA ( & cfmtime_head , cfmtime , list , filename ) ;
}
}
if ( cfmtime & & ( ! cfmtime - > has_exec ) & & ( cfmtime - > mtime = = statbuf . st_mtime ) & & ast_test_flag ( & flags , CONFIG_FLAG_FILEUNCHANGED ) ) {
if ( cfmtime
& & ! cfmtime - > has_exec
& & ! cfmstat_cmp ( cfmtime , & statbuf )
& & ast_test_flag ( & flags , CONFIG_FLAG_FILEUNCHANGED ) ) {
/* File is unchanged, what about the (cached) includes (if any)? */
int unchanged = 1 ;
AST_LIST_TRAVERSE ( & cfmtime - > includes , cfinclude , list ) {
@ -1651,8 +1717,9 @@ static struct ast_config *config_text_file_load(const char *database, const char
return NULL ;
}
if ( cfmtime )
cfmtime - > mtime = statbuf . st_mtime ;
if ( cfmtime ) {
cfmstat_save ( cfmtime , & statbuf ) ;
}
if ( ! ( f = fopen ( fn , " r " ) ) ) {
ast_debug ( 1 , " No file to parse: %s \n " , fn ) ;