Skip to content

Instantly share code, notes, and snippets.

@bDrwx
Created January 14, 2019 18:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bDrwx/45358425c05f3e891a0662ddd9e8d034 to your computer and use it in GitHub Desktop.
Save bDrwx/45358425c05f3e891a0662ddd9e8d034 to your computer and use it in GitHub Desktop.
memory-mapped files
#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