reparsed
door_return or else...
The reparsed_door_call_error function is decorated with __NORETURN:
__NORETURN static void
reparsed_door_call_error(int error, int buflen)
{
reparsed_door_res_t rpd_res;
memset(&rpd_res, 0, sizeof (reparsed_door_res_t));
rpd_res.res_status = error;
rpd_res.res_len = buflen;
(void) door_return((char *)&rpd_res,
sizeof (reparsed_door_res_t), NULL, 0);
(void) door_return(NULL, 0, NULL, 0);
abort();
}
Why do we try so hard to recover from door_return, even when it is passing
nothing? Also, why are the calls being cast to void?
This is interesting, because it a single server thread fails to call
door_return, then abort(3C) will
stop the entire process.
Unusual payload
The payload to the reparsed_doorfunc server procedure has an unusual format:
it is a string immediately followed by a struct. So the server procedure uses
strchr(3C) to find the end of the
"string" part (by treating ':' as a terminal character) and then the rest of the
buffer is assumed to be a reparsed_door_res_t structure. This is made apparent
by the DOOR_RESULT_BUFSZ macro:
#define DOOR_RESULT_BUFSZ (MAXPATHLEN + sizeof (reparsed_door_res_t))
Stack allocation
Again, the admonishment to use
alloca(3C) to allocate memory on the
stack rather than the heap so that we don't create leaks when returing to the
door client:
/*
* We cannot use malloc() here because door_return() never
* returns, and memory allocated by malloc() would get leaked.
*/
sbuf = alloca(bufsz + sizeof (reparsed_door_res_t));
Server Initialization
The start_reparsed_svcs function follows the usual pattern of:
- Create a door fd
- Create (if not exists) a door jamb with appropriate permissions
- Detach any stale doors from the jamb
- Attach the new door to the jamb (and then close the fd for the jamb file)
- Wait for incoming calls
This uses a common wait pattern:
/*
* Wait for incoming calls
*/
while (1)
(void) pause();
pause(2) suspends the process until it
is interrupted by a signal, but this loop effectively just discards that
interruption and goes back to the pause state. How does this compare to binding
the current thread to the door pool (via door_return)?