1717 along with this program. If not, see <http://www.gnu.org/licenses/>.
1818 */
1919
20+ //! This module implements a wrapper around an arbitrary executable.
21+ //!
22+ //! The wrapper is used to intercept the execution of the executable and
23+ //! report it to a remote server. The wrapper is named after the executable
24+ //! via a soft link (or a hard copy on platforms where soft links are not
25+ //! supported). The wrapper process is called instead of the original executable.
26+ //! This is arranged by the process that supervise the build process.
27+ //! The build supervisor creates a directory with soft links and place
28+ //! that directory at the beginning of the PATH variable. Which guarantees
29+ //! that the wrapper is called instead of the original executable.
30+ //!
31+ //! The wrapper reads the PATH variable and finds the next executable with
32+ //! the same name as the wrapper. It reports the execution of the real
33+ //! executable and then calls the real executable with the same arguments.
34+
2035extern crate core;
2136
2237use anyhow:: { Context , Result } ;
2338use intercept:: reporter:: { Reporter , TcpReporter } ;
2439use intercept:: KEY_DESTINATION ;
2540use std:: path:: { Path , PathBuf } ;
2641
42+ /// Implementation of the wrapper process.
43+ ///
44+ /// The process exit code is the same as the executed process exit code.
45+ /// Besides the functionality described in the module documentation, the
46+ /// wrapper process logs the execution and the relevant steps leading to
47+ /// the execution.
2748fn main ( ) -> Result < ( ) > {
2849 env_logger:: init ( ) ;
2950 // Find out what is the executable name the execution was started with
@@ -33,18 +54,19 @@ fn main() -> Result<()> {
3354 let real_executable = next_in_path ( & executable) ?;
3455 log:: info!( "Executable to call: {:?}" , real_executable) ;
3556
36- // Report the execution with the real executable
57+ // Reporting failures shall not fail the execution.
3758 match into_execution ( & real_executable) . and_then ( report) {
3859 Ok ( _) => log:: info!( "Execution reported" ) ,
3960 Err ( e) => log:: error!( "Execution reporting failed: {}" , e) ,
4061 }
4162
4263 // Execute the real executable with the same arguments
64+ // TODO: handle signals and forward them to the child process.
4365 let status = std:: process:: Command :: new ( real_executable)
4466 . args ( std:: env:: args ( ) . skip ( 1 ) )
4567 . status ( ) ?;
4668 log:: info!( "Execution finished with status: {:?}" , status) ;
47- // Return the status code
69+ // Return the child process status code
4870 std:: process:: exit ( status. code ( ) . unwrap_or ( 1 ) ) ;
4971}
5072
@@ -75,7 +97,8 @@ fn next_in_path(target: &Path) -> Result<PathBuf> {
7597
7698 path. split ( ':' )
7799 . map ( |dir| Path :: new ( dir) . join ( target) )
78- . filter ( |path| path. is_file ( ) ) // TODO: check if it is executable
100+ // FIXME: check if it is executable
101+ . filter ( |path| path. is_file ( ) )
79102 . filter ( |path| {
80103 // We need to compare it with the real path of the candidate executable to avoid
81104 // calling the same executable again.
@@ -111,6 +134,7 @@ fn into_execution(path_buf: &Path) -> Result<intercept::Execution> {
111134 . with_context ( || "Cannot get current directory" )
112135 . map ( |working_dir| intercept:: Execution {
113136 executable : path_buf. to_path_buf ( ) ,
137+ // FIXME: substitute the executable name on the first position
114138 arguments : std:: env:: args ( ) . collect ( ) ,
115139 working_dir,
116140 environment : std:: env:: vars ( ) . collect ( ) ,
0 commit comments