Changeset 10070


Ignore:
Timestamp:
Feb 2, 2010, 1:05:27 AM (12 years ago)
Author:
charles
Message:

(trunk libT) #2505 "Transmission loses config when disk is full" -- better implementation than r10068's from suggestions by elbandi

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/bencode.c

    r10068 r10070  
    15321532tr_bencToFile( const tr_benc * top, tr_fmt_mode mode, const char * filename )
    15331533{
    1534     FILE * fp;
    1535     struct stat sb;
     1534    char * tmp;
     1535    int fd;
    15361536    int err = 0;
    1537     char * backup = NULL;
    1538     tr_bool have_backup = FALSE;
    15391537
    15401538    /* if the file already exists, try to move it out of the way & keep it as a backup */
    1541     if( !stat( filename, &sb ) && S_ISREG( sb.st_mode ) ) {
    1542         backup = tr_strdup_printf( "%s.temp-backup", filename );
    1543         if( stat( backup, &sb ) && ( errno == ENOENT ) )
    1544             have_backup = !rename( filename, backup );
    1545     }
    1546 
    1547     /* save the bencoded data to the file */
    1548     fp = fopen( filename, "wb+" );
    1549     if( fp == NULL )
    1550     {
    1551         err = errno;
    1552         tr_err( _( "Couldn't open \"%1$s\": %2$s" ),
    1553                 filename, tr_strerror( errno ) );
    1554     }
    1555     else
     1539    tmp = tr_strdup_printf( "%s.tmp.XXXXXX", filename );
     1540    fd = mkstemp( tmp );
     1541    if( fd >= 0 )
    15561542    {
    15571543        int len;
    15581544        char * str = tr_bencToStr( top, mode, &len );
    1559 
    1560         if( fwrite( str, 1, len, fp ) == (size_t)len )
    1561             tr_dbg( "tr_bencToFile saved \"%s\"", filename );
    1562         else {
     1545        tr_dbg( "Writing %d bytes to temporary file \"%s\"", (int)len, tmp );
     1546
     1547        if( write( fd, str, len ) == (ssize_t)len )
     1548        {
     1549            close( fd );
     1550
     1551            if( !unlink( filename ) || ( errno == ENOENT ) )
     1552            {
     1553                tr_dbg( "Renaming \"%s\" as \"%s\"", tmp, filename );
     1554
     1555                if( !rename( tmp, filename ) )
     1556                {
     1557                    tr_inf( _( "Saved \"%s\"" ), filename );
     1558                }
     1559                else
     1560                {
     1561                    err = errno;
     1562                    tr_err( _( "Couldn't save file \"%1$s\": %2$s" ), filename, tr_strerror( err ) );
     1563                    unlink( tmp );
     1564                }
     1565            }
     1566            else
     1567            {
     1568                err = errno;
     1569                tr_err( _( "Couldn't save file \"%1$s\": %2$s" ), filename, tr_strerror( err ) );
     1570                unlink( tmp );
     1571            }
     1572        }
     1573        else
     1574        {
    15631575            err = errno;
    1564             tr_err( _( "Couldn't save file \"%1$s\": %2$s" ), filename, tr_strerror( errno ) );
     1576            tr_err( _( "Couldn't save temporary file \"%1$s\": %2$s" ), tmp, tr_strerror( err ) );
     1577            close( fd );
     1578            unlink( tmp );
    15651579        }
    15661580
    15671581        tr_free( str );
    1568         fclose( fp );
    1569     }
    1570 
    1571     if( have_backup ) {
    1572         if( err )
    1573             rename( backup, filename );
    1574         else
    1575             unlink( backup );
    1576     }
    1577 
    1578     tr_free( backup );
     1582    }
     1583    else
     1584    {
     1585        err = errno;
     1586        tr_err( _( "Couldn't save temporary file \"%1$s\": %2$s" ), tmp, tr_strerror( err ) );
     1587    }
     1588
     1589    tr_free( tmp );
    15791590    return err;
    15801591}
Note: See TracChangeset for help on using the changeset viewer.