Различать /сравнивать два файла по дескриптору файла (fd) вместо имени файла

Есть ли способ в Linux, используя c , чтобы создать diff /patch двух файлов, хранящихся в памяти, используя общий формат (то есть: унифицированный diff, как с командной строкой ---- +: = 0 =: +---- утилита)?показать вопросы с тегом "c"Я работаю в системе, в которой я генерирую два текстовых файла в памяти, а внешнее хранилище недоступно или не требуется.Мне нужно создать построчную разность двух файлов, и, поскольку они ---- +: = 1 =: + ---- 'ed, у них нет имен файлов, что мешает мне простозвонить ---- +: = 2 =: + ---- .У меня есть файловые дескрипторы ( ---- +: = 3 =: + ---- s), доступные для использования, и это моя единственная точка входа в данные.Есть ли способ сгенерировать diff /patch, сравнив два открытых файла?Если реализация лицензирована по MIT /BSD (т.е. не-GPL), тем лучше.Спасибо.
4 голоса | спросил DevNull 21 FebruaryEurope/MoscowbTue, 21 Feb 2017 23:35:46 +0300000000pmTue, 21 Feb 2017 23:35:46 +030017 2017, 23:35:46

2 ответа


0
Принимая во внимание требования, наилучшим вариантом будет реализация собственной памяти в памяти ---- +: = 0 =: + ---- .Возможно, вы могли бы адаптировать соответствующие части OpenBSD ---- +: = 1 =: + ---- к вашим потребностям.Вот схема того, как вы можете использовать команду ---- +: = 2 =: + ---- через каналы для получения унифицированной разницы между двумя строками, хранящимися в памяти:Создайте три трубы: I1 , I2 и O.Форк дочерний процесс.В дочернем процессе:Переместите концы чтения каналов I1 и I2 в дескрипторы 3 и 4, а конец записи канала O в дескриптор 1.Закройте другие концы этих каналов в дочернем процессе.Откройте дескриптор 0 для чтения из /dev /null и дескриптор 2 для записи в /dev /null.Выполнить ---- +: = 3 =: + ----Это выполняет двоичный файл ---- +: = 4 =: + ---- в дочернем процессе.Он будет читать входные данные от двух каналов, I1 и I2 , и выводить различия в канал O.Родительский процесс закрывает концы чтения каналов I1 и I2 и конец записи O- канала.Родительский процесс записывает данные сравнения на концах записи каналов I1 и I2 и считывает различия с конца чтения O- канала.Обратите внимание, что родительский процесс должен использовать ---- +: = 5 =: + ---- или ---- +: = 6 =: + ---- или аналогичный метод (желательно с неблокирующими дескрипторами), чтобы избежатьтупиковый.(Взаимная блокировка возникает, если родительский и дочерний элементы пытаются читать одновременно или писать одновременно.) Как правило, родительский процесс должен избегать блокировок любой ценой, поскольку это может привести к тупиковой ситуации.Когда входные данные полностью записаны, родительский процесс должен закрыть соответствующий конец записи канала, чтобы дочерний процесс обнаружил конец ввода.(Если не происходит ошибка, конец записи должен быть закрыт до того, как дочерний процесс закроет свой конец O- канала.)Когда родительский процесс замечает, что в O- канале больше нет данных ( ---- +: = 7 =: + ---- возвращение ---- +: = 8 =: + ---- ), либоон уже закрыл концы записи каналов I1 и I2 , или произошла ошибка.Если ошибки нет, передача данных завершена, и дочерний процесс может быть запущен.Родительский процесс пожинает дочерний процесс, используя, например, ---- +: = 9 =: + ---- .Обратите внимание, что если были какие-либо различия, ---- +: = 10 =: + ---- возвращается со статусом выхода 1.Вы можете использовать четвертый канал для получения стандартного потока ошибок от дочернего процесса;---- +: = 11 =: + ---- обычно ничего не выводит со стандартной ошибкой.Вы можете использовать пятый канал с записью конца, отмеченного ---- +: = 12 =: + ---- с ---- +: = 13 =: + ---- в дочернем элементе, чтобы обнаружить ---- +: = 14 =: + ---- ошибки.---- +: = 15 =: + ---- флаг означает, что дескриптор закрывается при выполнении другого двоичного файла, поэтому родительский процесс может обнаружить успешный запуск ---- +: = 16 =: + ---- команда путем обнаружения конца данных в конце чтения ( ---- +: = 17 =: + ---- возвращение ---- +: = 18 =: + ---- ).Если ---- +: = 19 =: + ---- не удается, дочерний элемент может, например, записать значение ---- +: = 20 =: + ---- (как десятичное число или как---- +: = 21 =: + ---- ) в этот канал, чтобы родительский процесс мог прочитать точную причину сбоя.В целом, полный метод (который записывает стандартную ошибку, иобнаруживает ошибки exec) использует 10 дескрипторов.Это не должно быть проблемой в обычном приложении, но может быть важным - например, рассмотрим сервер с выходом в Интернет с дескрипторами, используемыми входящими соединениями.
ответил Nominal Animal 22 FebruaryEurope/MoscowbWed, 22 Feb 2017 03:53:25 +0300000000amWed, 22 Feb 2017 03:53:25 +030017 2017, 03:53:25
0
В Linux вы можете использовать псевдо-файловую систему /dev /fd /(символическая ссылка на /proc /self /fd).Используйте snprintf () для создания пути для обоих файловых дескрипторов, таких как ---- +: = 0 =: + ---- ditto для fd2, и запустите diff для них.
ответил Ricardo Branco 22 FebruaryEurope/MoscowbWed, 22 Feb 2017 01:21:32 +0300000000amWed, 22 Feb 2017 01:21:32 +030017 2017, 01:21:32

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132