comparison www/code.html @ 256:20f1e3da0492

Partial update. Needs more work.
author Rob Landley <rob@landley.net>
date Tue, 12 Feb 2008 18:41:34 -0600
parents 4f1ca01db000
children f6ffc6685a9e
comparison
equal deleted inserted replaced
255:3fe66e630944 256:20f1e3da0492
12 nested loops. In general, a goto should only jump forward (not back), and 12 nested loops. In general, a goto should only jump forward (not back), and
13 should either jump to the end of an outer loop, or to error handling code 13 should either jump to the end of an outer loop, or to error handling code
14 at the end of the function. Goto labels are never indented: they override the 14 at the end of the function. Goto labels are never indented: they override the
15 block structure of the file. Putting them at the left edge makes them easy 15 block structure of the file. Putting them at the left edge makes them easy
16 to spot as overrides to the normal flow of control, which they are.</p> 16 to spot as overrides to the normal flow of control, which they are.</p>
17
18 <p>The primary goal of toybox is _simple_ code. Small is second,
19 speed and lots of features come in somewhere after that. Note that
20 environmental dependencies are a type of complexity, so needing other packages
21 to build or run is a downside. For example, don't use curses when you can
22 output ansi escape sequences instead.</p>
17 23
18 <p><h1>Infrastructure:</h1></p> 24 <p><h1>Infrastructure:</h1></p>
19 25
20 <p>The toybox source code is in following directories:</p> 26 <p>The toybox source code is in following directories:</p>
21 <ul> 27 <ul>
35 </ul> 41 </ul>
36 42
37 <p><h1>Adding a new command</h1></p> 43 <p><h1>Adding a new command</h1></p>
38 <p>To add a new command to toybox, add a C file implementing that command to 44 <p>To add a new command to toybox, add a C file implementing that command to
39 the toys directory. No other files need to be modified; the build extracts 45 the toys directory. No other files need to be modified; the build extracts
40 other information it needs (such as command line arguments) from specially 46 all the information it needs (such as command line arguments) from specially
41 formatted comments and macros in the C file. (See the description of the 47 formatted comments and macros in the C file. (See the description of the
42 <a href="#generated">generated directory</a> for details.)</p> 48 <a href="#generated">generated directory</a> for details.)</p>
43 49
44 <p>An easy way to start a new command is copy the file "hello.c" to 50 <p>An easy way to start a new command is copy the file "hello.c" to
45 the name of the new command, and modify this copy to implement the new command. 51 the name of the new command, and modify this copy to implement the new command.
46 This file is a small, simple command meant to be used as a "skeleton" for 52 This file is an example command meant to be used as a "skeleton" for
47 new commands (more or less by turning every instance of "hello" into the 53 new commands (more or less by turning every instance of "hello" into the
48 name of your command, updating the command line arguments, globals, and 54 name of your command, updating the command line arguments, globals, and
49 help data, and then filling out its "main" function with code that does 55 help data, and then filling out its "main" function with code that does
50 something interesting).</p> 56 something interesting). It provides examples of all the build infrastructure
57 (including optional elements like command line argument parsing and global
58 variables that a "hello world" program doesn't strictly need).</p>
51 59
52 <p>Here's a checklist of steps to turn hello.c into another command:</p> 60 <p>Here's a checklist of steps to turn hello.c into another command:</p>
53 61
54 <ul> 62 <ul>
55 <li><p>First "cd toys" and "cp hello.c yourcommand.c". Note that the name 63 <li><p>First "cd toys" and "cp hello.c yourcommand.c". Note that the name
67 whichever is appropriate.) The existing link goes to the directory of SUSv3 75 whichever is appropriate.) The existing link goes to the directory of SUSv3
68 command line utility standards on the Open Group's website, where there's often 76 command line utility standards on the Open Group's website, where there's often
69 a relevant commandname.html file. Feel free to link to other documentation or 77 a relevant commandname.html file. Feel free to link to other documentation or
70 standards as appropriate.</p></li> 78 standards as appropriate.</p></li>
71 79
72 <li><p>Update the USE_YOURCOMMAND(NEWTOY(yourcommand,NULL,0)) line. This 80 <li><p>Update the USE_YOURCOMMAND(NEWTOY(yourcommand,"blah",0)) line. The
73 specifies the name used to run your command, the command line arguments (NULL 81 arguments to newtoy are: 1) the name used to run your command, 2)
74 if none), and where your command should be installed on a running system. See 82 the command line arguments (NULL if none), and additional information such
75 [TODO] for details.</p></li> 83 as where your command should be installed on a running system. See [TODO] for
84 details.</p></li>
76 85
77 <li><p>Change the kconfig data (from "config YOURCOMMAND" to the end of the 86 <li><p>Change the kconfig data (from "config YOURCOMMAND" to the end of the
78 comment block) to supply your command's configuration and help 87 comment block) to supply your command's configuration and help
79 information. The uppper case config symbols are used by menuconfig, and are 88 information. The uppper case config symbols are used by menuconfig, and are
80 also what the CFG_ and USE_() macros are generated from (see [TODO]). The 89 also what the CFG_ and USE_() macros are generated from (see [TODO]). The
89 two-character command line arguments in NEWTOY(), the first few global 98 two-character command line arguments in NEWTOY(), the first few global
90 variables will be initialized by the automatic argument parsing logic, and 99 variables will be initialized by the automatic argument parsing logic, and
91 the type and order of these variables must correspond to the arguments 100 the type and order of these variables must correspond to the arguments
92 specified in NEWTOY(). See [TODO] for details.</p></li> 101 specified in NEWTOY(). See [TODO] for details.</p></li>
93 102
94 <li><p>Change the "#define TT this.hello" line to use your command name in 103 <li><p>If you didn't delete the DEFINE_GLOBALS macro, change the "#define TT
95 place of the "hello". This is a shortcut to access your global variables 104 this.hello" line to use your command name in place of the "hello". This is a
96 as if they were members of the global struct "TT". (Access these members with 105 shortcut to access your global variables as if they were members of the global
97 a period ".", not a right arrow "->".)</p></li> 106 struct "TT". (Access these members with a period ".", not a right arrow
107 "->".)</p></li>
98 108
99 <li><p>Rename hello_main() to yourcommand_main(). This is the main() function 109 <li><p>Rename hello_main() to yourcommand_main(). This is the main() function
100 where execution off your command starts. See [TODO] to figure out what 110 where execution of your command starts. See [TODO] to figure out what
101 happened to your command line arguments and how to access them.</p></li> 111 happened to your command line arguments and how to access them.</p></li>
102 </ul> 112 </ul>
103 113
104 <p><a name="top" /><h2>Top level directory.</h2></p> 114 <p><a name="top" /><h2>Top level directory.</h2></p>
105 115
106 <p>This directory contains global infrastructure. 116 <p>This directory contains global infrastructure.
107 117
108 <h3>main.c</h3> 118 <h3>main.c</h3>
109 <p>Contains the main() function where execution starts, plus 119 <p>Contains the main() function where execution starts, plus
110 common infrastructure to initialize global variables and select which command 120 common infrastructure to initialize global variables and select which command
111 to run. The "toybox" multiplexer command is also defined here. (This is the 121 to run. The "toybox" multiplexer command also lives here. (This is the
112 only command defined outside of the toys directory.)</p> 122 only command defined outside of the toys directory.)</p>
113 123
114 <p>Execution starts in main() which removes the path from the first command 124 <p>Execution starts in main() which trims any path off of the first command
115 name and calls toybox_main(), which calls toy_exec(), which calls toy_find(), 125 name and calls toybox_main(), which calls toy_exec(), which calls toy_find()
116 toy_init() and the appropriate command's function from toy_list. If 126 and toy_init() before calling the appropriate command's function from toy_list.
117 the command is "toybox", execution returns to toybox_main(), otherwise 127 If the command is "toybox", execution recurses into toybox_main(), otherwise
118 the call goes to the appropriate command_main() from the toys directory.</p> 128 the call goes to the appropriate commandname_main() from a C file in the toys
119 129 directory.</p>
120 <p>The following global variables are defined here:</p> 130
131 <p>The following global variables are defined in main.c:</p>
121 <ul> 132 <ul>
122 <li><p>struct toy_list <b>toy_list[]</b> - array describing all the 133 <li><p>struct toy_list <b>toy_list[]</b> - array describing all the
123 commands currently configured into toybox. The first entry (toy_list[0]) is 134 commands currently configured into toybox. The first entry (toy_list[0]) is
124 for the "toybox" multiplexer command, which runs all the other built-in commands 135 for the "toybox" multiplexer command, which runs all the other built-in commands
125 without symlinks by using its first argument as the name of the command to 136 without symlinks by using its first argument as the name of the command to
126 run and the rest as that command's argument list (ala "./toybox echo hello"). 137 run and the rest as that command's argument list (ala "./toybox echo hello").
127 The remaining entries are the commands in alphabetical order (for efficient 138 The remaining entries are the commands in alphabetical order (for efficient
128 binary search).</p> 139 binary search).</p>
129 140
130 <p>This is a read-only array initialized at compile time by 141 <p>This is a read-only array initialized at compile time by
131 defining macros and #including toys/toylist.h.</p> 142 defining macros and #including generated/newtoys.h.</p>
132 143
133 <p>Members of struct toy_list include:</p> 144 <p>Members of struct toy_list include:</p>
134 <ul> 145 <ul>
135 <li><p>char *<b>name</b> - the name of this command.</p></li> 146 <li><p>char *<b>name</b> - the name of this command.</p></li>
136 <li><p>void (*<b>toy_main</b>)(void) - function pointer to run this 147 <li><p>void (*<b>toy_main</b>)(void) - function pointer to run this
137 command.</p></li> 148 command.</p></li>
138 <li><p>char *<b>options</b> - command line option string (used by 149 <li><p>char *<b>options</b> - command line option string (used by
139 get_optflags() in lib/args.c to intialize toys.optflags, toys.optargs, and 150 get_optflags() in lib/args.c to intialize toys.optflags, toys.optargs, and
140 entries in the toy union). If this is NULL, no option parsing is done before 151 entries in the toy union). If this is NULL, no option parsing is done before
141 calling toy_main().</p></li> 152 calling toy_main().</p></li>
142 <li><p>int <b>flags</b> - Behavior flags such as where to install this command 153 <li><p>int <b>flags</b> - Behavior flags for this command. The following flags are currently understood:</p>
143 (in usr/bin/sbin) and whether this is a shell builtin (NOFORK) or a standalone 154
144 command.</p></li> 155 <ul>
145 </ul><br> 156 <li><b>TOYFLAG_USR</b> - Install this command under /usr</li>
157 <li><b>TOYFLAG_BIN</b> - Install this command under /bin</li>
158 <li><b>TOYFLAG_SBIN</b> - Install this command under /sbin</li>
159 <li><b>TOYFLAG_NOFORK</b> - This command can be used as a shell builtin.</li>
160 <li><b>TOYFLAG_UMASK</b> - Call umask(0) before running this command.</li>
161 </ul>
162 <br>
163
164 <p>These flags are combined with | (or). For example, to install a command
165 in /usr/bin, or together TOYFLAG_USR|TOYFLAG_BIN.</p>
166 </ul>
146 </li> 167 </li>
147 168
148 <li><p>struct toy_context <b>toys</b> - global structure containing information 169 <li><p>struct toy_context <b>toys</b> - global structure containing information
149 common to all commands, initializd by toy_init(). Members of this structure 170 common to all commands, initializd by toy_init(). Members of this structure
150 include:</p> 171 include:</p>
162 <p>Most commands don't use this field, instead the use optargs, optflags, 183 <p>Most commands don't use this field, instead the use optargs, optflags,
163 and the fields in the toy union initialized by get_optflags().</p> 184 and the fields in the toy union initialized by get_optflags().</p>
164 </li> 185 </li>
165 <li><p>unsigned <b>optflags</b> - Command line option flags, set by 186 <li><p>unsigned <b>optflags</b> - Command line option flags, set by
166 get_optflags(). Indicates which of the command line options listed in 187 get_optflags(). Indicates which of the command line options listed in
167 toys->which.options were seen this time. See get_optflags() for 188 toys->which.options occurred this time.</p>
168 details.</p></li> 189
190 <p>The rightmost command line argument listed in toys->which.options sets bit
191 1, the next one sets bit 2, and so on. This means the bits are set in the same
192 order the binary digits would be listed if typed out as a string. For example,
193 the option string "abcd" would parse the command line "-c" to set optflags to 2,
194 "-a" would set optflags to 8, and "-bd" would set optflags to 6 (4|2).</p>
195
196 <p>Only letters are relevant to optflags. In the string "a*b:c#d", d=1, c=2,
197 b=4, a=8. The punctuation after a letter initializes global variables
198 (see [TODO] DECLARE_GLOBALS() for details).</p>
199
200 <p>For more information on option parsing, see [TODO] get_optflags().</p>
201
202 </li>
169 <li><p>char **<b>optargs</b> - Null terminated array of arguments left over 203 <li><p>char **<b>optargs</b> - Null terminated array of arguments left over
170 after get_optflags() removed all the ones it understood. Note: optarg[0] is 204 after get_optflags() removed all the ones it understood. Note: optarg[0] is
171 the first argument, not the command name. Use toys.which->name for the command 205 the first argument, not the command name. Use toys.which->name for the command
172 name.</p></li> 206 name.</p></li>
207 <li><p>int <b>optc</b> - Optarg count, equivalent to argc but for
208 optargs[].<p></li>
173 <li><p>int <b>exithelp</b> - Whether error_exit() should print a usage message 209 <li><p>int <b>exithelp</b> - Whether error_exit() should print a usage message
174 via help_main() before exiting. (True during option parsing, defaults to 210 via help_main() before exiting. (True during option parsing, defaults to
175 false afterwards.)</p></li> 211 false afterwards.)</p></li>
176 </ul><br> 212 </ul><br>
177 213
178 <li><p>union toy_union <b>toy</b> - Union of structures containing each 214 <li><p>union toy_union <b>this</b> - Union of structures containing each
179 command's global variables.</p> 215 command's global variables.</p>
180 216
181 <p>A command that needs global variables should declare a structure to 217 <p>Global variables are useful: they reduce the overhead of passing extra
218 command line arguments between functions, they conveniently start prezeroed to
219 save initialization costs, and the command line argument parsing infrastructure
220 can also initialize global variables with its results.</p>
221
222 <p>But since each toybox process can only run one command at a time, allocating
223 space for global variables belonging to other commands you aren't currently
224 running would be wasteful.</p>
225
226 <p>Toybox handles this by encapsulating each command's global variables in
227 a structure, and declaring a union of those structures. The DECLARE_GLOBALS()
228 macro contains the global variables that should go in a command's global
229 structure. Each variable can then be accessed as "this.commandname.varname".
230 Generally, the macro TT is #defined to this.commandname so the variable
231 can then be accessed as "TT.variable".</p>
232
233 A command that needs global variables should declare a structure to
182 contain them all, and add that structure to this union. A command should never 234 contain them all, and add that structure to this union. A command should never
183 declare global variables outside of this, because such global variables would 235 declare global variables outside of this, because such global variables would
184 allocate memory when running other commands that don't use those global 236 allocate memory when running other commands that don't use those global
185 variables.</p> 237 variables.</p>
186 238
193 commands don't need to allocate their own. Any command is free to use this, 245 commands don't need to allocate their own. Any command is free to use this,
194 and it should never be directly referenced by functions in lib/ (although 246 and it should never be directly referenced by functions in lib/ (although
195 commands are free to pass toybuf in to a library function as an argument).</li> 247 commands are free to pass toybuf in to a library function as an argument).</li>
196 </ul> 248 </ul>
197 249
198 <p>The following functions are defined here:</p> 250 <p>The following functions are defined in main.c:</p>
199 <ul> 251 <ul>
200 <li><p>struct toy_list *<b>toy_find</b>(char *name) - Return the toy_list 252 <li><p>struct toy_list *<b>toy_find</b>(char *name) - Return the toy_list
201 structure for this command name, or NULL if not found.</p></li> 253 structure for this command name, or NULL if not found.</p></li>
202 <li><p>void <b>toy_init</b>(struct toy_list *which, char *argv[]) - fill out 254 <li><p>void <b>toy_init</b>(struct toy_list *which, char *argv[]) - fill out
203 the global toys structure, calling get_optargs() if necessary.</p></li> 255 the global toys structure, calling get_optargs() if necessary.</p></li>
204 <li><p>void <b>toy_exec</b>(char *argv[]) - Run a built-in command with arguments. 256 <li><p>void <b>toy_exec</b>(char *argv[]) - Run a built-in command with
205 Calls toy_find() on the first argument (which must be just a command name 257 arguments.</p>
258 <p>Calls toy_find() on argv[0] (which must be just a command name
206 without path). Returns if it can't find this command, otherwise calls 259 without path). Returns if it can't find this command, otherwise calls
207 toy_init(), toys->which.toy_main(), and exit() instead of returning.</p></li> 260 toy_init(), toys->which.toy_main(), and exit() instead of returning.</p>
208 261
209 <li><p>void <b>toybox_main</b>(void) - the main function for multiplexer 262 <p>Use the library function xexec() to fall back to external executables
210 command. Given a command name as its first argument, calls toy_exec() on its 263 in $PATH if toy_exec() can't find a built-in command. Note that toy_exec()
211 arguments. With no arguments, it lists available commands. If the first 264 does not strip paths before searching for a command, so "./command" will
212 argument starts with "-" it lists each command with its default install 265 never match an internal command.</li>
213 path prepended.</p></li> 266
267 <li><p>void <b>toybox_main</b>(void) - the main function for the multiplexer
268 command (I.E. "toybox"). Given a command name as its first argument, calls
269 toy_exec() on its arguments. With no arguments, it lists available commands.
270 If the first argument starts with "-" it lists each command with its default
271 install path prepended.</p></li>
214 272
215 </ul> 273 </ul>
216 274
217 <h3>Config.in</h3> 275 <h3>Config.in</h3>
218 276
219 <p>Top level configuration file in a stylized variant of 277 <p>Top level configuration file in a stylized variant of
220 <a href=http://kernel.org/doc/Documentation/kbuild/kconfig-language.txt>kconfig</a> format. Includes toys/Config.in.</p> 278 <a href=http://kernel.org/doc/Documentation/kbuild/kconfig-language.txt>kconfig</a> format. Includes generated/Config.in.</p>
221 279
222 <p>These files are directly used by "make menuconfig" to select which commands 280 <p>These files are directly used by "make menuconfig" to select which commands
223 to build into toybox (thus generating a .config file), and by 281 to build into toybox (thus generating a .config file), and by
224 scripts/config2help.py to generate toys/help.h.</p> 282 scripts/config2help.py to create generated/help.h.</p>
225 283
226 <h3>Temporary files:</h3> 284 <h3>Temporary files:</h3>
227 285
286 <p>There is one temporary file in the top level source directory:</p>
228 <ul> 287 <ul>
229 <li><p><b>.config</b> - Configuration file generated by kconfig, indicating 288 <li><p><b>.config</b> - Configuration file generated by kconfig, indicating
230 which commands (and options to commands) are currently enabled. Used 289 which commands (and options to commands) are currently enabled. Used
231 to generate gen_config.h and the toys/*.c dependency list.</p></li> 290 to make generated/config.h and determine which toys/*.c files to build.</p>
232 291
233 <li><p><b>gen_config.h</b> - list of CFG_SYMBOL and USE_SYMBOL() macros, 292 <p>You can create a human readable "miniconfig" version of this file using
293 <a href=http://landley.net/code/firmware/new_platform.html#miniconfig>these
294 instructions</a>.</p>
295 </li>
296 </ul>
297
298 <p>The "generated/" directory contains files generated from other source code
299 in toybox. All of these files can be recreated by the build system, although
300 some (such as generated/help.h) are shipped in release versions to reduce
301 environmental dependencies (I.E. so you don't need python on your build
302 system).</p>
303
304 <ul>
305 <li><p><b>generated/config.h</b> - list of CFG_SYMBOL and USE_SYMBOL() macros,
234 generated from .config by a sed invocation in the top level Makefile.</p> 306 generated from .config by a sed invocation in the top level Makefile.</p>
235 307
236 <p>CFG_SYMBOL is a comple time constant set to 1 for enabled symbols and 0 for 308 <p>CFG_SYMBOL is a comple time constant set to 1 for enabled symbols and 0 for
237 disabled symbols. This can be used via normal if() statements to remove 309 disabled symbols. This allows the use of normal if() statements to remove
238 code at compile time via the optimizer's dead code elimination, which removes 310 code at compile time via the optimizer's dead code elimination (which removes
239 from the binary any code that cannot be reached. This saves space without 311 from the binary any code that cannot be reached). This saves space without
240 cluttering the code with #ifdefs or leading to configuration dependent build 312 cluttering the code with #ifdefs or leading to configuration dependent build
241 breaks. (See the 1992 Usenix paper 313 breaks. (See the 1992 Usenix paper
242 <a href=http://www.chris-lott.org/resources/cstyle/ifdefs.pdf>#ifdef 314 <a href=http://www.chris-lott.org/resources/cstyle/ifdefs.pdf>#ifdef
243 Considered Harmful</a> for more information.)</p> 315 Considered Harmful</a> for more information.)</p>
244 316
245 <p>USE_SYMBOL(code) evaluates to the code in parentheses when the symbol 317 <p>USE_SYMBOL(code) evaluates to the code in parentheses when the symbol
246 is enabled, and nothing when the symbol is disabled. This can be used 318 is enabled, and nothing when the symbol is disabled. This can be used
247 for things like varargs or variable declarations which can't always be 319 for things like varargs or variable declarations which can't always be
248 eliminated by a compile time removalbe test on CFG_SYMBOL. Note that 320 eliminated by a simple test on CFG_SYMBOL. Note that
249 (unlike CFG_SYMBOL) this is really just a variant of #ifdef, and can 321 (unlike CFG_SYMBOL) this is really just a variant of #ifdef, and can
250 still result in configuration dependent build breaks. Use with caution.</p> 322 still result in configuration dependent build breaks. Use with caution.</p>
251 </li> 323 </li>
252 </ul> 324 </ul>
253 325