西邮Linux兴趣小组

[C代码示例]mmap的使用和Linux下的错误处理

, ,

下面一段代码的作用是用mmap实现文件的拷贝,它可以给你演示mmap的使用,同时也告诉你在Linux上如何正确有效地处理错误。(代码可以在这里下载:http://wangcong.org/src/mmcpy.c

读完这段代码,请试着回答后面的几个问题。
/*
 * Copyright (C) WANG Cong, Apr. 2007.
 * GPLv2 applies.
 */
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
	int infd, outfd;
	void *from, *to;
	struct stat infstat;
	int ret = 0;
	if(argc != 3){
		fprintf(stderr, "Bad usage!\n");
		ret = -1;
		goto fail;
	}
	infd = open(argv[1], O_RDWR| O_CREAT, 0600);
	if(infd == -1){
		perror("Open failed");
		ret = -1;
		goto fail;
	}
	outfd = open(argv[2], O_RDWR| O_CREAT, 0600);
	if(outfd == -1){
		perror("Open failed");
		ret = -1;
		goto close_fail1;
	}
	if(fstat(infd, &infstat)){
		perror("fstat failed");
		ret = -1;
		goto close_fail2;
	}
	if(lseek(outfd, infstat.st_size-1, SEEK_SET) == (off_t) -1){
		perror("lseek failed");
		ret = -1;
		goto close_fail2;
	}
	if(write(outfd, "", 1) != 1){
		perror("write failed");
		ret = -1;
		goto close_fail2;
	}
	if(lseek(outfd, 0, SEEK_SET) == (off_t) -1){
		perror("lseek failed");
		ret = -1;
		goto close_fail2;
	}
	from = mmap(0, (size_t)infstat.st_size, PROT_READ,  MAP_PRIVATE | MAP_NORESERVE, infd, 0);
	if(from == (void*) -1){
		perror("mmap failed");
		ret = -1;
		goto close_fail2;
	}
	to = mmap(0, (size_t)infstat.st_size, PROT_WRITE, MAP_SHARED, outfd, 0);
	if(to == (void*) -1){
		perror("mmap failed");
		ret = -1;
		goto unmap_fail1;
	}
	memcpy(to, from, infstat.st_size);
	if( -1 == msync(to, (size_t)infstat.st_size, MS_SYNC)){
		perror("msync failed");
		ret = -1;
	}
	if (-1 == munmap(to, infstat.st_size)){
		perror("munmap failed");
		ret = -1;
	}

unmap_fail1:
	if( -1 == munmap(from, infstat.st_size)){
		perror("munmap failed");
		ret = -1;
	}

close_fail2:
	if( -1 == close(outfd)){
		perror("close failed");
		ret = -1;
	}

close_fail1:
	if( -1 == close(infd)){
		perror("close failed");
		ret = -1;
	}
fail:
	exit(ret);
}
问题:
1. mmap利用了操作系统中的什么原理?
2. 我们知道好的程序应该避免goto的使用,这里的goto没有问题吗?
3. 为什么这种情况下goto比单纯的return要更好?
4. 这种情况下的错误处理有什么特点?

GNOME 操作快捷键(转)vim 次常用指令列表

Write a comment

You must be logged in to write a comment. If you're not a registered member, please sign up.