Created
January 14, 2019 18:27
-
-
Save bDrwx/45358425c05f3e891a0662ddd9e8d034 to your computer and use it in GitHub Desktop.
memory-mapped files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <fcntl.h> | |
#include <sys/mman.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <errno.h> | |
#include <stdarg.h> | |
#define MAXLINE 4096 /* max line length */ | |
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) | |
static void err_doit(int, int, const char *, va_list); | |
/* | |
* Обрабатывает фатальные ошибки, связанные с системными вызовами. | |
* Выводит сообщение и завершает работу процесса. | |
*/ | |
void err_sys(const char *fmt, ...){ | |
va_list ap; | |
va_start(ap, fmt); | |
err_doit(1, errno, fmt, ap); | |
exit(1); | |
} | |
/* | |
* Обрабатывает нефатальные ошибки, не связанные с системными вызовами. | |
* Код ошибки передается в аргументе. | |
* Выводит сообщение и возвращает управление. | |
*/ | |
void err_cont(int error, const char *fmt, ...){ | |
va_list ap; | |
va_start(ap, fmt); | |
err_doit(1, error, fmt, ap); | |
va_end(ap); | |
} | |
/* | |
* Обрабатывает фатальные ошибки, не связанные с системными вызовами. | |
* Выводит сообщение и завершает работу процесса. | |
*/ | |
void err_quit(const char *fmt, ...){ | |
va_list ap; | |
va_start(ap, fmt); | |
err_doit(0, 0, fmt, ap); | |
va_end(ap); | |
exit(1); | |
} | |
static void err_doit(int errnoflag, int error, const char *fmt, va_list ap){ | |
char buf[MAXLINE]; | |
vsnprintf(buf, MAXLINE-1, fmt, ap); | |
if (errnoflag) | |
snprintf(buf+strlen(buf), MAXLINE-strlen(buf)-1, ": %s", strerror(error)); | |
strcat(buf, "\n"); | |
fflush(stdout); /* в случае, когда stdout и stderr - одно и то же устройство */ | |
fputs(buf, stderr); | |
fflush(NULL); /* сбрасывает все выходные потоки */ | |
} | |
int main(int argc, char *argv[]){ | |
int fdin, fdout; | |
void *src, *dst; | |
struct stat statbuf; | |
if (argc != 3) | |
err_quit("Использование: %s <fromfile><tofile>", argv[0]); | |
if ((fdin = open(argv[1], O_RDONLY)) < 0) | |
err_sys("невозможно открыть %s для чтения", argv[1]); | |
if ((fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, FILE_MODE))<0) | |
err_sys("невозможно создать %s для записи", argv[2]); | |
if ( fstat(fdin, &statbuf) < 0) | |
err_sys("fstat error"); | |
if ( lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1 ) | |
err_sys("ошибка вызова функци lseek"); | |
if ( write(fdout, "", 1 ) != 1 ) | |
err_sys("ошибка вызова функции write"); | |
if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0)) == MAP_FAILED) | |
err_sys("ошибка вызова функции mmap для входного файла"); | |
if ((dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0)) == MAP_FAILED) | |
err_sys("ошибка вызова функции mmap для выходного файла"); | |
memcpy(dst, src, statbuf.st_size); | |
exit(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment