protocol: learn to describe fd passing in messages

Add a new type, "unix_fd", used to describe file descriptor sharing via
socket ancillary data (these messages are local only).

The marshaller/demarshaller can't serialize this in memory (consume_fd
implementation is empty), so it is the responsability of the marshaller
user to handle sending and receiving the handles, which are appended at
the end of the message with an extra stream byte (because some Unix
requires sending at least a byte with ancillary data).

Even if there is no fd to send (or if the fd is invalid etc), the
receiver side expects an extra byte anyway.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
Marc-Andre Lureau 2015-12-22 16:08:08 +01:00 committed by Frediano Ziglio
parent 6b86c1a510
commit 267391c8fd
3 changed files with 15 additions and 1 deletions

View File

@ -72,6 +72,10 @@ def write_parser_helpers(writer):
writer.statement("return val")
writer.end_block()
writer.function("SPICE_GNUC_UNUSED consume_fd", "int", "uint8_t **ptr", True)
writer.statement("return -1")
writer.end_block()
writer.newline()
writer.statement("typedef struct PointerInfo PointerInfo")
writer.statement("typedef void (*message_destructor_t)(uint8_t *message)")

View File

@ -1119,6 +1119,14 @@ class ProtocolType(Type):
return self
class FdType(IntegerType):
def primitive_type(self):
return "fd"
def c_type(self):
return "int"
int8 = IntegerType(8, True)
uint8 = IntegerType(8, False)
int16 = IntegerType(16, True)
@ -1127,3 +1135,4 @@ int32 = IntegerType(32, True)
uint32 = IntegerType(32, False)
int64 = IntegerType(64, True)
uint64 = IntegerType(64, False)
unix_fd = FdType(1, True)

View File

@ -56,6 +56,7 @@ def SPICE_BNF():
uint32_ = Keyword("uint32").setParseAction(replaceWith(ptypes.uint32))
int64_ = Keyword("int64").setParseAction(replaceWith(ptypes.int64))
uint64_ = Keyword("uint64").setParseAction(replaceWith(ptypes.uint64))
unix_fd_ = Keyword("unix_fd").setParseAction(replaceWith(ptypes.unix_fd))
# keywords
enum32_ = Keyword("enum32").setParseAction(replaceWith(32))
@ -108,7 +109,7 @@ def SPICE_BNF():
# have to use longest match for type, in case a user-defined type name starts with a keyword type, like "channel_type"
typeSpec << ( structSpec ^ int8_ ^ uint8_ ^ int16_ ^ uint16_ ^
int32_ ^ uint32_ ^ int64_ ^ uint64_ ^
int32_ ^ uint32_ ^ int64_ ^ uint64_ ^ unix_fd_ ^
typename).setName("type")
flagsBody = enumBody = Group(lbrace + delimitedList(Group (enumname + Optional(equals + integer))) + Optional(comma) + rbrace)