Проблемы использовать memcpy с mmap

Пытаясь скопировать файл, используя эти функции, все идет прекрасное, пока программа не поражает функцию memcpy, которая дает ошибку шины и заканчивает процесс.

void copy_mmap(char* in, char* out){

int input_fd, output_fd;

input_fd = open (in, O_RDONLY);
if (input_fd == -1) {
        printf("Error opening input file.\n");
        exit(2);
}

output_fd = open(out, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR);
if(output_fd == -1){
    printf("Error opening output file.\n");
    exit(3);
}

struct stat st;
fstat(input_fd, &st);

char* target;
target=mmap(0, st.st_size+1, PROT_READ, MAP_SHARED, input_fd, 0);
if (target==(void*) -1){
    printf("Error mapping target with errno: %d.\n", errno);
    exit(6);
}


char* destination;
destination=mmap(0, st.st_size+1, PROT_READ | PROT_WRITE, MAP_SHARED, output_fd, 0);
if (destination==(void*) -1){
    printf("Error mapping destination with errno: %d.\n", errno);
    exit(5);
}

memcpy(destination, target, st.st_size);
munmap(destination, st.st_size);



}

Был не в состоянии выяснить что не так, поскольку "Ошибка шины" не описательное сообщение об ошибке и нет никакого большого количества материала в Интернете относительно этой проблемы.

5
nl ja de

3 ответы

Когда вы создаете файл назначения как новый файл, его размер составляет 0 байтов. memcpy терпит крах, потому что это пытается написать данные вне конца файла.

Можно сделать эту работу, предварительно измерив файл назначения к размеру исходного файла (использующий ftruncate() ), прежде чем вы mmap() это.

Кроме того, необходимо пройти Св. st_size как второй аргумент, чтобы mmap , не st.st_size+1 . st.st_size+1 пытается нанести на карту диапазон, который больше, чем размер файла, который недействителен.

16
добавлено
Также, если вы чрезвычайно заботитесь о скорости и don' t возражают писать OS определенный код, вы могли использовать различное sendfile варианты, который существует на Unix (-как) операционные системы. Этот файл делает целую копию, работающую в ядерном космосе (никакие данные не копируются назад и вперед к пространству пользователя): linux.die.net/man/2/sendfilefreebsd.org/cgi/man.cgi?query=sendfile&sektion=2developer.apple.com/library/mac/documentation/Darwin/Referen‌​ce/…
добавлено автор panzi, источник
Обработанный как чудеса. Спасибо:)
добавлено автор cngkaygusuz, источник

Возможно, попытайтесь использовать memmove? Разве вы не читаете и пишете от той же самой памяти/файла/местоположения устройства? Мемкпи терпит неудачу в таких ситуациях.

0
добавлено
@KeithThompson я сомневаюсь относительно there' s любая память ассигновал через mmap, она только создает отображение к указанному месту. Они были теми же самыми файлами, я все еще полагаю, что memmove, возможно, помог.
добавлено автор Dariusz, источник
<у кода> memcpy() только есть проблемы (который может быть решен при помощи memmove() ), если исходные и целевые массивы накладываются. Так как источник и место назначения ассигнуются двумя отдельными успешными требованиями mmap() с нулевым указателем как первый аргумент, они can' t наложение.
добавлено автор Keith Thompson, источник
@DariuszWawer: Называете ли вы его распределением или нет, это делает ряд (виртуальных) адресов памяти доступным программе. Два диапазона, сделанные доступный двумя требованиями mmap() , не могут наложиться (если mmap() isn' t сломанный), таким образом, 'memmove() won' t помощь. Новые доказательства: OP попробовал его и это didn' t помощь, но Celada' s ответ работал.
добавлено автор Keith Thompson, источник
Нет. Все еще получение ошибки шины.
добавлено автор cngkaygusuz, источник

вы могли также lseek к off_t fileposition = lseek (output_fd, st.st_size-1, SEEK_SET) и писать пустой характер output_fd.

0
добавлено
Linux Help
Linux Help
2 686 участник(ов)

Правила: https://telegra.ph/Pravila-Linux-Help-10-15

Linux Security
Linux Security
652 участник(ов)

Данная группа принципиально про безопасность и в частности про безопасность Linux. Прочие темы просим обсуждать в профильных чатах.

Linux Gaming RUS
Linux Gaming RUS
28 участник(ов)

Русскоязычный чатик, посвящённый играм на различных дистрибутивах Linux, а также wine, proton Arch Linux RU @ArchLinuxChatRU Gnome RU @gnome_ru