1.HTML "APE — The ANSI/POSIX Environment 2.de XX 3.IP \ \ \ \- 4.. 5.TL 6APE \(em The ANSI/POSIX Environment 7.AU 8Howard Trickey 9howard@plan9.bell-labs.com 10.SH 11Introduction 12.PP 13When a large or frequently-updated program must be ported 14to or from Plan 9, the ANSI/POSIX environment known as APE can be useful. 15APE combines the set of headers and object code libraries specified by 16the ANSI C standard (ANSI X3.159-1989) with the POSIX operating system 17interface standard (IEEE 1003.1-1990, ISO 9945-1), the part of POSIX 18defining the basic operating system functions. 19Using APE will cause slower compilation and marginally slower execution speeds, 20so if the importing or exporting happens only infrequently, due consideration 21should be given to using the usual Plan 9 compilation environment instead. 22Another factor to consider is that the Plan 9 header organization is 23much simpler to remember and use. 24.PP 25There are some aspects of required POSIX behavior that are impossible or 26very hard to simulate in Plan 9. They are described below. 27Experience has shown, however, that the simulation is adequate for the 28vast majority of programs. A much more common problem is that 29many programs use functions or headers not defined by POSIX. 30APE has some extensions to POSIX to help in this regard. 31Extensions must be explicitly enabled with an appropriate 32.CW #define , 33in order that the APE environment be a good aid for testing 34ANSI/POSIX compliance of programs. 35.SH 36Pcc 37.PP 38The 39.CW pcc 40command acts as a front end to the Plan 9 C compilers and loaders. 41It runs an ANSI C preprocessor over source files, using the APE 42headers to satisfy 43.CW "#include <\fIfile\fP>" 44directives; then it runs a Plan 9 C compiler; finally, it may load 45with APE libraries to produce an executable program. 46The document 47.I "How to Use the Plan 9 C Compiler" 48explains how environment variables are used by convention to 49handle compilation for differing architectures. 50The environment variable 51.CW $objtype 52controls which Plan 9 compiler and loader are used by 53.CW pcc , 54as well as the location of header and library files. 55For example, if 56.CW $objtype 57is 58.CW mips , 59then 60.CW pcc 61has 62.CW cpp 63look for headers in 64.CW /mips/include/ape 65followed by 66.CW /sys/include/ape ; 67then 68.CW pcc 69uses 70.CW vc 71to create 72.CW .v 73object files; 74finally, 75.CW vl 76is used to create an executable using libraries in 77.CW /mips/lib/ape . 78.SH 79Psh and Cc 80.PP 81The 82.CW pcc 83command is intended for uses where the source code is 84ANSI/POSIX, but the programs are built in the usual Plan 9 85manner \(em with 86.CW mk 87and producing object files with names ending in 88.CW .v , 89etc. 90Sometimes it is best to use the standard POSIX 91.CW make 92and 93.CW cc 94(which produces object files with names ending in 95.CW .o , 96and automatically calls the loader unless 97.CW -c 98is specified). 99Under these circumstances, execute the command: 100.DS 101.CW "ape/psh" 102.DE 103This starts a POSIX shell, with an environment that 104includes the POSIX commands 105.CW ar89 , 106.CW c89 , 107.CW cc , 108.CW basename , 109.CW dirname , 110.CW expr , 111.CW false , 112.CW grep , 113.CW kill , 114.CW make , 115.CW rmdir , 116.CW sed , 117.CW sh , 118.CW stty , 119.CW true , 120.CW uname , 121and 122.CW yacc . 123There are also a few placeholders for commands that cannot be 124implemented in Plan 9: 125.CW chown , 126.CW ln , 127and 128.CW umask . 129.PP 130The 131.CW cc 132command accepts the options mandated for 133the POSIX command 134.CW c89 , 135as specified in the C-Language Development Utilities Option 136annex of the POSIX Shell and Utilities standard. 137It also accepts the following nonstandard options: 138.CW -v 139for echoing the commands for each pass to stdout; 140.CW -A 141to turn on ANSI prototype warnings; 142.CW -S 143to leave assembly language in 144.I file .s; 145.CW -Wp,\fIargs\fP 146to pass 147.I args 148to the 149.CW cpp ; 150.CW -W0,\fIargs\fP 151to pass 152.I args 153to 2c, etc.; 154and 155.CW -Wl,\fIargs\fP 156to pass 157.I args 158to 2l, etc. 159.PP 160The 161.CW sh 162command is pdksh, a mostly POSIX-compliant public domain Korn Shell. 163The Plan 9 implementation does not include 164the emacs and vi editing modes. 165.PP 166The 167.CW stty 168command only has effect if the 169.CW ape/ptyfs 170command has been started to interpose a pseudo-tty interface 171between 172.CW /dev/cons 173and the running command. 174None of the distributed commands do this automatically. 175.SH 176Symbols 177.PP 178The C and POSIX standards require that certain symbols be 179defined in headers. 180They also require that certain other classes of symbols not 181be defined in the headers, and specify certain other 182symbols that may be defined in headers at the discretion 183of the implementation. 184POSIX defines 185.I "feature test macros" , 186which are preprocessor symbols beginning with an underscore 187and then a capital letter; if the program 188.CW #defines 189a feature test macro before the inclusion of any headers, 190then it is requesting that certain symbols be visible in the headers. 191The most important feature test macro is 192.CW _POSIX_SOURCE : 193when it is defined, exactly the symbols required by POSIX are 194visible in the appropriate headers. 195Consider 196.CW <signal.h> 197for example: 198ANSI defines some names that must be defined in 199.CW <signal.h> , 200but POSIX defines others, such as 201.CW sigset_t , 202which are not allowed according to ANSI. 203The solution is to make the additional symbols visible only when 204.CW _POSIX_SOURCE 205is defined. 206.PP 207To export a program, it helps to know whether it fits 208in one of the following categories: 209.IP 1. 210Strictly conforming ANSI C program. It only uses features of the language, 211libraries, and headers explicitly required by the C standard. It does not 212depend on unspecified, undefined, or implementation-dependent behavior, 213and does not exceed any minimum implementation limit. 214.IP 2. 215Strictly conforming POSIX program. Similar, but for the POSIX standard as well. 216.IP 3. 217Some superset of POSIX, with extensions. Each extension 218is selected by a feature test macro, so it is clear which extensions 219are being used. 220.PP 221With APE, if headers are always included to declare any library functions 222used, then the set of feature test macros defined by a program will 223show which of the above categories the program is in. 224To accomplish this, no symbol is defined in a header if it is not required 225by the C or POSIX standard, and those required by the POSIX standard 226are protected by 227.CW "#ifdef _POSIX_SOURCE" . 228For example, 229.CW <errno.h> 230defines 231.CW EDOM , 232.CW ERANGE , 233and 234.CW errno , 235as required by the C standard. 236The C standard allows more names beginning with 237.CW E , 238but our header defines only those unless 239.CW _POSIX_SOURCE 240is defined, in which case the symbols required by POSIX are also defined. 241This means that a program that uses 242.CW ENAMETOOLONG 243cannot masquerade as a strictly conforming ANSI C program. 244.PP 245.CW Pcc 246and 247.CW cc 248do not predefine any preprocessor symbols except those required by 249the ANSI C standard: 250.CW __STDC__ , 251.CW __LINE__ , 252.CW __FILE__ , 253.CW __DATE__ , 254and 255.CW __TIME__ . 256Any others must be defined in the program itself or by using 257.CW -D 258on the command line. 259.SH 260Extensions 261.PP 262The discipline enforced by putting only required 263names in the headers is useful for exporting programs, 264but it gets in the way when importing programs. 265The compromise is to allow additional symbols in headers, 266additional headers, and additional library functions, 267but only under control of extension feature test macros. 268The following extensions are provided; unless otherwise 269specified, the additional library functions are in the 270default APE library. 271.XX 272.CW _LIBG_EXTENSION . 273This allows the use of the Plan 9 graphics library. 274The functions are as described in the Plan 9 manual (see 275.I graphics (2)) 276except that 277.CW div 278had to be renamed 279.CW ptdiv . 280Include the 281.CW <libg.h> 282header to declare the needed types and functions. 283.XX 284.CW _LIMITS_EXTENSION . 285POSIX does not require that names such as 286.CW PATH_MAX 287and 288.CW OPEN_MAX 289be defined in 290.CW <limits.h> , 291but many programs assume they are defined there. 292If 293.CW _LIMITS_EXTENSION 294is defined, those names will all be defined when 295.CW <limits.h> 296is included. 297.XX 298.CW _BSD_EXTENSION . 299This extension includes not only Berkeley Unix routines, 300but also a grab bag of other miscellaneous routines often 301found in Unix implementations. 302The extension allows the inclusion of any of: 303.CW <bsd.h> 304for 305.CW bcopy() , 306.CW bcmp() , 307and similar Berkeley functions; 308.CW <netdb.h> 309for 310.CW gethostbyname() , 311etc., 312and associated structures; 313.CW <select.h> 314for the Berkeley 315.CW select 316function and associated types and macros 317for dealing with multiple input sources; 318.CW <sys/ioctl.h> 319for the 320.CW ioctl 321function (minimally implemented); 322.CW <sys/param.h> 323for 324.CW NOFILES_MAX ; 325.CW <sys/pty.h> 326for pseudo-tty support via the 327.CW ptsname(int) 328and 329.CW ptmname(int) 330functions; 331.CW <sys/resource.h> ; 332.CW <sys/socket.h> 333for socket structures, constants, and functions; 334.CW <sys/time.h> 335for definitions of the 336.CW timeval 337and 338.CW timezone 339structures; 340and 341.CW <sys/uio.h> 342for the 343.CW iovec 344structure and the 345.CW writev 346and 347.CW readv 348functions used for scatter/gather I/O. 349Defining 350.CW _BSD_EXTENSION 351also enables various extra definitions in 352.CW <ctype.h> , 353.CW <signal.h> , 354.CW <stdio.h> , 355.CW <unistd.h> , 356.CW <sys/stat.h> , 357and 358.CW <sys/times.h> . 359.XX 360.CW _NET_EXTENSION . 361This extension allows inclusion of 362.CW <libnet.h> , 363which defines the networking functions described in the Plan 9 manual page 364.I dial (2). 365.XX 366.CW _PLAN9_EXTENSION . 367This extension allows inclusion of 368.CW <u.h> , 369.CW <lock.h> , 370.CW <qlock.h> , 371.CW <utf.h> , 372.CW <fmt.h> , 373and 374.CW <draw.h> . 375These are pieces of Plan 9 source code ported into APE, 376mostly from 377.CW <libc.h> . 378.XX 379.CW _REGEXP_EXTENSION . 380This extension allows inclusion of 381.CW <regexp.h> , 382which defines the regular expression matching functions described 383in the Plan 9 manual page 384.I regexp (2). 385.XX 386.CW _RESEARCH_SOURCE . 387This extension enables a small library of functions from the Tenth Edition Unix 388Research System (V10). 389These functions and the types needed to use them are all defined in the 390.CW <libv.h> 391header. 392The provided functions are: 393.CW srand , 394.CW rand , 395.CW nrand , 396.CW lrand , 397and 398.CW frand 399(better random number generators); 400.CW getpass , 401.CW tty_echoon , 402.CW tty_echooff 403(for dealing with the common needs for mucking with terminal 404characteristics); 405.CW min 406and 407.CW max ; 408.CW nap ; 409and 410.CW setfields , 411.CW getfields , 412and 413.CW getmfields 414(for parsing a line into fields). 415See the Research Unix System Programmer's Manual, Tenth Edition, for a description 416of these functions. 417.XX 418.CW _C99_SNPRINTF_EXTENSION . 419This extension permits the use of the return values of 420.I snprintf 421and 422.I vsnprintf . 423Before C99, the 1999 C standard, 424these functions usually returned the number of bytes, 425excluding terminating NUL, 426actually stored in the target string. 427(GNU, as usual, had to be different and returned -1 if the target 428string was too small.) 429C99 requires them to instead return the number of bytes, 430excluding terminating NUL, 431that would have been written into the target string if it were infinitely large 432or a negative value if an `encoding error' occurs, 433so old programs compiled under C99 rules will be prone to overrunning 434their buffers. 435This extension is a way for the programmer to declare that he or she understands 436the situation and has adjusted the code being compiled to compensate. 437.SH 438Common Problems 439.PP 440Some large systems, including X11, have been ported successfully 441to Plan 9 using APE 442(the X11 port is not included in the distribution, however, 443because supporting it properly is too big a job). 444The problems encountered fall into three categories: 445(1) non-ANSI C/POSIX features used; (2) inadequate simulation of POSIX functions; 446and (3) compiler/loader bugs. 447By far the majority of problems are in the first category. 448.PP 449POSIX is just starting to be a target for programmers. 450Most existing code is written to work with one or both of a BSD or a System V Unix. 451System V is fairly close to POSIX, but there are some differences. 452Also, many System V systems have imported some BSD features that are 453not part of POSIX. 454A good strategy for porting external programs is to first try using 455.CW CFLAGS=-D_POSIX_SOURCE ; 456if that doesn't work, try adding 457.CW _D_BSD_EXTENSION 458and perhaps include 459.CW <bsd.h> 460in source files. 461Here are some solutions to problems that might remain: 462.XX 463Third (environment) argument to 464.CW main . 465Use the 466.CW environ 467global instead. 468.XX 469.CW OPEN_MAX , 470.CW PATH_MAX , 471etc., assumed in 472.CW <limits.h> . 473Rewrite to call 474.CW sysconf 475or define 476.CW _LIMITS_EXTENSION . 477.XX 478.CW <varargs.h> . 479Rewrite to use 480.CW <stdarg.h> . 481.PP 482The second class of problems has to do with inadequacies in the Plan 9 483simulation of POSIX functions. 484These shortcomings have rarely gotten in the way 485(except, perhaps, for the 486.CW link 487problem). 488.XX 489Functions for setting the userid, groupid, effective userid and effective groupid 490do not do anything useful. The concept is impossible to simulate in Plan 9. 491.CW Chown 492also does nothing. 493.XX 494.CW execlp 495and the related functions do not look at the 496.CW PATH 497environment variable. They just try the current directory and 498.CW /bin 499if the pathname is not absolute. 500.XX 501Advisory locking via 502.CW fcntl 503is not implemented. 504.XX 505.CW isatty 506is hard to do correctly. 507The approximation used is only sometimes correct. 508.XX 509.CW link 510always fails. 511.XX 512With 513.CW open , 514the 515.CW O_NOCTTY 516option has no effect. 517The concept of a controlling tty is foreign to Plan 9. 518.XX 519.CW setsid 520forks the name space and note group, 521which is only approximately the right behavior. 522.XX 523The functions dealing with stacking signals, 524.CW sigpending , 525.CW sigprocmask 526and 527.CW sigsuspend , 528do not work. 529.XX 530.CW umask 531has no effect, as there is no such concept in Plan 9. 532.XX 533code that does 534.CW getenv("HOME") 535should be changed to 536.CW getenv("home") 537on Plan 9. 538