I have written a Hurd translator and a client in an attempt to understand the Hurd system. The full source is in this repo on github, and I will quote the salient parts here. My message format is described in a mig
interface definition:
routine machoo_msg_send(
receiver: mach_port_t; /* request port */
selector: machoo_selector; /* message selector */
out response: mach_port_send_t /* result */
);
The goal is that a translator should do the method requested in the selector, then fill in response
with a port that represents the 'object' resulting from the method.
I'm following two examples to try to set this up: an example on gnu.org and the password server from the Hurd itself. My server provides the message implementation:
kern_return_t machoo_msg_send(
mach_port_t receiver,
machoo_selector selector,
mach_port_t *response)
{
// for the moment, prove that we're receiving the message
fprintf(stderr, "[%d %s]\n", receiver, selector);
// return self
if (response != NULL)
{
*response = receiver;
}
return ERR_SUCCESS;
}
and also uses the trivfs
library to handle port operations.
My client looks up the port on the filesystem and sends it the message:
int main(int argc, char *argv[])
{
mach_port_t null_object;
mach_port_t returned_object;
kern_return_t retVal;
null_object = file_name_lookup("/tmp/null", 0, 0);
printf("null object port: %u\n", null_object);
retVal = machoo_msg_send(null_object, "doNothing", &returned_object);
if (retVal != 0) {
fprintf(stderr, "error sending message: %d\n", retVal);
exit(-1);
}
printf("returned object from [%u doNothing]: %u\n", null_object, returned_object);
return 0;
}
What I see is:
file_name_lookup
MIG_TYPE_ERROR
in response.As the types match on both sides of the interaction (the routine generation from MIG is used in both the server and the client) I would not expect a type error. Why is that error generated and what do I do to address it?
If I change the 'out' parameter type from mach_port_t
or mach_port_send_t
to int
, then my message is correctly sent, demuxed, acted on, and received. However, this fails to meet my goal, which is to have a translator reply to a message with a port, on which the client could send another message.
The type error arose because the mach_port_send_t
type is polymorphic on the server side. The server handler for the routine gets an extra parameter, resultPoly
, used to express how the send right is transferred to the client.
This parameter does not appear in the (shared) header that declares the routine, because the client does not receive that parameter; it just receives a mach_port_t
. Do not include the header in your server code, instead declare the handler (with its additional argument) yourself.