Как recvmsg () управляет сообщениями в стеке буфера, не нарушая строгий псевдоним? - PullRequest
2 голосов
/ 17 марта 2019

При передаче файловых дескрипторов через доменные сокеты Unix используются управляющие сообщения на уровне SOL_SOCKET типа SCM_RIGHTS.

Управляющие сообщения читаются и записываются с использованием макросов CMSG_FIRSTHDR, CMSG_NXTHDR иCMSG_DATA.Они принимают во внимание вопросы выравнивания.В зависимости от операционной системы и реализации libc они приводят указатели и разыменовывают результат либо в том же, либо в другом модуле перевода.Они также возвращают такие указатели, и вызывающий код обычно разыменовывает их.

В результате, использование простого выделенного в стеке char buf[CMSG_SPACE(sizeof(int))] в качестве буфера управляющего сообщения нарушит строгое псевдонимы, так как доступ к буферу возможен только с использованиемЗначения типа char, signed char, unsigned char или их квалифицированные версии.(На некоторых платформах буфер также может быть неправильно выровнен, но соглашения о вызовах amd64, кажется, гарантируют это, потому что буфер достаточно большой.)

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

В https://svnweb.freebsd.org/base/head/lib/libopenbsd/imsg.c?revision=292023&view=markup Я нашел другой подход, когда буфер стека имеет тип union { struct cmsghdr hdr; char buf[CMSG_SPACE(sizeof(int))]; }, но я не знаю, так ли этоверно.Я думаю, это помогает, что struct cmsghdr имеет поле типа int.

Дополнительный вопрос: как сделать это в C ++, учитывая, что C ++ имеет другие правила относительно (среди прочего) объединений, чем C?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...