123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537 |
- .HTML "APE — The ANSI/POSIX Environment
- .de XX
- .IP \ \ \ \-
- ..
- .TL
- APE \(em The ANSI/POSIX Environment
- .AU
- Howard Trickey
- howard@plan9.bell-labs.com
- .SH
- Introduction
- .PP
- When a large or frequently-updated program must be ported
- to or from Plan 9, the ANSI/POSIX environment known as APE can be useful.
- APE combines the set of headers and object code libraries specified by
- the ANSI C standard (ANSI X3.159-1989) with the POSIX operating system
- interface standard (IEEE 1003.1-1990, ISO 9945-1), the part of POSIX
- defining the basic operating system functions.
- Using APE will cause slower compilation and marginally slower execution speeds,
- so if the importing or exporting happens only infrequently, due consideration
- should be given to using the usual Plan 9 compilation environment instead.
- Another factor to consider is that the Plan 9 header organization is
- much simpler to remember and use.
- .PP
- There are some aspects of required POSIX behavior that are impossible or
- very hard to simulate in Plan 9. They are described below.
- Experience has shown, however, that the simulation is adequate for the
- vast majority of programs. A much more common problem is that
- many programs use functions or headers not defined by POSIX.
- APE has some extensions to POSIX to help in this regard.
- Extensions must be explicitly enabled with an appropriate
- .CW #define ,
- in order that the APE environment be a good aid for testing
- ANSI/POSIX compliance of programs.
- .SH
- Pcc
- .PP
- The
- .CW pcc
- command acts as a front end to the Plan 9 C compilers and loaders.
- It runs an ANSI C preprocessor over source files, using the APE
- headers to satisfy
- .CW "#include <\fIfile\fP>"
- directives; then it runs a Plan 9 C compiler; finally, it may load
- with APE libraries to produce an executable program.
- The document
- .I "How to Use the Plan 9 C Compiler"
- explains how environment variables are used by convention to
- handle compilation for differing architectures.
- The environment variable
- .CW $objtype
- controls which Plan 9 compiler and loader are used by
- .CW pcc ,
- as well as the location of header and library files.
- For example, if
- .CW $objtype
- is
- .CW mips ,
- then
- .CW pcc
- has
- .CW cpp
- look for headers in
- .CW /mips/include/ape
- followed by
- .CW /sys/include/ape ;
- then
- .CW pcc
- uses
- .CW vc
- to create
- .CW .v
- object files;
- finally,
- .CW vl
- is used to create an executable using libraries in
- .CW /mips/lib/ape .
- .SH
- Psh and Cc
- .PP
- The
- .CW pcc
- command is intended for uses where the source code is
- ANSI/POSIX, but the programs are built in the usual Plan 9
- manner \(em with
- .CW mk
- and producing object files with names ending in
- .CW .v ,
- etc.
- Sometimes it is best to use the standard POSIX
- .CW make
- and
- .CW cc
- (which produces object files with names ending in
- .CW .o ,
- and automatically calls the loader unless
- .CW -c
- is specified).
- Under these circumstances, execute the command:
- .DS
- .CW "ape/psh"
- .DE
- This starts a POSIX shell, with an environment that
- includes the POSIX commands
- .CW ar89 ,
- .CW c89 ,
- .CW cc ,
- .CW basename ,
- .CW dirname ,
- .CW expr ,
- .CW false ,
- .CW grep ,
- .CW kill ,
- .CW make ,
- .CW rmdir ,
- .CW sed ,
- .CW sh ,
- .CW stty ,
- .CW true ,
- .CW uname ,
- and
- .CW yacc .
- There are also a few placeholders for commands that cannot be
- implemented in Plan 9:
- .CW chown ,
- .CW ln ,
- and
- .CW umask .
- .PP
- The
- .CW cc
- command accepts the options mandated for
- the POSIX command
- .CW c89 ,
- as specified in the C-Language Development Utilities Option
- annex of the POSIX Shell and Utilities standard.
- It also accepts the following nonstandard options:
- .CW -v
- for echoing the commands for each pass to stdout;
- .CW -A
- to turn on ANSI prototype warnings;
- .CW -S
- to leave assembly language in
- .I file .s;
- .CW -Wp,\fIargs\fP
- to pass
- .I args
- to the
- .CW cpp ;
- .CW -W0,\fIargs\fP
- to pass
- .I args
- to 2c, etc.;
- and
- .CW -Wl,\fIargs\fP
- to pass
- .I args
- to 2l, etc.
- .PP
- The
- .CW sh
- command is pdksh, a mostly POSIX-compliant public domain Korn Shell.
- The Plan 9 implementation does not include
- the emacs and vi editing modes.
- .PP
- The
- .CW stty
- command only has effect if the
- .CW ape/ptyfs
- command has been started to interpose a pseudo-tty interface
- between
- .CW /dev/cons
- and the running command.
- None of the distributed commands do this automatically.
- .SH
- Symbols
- .PP
- The C and POSIX standards require that certain symbols be
- defined in headers.
- They also require that certain other classes of symbols not
- be defined in the headers, and specify certain other
- symbols that may be defined in headers at the discretion
- of the implementation.
- POSIX defines
- .I "feature test macros" ,
- which are preprocessor symbols beginning with an underscore
- and then a capital letter; if the program
- .CW #defines
- a feature test macro before the inclusion of any headers,
- then it is requesting that certain symbols be visible in the headers.
- The most important feature test macro is
- .CW _POSIX_SOURCE :
- when it is defined, exactly the symbols required by POSIX are
- visible in the appropriate headers.
- Consider
- .CW <signal.h>
- for example:
- ANSI defines some names that must be defined in
- .CW <signal.h> ,
- but POSIX defines others, such as
- .CW sigset_t ,
- which are not allowed according to ANSI.
- The solution is to make the additional symbols visible only when
- .CW _POSIX_SOURCE
- is defined.
- .PP
- To export a program, it helps to know whether it fits
- in one of the following categories:
- .IP 1.
- Strictly conforming ANSI C program. It only uses features of the language,
- libraries, and headers explicitly required by the C standard. It does not
- depend on unspecified, undefined, or implementation-dependent behavior,
- and does not exceed any minimum implementation limit.
- .IP 2.
- Strictly conforming POSIX program. Similar, but for the POSIX standard as well.
- .IP 3.
- Some superset of POSIX, with extensions. Each extension
- is selected by a feature test macro, so it is clear which extensions
- are being used.
- .PP
- With APE, if headers are always included to declare any library functions
- used, then the set of feature test macros defined by a program will
- show which of the above categories the program is in.
- To accomplish this, no symbol is defined in a header if it is not required
- by the C or POSIX standard, and those required by the POSIX standard
- are protected by
- .CW "#ifdef _POSIX_SOURCE" .
- For example,
- .CW <errno.h>
- defines
- .CW EDOM ,
- .CW ERANGE ,
- and
- .CW errno ,
- as required by the C standard.
- The C standard allows more names beginning with
- .CW E ,
- but our header defines only those unless
- .CW _POSIX_SOURCE
- is defined, in which case the symbols required by POSIX are also defined.
- This means that a program that uses
- .CW ENAMETOOLONG
- cannot masquerade as a strictly conforming ANSI C program.
- .PP
- .CW Pcc
- and
- .CW cc
- do not predefine any preprocessor symbols except those required by
- the ANSI C standard:
- .CW __STDC__ ,
- .CW __LINE__ ,
- .CW __FILE__ ,
- .CW __DATE__ ,
- and
- .CW __TIME__ .
- Any others must be defined in the program itself or by using
- .CW -D
- on the command line.
- .SH
- Extensions
- .PP
- The discipline enforced by putting only required
- names in the headers is useful for exporting programs,
- but it gets in the way when importing programs.
- The compromise is to allow additional symbols in headers,
- additional headers, and additional library functions,
- but only under control of extension feature test macros.
- The following extensions are provided; unless otherwise
- specified, the additional library functions are in the
- default APE library.
- .XX
- .CW _LIBG_EXTENSION .
- This allows the use of the Plan 9 graphics library.
- The functions are as described in the Plan 9 manual (see
- .I graphics (2))
- except that
- .CW div
- had to be renamed
- .CW ptdiv .
- Include the
- .CW <libg.h>
- header to declare the needed types and functions.
- .XX
- .CW _LIMITS_EXTENSION .
- POSIX does not require that names such as
- .CW PATH_MAX
- and
- .CW OPEN_MAX
- be defined in
- .CW <limits.h> ,
- but many programs assume they are defined there.
- If
- .CW _LIMITS_EXTENSION
- is defined, those names will all be defined when
- .CW <limits.h>
- is included.
- .XX
- .CW _BSD_EXTENSION .
- This extension includes not only Berkeley Unix routines,
- but also a grab bag of other miscellaneous routines often
- found in Unix implementations.
- The extension allows the inclusion of any of:
- .CW <bsd.h>
- for
- .CW bcopy() ,
- .CW bcmp() ,
- and similar Berkeley functions;
- .CW <netdb.h>
- for
- .CW gethostbyname() ,
- etc.,
- and associated structures;
- .CW <select.h>
- for the Berkeley
- .CW select
- function and associated types and macros
- for dealing with multiple input sources;
- .CW <sys/ioctl.h>
- for the
- .CW ioctl
- function (minimally implemented);
- .CW <sys/param.h>
- for
- .CW NOFILES_MAX ;
- .CW <sys/pty.h>
- for pseudo-tty support via the
- .CW ptsname(int)
- and
- .CW ptmname(int)
- functions;
- .CW <sys/resource.h> ;
- .CW <sys/socket.h>
- for socket structures, constants, and functions;
- .CW <sys/time.h>
- for definitions of the
- .CW timeval
- and
- .CW timezone
- structures;
- and
- .CW <sys/uio.h>
- for the
- .CW iovec
- structure and the
- .CW writev
- and
- .CW readv
- functions used for scatter/gather I/O.
- Defining
- .CW _BSD_EXTENSION
- also enables various extra definitions in
- .CW <ctype.h> ,
- .CW <signal.h> ,
- .CW <stdio.h> ,
- .CW <unistd.h> ,
- .CW <sys/stat.h> ,
- and
- .CW <sys/times.h> .
- .XX
- .CW _NET_EXTENSION .
- This extension allows inclusion of
- .CW <libnet.h> ,
- which defines the networking functions described in the Plan 9 manual page
- .I dial (2).
- .XX
- .CW _PLAN9_EXTENSION .
- This extension allows inclusion of
- .CW <u.h> ,
- .CW <lock.h> ,
- .CW <qlock.h> ,
- .CW <utf.h> ,
- .CW <fmt.h> ,
- and
- .CW <draw.h> .
- These are pieces of Plan 9 source code ported into APE,
- mostly from
- .CW <libc.h> .
- .XX
- .CW _REGEXP_EXTENSION .
- This extension allows inclusion of
- .CW <regexp.h> ,
- which defines the regular expression matching functions described
- in the Plan 9 manual page
- .I regexp (2).
- .XX
- .CW _RESEARCH_SOURCE .
- This extension enables a small library of functions from the Tenth Edition Unix
- Research System (V10).
- These functions and the types needed to use them are all defined in the
- .CW <libv.h>
- header.
- The provided functions are:
- .CW srand ,
- .CW rand ,
- .CW nrand ,
- .CW lrand ,
- and
- .CW frand
- (better random number generators);
- .CW getpass ,
- .CW tty_echoon ,
- .CW tty_echooff
- (for dealing with the common needs for mucking with terminal
- characteristics);
- .CW min
- and
- .CW max ;
- .CW nap ;
- and
- .CW setfields ,
- .CW getfields ,
- and
- .CW getmfields
- (for parsing a line into fields).
- See the Research Unix System Programmer's Manual, Tenth Edition, for a description
- of these functions.
- .XX
- .CW _C99_SNPRINTF_EXTENSION .
- This extension permits the use of the return values of
- .I snprintf
- and
- .I vsnprintf .
- Before C99, the 1999 C standard,
- these functions usually returned the number of bytes,
- excluding terminating NUL,
- actually stored in the target string.
- (GNU, as usual, had to be different and returned -1 if the target
- string was too small.)
- C99 requires them to instead return the number of bytes,
- excluding terminating NUL,
- that would have been written into the target string if it were infinitely large
- or a negative value if an `encoding error' occurs,
- so old programs compiled under C99 rules will be prone to overrunning
- their buffers.
- This extension is a way for the programmer to declare that he or she understands
- the situation and has adjusted the code being compiled to compensate.
- .SH
- Common Problems
- .PP
- Some large systems, including X11, have been ported successfully
- to Plan 9 using APE
- (the X11 port is not included in the distribution, however,
- because supporting it properly is too big a job).
- The problems encountered fall into three categories:
- (1) non-ANSI C/POSIX features used; (2) inadequate simulation of POSIX functions;
- and (3) compiler/loader bugs.
- By far the majority of problems are in the first category.
- .PP
- POSIX is just starting to be a target for programmers.
- Most existing code is written to work with one or both of a BSD or a System V Unix.
- System V is fairly close to POSIX, but there are some differences.
- Also, many System V systems have imported some BSD features that are
- not part of POSIX.
- A good strategy for porting external programs is to first try using
- .CW CFLAGS=-D_POSIX_SOURCE ;
- if that doesn't work, try adding
- .CW _D_BSD_EXTENSION
- and perhaps include
- .CW <bsd.h>
- in source files.
- Here are some solutions to problems that might remain:
- .XX
- Third (environment) argument to
- .CW main .
- Use the
- .CW environ
- global instead.
- .XX
- .CW OPEN_MAX ,
- .CW PATH_MAX ,
- etc., assumed in
- .CW <limits.h> .
- Rewrite to call
- .CW sysconf
- or define
- .CW _LIMITS_EXTENSION .
- .XX
- .CW <varargs.h> .
- Rewrite to use
- .CW <stdarg.h> .
- .PP
- The second class of problems has to do with inadequacies in the Plan 9
- simulation of POSIX functions.
- These shortcomings have rarely gotten in the way
- (except, perhaps, for the
- .CW link
- problem).
- .XX
- Functions for setting the userid, groupid, effective userid and effective groupid
- do not do anything useful. The concept is impossible to simulate in Plan 9.
- .CW Chown
- also does nothing.
- .XX
- .CW execlp
- and the related functions do not look at the
- .CW PATH
- environment variable. They just try the current directory and
- .CW /bin
- if the pathname is not absolute.
- .XX
- Advisory locking via
- .CW fcntl
- is not implemented.
- .XX
- .CW isatty
- is hard to do correctly.
- The approximation used is only sometimes correct.
- .XX
- .CW link
- always fails.
- .XX
- With
- .CW open ,
- the
- .CW O_NOCTTY
- option has no effect.
- The concept of a controlling tty is foreign to Plan 9.
- .XX
- .CW setsid
- forks the name space and note group,
- which is only approximately the right behavior.
- .XX
- The functions dealing with stacking signals,
- .CW sigpending ,
- .CW sigprocmask
- and
- .CW sigsuspend ,
- do not work.
- .XX
- .CW umask
- has no effect, as there is no such concept in Plan 9.
- .XX
- code that does
- .CW getenv("HOME")
- should be changed to
- .CW getenv("home")
- on Plan 9.
|