[C代码示例]mmap的使用和Linux下的错误处理
Sunday, May 6, 2007 8:02:21 AM
读完这段代码,请试着回答后面的几个问题。
/*
* 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. 这种情况下的错误处理有什么特点?













