makedep: Clean up output files on failure.

This commit is contained in:
Alexandre Julliard 2013-12-28 11:47:15 +01:00
parent 3b7cc5ec92
commit 8aa529417d
1 changed files with 48 additions and 30 deletions

View File

@ -28,6 +28,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
@ -104,6 +105,8 @@ static const char *parent_dir;
static const char *makefile_name = "Makefile";
static const char *Separator = "### Dependencies";
static const char *input_file_name;
static const char *output_file_name;
static const char *temp_file_name;
static int parse_makefile_mode;
static int relative_dir_mode;
static int input_line;
@ -173,6 +176,25 @@ static void fatal_perror( const char *msg, ... )
}
/*******************************************************************
* cleanup_files
*/
static void cleanup_files(void)
{
if (temp_file_name) unlink( temp_file_name );
if (output_file_name) unlink( output_file_name );
}
/*******************************************************************
* exit_on_signal
*/
static void exit_on_signal( int sig )
{
exit( 1 ); /* this will call the atexit functions */
}
/*******************************************************************
* xmalloc
*/
@ -1668,7 +1690,7 @@ static struct strarray output_sources(void)
/*******************************************************************
* create_temp_file
*/
static FILE *create_temp_file( const char *orig, char **tmp_name )
static FILE *create_temp_file( const char *orig )
{
char *name = xmalloc( strlen(orig) + 13 );
unsigned int i, id = getpid();
@ -1687,7 +1709,7 @@ static FILE *create_temp_file( const char *orig, char **tmp_name )
id += 7777;
}
if (!ret) fatal_error( "failed to create output file for '%s'\n", orig );
*tmp_name = name;
temp_file_name = name;
return ret;
}
@ -1695,20 +1717,17 @@ static FILE *create_temp_file( const char *orig, char **tmp_name )
/*******************************************************************
* rename_temp_file
*/
static void rename_temp_file( const char *tmp_name, const char *dest )
static void rename_temp_file( const char *dest )
{
int ret = rename( tmp_name, dest );
int ret = rename( temp_file_name, dest );
if (ret == -1 && errno == EEXIST)
{
/* rename doesn't overwrite on windows */
unlink( dest );
ret = rename( tmp_name, dest );
}
if (ret == -1)
{
unlink( tmp_name );
fatal_error( "failed to rename output file to '%s'\n", dest );
ret = rename( temp_file_name, dest );
}
if (ret == -1) fatal_error( "failed to rename output file to '%s'\n", dest );
temp_file_name = NULL;
}
@ -1717,10 +1736,9 @@ static void rename_temp_file( const char *tmp_name, const char *dest )
*/
static void output_gitignore( const char *dest, const struct strarray *files )
{
char *tmp_name;
int i;
output_file = create_temp_file( dest, &tmp_name );
output_file = create_temp_file( dest );
output( "# Automatically generated by make depend; DO NOT EDIT!!\n" );
output( "/.gitignore\n" );
@ -1731,35 +1749,31 @@ static void output_gitignore( const char *dest, const struct strarray *files )
output( "%s\n", files->str[i] );
}
fclose( output_file );
if (fclose( output_file )) fatal_perror( "write" );
output_file = NULL;
rename_temp_file( tmp_name, dest );
free( tmp_name );
rename_temp_file( dest );
}
/*******************************************************************
* output_dependencies
*/
static void output_dependencies(void)
static void output_dependencies( const char *path )
{
char *tmp_name = NULL;
char *path = strmake( "%s/%s", base_dir, makefile_name );
struct strarray targets = empty_strarray;
if (Separator && ((output_file = fopen( path, "r" ))))
{
char buffer[1024];
FILE *tmp_file = create_temp_file( path, &tmp_name );
FILE *tmp_file = create_temp_file( path );
int found = 0;
while (fgets( buffer, sizeof(buffer), output_file ) && !found)
{
if (fwrite( buffer, 1, strlen(buffer), tmp_file ) != strlen(buffer))
fatal_error( "failed to write to %s\n", tmp_name );
if (fwrite( buffer, 1, strlen(buffer), tmp_file ) != strlen(buffer)) fatal_perror( "write" );
found = !strncmp( buffer, Separator, strlen(Separator) );
}
fclose( output_file );
if (fclose( output_file )) fatal_perror( "write" );
output_file = tmp_file;
if (!found && !list_empty(&sources)) output( "\n%s\n", Separator );
}
@ -1773,12 +1787,7 @@ static void output_dependencies(void)
fclose( output_file );
output_file = NULL;
if (tmp_name)
{
rename_temp_file( tmp_name, path );
free( tmp_name );
}
free( path );
if (temp_file_name) rename_temp_file( path );
if (!src_dir) output_gitignore( strmake( "%s/.gitignore", base_dir ), &targets );
}
@ -1817,6 +1826,7 @@ static void update_makefile( const char *path )
struct incl_file *file;
base_dir = path;
output_file_name = strmake( "%s/%s", base_dir, makefile_name );
parse_makefile();
src_dir = get_expanded_make_variable( "srcdir" );
@ -1860,7 +1870,8 @@ static void update_makefile( const char *path )
}
LIST_FOR_EACH_ENTRY( file, &includes, struct incl_file, entry ) parse_file( file, 0 );
output_dependencies();
output_dependencies( output_file_name );
output_file_name = NULL;
}
@ -1974,6 +1985,13 @@ int main( int argc, char *argv[] )
exit( 0 );
}
atexit( cleanup_files );
signal( SIGTERM, exit_on_signal );
signal( SIGINT, exit_on_signal );
#ifdef SIGHUP
signal( SIGHUP, exit_on_signal );
#endif
if (parse_makefile_mode)
{
for (i = 1; i < argc; i++) update_makefile( argv[i] );
@ -1985,6 +2003,6 @@ int main( int argc, char *argv[] )
add_generated_sources();
LIST_FOR_EACH_ENTRY( pFile, &includes, struct incl_file, entry ) parse_file( pFile, 0 );
output_dependencies();
output_dependencies( makefile_name );
return 0;
}