# HG changeset patch # User Rob Landley # Date 1376853899 18000 # Node ID 27275d0d97e9933e9569e1377dd289c1cac4a619 # Parent 9c22b351d5016ca1ee720a78e1e3b09cef1ff7e2 Document the toybox entry path from main() into a command. diff -r 9c22b351d501 -r 27275d0d97e9 www/code.html --- a/www/code.html Sun Aug 18 14:04:18 2013 -0500 +++ b/www/code.html Sun Aug 18 14:24:59 2013 -0500 @@ -1,6 +1,6 @@ -

Code style

+

Code style

The primary goal of toybox is _simple_ code. Keeping the code small is second, with speed and lots of features coming in somewhere after that. @@ -23,7 +23,7 @@ block structure of the file. Putting them at the left edge makes them easy to spot as overrides to the normal flow of control, which they are.

-

Building Toybox:

+

Building Toybox

Toybox is configured using the Kconfig language pioneered by the Linux kernel, and adopted by many other projects (uClibc, OpenEmbedded, etc). @@ -55,7 +55,53 @@

(To clarify: "configure" describes the build and installation environment, ".config" lists the features selected by defconfig/menuconfig.)

-

Infrastructure:

+

Running a command

+ +

main

+ +

The toybox main() function is at the end of main.c at the top level. It has +two possible codepaths, only one of which is configured into any given build +of toybox.

+ +

If CONFIG_SINGLE is selected, toybox is configured to contain only a single +command, so most of the normal setup can be skipped. In this case the +multiplexer isn't used, instead main() calls toy_singleinit() (also in main.c) +to set up global state and parse command line arguments, calls the command's +main function out of toy_list (in the CONFIG_SINGLE case the array has a single entry, no need to search), and if the function returns instead of exiting +it flushes stdout (detecting error) and returns toys.exitval.

+ +

When CONFIG_SINGLE is not selected, main() uses basename() to find the +name it was run as, shifts its argument list one to the right so it lines up +with where the multiplexer function expects it, and calls toybox_main(). This +leverages the multiplexer command's infrastructure to find and run the +appropriate command. (A command name starting with "toybox" will +recursively call toybox_main(); you can go "./toybox toybox toybox toybox ls" +if you want to...)

+ +

toybox_main

+ +

The toybox_main() function is also in main,c. It handles a possible +--help option ("toybox --help ls"), prints the list of available commands if no +arguments were provided to the multiplexer (or with full path names if any +other option is provided before a command name, ala "toybox --list"). +Otherwise it calls toy_exec() on its argument list.

+ +

Note that the multiplexer is the first entry in toy_list (the rest of the +list is sorted alphabetically to allow binary search), so toybox_main can +cheat and just grab the first entry to quickly set up its context without +searching. Since all command names go through the multiplexer at least once +in the non-TOYBOX_SINGLE case, this avoids a redundant search of +the list.

+ +

The toy_exec() function is also in main.c. It performs toy_find() to +perform a binary search on the toy_list array to look up the command's +entry by name and saves it in the global variable which, calls toy_init() +to parse command line arguments and set up global state (using which->options), +and calls the appropriate command's main() function (which->toy_main). On +return it flushes all pending ansi FILE * I/O, detects if stdout had an +error, and then calls xexit() (which uses toys.exitval).

+ +

Infrastructure

The toybox source code is in following directories: