diff options
Diffstat (limited to '')
-rw-r--r-- | doc/info/mds.texinfo | 290 | ||||
-rw-r--r-- | src/mds-base.c | 4 | ||||
-rw-r--r-- | src/mds-base.h | 12 |
3 files changed, 278 insertions, 28 deletions
diff --git a/doc/info/mds.texinfo b/doc/info/mds.texinfo index a913687..0f73c7e 100644 --- a/doc/info/mds.texinfo +++ b/doc/info/mds.texinfo @@ -55,6 +55,7 @@ Texts. A copy of the license is included in the section entitled * Architecture:: Architectural overview of @command{mds}. * Protocol:: The @command{mds} procotol. * libmdsserver:: Overview of @command{libmdsserver}. +* mds-base:: Overview of @command{mds-base}. * GNU Free Documentation License:: Copying and sharing this manual. @end menu @@ -1293,16 +1294,16 @@ specifically, since it is doubly linked@footnote{And not using XOR-linking.}, it is implemented using three arrays: -@table @code -@item size_t* values +@table @asis +@item @code{values} [@code{size_t*}] The value stored in each node. -@item ssize_t* next +@item @code{next} [@code{ssize_t*}] The next node for each node, @code{edge} if the current node is the last node, and @code{LINKED_LIST_UNUSED} if there is no node on this position. -@item ssize_t* previous +@item @code{previous} [@code{ssize_t*}] The previous node for each node, @code{edge} if the current node is the first node, and @code{LINKED_LIST_UNUSED} if there is no node on this position. @@ -1585,12 +1586,12 @@ arguments. The data type for @code{value_comparator} is @code{hash_table_t} also contains two other variables: -@table @code -@item compare_func* key_comparator +@table @asis +@item @code{key_comparator} [@code{compare_func*}] Identical to @code{value_comparator}, except it is used for keys rather the values. -@item hash_func* hasher +@item @code{hasher} [@code{hash_func*}] By default, the hash value for key is identical to the key itself. However, if this variable is not @code{NULL}, it will be used to calculate the hash value for keys. @@ -1601,14 +1602,14 @@ There is a secondary data structure defined for hash tables: It is the data structure used for entries in a hash table. @code{hash_entry_t} contain three variables you may be interested in: -@table @code -@item size_t key +@table @asis +@item @code{key} [@code{size_t}] The key. -@item size_t value +@item @code{value} [@code{size_t}] The value associated with the key. -@item size_t hash +@item @code{hash} [@code{size_t}] The hash value of the key. @end table @@ -1662,8 +1663,8 @@ These functions are defined as pure and @code{static inline}. Apart from internal data @code{mds_message_t} contains four variables: -@table @code -@item char** headers +@table @asis +@item @code{headers} [@code{char**}] The headers in the message, each element in this list as an unparsed header, it consists of both the header name and its associated value, joined by `: '. A header @@ -1672,14 +1673,14 @@ but @code{headers} itself is @code{NULL} if there are no headers. The `Length' header should be included in this list. -@item size_t header_count +@item @code{header_count} [@code{size_t}] The number of headers in the message. -@item char* payload +@item @code{payload} [@code{char*}] The payload of the message, @code{NULL} if none (of zero-length). -@item size_t payload_size +@item @code{payload_size} [@code{size_t}] The length of the message's payload. This value will be the same as the value of the `Length' header. @@ -1731,6 +1732,263 @@ in the display server message passing system. +@node mds-base +@chapter @file{mds-base} + +@file{mds-base.c} and @file{mds-base.h} as an object +filepair whose purpose is similar to libmdsserver. +@file{mds-base} is compiled into all @command{mds} +servers and implements common procedures including +@code{main}. It also complements procedures that are +weakly defined, that is, if the server implementation +also defines them, the server implementations procedure +replaces @file{mds-base}'s implementation at +compile-time. + +@file{mds-base} defines one function that you can +call from threads you create and functions that should +be implement depending on specified conditions: + +@table @asis +@item @code{trap_signals} [(@code{void}) @arrow{} @code{int}] +Set up signal traps for all especially handled signals. +Returns zero on and only on success. +@end table + +@file{mds-base} weakly defines functions that you can +replace if they do not suit your needs: + +@table @asis +@item @code{parse_cmdline} [(@code{void}) @arrow{} @code{int}] +Parses command line arguments. +Returns zero on and only on success. + +This function will parse the following options: + +@table @option +@item --initial-spawn +It is the first time the server is spawn by its +spawner process. + +@item --respawn +The server was respawned. + +@item --re-exec +The server is re-executing. + +@item --alarm=SECONDS +Kill the process after @var{SECONDS} seconds. +At most one minute. + +@item --on-init-fork +Fork the process to detach it from its parent when +the server has been initialised. + +@item --on-init-sh=COMMAND +When the server has been initialised, run the +command @var{COMMAND}. + +@item --immortal +The server should to its best not to die. For example +do not die if @code{SIGDANGER} is received even if that +is the server's default action. +@end table + +@item @code{connect_to_display} [(@code{void}) @arrow{} @code{int}] +Connects to the display. +Returns zero on and only on success. + +@item @code{server_initialised} [(@code{void}) @arrow{} @code{int}] +This function should be called when the server has +been properly initialised but before initialisation +of anything that is removed at forking is initialised. +Returns zero on and only on success. + +@item @code{signal_all} [(@code{int signo}) @arrow{} @code{void}] +This function should be implemented by the actual server +implementation if the server is multi-threaded. It sends +the singal @code{signo} to all threads except the current +thread. + +@item @code{received_reexec} [(@code{int signo}) @arrow{} @code{void}] +This function is called when a signal that signals the +server to re-execute has been received. The exact +received signal is specified by the parameter @code{signo}. +When this function is invoked, it should set the variables +@code{reexecing} and @code{terminating} to a non-zero value. + +@item @code{received_terminate} [(@code{int signo}) @arrow{} @code{void}] +This function is called when a signal that signals the +server to terminate has been received. The exact received +signal is specified by the parameter @code{signo}. When +this function is invoked, it should set the variable +@code{terminating} to a non-zero value. + +@item @code{fork_cleanup} [(@code{int status}) @arrow{} @code{void}] +This function should be implemented by the actual server +implementation if the server has set +@code{server_characteristics.fork_for_safety} to be a +non-zero value. This function is called by the parent server +process when the child server process exits, if the server +has completed its initialisation. The parameter @code{status} +specifies the child process exit status as returned by +@code{waitpid}. +@end table + +Additionally, @file{mds-base} expects the server implementation +to define and implement a set of functions: + +@table @asis +@item @code{preinitialise_server} [(@code{void}) @arrow{} @code{int}] +This function will be invoked before @code{initialise_server} +(if not re-executing) or before @code{unmarshal_server} +(if not re-executing). Returns zero on and only on success. + +@item @code{initialise_server} [(@code{void}) @arrow{} @code{int}] +This function should initialise the server. It not invoked +after a re-execution. Returns zero on and only on success. + +@item @code{postinitialise_server} [(@code{void}) @arrow{} @code{int}] +This function will be invoked after @code{initialise_server} +(if not re-executing) or after @code{unmarshal_server} (if +re-executing). Returns zero on and only on success. + +@item @code{marshal_server_size} [(@code{void}) @arrow{} @code{size_t}, pure] +Calculate and returns the number of bytes that will be stored +by @code{marshal_server}. On failure the server should call +@code{abort} or exit with failure status by other means. +However it should not be possible for this function to fail. +@code{marshal_server_size} must be pure.@footnote{That is, +define with and conforming to @code{__attribute__((pure))}}. + +@item @code{marshal_server} [(@code{char* state_buf}) @arrow{} @code{int}] +Marshal server implementation specific data into the buffer +@code{state_buf}. Returns zero on and only on success. + +@item @code{unmarshal_server} [(@code{char* state_buf}) @arrow{} @code{int}] +Unmarshal server implementation specific data from the +buffer @code{state_buf} and update the servers state +accordingly. Returns zero on and only on success. + +On critical failure the program should call @code{abort} +or exit with failure status by other means. That is, do not +let @code{reexec_failure_recover} run successfully, if it +unrecoverable error has occurred or one severe enough that +it is better to simply respawn. + +@item @code{reexec_failure_recover} [(@code{void}) @arrow{} @code{int}] +Attempt to recover from a re-execution failure that has been +detected after the server successfully updated it execution +image. Returns zero on and only on success. + +@item @code{master_loop} [(@code{void}) @arrow{} @code{int}] +Perform the server's mission. Returns zero on and only on success. +@end table + +@file{mds-base} also defines a number of global variables. + +@table @asis +@item @code{argc} [@code{int}] +Number of elements in @code{argv}. + +@item @code{argv} [@code{char**}] +Command line arguments. + +@item @code{is_respawn} [@code{int}] +Whether the server has been respawn rather than this +being the initial spawn. This will be at least as true +as @code{is_reexec}. + +@item @code{is_reexec} [@code{int}] +Whether the server is continuing from a self-reexecution. + +@item @code{is_immortal} [@code{int}] +Whether the server should do its best to resist event +triggered death. + +@item @code{on_init_fork} [@code{int}] +Whether to fork the process when the server has been +properly initialised. + +@item @code{on_init_sh} [@code{char*}] +Command the run (@code{NULL} for none) when the server +has been properly initialised. + +@item @code{master_thread} [@code{pthread_t}] +The thread that runs the master loop. + +@item @code{terminating} [@code{volatile sig_atomic_t}] +Whether the server has been signaled to terminate. + +@item @code{reexecing} [@code{volatile sig_atomic_t}] +Whether the server has been signaled to re-execute. + +@item @code{socket_fd} [@code{int}] +The file descriptor of the socket that is connected +to the server. +@end table + +@file{mds-base} expects the server implementation to define +a variable that specifies how @file{mds-base} should behave: + +@table @asis +@item @code{server_characteristics} [@code{server_characteristics_t}] +This variable should declared by the actual server +implementation. It must be configured before @code{main} +is invoked. That is, it should be configured by a +constructor. If it is configured at its definition, +it is configured by a constructor; that is normally +how you want to configured it. +@end table + +@code{server_characteristics_t} @{also known as +@code{struct server_characteristics}@} is a packed +@footnote{That is, define with @code{__attribute__((packed))}} +with the following fields: + +@table @asis +@item @code{require_privileges} [@code{unsigned : 1}] +Setting this to zero will cause the server to drop +privileges as a security precaution. + +@item @code{require_display} [@code{unsigned : 1}] +Setting this to non-zero will cause the server to connect +to the display. + +@item @code{require_respawn_info} [@code{unsigned : 1}] +Setting this to non-zero will cause the server to refuse +to start unless either @option{--initial-spawn} or +@option{--respawn} is used. + +@item @code{sanity_check_argc} [@code{unsigned : 1}] +Setting this to non-zero will cause the server to refuse to +start if there are too many command line arguments. + +@item @code{fork_for_safety} [@code{unsigned : 1}] +Setting this to non-zero will cause the server to place +itself in a fork of itself when initialised. This can be +used to let the server clean up fatal stuff after itself +if it crashes. When the child exits, no matter how it +exits, the parent will call @code{fork_cleanup} and then +die it the same manner as the child. + +@item @code{danger_is_deadly} [@code{unsigned : 1}] +Setting this to non-zero without setting a signal action +for @code{SIGDANGER} will cause the server to die if +@code{SIGDANGER} is received. It is safe to set both +@code{danger_is_deadly} and @code{fork_for_safety} to +non-zero, during the call of @code{server_initialised} +the signal handler for @code{SIGDANGER} in the parent +process will be set to @code{SIG_IGN} independently of +the value of @code{danger_is_deadly} if +@code{fork_for_safety} is set to non-zero. + +This setting will be treated as set to zero if +@option{--immortal} is used. +@end table + + + @node GNU Free Documentation License @appendix GNU Free Documentation License @include fdl.texinfo diff --git a/src/mds-base.c b/src/mds-base.c index f676e66..4584670 100644 --- a/src/mds-base.c +++ b/src/mds-base.c @@ -281,7 +281,7 @@ int __attribute__((weak)) server_initialised(void) * * @param signo The signal that has been received */ -void received_noop(int signo) +static void __attribute__((const)) received_noop(int signo) { (void) signo; } @@ -327,7 +327,7 @@ void __attribute__((weak)) received_reexec(int signo) /** * This function is called when a signal that - * signals the server to re-exec has been received + * signals the server to terminate has been received * * When this function is invoked, it should set `terminating` to a non-zero value * diff --git a/src/mds-base.h b/src/mds-base.h index 89231bf..1ea132a 100644 --- a/src/mds-base.h +++ b/src/mds-base.h @@ -192,14 +192,6 @@ int server_initialised(void); /* __attribute__((weak)) */ /** - * This function is called when an intraprocess signal - * that used to send a notification to a thread - * - * @param signo The signal that has been received - */ -void received_noop(int signo) __attribute__((weak, const)); - -/** * This function should be implemented by the actual server implementation * if the server is multi-threaded * @@ -207,7 +199,7 @@ void received_noop(int signo) __attribute__((weak, const)); * * @param signo The signal */ -void signal_all(int signo) __attribute__((weak)); +void signal_all(int signo); /* __attribute__((weak)) */ /** * This function is called when a signal that @@ -222,7 +214,7 @@ void received_reexec(int signo); /* __attribute__((weak)) */ /** * This function is called when a signal that - * signals the server to re-exec has been received + * signals the server to terminate has been received * * When this function is invoked, it should set `terminating` to a non-zero value * |