Hello,
I've made a file synchronization application that copies files from one machine to another across the network. For this I use the standard fopen, fread, fwrite and fclose calls (see code below). The copying itself works a treat but when I call fclose (specially for big files) it takes a long time to close the file (even longer than it took to copy!). I've disabled buffering with a setbuf call but this does not seem to have any effect. I even throw in a fflush call during the copy process. It's really annoying - the user sees a progress bar when copying the file which runs fine up to 100% and then hangs for a long time while it's closing the file. Is there anything I can do to make the fclose return quicker?
I'm copying from a Linux PC to a Windows PC across my home network.
Also, other sync programs that I have do not seem to have this problem.
I'm using GNU C on a Linux PC (Xubuntu)
IDE = Anjuta + GTK+ and Libglade
Ruud
==========================================
Code:
gboolean copy ( gchar *src_name,
gchar *dst_name,
int size )
{
gchar buf [ BUFSIZ ];
FILE *src;
FILE *dst;
int r,w;
int done = 0;
struct stat src_sb;
struct utimbuf file_times;
gboolean rtn = TRUE;
set_progress ( done, size );
if ( stat ( src_name, &src_sb ) < 0 )
{
g_warning ( "Could not stat %s\n", src_name );
return FALSE;
}
if ( ( src = fopen ( src_name, "rb" ) ) == NULL )
{
g_warning ( "Error opening %s", src_name );
return FALSE;
}
setbuf ( src, NULL );
if ( ( dst = fopen ( dst_name, "wb" ) ) == NULL ) // consider using tmpfile
{
g_warning ( "Error opening %s", dst_name );
rtn = FALSE;
}
else
{
setbuf ( dst, NULL );
rtn = in_progress ();
while ( rtn && ( r = fread ( &buf, sizeof ( gchar ), BUFSIZ, src ) ) > 0 )
{
rtn = in_progress ();
if ( rtn )
{
w = fwrite ( &buf, sizeof ( gchar ), r, dst );
fflush ( dst );
done = done + w;
set_progress ( done, size );
if ( w != r )
{
g_warning ( "Error writing to %s", dst_name );
rtn = FALSE;
}
}
else
g_warning ( "Aborted...." );
}
fclose ( dst );
}
fclose ( src );
if ( rtn )
{
file_times.actime = src_sb.st_atime;
file_times.modtime = src_sb.st_mtime;
if ( utime ( dst_name, &file_times ) != 0 )
{
g_warning ( "Error preserving times for %s", dst_name );
rtn = FALSE;
}
}
return rtn;
}