# Include <stdio. h>
# Include <unistd. h>
# Include <stdlib. h>
# Include <string. h>
# Include <errno. h>
# Include <pthread. h>
# Include <dirent. h>
# Include <fcntl. h>
# Include <sys/types. h>
# Include <sys/STAT. h>
# Include <sys/time. h>
# Define buffer 512.
Struct copy_file {
Int infile;
Int OUTFILE;
};
Void * Copy (void * Arg)
{
Int infile, OUTFILE;
Int bytes_read, bytes_write, * bytes_copy_p;
Char buffer [buffer], * buffer_p;
Struct copy_file * file = (struct copy_file *) ARG;
Infile = file-> infile;
OUTFILE = file-> OUTFILE;
/* Because all the variable space will be released when the thread exits, We have to allocate the memory by ourselves */
If (bytes_copy_p = (int *) malloc (sizeof (INT) = NULL) pthread_exit (null );
Bytes_read = bytes_write = 0;
* Bytes_copy_p = 0;
While (bytes_read = read (infile, buffer, buffer ))! = 0)
{
If (bytes_read =-1) & (errno! = Eintr) break;
Else if (bytes_read> 0)
{
Buffer_p = buffer;
While (bytes_write = write (OUTFILE, buffer_p, bytes_read ))! = 0)
{
If (bytes_write =-1) & (errno! = Eintr) break;
Else if (bytes_write = bytes_read) break;
Else if (bytes_write> 0)
{
Buffer_p + = bytes_write;
Bytes_read-= bytes_write;
}
}
If (bytes_write =-1) break;
* Bytes_copy_p + = bytes_read;
}
}
Close (infile );
Close (OUTFILE );
Pthread_exit (bytes_copy_p );
}
Int main (INT argc, char ** argv)
{
Pthread_t * thread;
Struct copy_file * file;
Int byte_copy, * byte_copy_p, num, I, j;
Char filename [buffer];
Struct dirent ** namelist;
Struct stat filestat;
/* Obtain the number of all files (including directories) in the current path */
If (num = scandir (".", & namelist, 0, alphasort) <0)
{
Fprintf (stderr, "Get File num error: % s/n/a", strerror (errno ));
Exit (1 );
}
/* Allocate space to the thread. In fact, there is no need to allocate so much space */
If (thread = (pthread_t *) malloc (sizeof (pthread_t) * num) = NULL) |
(File = (struct copy_file *) malloc (sizeof (struct copy_file) * num) = NULL)
)
{
Fprintf (stderr, "out of memory! /N/");
Exit (1 );
}
For (I = 0, j = 0; I <num; I ++)
{
Memset (filename, '/0', buffer );
Strcpy (filename, namelist [I]-> d_name );
If (STAT (filename, & filestat) =-1)
{
Fprintf (stderr, "Get File Information: % s/n/a", strerror (errno ));
Exit (1 );
}
/* We ignore the directory */
If (! S_isreg (filestat. st_mode) continue;
If (file [J]. infile = open (filename, o_rdonly) <0)
{
Fprintf (stderr, "Open % s error: % s/n/a", filename, strerror (errno ));
Continue;
}
Strcat (filename, ". Bak ");
If (file [J]. OUTFILE = open (filename, o_wronly | o_creat, s_irusr | s_iwusr ))
<0)
{
Fprintf (stderr, "creat % s error: % s/n/a", filename, strerror (errno
));
Continue;
}
/* Create a thread to copy files */
If (pthread_create (& Thread [J], null, copy, (void *) & file [J])! = 0)
Fprintf (stderr, "Create thread [% d] error: % s/n/a", I, strerror (errno ));
J ++;
}
Byte_copy = 0;
For (I = 0; I <j; I ++)
{
/* Wait for the thread to end */
If (pthread_join (thread [I], (void **) & byte_copy_p )! = 0)
Fprintf (stderr, "thread [% d] Join error: % s/n/",
I, strerror (errno ));
Else
{
If (bytes_copy_p = NULL) continue;
Printf ("thread [% d] Copy % d Bytes/n/a", I, * byte_copy_p );
Byte_copy + = * byte_copy_p;
/* Release the memory we created in the copy function */
Free (byte_copy_p );
}
}
Printf ("Total copy bytes % d/n/a", byte_copy );
Free (thread );
Free (File );
Exit (0 );
}
|