xref: /titanic_51/usr/src/lib/libshell/common/builtins.mm (revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968)
1*da2e3ebdSchin.ds DT July 9, 1993  \" use troff -mm
2*da2e3ebdSchin.nr C 3
3*da2e3ebdSchin.nr N 2
4*da2e3ebdSchin.SA 1  \"  right justified
5*da2e3ebdSchin.TL "311466-6713" "49059-6"  \" charging case filing case
6*da2e3ebdSchinGuidelines for writing \f5ksh-93\fP built-in commands
7*da2e3ebdSchin.AU "David G. Korn" DGK FP 11267 8062 D-237 "(research!dgk)"
8*da2e3ebdSchin.AF
9*da2e3ebdSchin.TM  11267-930???-93  \"  technical memo + TM numbers
10*da2e3ebdSchin.MT 4
11*da2e3ebdSchin.AS 2   \" abstract start for TM
12*da2e3ebdSchinOne of the features of \f5ksh93\fP, the latest version of \f5ksh\fP,
13*da2e3ebdSchinis the ability to add built-in commands at run time.
14*da2e3ebdSchinThis feature only works on operating systems that have the ability
15*da2e3ebdSchinto load and link code into the current process at run time.
16*da2e3ebdSchinSome examples of the systems that have this feature
17*da2e3ebdSchinare System V Release 4, Solaris, Sun OS, HP-UX Release 8 and above,
18*da2e3ebdSchinAIX 3.2 and above, and Microsoft Windows systems.
19*da2e3ebdSchin.P
20*da2e3ebdSchinThis memo describes how to write and compile programs
21*da2e3ebdSchinto can be loaded into \f5ksh\fP at run  time as built-in
22*da2e3ebdSchincommands.
23*da2e3ebdSchin.AE   \" abstract end
24*da2e3ebdSchin.OK Shell "Command interpreter" Language UNIX  \" keyword
25*da2e3ebdSchin.MT 1  \"  memo type
26*da2e3ebdSchin.H 1 INTRODUCTION
27*da2e3ebdSchinA built-in command is executed without creating a separate process.
28*da2e3ebdSchinInstead, the command is invoked as a C function by \f5ksh\fP.
29*da2e3ebdSchinIf this function has no side effects in the shell process,
30*da2e3ebdSchinthen the behavior of this built-in is identical to that of
31*da2e3ebdSchinthe equivalent stand-alone command.  The primary difference
32*da2e3ebdSchinin this case is performance.  The overhead of process creation
33*da2e3ebdSchinis eliminated.  For commands of short duration, the effect
34*da2e3ebdSchincan be dramatic.  For example, on SUN OS 4.1, the time do
35*da2e3ebdSchinrun \f5wc\fP on a small file of about 1000 bytes, runs
36*da2e3ebdSchinabout 50 times faster as a built-in command.
37*da2e3ebdSchin.P
38*da2e3ebdSchinIn addition, built-in commands that have side effects on the
39*da2e3ebdSchinshell environment can be written.
40*da2e3ebdSchinThis is usually done to extend the application domain for
41*da2e3ebdSchinshell programming.  For example, an X-windows extension
42*da2e3ebdSchinthat makes heavy use of the shell variable namespace
43*da2e3ebdSchinwas added as a group of built-ins commands that
44*da2e3ebdSchinare added at run time.
45*da2e3ebdSchinThe result is a windowing shell that can be used to write
46*da2e3ebdSchinX-windows applications.
47*da2e3ebdSchin.P
48*da2e3ebdSchinWhile there are definite advantages to adding built-in
49*da2e3ebdSchincommands, there are some disadvantages as well.
50*da2e3ebdSchinSince the built-in command and \f5ksh\fP share the same
51*da2e3ebdSchinaddress space, a coding error in the built-in program
52*da2e3ebdSchinmay affect the behavior of \f5ksh\fP; perhaps causing
53*da2e3ebdSchinit to core dump or hang.
54*da2e3ebdSchinDebugging is also more complex since your code is now
55*da2e3ebdSchina part of a larger entity.
56*da2e3ebdSchinThe isolation provided by a separate process
57*da2e3ebdSchinguarantees that all resources used by the command
58*da2e3ebdSchinwill be freed when the command completes.
59*da2e3ebdSchinAlso, since the address space of \f5ksh\fP will be larger,
60*da2e3ebdSchinthis may increase the time it takes \f5ksh\fP to fork() and
61*da2e3ebdSchinexec() a non-builtin command.
62*da2e3ebdSchinIt makes no sense to add a built-in command that takes
63*da2e3ebdSchina long time to run or that is run only once, since the performance
64*da2e3ebdSchinbenefits will be negligible.
65*da2e3ebdSchinBuilt-ins that have side effects in the current shell
66*da2e3ebdSchinenvironment have the disadvantage of increasing the
67*da2e3ebdSchincoupling between the built-in and \f5ksh\fP making
68*da2e3ebdSchinthe overall system less modular and more monolithic.
69*da2e3ebdSchin.P
70*da2e3ebdSchinDespite these drawbacks, in many cases extending
71*da2e3ebdSchin\f5ksh\fP by adding built-in
72*da2e3ebdSchincommands makes sense and allows reuse of the shell
73*da2e3ebdSchinscripting ability in an application specific domain.
74*da2e3ebdSchinThis memo describes how to write \f5ksh\fP extensions.
75*da2e3ebdSchin.H 1 "WRITING BUILT-IN COMMANDS"
76*da2e3ebdSchinThere is a development kit available for writing \f5ksh\fP
77*da2e3ebdSchinbuilt-ins.  The development kit has three directories,
78*da2e3ebdSchin\f5include\fP, \f5lib\fP, and \f5bin\fP.
79*da2e3ebdSchinThe \f5include\fP directory contains a sub-directory
80*da2e3ebdSchinnamed \f5ast\fP that contains interface prototypes
81*da2e3ebdSchinfor functions that you can call from built-ins.  The \f5lib\fP
82*da2e3ebdSchindirectory contains the \fBast\fP library\*F
83*da2e3ebdSchin.FS
84*da2e3ebdSchin\fBast\fP stands for Advanced Software Technology
85*da2e3ebdSchin.FE
86*da2e3ebdSchinand a library named \fBlibcmd\fP that contains a version
87*da2e3ebdSchinof several of the standard POSIX\*(Rf
88*da2e3ebdSchin.RS
89*da2e3ebdSchin.I "POSIX \- Part 2: Shell and Utilities,"
90*da2e3ebdSchinIEEE Std 1003.2-1992, ISO/IEC 9945-2:1993.
91*da2e3ebdSchin.RF
92*da2e3ebdSchinutilities that can be made run time built-ins.
93*da2e3ebdSchinIt is best to set the value of the environment variable
94*da2e3ebdSchin\fB\s-1PACKAGE_\s+1ast\fP to the pathname of the directory
95*da2e3ebdSchincontaining the development kit.
96*da2e3ebdSchinUsers of \f5nmake\fP\*(Rf
97*da2e3ebdSchin.RS
98*da2e3ebdSchinGlenn Fowler,
99*da2e3ebdSchinNmake reference needed
100*da2e3ebdSchin.RF
101*da2e3ebdSchin2.3 and above will then be able to
102*da2e3ebdSchinuse the rule
103*da2e3ebdSchin.nf
104*da2e3ebdSchin.in .5i
105*da2e3ebdSchin\f5:PACKAGE:	ast\fP
106*da2e3ebdSchin.in
107*da2e3ebdSchin.fi
108*da2e3ebdSchinin their makefiles and not have to specify any \f5-I\fP switches
109*da2e3ebdSchinto the compiler.
110*da2e3ebdSchin.P
111*da2e3ebdSchinA built-in command has a calling convention similar to
112*da2e3ebdSchinthe \f5main\fP function of a program,
113*da2e3ebdSchin.nf
114*da2e3ebdSchin.in .5i
115*da2e3ebdSchin\f5int main(int argc, char *argv[])\fP.
116*da2e3ebdSchin.in
117*da2e3ebdSchin.fi
118*da2e3ebdSchinHowever, instead of \f5main\fP, you must use the function name
119*da2e3ebdSchin\f5b_\fP\fIname\fP, where \fIname\fP is the name
120*da2e3ebdSchinof the built-in you wish to define.
121*da2e3ebdSchinThe built-in function takes a third
122*da2e3ebdSchin\f5void*\fP  argument which you can define as \f5NULL\fP.
123*da2e3ebdSchinInstead of \f5exit\fP, you need to use \f5return\fP
124*da2e3ebdSchinto terminate your command.
125*da2e3ebdSchinThe return value, will become the exit status of the command.
126*da2e3ebdSchin.P
127*da2e3ebdSchinThe steps necessary to create and add a run time built-in are
128*da2e3ebdSchinillustrated in the following simple example.
129*da2e3ebdSchinSuppose, you wish to add a built-in command named \f5hello\fP
130*da2e3ebdSchinwhich requires one argument and prints the word hello followed
131*da2e3ebdSchinby its argument.  First, write the following program in the file
132*da2e3ebdSchin\f5hello.c\fP:
133*da2e3ebdSchin.nf
134*da2e3ebdSchin.in .5i
135*da2e3ebdSchin\f5#include     <stdio.h>
136*da2e3ebdSchinint b_hello(int argc, char *argv[], void *context)
137*da2e3ebdSchin{
138*da2e3ebdSchin        if(argc != 2)
139*da2e3ebdSchin        {
140*da2e3ebdSchin                fprintf(stderr,"Usage: hello arg\en");
141*da2e3ebdSchin                return(2);
142*da2e3ebdSchin        }
143*da2e3ebdSchin        printf("hello %s\en",argv[1]);
144*da2e3ebdSchin        return(0);
145*da2e3ebdSchin}\fP
146*da2e3ebdSchin.in
147*da2e3ebdSchin.fi
148*da2e3ebdSchin.P
149*da2e3ebdSchinNext, the program needs to be compiled.
150*da2e3ebdSchinOn some systems it is necessary to specify a compiler
151*da2e3ebdSchinoption to produce position independent code
152*da2e3ebdSchinfor dynamic linking.
153*da2e3ebdSchinIf you do not compile with \f5nmake\fP
154*da2e3ebdSchinit is important to specify the a special include directory
155*da2e3ebdSchinwhen compiling built-ins.
156*da2e3ebdSchin.nf
157*da2e3ebdSchin.in .5i
158*da2e3ebdSchin\f5cc -pic -I$PACKAGE_ast/include -c hello.c\fP
159*da2e3ebdSchin.in
160*da2e3ebdSchin.fi
161*da2e3ebdSchinsince the special version of \f5<stdio.h>\fP
162*da2e3ebdSchinin the development kit is required.
163*da2e3ebdSchinThis command generates \f5hello.o\fP in the current
164*da2e3ebdSchindirectory.
165*da2e3ebdSchin.P
166*da2e3ebdSchinOn some systems, you cannot load \f5hello.o\fP directly,
167*da2e3ebdSchinyou must build a shared library instead.
168*da2e3ebdSchinUnfortunately, the method for generating a shared library
169*da2e3ebdSchindiffers with operating system.
170*da2e3ebdSchinHowever, if you are building with the AT\&T \f5nmake\fP
171*da2e3ebdSchinprogram you can use the \f5:LIBRARY:\fP rule to specify
172*da2e3ebdSchinthis in a system independent fashion.
173*da2e3ebdSchinIn addition, if you have several built-ins, it is desirable
174*da2e3ebdSchinto build a shared library that contains them all.
175*da2e3ebdSchin.P
176*da2e3ebdSchinThe final step is using the built-in.
177*da2e3ebdSchinThis can be done with the \f5ksh\fP command \f5builtin\fP.
178*da2e3ebdSchinTo load the shared library \f5hello.so\fP and to add
179*da2e3ebdSchinthe built-in \f5hello\fP, invoke the command,
180*da2e3ebdSchin.nf
181*da2e3ebdSchin.in .5i
182*da2e3ebdSchin\f5builtin -f hello hello\fP
183*da2e3ebdSchin.in
184*da2e3ebdSchin.fi
185*da2e3ebdSchinThe suffix for the shared library can be omitted in
186*da2e3ebdSchinwhich case the shell will add an appropriate suffix
187*da2e3ebdSchinfor the system that it is loading from.
188*da2e3ebdSchinOnce this command has been invoked, you can invoke \f5hello\fP
189*da2e3ebdSchinas you do any other command.
190*da2e3ebdSchin.P
191*da2e3ebdSchinIt is often desirable to make a command \fIbuilt-in\fP
192*da2e3ebdSchinthe first time that it is referenced.  The first
193*da2e3ebdSchintime \f5hello\fP is invoked, \f5ksh\fP should load and execute it,
194*da2e3ebdSchinwhereas for subsequent invocations \f5ksh\fP should just execute the built-in.
195*da2e3ebdSchinThis can be done by creating a file named \f5hello\fP
196*da2e3ebdSchinwith the following contents:
197*da2e3ebdSchin.nf
198*da2e3ebdSchin.in .5i
199*da2e3ebdSchin\f5function hello
200*da2e3ebdSchin{
201*da2e3ebdSchin        unset -f hello
202*da2e3ebdSchin        builtin -f hello hello
203*da2e3ebdSchin        hello "$@"
204*da2e3ebdSchin}\fP
205*da2e3ebdSchin.in
206*da2e3ebdSchin.fi
207*da2e3ebdSchinThis file \f5hello\fP needs to be placed in a directory that is
208*da2e3ebdSchinin your \fB\s-1FPATH\s+1\fP variable.  In addition, the full
209*da2e3ebdSchinpathname for \f5hello.so\fP should be used in this script
210*da2e3ebdSchinso that the run time loader will be able to find this shared library
211*da2e3ebdSchinno matter where the command \f5hello\fP is invoked.
212*da2e3ebdSchin.H 1 "CODING REQUIREMENTS AND CONVENTIONS"
213*da2e3ebdSchinAs mentioned above, the entry point for built-ins must be of
214*da2e3ebdSchinthe form \f5b_\fP\fIname\fP.
215*da2e3ebdSchinYour built-ins can call functions from the standard C library,
216*da2e3ebdSchinthe \fBast\fP library, interface functions provided by \f5ksh\fP,
217*da2e3ebdSchinand your own functions.
218*da2e3ebdSchinYou should avoid using any global symbols beginning with
219*da2e3ebdSchin.BR sh_ ,
220*da2e3ebdSchin.BR nv_ ,
221*da2e3ebdSchinand
222*da2e3ebdSchin.B ed_
223*da2e3ebdSchinsince these are used by \f5ksh\fP itself.
224*da2e3ebdSchinIn addition, \f5#define\fP constants in \f5ksh\fP interface
225*da2e3ebdSchinfiles, use symbols beginning with \fBSH_\fP to that you should
226*da2e3ebdSchinavoid using names beginning with \fBSH_\fP.
227*da2e3ebdSchin.H 2 "Header Files"
228*da2e3ebdSchinThe development kit provides a portable interface
229*da2e3ebdSchinto the C library and to libast.
230*da2e3ebdSchinThe header files in the development kit are compatible with
231*da2e3ebdSchinK&R C\*(Rf,
232*da2e3ebdSchin.RS
233*da2e3ebdSchinBrian W. Kernighan and Dennis M. Ritchie,
234*da2e3ebdSchin.IR "The C Programming Language" ,
235*da2e3ebdSchinPrentice Hall, 1978.
236*da2e3ebdSchin.RF
237*da2e3ebdSchinANSI-C\*(Rf,
238*da2e3ebdSchin.RS
239*da2e3ebdSchinAmerican National Standard for Information Systems \- Programming
240*da2e3ebdSchinLanguage \- C, ANSI X3.159-1989.
241*da2e3ebdSchin.RF
242*da2e3ebdSchinand C++\*(Rf.
243*da2e3ebdSchin.RS
244*da2e3ebdSchinBjarne Stroustroup,
245*da2e3ebdSchin.IR "C++" ,
246*da2e3ebdSchinAddison Wesley, xxxx
247*da2e3ebdSchin.RF
248*da2e3ebdSchin.P
249*da2e3ebdSchinThe best thing to do is to include the header file \f5<shell.h>\fP.
250*da2e3ebdSchinThis header file causes the \f5<ast.h>\fP header, the
251*da2e3ebdSchin\f5<error.h>\fP header and the \f5<stak.h>\fP
252*da2e3ebdSchinheader to be included as well as defining prototypes
253*da2e3ebdSchinfor functions that you can call to get shell
254*da2e3ebdSchinservices for your builtins.
255*da2e3ebdSchinThe header file \f5<ast.h>\fP
256*da2e3ebdSchinprovides prototypes for many \fBlibast\fP functions
257*da2e3ebdSchinand all the symbol and function definitions from the
258*da2e3ebdSchinANSI-C headers, \f5<stddef.h>\fP,
259*da2e3ebdSchin\f5<stdlib.h>\fP, \f5<stdarg.h>\fP, \f5<limits.h>\fP,
260*da2e3ebdSchinand \f5<string.h>\fP.
261*da2e3ebdSchinIt also provides all the symbols and definitions for the
262*da2e3ebdSchinPOSIX\*(Rf
263*da2e3ebdSchin.RS
264*da2e3ebdSchin.I "POSIX \- Part 1: System Application Program Interface,"
265*da2e3ebdSchinIEEE Std 1003.1-1990, ISO/IEC 9945-1:1990.
266*da2e3ebdSchin.RF
267*da2e3ebdSchinheaders \f5<sys/types.h>\fP, \f5<fcntl.h>\fP, and
268*da2e3ebdSchin\f5<unistd.h>\fP.
269*da2e3ebdSchinYou should include \f5<ast.h>\fP instead of one or more of
270*da2e3ebdSchinthese headers.
271*da2e3ebdSchinThe \f5<error.h>\fP header provides the interface to the error
272*da2e3ebdSchinand option parsing routines defined below.
273*da2e3ebdSchinThe \f5<stak.h>\fP header provides the interface to the memory
274*da2e3ebdSchinallocation routines described below.
275*da2e3ebdSchin.P
276*da2e3ebdSchinPrograms that want to use the information in \f5<sys/stat.h>\fP
277*da2e3ebdSchinshould include the file \f5<ls.h>\fP instead.
278*da2e3ebdSchinThis provides the complete POSIX interface to \f5stat()\fP
279*da2e3ebdSchinrelated functions even on non-POSIX systems.
280*da2e3ebdSchin.P
281*da2e3ebdSchin.H 2 "Input/Output"
282*da2e3ebdSchin\f5ksh\fP uses \fBsfio\fP,
283*da2e3ebdSchinthe Safe/Fast I/O library\*(Rf,
284*da2e3ebdSchin.RS
285*da2e3ebdSchinDavid Korn and Kiem-Phong Vo,
286*da2e3ebdSchin.IR "SFIO - A Safe/Fast Input/Output library,"
287*da2e3ebdSchinProceedings of the Summer Usenix,
288*da2e3ebdSchinpp. , 1991.
289*da2e3ebdSchin.RF
290*da2e3ebdSchinto perform all I/O operations.
291*da2e3ebdSchinThe \fBsfio\fP library, which is part of \fBlibast\fP,
292*da2e3ebdSchinprovides a superset of the functionality provided by the standard
293*da2e3ebdSchinI/O library defined in ANSI-C.
294*da2e3ebdSchinIf none of the additional functionality is required,
295*da2e3ebdSchinand if you are not familiar with \fBsfio\fP and
296*da2e3ebdSchinyou do not want to spend the time learning it,
297*da2e3ebdSchinthen you can use \fBsfio\fP via the \fBstdio\fP library
298*da2e3ebdSchininterface.  The development kit contains the header \f5<stdio.h>\fP
299*da2e3ebdSchinwhich maps \fBstdio\fP calls to \fBsfio\fP calls.
300*da2e3ebdSchinIn most instances the mapping is done
301*da2e3ebdSchinby macros or inline functions so that there is no overhead.
302*da2e3ebdSchinThe man page for the \fBsfio\fP library is in an Appendix.
303*da2e3ebdSchin.P
304*da2e3ebdSchinHowever, there are some very nice extensions and
305*da2e3ebdSchinperformance improvements in \fBsfio\fP
306*da2e3ebdSchinand if you plan any major extensions I recommend
307*da2e3ebdSchinthat you use it natively.
308*da2e3ebdSchin.H 2 "Error Handling"
309*da2e3ebdSchinFor error messages it is best to use the \fBast\fP library
310*da2e3ebdSchinfunction \f5errormsg()\fP rather that sending output to
311*da2e3ebdSchin\f5stderr\fP or the equivalent \f5sfstderr\fP directly.
312*da2e3ebdSchinUsing \f5errormsg()\fP will make error message appear
313*da2e3ebdSchinmore uniform to the user.
314*da2e3ebdSchinFurthermore, using \f5errormsg()\fP should make it easier
315*da2e3ebdSchinto do error message translation for other locales
316*da2e3ebdSchinin future versions of \f5ksh\fP.
317*da2e3ebdSchin.P
318*da2e3ebdSchinThe first argument to
319*da2e3ebdSchin\f5errormsg()\fP specifies the dictionary in which the string
320*da2e3ebdSchinwill be searched for translation.
321*da2e3ebdSchinThe second argument to \f5errormsg()\fP contains that error type
322*da2e3ebdSchinand value.  The third argument is a \fIprintf\fP style format
323*da2e3ebdSchinand the remaining arguments are arguments to be printed
324*da2e3ebdSchinas part of the message.  A new-line is inserted at the
325*da2e3ebdSchinend of each message and therefore, should not appear as
326*da2e3ebdSchinpart of the format string.
327*da2e3ebdSchinThe second argument should be one of the following:
328*da2e3ebdSchin.VL .5i
329*da2e3ebdSchin.LI \f5ERROR_exit(\fP\fIn\fP\f5)\fP:
330*da2e3ebdSchinIf \fIn\fP is not-zero, the builtin will exit value \fIn\fP after
331*da2e3ebdSchinprinting the message.
332*da2e3ebdSchin.LI \f5ERROR_system(\fP\fIn\fP\f5)\fP:
333*da2e3ebdSchinExit builtin with exit value \fIn\fP after printing the message.
334*da2e3ebdSchinThe message will display the message corresponding to \f5errno\fP
335*da2e3ebdSchinenclosed within \f5[\ ]\fP at the end of the message.
336*da2e3ebdSchin.LI \f5ERROR_usage(\fP\fIn\fP\f5)\fP:
337*da2e3ebdSchinWill generate a usage message and exit.  If \fIn\fP is non-zero,
338*da2e3ebdSchinthe exit value will be 2.  Otherwise the exit value will be 0.
339*da2e3ebdSchin.LI \f5ERROR_debug(\fP\fIn\fP\f5)\fP:
340*da2e3ebdSchinWill print a level \fIn\fP debugging message and will then continue.
341*da2e3ebdSchin.LI \f5ERROR_warn(\fP\fIn\fP\f5)\fP:
342*da2e3ebdSchinPrints a warning message. \fIn\fP is ignored.
343*da2e3ebdSchin.H 2 "Option Parsing"
344*da2e3ebdSchinThe first thing that a built-in should do is to check
345*da2e3ebdSchinthe arguments for correctness and to print any usage
346*da2e3ebdSchinmessages on standard error.
347*da2e3ebdSchinFor consistency with the rest of \f5ksh\fP, it is best
348*da2e3ebdSchinto use the \f5libast\fP functions \f5optget()\fP and
349*da2e3ebdSchin\f5optusage()\fPfor this
350*da2e3ebdSchinpurpose.
351*da2e3ebdSchinThe header \f5<error.h>\fP included prototypes for
352*da2e3ebdSchinthese functions.
353*da2e3ebdSchinThe \f5optget()\fP function is similar to the
354*da2e3ebdSchinSystem V C library function \f5getopt()\fP,
355*da2e3ebdSchinbut provides some additional capabilities.
356*da2e3ebdSchinBuilt-ins that use \f5optget()\fP provide a more
357*da2e3ebdSchinconsistent user interface.
358*da2e3ebdSchin.P
359*da2e3ebdSchinThe \f5optget()\fP function is invoked as
360*da2e3ebdSchin.nf
361*da2e3ebdSchin.in .5i
362*da2e3ebdSchin\f5int optget(char *argv[], const char *optstring)\fP
363*da2e3ebdSchin.in
364*da2e3ebdSchin.fi
365*da2e3ebdSchinwhere \f5argv\fP is the argument list and \f5optstring\fP
366*da2e3ebdSchinis a string that specifies the allowable arguments and
367*da2e3ebdSchinadditional information that is used to format \fIusage\fP
368*da2e3ebdSchinmessages.
369*da2e3ebdSchinIn fact a complete man page in \f5troff\fP or \f5html\fP
370*da2e3ebdSchincan be generated by passing a usage string as described
371*da2e3ebdSchinby the \f5getopts\fP command.
372*da2e3ebdSchinLike \f5getopt()\fP,
373*da2e3ebdSchinsingle letter options are represented by the letter itself,
374*da2e3ebdSchinand options that take a string argument are followed by the \f5:\fP
375*da2e3ebdSchincharacter.
376*da2e3ebdSchinOption strings have the following special characters:
377*da2e3ebdSchin.VL .5i
378*da2e3ebdSchin.LI \f5:\fP
379*da2e3ebdSchinUsed after a letter option to indicate that the option
380*da2e3ebdSchintakes an option argument.
381*da2e3ebdSchinThe variable \f5opt_info.arg\fP will point to this
382*da2e3ebdSchinvalue after the given argument is encountered.
383*da2e3ebdSchin.LI \f5#\fP
384*da2e3ebdSchinUsed after a letter option to indicate that the option
385*da2e3ebdSchincan only take a numerical value.
386*da2e3ebdSchinThe variable \f5opt_info.num\fP will contain this
387*da2e3ebdSchinvalue after the given argument is encountered.
388*da2e3ebdSchin.LI \f5?\fP
389*da2e3ebdSchinUsed after a \f5:\fP or \f5#\fP (and after the optional \f5?\fP)
390*da2e3ebdSchinto indicate the the
391*da2e3ebdSchinpreceding option argument is not required.
392*da2e3ebdSchin.LI \f5[\fP...\f5]\fP
393*da2e3ebdSchinAfter a \f5:\fP or \f5#\fP, the characters contained
394*da2e3ebdSchininside the brackets are used to identify the option
395*da2e3ebdSchinargument when generating a \fIusage\fP message.
396*da2e3ebdSchin.LI \fIspace\fP
397*da2e3ebdSchinThe remainder of the string will only be used when generating
398*da2e3ebdSchinusage messages.
399*da2e3ebdSchin.LE
400*da2e3ebdSchin.P
401*da2e3ebdSchinThe \f5optget()\fP function returns the matching option letter if
402*da2e3ebdSchinone of the legal option is matched.
403*da2e3ebdSchinOtherwise, \f5optget()\fP returns
404*da2e3ebdSchin.VL .5i
405*da2e3ebdSchin.LI \f5':'\fP
406*da2e3ebdSchinIf there is an error.  In this case the variable \f5opt_info.arg\fP
407*da2e3ebdSchincontains the error string.
408*da2e3ebdSchin.LI \f50\fP
409*da2e3ebdSchinIndicates the end of options.
410*da2e3ebdSchinThe variable \f5opt_info.index\fP contains the number of arguments
411*da2e3ebdSchinprocessed.
412*da2e3ebdSchin.LI \f5'?'\fP
413*da2e3ebdSchinA usage message has been required.
414*da2e3ebdSchinYou normally call \f5optusage()\fP to generate and display
415*da2e3ebdSchinthe usage message.
416*da2e3ebdSchin.LE
417*da2e3ebdSchin.P
418*da2e3ebdSchinThe following is an example of the option parsing portion
419*da2e3ebdSchinof the \f5wc\fP utility.
420*da2e3ebdSchin.nf
421*da2e3ebdSchin.in +5
422*da2e3ebdSchin\f5#include <shell.h>
423*da2e3ebdSchinwhile(1) switch(n=optget(argv,"xf:[file]"))
424*da2e3ebdSchin{
425*da2e3ebdSchin	case 'f':
426*da2e3ebdSchin		file = opt_info.arg;
427*da2e3ebdSchin		break;
428*da2e3ebdSchin	case ':':
429*da2e3ebdSchin		error(ERROR_exit(0), opt_info.arg);
430*da2e3ebdSchin		break;
431*da2e3ebdSchin	case '?':
432*da2e3ebdSchin		error(ERROR_usage(2), opt_info.arg);
433*da2e3ebdSchin		break;
434*da2e3ebdSchin}\fP
435*da2e3ebdSchin.in
436*da2e3ebdSchin.fi
437*da2e3ebdSchin.H 2 "Storage Management"
438*da2e3ebdSchinIt is important that any memory used by your built-in
439*da2e3ebdSchinbe returned.  Otherwise, if your built-in is called frequently,
440*da2e3ebdSchin\f5ksh\fP will eventually run out of memory.
441*da2e3ebdSchinYou should avoid using \f5malloc()\fP for memory that must
442*da2e3ebdSchinbe freed before returning from you built-in, because by default,
443*da2e3ebdSchin\f5ksh\fP will terminate you built-in in the event of an
444*da2e3ebdSchininterrupt and the memory will not be freed.
445*da2e3ebdSchin.P
446*da2e3ebdSchinThe best way to to allocate variable sized storage is
447*da2e3ebdSchinthrough calls to the \fBstak\fP library
448*da2e3ebdSchinwhich is included in \fBlibast\fP
449*da2e3ebdSchinand which is used extensively by \f5ksh\fP itself.
450*da2e3ebdSchinObjects allocated with the \f5stakalloc()\fP
451*da2e3ebdSchinfunction are freed when you function completes
452*da2e3ebdSchinor aborts.
453*da2e3ebdSchinThe \fBstak\fP library provides a convenient way to
454*da2e3ebdSchinbuild variable length strings and other objects dynamically.
455*da2e3ebdSchinThe man page for the \fBstak\fP library is contained
456*da2e3ebdSchinin the Appendix.
457*da2e3ebdSchin.P
458*da2e3ebdSchinBefore \f5ksh\fP calls each built-in command, it saves
459*da2e3ebdSchinthe current stack location and restores it after
460*da2e3ebdSchinit returns.
461*da2e3ebdSchinIt is not necessary to save and restore the stack
462*da2e3ebdSchinlocation in the \f5b_\fP entry function,
463*da2e3ebdSchinbut you may want to write functions that use this stack
464*da2e3ebdSchinare restore it when leaving the function.
465*da2e3ebdSchinThe following coding convention will do this in
466*da2e3ebdSchinan efficient manner:
467*da2e3ebdSchin.nf
468*da2e3ebdSchin.in .5i
469*da2e3ebdSchin\fIyourfunction\fP\f5()
470*da2e3ebdSchin{
471*da2e3ebdSchin        char	*savebase;
472*da2e3ebdSchin        int	saveoffset;
473*da2e3ebdSchin        if(saveoffset=staktell())
474*da2e3ebdSchin        	savebase = stakfreeze(0);
475*da2e3ebdSchin        \fP...\f5
476*da2e3ebdSchin        if(saveoffset)
477*da2e3ebdSchin        	stakset(savebase,saveoffset);
478*da2e3ebdSchin        else
479*da2e3ebdSchin        	stakseek(0);
480*da2e3ebdSchin}\fP
481*da2e3ebdSchin.in
482*da2e3ebdSchin.fi
483*da2e3ebdSchin.H 1 "CALLING \f5ksh\fP SERVICES"
484*da2e3ebdSchinSome of the more interesting applications are those that extend
485*da2e3ebdSchinthe functionality of \f5ksh\fP in application specific directions.
486*da2e3ebdSchinA prime example of this is the X-windows extension which adds
487*da2e3ebdSchinbuiltins to create and delete widgets.
488*da2e3ebdSchinThe \fBnval\fP library is used to interface with the shell
489*da2e3ebdSchinname space.
490*da2e3ebdSchinThe \fBshell\fP library is used to access other shell services.
491*da2e3ebdSchin.H 2 "The nval library"
492*da2e3ebdSchinA great deal of power is derived from the ability to use
493*da2e3ebdSchinportions of the hierarchal variable namespace provided by \f5ksh-93\fP
494*da2e3ebdSchinand turn these names into active objects.
495*da2e3ebdSchin.P
496*da2e3ebdSchinThe \fBnval\fP library is used to interface with shell
497*da2e3ebdSchinvariables.
498*da2e3ebdSchinA man page for this file is provided in an Appendix.
499*da2e3ebdSchinYou need to include the header \f5<nval.h>\fP
500*da2e3ebdSchinto access the functions defined in the \fBnval\fP library.
501*da2e3ebdSchinAll the functions provided by the \fBnval\fP library begin
502*da2e3ebdSchinwith the prefix \f5nv_\fP.
503*da2e3ebdSchinEach shell variable is an object in an associative table
504*da2e3ebdSchinthat is referenced by name.
505*da2e3ebdSchinThe type \f5Namval_t*\fP is pointer to a shell variable.
506*da2e3ebdSchinTo operate on a shell variable, you first get a handle
507*da2e3ebdSchinto the variable with the \f5nv_open()\fP function
508*da2e3ebdSchinand then supply the handle returned as the first
509*da2e3ebdSchinargument of the function that provides an operation
510*da2e3ebdSchinon the variable.
511*da2e3ebdSchinYou must call \f5nv_close()\fP when you are finished
512*da2e3ebdSchinusing this handle so that the space can be freed once
513*da2e3ebdSchinthe value is unset.
514*da2e3ebdSchinThe two most frequent operations are to get the value of
515*da2e3ebdSchinthe variable, and to assign value to the variable.
516*da2e3ebdSchinThe \f5nv_getval()\fP returns a pointer the the
517*da2e3ebdSchinvalue of the variable.
518*da2e3ebdSchinIn some cases the pointer returned is to a region that
519*da2e3ebdSchinwill be overwritten by the next \f5nv_getval()\fP call
520*da2e3ebdSchinso that if the value isn't used immediately, it should
521*da2e3ebdSchinbe copied.
522*da2e3ebdSchinMany variables can also generate a numeric value.
523*da2e3ebdSchinThe \f5nv_getnum()\fP function returns a numeric
524*da2e3ebdSchinvalue for the given variable pointer, calling the
525*da2e3ebdSchinarithmetic evaluator if necessary.
526*da2e3ebdSchin.P
527*da2e3ebdSchinThe \f5nv_putval()\fP function is used to assign a new
528*da2e3ebdSchinvalue to a given variable.
529*da2e3ebdSchinThe second argument to \f5putval()\fP is the value
530*da2e3ebdSchinto be assigned
531*da2e3ebdSchinand the third argument is a \fIflag\fP which
532*da2e3ebdSchinis used in interpreting the second argument.
533*da2e3ebdSchin.P
534*da2e3ebdSchinEach shell variable can have one or more attributes.
535*da2e3ebdSchinThe \f5nv_isattr()\fP is used to test for the existence
536*da2e3ebdSchinof one or more attributes.
537*da2e3ebdSchinSee the appendix for a complete list of attributes.
538*da2e3ebdSchin.P
539*da2e3ebdSchinBy default, each shell variable passively stores the string you
540*da2e3ebdSchingive with with \f5nv_putval()\fP, and returns the value
541*da2e3ebdSchinwith \f5getval()\fP.  However, it is possible to turn
542*da2e3ebdSchinany node into an active entity by assigning functions
543*da2e3ebdSchinto it that will be called whenever \f5nv_putval()\fP
544*da2e3ebdSchinand/or \f5nv_getval()\fP is called.
545*da2e3ebdSchinIn fact there are up to five functions that can
546*da2e3ebdSchinassociated with each variable to override the
547*da2e3ebdSchindefault actions.
548*da2e3ebdSchinThe type \f5Namfun_t\fP is used to define these functions.
549*da2e3ebdSchinOnly those that are non-\f5NULL\fP override the
550*da2e3ebdSchindefault actions.
551*da2e3ebdSchinTo override the default actions, you must allocate an
552*da2e3ebdSchininstance of \f5Namfun_t\fP, and then assign
553*da2e3ebdSchinthe functions that you wish to override.
554*da2e3ebdSchinThe \f5putval()\fP
555*da2e3ebdSchinfunction is called by the \f5nv_putval()\fP function.
556*da2e3ebdSchinA \f5NULL\fP for the \fIvalue\fP argument
557*da2e3ebdSchinindicates a request to unset the variable.
558*da2e3ebdSchinThe \fItype\fP argument might contain the \f5NV_INTEGER\fP
559*da2e3ebdSchinbit so you should be prepared to do a conversion if
560*da2e3ebdSchinnecessary.
561*da2e3ebdSchinThe \f5getval()\fP
562*da2e3ebdSchinfunction is called by \f5nv_getval()\fP
563*da2e3ebdSchinvalue and must return a string.
564*da2e3ebdSchinThe \f5getnum()\fP
565*da2e3ebdSchinfunction is called by by the arithmetic evaluator
566*da2e3ebdSchinand must return double.
567*da2e3ebdSchinIf omitted, then it will call \f5nv_getval()\fP and
568*da2e3ebdSchinconvert the result to a number.
569*da2e3ebdSchin.P
570*da2e3ebdSchinThe functionality of a variable can further be increased
571*da2e3ebdSchinby adding discipline functions that
572*da2e3ebdSchincan be associated with the variable.
573*da2e3ebdSchinA discipline function allows a script that uses your
574*da2e3ebdSchinvariable to define functions whose name is
575*da2e3ebdSchin\fIvarname\fP\f5.\fP\fIdiscname\fP
576*da2e3ebdSchinwhere \fIvarname\fP is the name of the variable, and \fIdiscname\fP
577*da2e3ebdSchinis the name of the discipline.
578*da2e3ebdSchinWhen the user defines such a function, the \f5settrap()\fP
579*da2e3ebdSchinfunction will be called with the name of the discipline and
580*da2e3ebdSchina pointer to the parse tree corresponding to the discipline
581*da2e3ebdSchinfunction.
582*da2e3ebdSchinThe application determines when these functions are actually
583*da2e3ebdSchinexecuted.
584*da2e3ebdSchinBy default, \f5ksh\fP defines \f5get\fP,
585*da2e3ebdSchin\f5set\fP, and \f5unset\fP as discipline functions.
586*da2e3ebdSchin.P
587*da2e3ebdSchinIn addition, it is possible to provide a data area that
588*da2e3ebdSchinwill be passed as an argument to
589*da2e3ebdSchineach of these functions whenever any of these functions are called.
590*da2e3ebdSchinTo have private data, you need to define and allocate a structure
591*da2e3ebdSchinthat looks like
592*da2e3ebdSchin.nf
593*da2e3ebdSchin.in .5i
594*da2e3ebdSchin\f5struct \fIyours\fP
595*da2e3ebdSchin{
596*da2e3ebdSchin        Namfun_t	fun;
597*da2e3ebdSchin	\fIyour_data_fields\fP;
598*da2e3ebdSchin};\fP
599*da2e3ebdSchin.in
600*da2e3ebdSchin.fi
601*da2e3ebdSchin.H 2 "The shell library"
602*da2e3ebdSchinThere are several functions that are used by \f5ksh\fP itself
603*da2e3ebdSchinthat can also be called from built-in commands.
604*da2e3ebdSchinThe man page for these routines are in the Appendix.
605*da2e3ebdSchin.P
606*da2e3ebdSchinThe \f5sh_addbuiltin()\fP function can be used to add or delete
607*da2e3ebdSchinbuiltin commands.  It takes the name of the built-in, the
608*da2e3ebdSchinaddress of the function that implements the built-in, and
609*da2e3ebdSchina \f5void*\fP pointer that will be passed to this function
610*da2e3ebdSchinas the third agument whenever it is invoked.
611*da2e3ebdSchinIf the function address is \f5NULL\fP, the specified built-in
612*da2e3ebdSchinwill be deleted.  However, special built-in functions cannot
613*da2e3ebdSchinbe deleted or modified.
614*da2e3ebdSchin.P
615*da2e3ebdSchinThe \f5sh_fmtq()\fP function takes a string and returns
616*da2e3ebdSchina string that is quoted as necessary so that it can
617*da2e3ebdSchinbe used as shell input.
618*da2e3ebdSchinThis function is used to implement the \f5%q\fP option
619*da2e3ebdSchinof the shell built-in \f5printf\fP command.
620*da2e3ebdSchin.P
621*da2e3ebdSchinThe \f5sh_parse()\fP function returns a parse tree corresponding
622*da2e3ebdSchinto a give file stream.  The tree can be executed by supplying
623*da2e3ebdSchinit as the first argument to
624*da2e3ebdSchinthe \f5sh_trap()\fP function and giving a value of \f51\fP as the
625*da2e3ebdSchinsecond argument.
626*da2e3ebdSchinAlternatively, the \f5sh_trap()\fP function can parse and execute
627*da2e3ebdSchina string by passing the string as the first argument and giving \f50\fP
628*da2e3ebdSchinas the second argument.
629*da2e3ebdSchin.P
630*da2e3ebdSchinThe \f5sh_isoption()\fP function can be used to set to see whether one
631*da2e3ebdSchinor more of the option settings is enabled.
632