takfjt’s blog

いろいろつらつらと

Re: ファイルをコピーするプログラム


mixiのトピで書いたプログラムのメモ.
http://mixi.jp/view_bbs.pl?id=13304077&comment_count=150&comm_id=2880

荒れに荒れたトピックの中で空気を読まずに書いたファイルコピーのコード.
手元で確認した限りの最速.

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define nonfatal(s) \
	do { \
		fprintf(stderr, "%s(%d): ", __FILE__, __LINE__); \
		perror(s); \
		return EXIT_FAILURE; \
	} while (0)

int main(void)
{
	int in, out;
	char *in_data, *out_data, *endp;
	ssize_t in_len;
	struct stat st;

	in = open("infile", O_RDONLY, 0666);
	if (in < 0) nonfatal("open(in)");

	if (fstat(in, &st) < 0) nonfatal("fstat");

	in_len = st.st_size;

	in_data = mmap(NULL, in_len, PROT_READ, MAP_PRIVATE, in, 0);
	if (in_data == MAP_FAILED) nonfatal("mmap(in)");

	out = open("outfile", O_RDWR | O_CREAT | O_TRUNC, 0666);
	if (out < 0) nonfatal("open(out)");

	if (lseek(out, in_len - sizeof(int), SEEK_SET) < 0) nonfatal("lseek");
	if (write(out, &out, sizeof(int)) < 0) nonfatal("write");

	out_data = mmap(NULL, in_len, PROT_WRITE, MAP_SHARED, out, 0);
	if (out_data == MAP_FAILED) nonfatal("mmap(out)");

	endp = in_data + (sizeof(int) - (size_t)in_data % sizeof(int)) % sizeof(int);
	while (in_data != endp) {
		*out_data++ = *in_data++;
		in_len--;
	}

	endp = in_data + in_len - in_len % sizeof(int);
	while (in_data != endp) {
		*(int *)out_data = *(int *)in_data;
		out_data += sizeof(int);
		in_data += sizeof(int);
	}

	endp = in_data + in_len % sizeof(int);
	while (in_data != endp) *out_data++ = *in_data++;

	if (msync(out_data, st.st_size, MS_SYNC)) nonfatal("msync");

	return EXIT_SUCCESS;
}


Leave a Reply