@ -43,6 +43,7 @@
# include <unistd.h>
# include <unistd.h>
# include <stdlib.h>
# include <stdlib.h>
# include <stdio.h>
# include <stdio.h>
# include <limits.h>
/*
/*
* Build the libr_file handle for processing with libbfd
* Build the libr_file handle for processing with libbfd
@ -324,12 +325,28 @@ int safe_rename(const char *old, const char *new)
size_t read ;
size_t read ;
int status_in ;
int status_in ;
int status_out ;
int status_out ;
char linkdest [ PATH_MAX ] ;
char linkdest_test [ PATH_MAX ] ;
int ret ;
int is_symlink = 0 ;
ret = readlink ( new , linkdest_test , PATH_MAX ) ;
while ( ret > = 0 ) {
// Symlink encountered
is_symlink = 1 ;
linkdest_test [ ret ] = 0 ;
char * cwd = getcwd ( NULL , 0 ) ;
snprintf ( linkdest , PATH_MAX , " %s/%s " , cwd , linkdest_test ) ;
free ( cwd ) ;
ret = readlink ( linkdest , linkdest_test , PATH_MAX ) ;
}
in = fopen ( old , " r " ) ;
in = fopen ( old , " r " ) ;
if ( ! in ) {
if ( ! in ) {
return - 1 ;
return - 1 ;
}
}
out = fopen ( new , " w " ) ;
// Avoid bus error if modifying a library we are currently using
unlink ( ( is_symlink ) ? linkdest : new ) ;
out = fopen ( ( is_symlink ) ? linkdest : new , " w " ) ;
if ( ! out ) {
if ( ! out ) {
fclose ( in ) ;
fclose ( in ) ;
return - 1 ;
return - 1 ;
@ -342,7 +359,7 @@ int safe_rename(const char *old, const char *new)
if ( ferror ( in ) | | ferror ( out ) ) {
if ( ferror ( in ) | | ferror ( out ) ) {
fclose ( in ) ;
fclose ( in ) ;
fclose ( out ) ;
fclose ( out ) ;
remove ( new ) ;
remove ( ( is_symlink ) ? linkdest : new ) ;
return - 1 ;
return - 1 ;
}
}
}
}
@ -351,7 +368,7 @@ int safe_rename(const char *old, const char *new)
fclose ( in ) ;
fclose ( in ) ;
fclose ( out ) ;
fclose ( out ) ;
if ( status_in | | status_out ) {
if ( status_in | | status_out ) {
remove ( new ) ;
remove ( ( is_symlink ) ? linkdest : new ) ;
return - 1 ;
return - 1 ;
}
}
return remove ( old ) ;
return remove ( old ) ;