X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=afs.c;h=710670255b2ec1cf67b9ab4e74823bfe19dd3a02;hb=d440a71683940a58747de6dc32643db452d9cf54;hp=031a00993ffec086a1fe447fb6d4f1bc528234fd;hpb=9a7ca3036b86989d385a094c4d616af3fb8a566b;p=paraslash.git diff --git a/afs.c b/afs.c index 031a0099..71067025 100644 --- a/afs.c +++ b/afs.c @@ -90,26 +90,26 @@ static char *current_mop; /* mode or playlist specifier. NULL means dummy mood * extern uint32_t afs_socket_cookie; /** - * Struct to let command handlers execute a callback in afs context. + * Passed from command handlers to afs. * - * Commands that need to change the state of afs can't change the relevant data - * structures directly because commands are executed in a child process, i.e. - * they get their own virtual address space. + * Command handlers cannot change the afs database directly because they run in + * a separate process. The callback query structure circumvents this + * restriction as follows. To instruct the afs process to execute a particular + * function, the command hander writes an instance of this structure to a + * shared memory area, along with the arguments to the callback function. The + * identifier of the shared memory area is transferred to the afs process via + * the command socket. * - * This structure is used by \p send_callback_request() (executed from handler - * context) in order to let the afs process call the specified function. An - * instance of that structure is written to a shared memory area together with - * the arguments to the callback function. The identifier of the shared memory - * area is written to the command socket. + * The afs process reads the shared memory id from the command socket, attaches + * the corresponding area, and calls the callback function whose address is + * stored in the area. * - * The afs process accepts connections on the command socket and reads the - * shared memory id, attaches the corresponding area, calls the given handler to - * perform the desired action and to optionally compute a result. - * - * The result and a \p callback_result structure is then written to another - * shared memory area. The identifier for that area is written to the handler's - * command socket, so that the handler process can read the id, attach the - * shared memory area and use the result. + * The command output, if any, is transferred back to the command handler in + * the same way: The afs process writes the output to a second shared memory + * area together with a fixed size metadata header whose format corresponds to + * the \ref callback_result structure. The identifier of this area is sent back + * to the command handler which attaches the area and forwards the output to + * the remote client. * * \sa \ref struct callback_result. */ @@ -481,6 +481,12 @@ static int activate_mood_or_playlist(const char *arg, int *num_admissible, if (num_admissible) *num_admissible = ret; current_play_mode = mode; + /* + * We get called with arg == current_mop from the signal dispatcher + * after SIGHUP and from the error path of the select command to + * re-select the current mood or playlist. In this case the assignment + * to current_mop below would result in a use-after-free condition. + */ if (arg != current_mop) { free(current_mop); if (arg) {