Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Lightweight safe and fast file copy function in C. (zlib license)
- * (Windows CopyFile wrapper for Unix/Linux)
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifdef WIN32
- #include <windows.h>
- #else
- #include <unistd.h>
- #include <sys/time.h>
- #endif
- /* require bool (C99) */
- #ifdef HAVE_STDBOOL_H
- # include <stdbool.h>
- #else
- # ifndef HAVE__BOOL
- # ifdef __cplusplus
- typedef bool _Bool;
- # else
- # define _Bool signed char
- # endif
- # endif
- # define bool _Bool
- # define false 0
- # define true 1
- # define __bool_true_false_are_defined 1
- #endif
- #define FILE_IO_MEMBLOCK_SIZE 7
- /**
- * Copy a file to another file.
- * @param src_path Source file path.
- * @param dst_path Destination file path.
- * @param fail_if_exist true if the operation should be failed when the destination file already exists.
- * @return true if the source file is successfully copied to the destination path, false otherwise.
- * Additional error code can be retrieved from errno, or GetLastError() in Windows system.
- */
- bool copy_file(const char *src_path, const char *dst_path, bool fail_if_exist)
- {
- #ifdef WIN32
- return CopyFileA(src_path, dst_path, fail_if_exist);
- #else
- struct stat src_stat;
- struct stat dst_stat;
- FILE * src_file = NULL;
- FILE * dst_file = NULL;
- char * buf = NULL;
- const int buf_size = 512 * 1024;
- off_t transferred_bytes;
- bool succeeded = false;
- int errno_saved;
- int ret;
- /* get source file attributes */
- ret = stat(src_path, &src_stat);
- if (ret == -1) {
- goto finish;
- }
- /* get destination file attributes */
- ret = stat(dst_path, &dst_stat);
- if (ret == -1 && errno != ENOENT) {
- goto finish;
- }
- /* prevent overwriting to existing file, if necessary */
- if (ret == 0 && fail_if_exist) {
- errno = EEXIST;
- goto finish;
- }
- /* open source file */
- src_file = fopen(src_path, "rb");
- if (src_file == NULL) {
- goto finish;
- }
- /* open destination file */
- dst_file = fopen(dst_path, "wb");
- if (dst_file == NULL) {
- goto finish;
- }
- /* copy content of file unless source file is empty */
- if (src_stat.st_size > 0) {
- /* allocate memory block for copying */
- buf = (char *) malloc(buf_size);
- if (buf == NULL) {
- goto finish;
- }
- /* read and write blocks */
- transferred_bytes = 0;
- while (transferred_bytes < src_stat.st_size) {
- int transfer_bytes = buf_size;
- if (transferred_bytes + transfer_bytes > src_stat.st_size) {
- transfer_bytes = src_stat.st_size - transferred_bytes;
- }
- if (fread(buf, 1, transfer_bytes, src_file) != transfer_bytes) {
- errno = EIO;
- goto finish;
- }
- if (fwrite(buf, 1, transfer_bytes, dst_file) != transfer_bytes) {
- errno = EIO;
- goto finish;
- }
- transferred_bytes += transfer_bytes;
- }
- }
- /* finish the file creation */
- fclose(dst_file);
- dst_file = NULL;
- /* copy file permissions as well */
- chmod(dst_path, src_stat.st_mode);
- /* everything has been done */
- succeeded = true;
- finish:
- errno_saved = errno;
- if (src_file != NULL) {
- fclose(src_file);
- }
- if (dst_file != NULL) {
- fclose(dst_file);
- }
- if (buf != NULL) {
- free(buf);
- }
- errno = errno_saved;
- return succeeded;
- #endif
- }
- #include <time.h>
- int main(void)
- {
- time_t start_time;
- time_t end_time;
- #ifdef WIN32
- printf("Platform: Windows\n");
- printf("\n");
- #else
- printf("Platform: Unix\n");
- printf("\n");
- #endif
- time(&start_time);
- if (copy_file("a.bin", "b.bin", true)) {
- printf("Success.\n");
- }
- else {
- #ifdef WIN32
- printf("Failed. %d\n", GetLastError());
- #else
- printf("Failed. %d\n", errno);
- #endif
- }
- time(&end_time);
- printf("Elapsed: %d seconds.\n", end_time - start_time);
- }
Add Comment
Please, Sign In to add comment