diff options
author | Edwin Groothuis <edwin@FreeBSD.org> | 2009-05-21 07:54:21 +0000 |
---|---|---|
committer | Edwin Groothuis <edwin@FreeBSD.org> | 2009-05-21 07:54:21 +0000 |
commit | b16ac5b53f6b943b7017f01d411721173b4f1b96 (patch) | |
tree | 4f4a683a19a5fb250b588f359f30f135a697f2f7 | |
parent | c1dc0a1745ca8959fc4ce61ce026e2a83984c13e (diff) |
Vendor import of top-3.8b1vendor/top/3.8b1vendor/top
Obtained from: http://www.unixtop.org
Notes
Notes:
svn path=/vendor/top/dist/; revision=192526
svn path=/vendor/top/3.8b1/; revision=192527; tag=vendor/top/3.8b1
-rw-r--r-- | ADVERTISEMENT | 28 | ||||
-rw-r--r-- | Changes | 317 | ||||
-rwxr-xr-x | Configure | 565 | ||||
-rw-r--r-- | DISCLAIMER | 31 | ||||
-rw-r--r-- | FAQ | 518 | ||||
-rw-r--r-- | INSTALL | 184 | ||||
-rw-r--r-- | LICENSE | 30 | ||||
-rw-r--r-- | Make.desc.X | 24 | ||||
-rw-r--r-- | Makefile.X | 117 | ||||
-rw-r--r-- | Makefile.in | 92 | ||||
-rw-r--r-- | Porting | 68 | ||||
-rw-r--r-- | README | 195 | ||||
-rw-r--r-- | Y2K | 2 | ||||
-rw-r--r-- | ap_snprintf.c | 1193 | ||||
-rw-r--r-- | color.c | 376 | ||||
-rw-r--r-- | color.h | 91 | ||||
-rw-r--r-- | commands.c | 970 | ||||
-rw-r--r-- | commands.h | 42 | ||||
-rw-r--r-- | config.default.makeinstall | 5 | ||||
-rwxr-xr-x | config.guess | 1407 | ||||
-rw-r--r-- | config.h.in | 256 | ||||
-rwxr-xr-x | config.sub | 1504 | ||||
-rwxr-xr-x | configure | 7969 | ||||
-rw-r--r-- | configure.ac | 529 | ||||
-rw-r--r-- | display.c | 2030 | ||||
-rw-r--r-- | display.h | 85 | ||||
-rwxr-xr-x | getans | 118 | ||||
-rw-r--r-- | getopt.c | 37 | ||||
-rw-r--r-- | globalstate.h | 66 | ||||
-rw-r--r-- | hash.c | 2001 | ||||
-rw-r--r-- | hash.h | 155 | ||||
-rwxr-xr-x | hash.m4c | 666 | ||||
-rwxr-xr-x | hash.m4h | 103 | ||||
-rwxr-xr-x | install-sh | 296 | ||||
-rw-r--r-- | layout.h | 86 | ||||
-rw-r--r-- | loadavg.h | 32 | ||||
-rw-r--r-- | m-template | 241 | ||||
-rw-r--r-- | m_freebsd.c | 1780 | ||||
-rw-r--r-- | m_freebsd.man | 134 | ||||
-rw-r--r-- | machine.h | 78 | ||||
-rw-r--r-- | message.h | 44 | ||||
-rwxr-xr-x | metatop | 25 | ||||
-rw-r--r-- | os.h | 159 | ||||
-rw-r--r-- | patchlevel.h | 2 | ||||
-rw-r--r-- | prime.c | 41 | ||||
-rw-r--r-- | screen.c | 375 | ||||
-rw-r--r-- | screen.h | 64 | ||||
-rw-r--r-- | sigconv.awk | 48 | ||||
-rw-r--r-- | top.1.in | 464 | ||||
-rw-r--r-- | top.X | 336 | ||||
-rw-r--r-- | top.c | 1698 | ||||
-rw-r--r-- | top.h | 64 | ||||
-rw-r--r-- | top.local.H | 68 | ||||
-rw-r--r-- | username.c | 245 | ||||
-rw-r--r-- | username.h | 42 | ||||
-rw-r--r-- | utils.c | 409 | ||||
-rw-r--r-- | utils.h | 89 | ||||
-rw-r--r-- | version.c | 51 | ||||
-rw-r--r-- | version.h | 37 |
59 files changed, 24382 insertions, 4300 deletions
diff --git a/ADVERTISEMENT b/ADVERTISEMENT deleted file mode 100644 index b8fc68c1b979..000000000000 --- a/ADVERTISEMENT +++ /dev/null @@ -1,28 +0,0 @@ - William LeFebvre - Group sys Consulting - wnl@groupsys.com - +1-770-813-3224 - - -William LeFebvre is available for consulting and teaching engagements -through the company Group sys Consulting. William's specialties are: - - Unix system administration issues - Local area network design - Design of safe connections to the Internet - Domain Name Service - Threaded programming with pthreads - Netscape Server API plugins - INN news server configuration - SunOS to Solaris migration - Troubleshooting - - -Although located in the Atlanta metropolitan area, William can easily -travel to any location in the United States and Canada. Trips to -other countries can be arranged as well. - -If you are interested in having William work for your organization, -contact him at +1-770-813-3224 or via the address "wnl@groupsys.com". -You may also wish to visit the Group sys web page at www.groupsys.com. - @@ -1,3 +1,320 @@ +Tue May 6 2008 - wnl (3.8beta1) + Main code: fixed bugs in screen_cleareol and in display code. Fixed + bug in i_swap when all data is 0. Added ^W patch (from thaquis). + Fixed bug in xdprintf. Added command line options for the "t" and + "m" commands. + SunOS 5 changes: Support for showing individual threads. Redid + allocation of prpsinfo structures. Added a pidthr hash that uses + both pid and thread id for a key. Changed format_process_header + and format_next_process to use a table-driven method for generating + the columns. Status files from /proc (psinfo and lpsinfo) are now + cached to avoid repeatedly reopening them. Column showing number of + LWPs is now called "NLWP" and column showing lwpid is "LWP". + FreeBSD changes: Runtime check to ensure binary is running on + the same machine type it was compiled for. Lots of cleanup and + changed nearly everything to use sysctl rather than kvm, and + inability to open kvm is no longer fatal. Improved thread reporting: + disabled for 7.x and lower. Added lwpid hash for proper tracking + of threads. Changed format_process_header and format_next_process + to use a table-driven method for generating the columns. + Dec Alpha: configure uses compile-time options to properly trap + and handle exceptions from the Alpha FPU (from Brian Maly). + +Tue Feb 26 2008 - wnl (3.7) + Prepare for version 3.7 release. + +Fri Feb 1 2008 - wnl (3.7beta4) + Using the $ notation in printf formats for freebsd apparently was + causing problems on 64-bit systems. All such usage has been + removed and the process line is formatted piecemeal. + +Thu Dec 27 2007 - wnl (3.7beta3) + Improved function comments in display.c for message_error functions. + Changed some of the error messages in top.c to be more succint. + +Fri Dec 7 2007 - wnl (3.7beta3) + Changes to freebsd port: moved some functions up front to + eliminate forward references. Use sysctl to get all vm stats + information, as some of this isn't updated in the struct + vmmeter under FreeBSD 7.0. Added routines to support large-scale + sysctl access. + +Wed Nov 28 2007 - wnl (3.7beta3) + Changes to documentation: FAQ, README, man page. + +Tue Nov 27 2007 - wnl (3.7beta3) + For freebsd, added page faults, pageins, pageouts, and pages + freed to the kernel display line. These numbers reflect the + values presented in vmstat. For sunos5, added page faults, + pageins and pageouts to the kernel display line. + +Fri Nov 2 2007 - wnl (3.7beta3) + Added copyright notices to the top of every source and include file. + Added copyright information to the man page. + Removed a few outdated things from the manifest. + Minor changes to sigconv.awk. + +Sat Oct 27 2007 - wnl (3.7beta3) + Added check for sys_signame at configure time and if it is + present then it is used in commands.c to translate signal names + in to numbers. + Added alternate snprintf and vsnprintf functions from apache (in + ap_snprintf.c). Added configure magic to define and compile them in + where needed. Added check to configure for variadic macros. + Preprocessor defintion of dprintf (in utils.h) now depends on + support for variadic macros. Cleaned up m_linux code. + +Wed Oct 3 2007 - wnl (3.7beta3) + Lots of changes, thanks to Mark Wong. Most changes were to + clean the code up so that it would compile cleanly with -Wall + (all warnings). Changed function names in screen.c so that + they all start with "screen_". Isolated all interaction with + termcap to screen.c by adding a real function for cursor + addressing (in the past it was just a macro). Only screen.c + now needs to worry about defining templates for the termcap + functions. Added configure and preprocessor magic to ensure + that all the termcap functions used in the code are defined + with templates. Changed names of some other functions and + global variables to avoid name conflicts with functions in + curses and other well established libraries. Changed dprintf + macro to use variadic arguments so that the preprocessor can + gobble up the entire call when compiling without debugging + (this will have to be made more portable). All include files + are surrounded by #ifndef statements to accomodate multiple + inclusions. Platform module is now compiled with + -fno-strict-aliasing as some of the modules do type punning + that can confuse the optimizer. + +Wed Sep 26 2007 - wnl (3.7beta3) + For freebsd, priority is no longer normalized by PZERO. This + contradicts the behavior used by ps when it displays priority. + But normalizing by PZERO has become a bit of an anachronism + and it actually obscures the meaning of the priority without + adding any real value. + +Wed Sep 19 2007 - wnl (3.7beta3) + Many changes to improve the display of threads. Changed + process summary line to use the word "threads" when showing + individual threads. Added the system command to toggle the + display of system processes. Fixed bug in hash.c remove_pos. + For freebsd: count threads correctly when they are being + displayed, nice column is more closely in line with ps + (nothing fancy for real time processes), add two more process + states that didn't exist in older releases of freebsd (wait + and lock). + For linux: Threads done right. Now track individual threads + of multi-threaded processes separately so that we always know + their %cpu. Switch to format_process_header so that we can + change the column headings and remove the THR column when + displaying individual threads. Switched process (and thread) + tracking over to use generic hash table functions included + with the new version of top. Process states and total now + include threads when they are being shown. Added "SHR" column + to show the amount of shared memory per process. Improved + calculation of elapsed time and percent cpu to avoid + overflows. Remove weighted cpu calculations entirely as it is + an anachronism. + For Solaris: Moved check for libelf to accomodate older systems. + +Sun Sep 9 2007 - wnl (3.7beta2) + Documentation changes. Fixes to sunos5 port. Added display of + thread count and selection by command name to linux port. Removed + the use of inline functions from hash.c as that doesn't appear to + be very portable. + +Wed Sep 5 2007 - wnl (3.7beta1) + Fixed freebsd and linux configuration bugs. Added configuration + options for tweaking program defaults. Rewrote top level code + (top.c) from scratch, including command handling so that adding + new commands is much easier. Changed message-line handling to + ensure that the message is displayed for at least 5 seconds + regardless of the update frequency. Added a "miniupdate" that + occurs one second after the initial screen on systems that don't + already delay the first screen. The mini-update shows cpu state + percentages. Added ability to select output by command name on + some systems. Fixed color toggling via the "C" command. Added + long options via getopt_long to complement the existing single + character options. Added the freebsd "m" command to chose + alternate display modes. On freebsd this gives a process i/o + display. Added the freebsd "H" command to select the display of + individual threads. Added "-a" option ("all") to set number of + displays and number of processes to infinity (equivalent to + "-d all all"). Added dual architecture compilation for Solaris + to generate both a 32-bit and a 64-bit binary. This is on by + default when compiling on a 64-bit system and can be explicitly + set via "configure --enable-dualarch". Added uniform hashing + functions that use bucket hash for uint, pid, and string. Changed + username.c and the sunos and freebsd modules to use these functions. + Added the "kernel" information line to the display to show + statistics on what the kernel is doing (context switches, forks, + traps, etc.). This requires explicit support by the platform + module, currently only freebsd, linux, and sunos. + +Wed Apr 18 2007 - wnl (3.6.1) + Fixed a few bugs in sigconv.awk that were causing incorrect + results on FreeBSD. Changed configure.ac to fix a few linux + problems: signal include file and /proc/1/stat. + +Fri Apr 13 2007 - wnl (3.6.1) + Removed the use of VPATH for compiling the system module and used + an explicit dependency in the Makefile instead. VPATH is now set + to just srcdir to ensure that top will compile correctly when + configured from a different directory. On systems without VPATH + support, top will still configure and compile, but only + from within the source directory. This fixes bug 1699526. + +Fri Feb 2 2007 - wnl (3.6.1) + Revised the way that configure figures out owner, group, and mode. + For systems that don't use the kernel, it tries to match install + settings to allow access to stuff in /proc. More importantly, if + mode is 755 then neither owner nor group are set. This fixes bug + 1631136. Added patch from haanjdj@xs4all.nl to fix an occasional + core dump in m_decosf1.c. This checks return code from task_threads. + Made sure all get_system_info functions are declared void. Fixed + string termination bug. Cleaned up documetation for sunos5. + +Tue Aug 8 2006 - wnl (3.6.1) + For Solaris, changed the tag "swap" to "total swap" to clarify + what is beign displayed. Note that the calculations are still the + same: the display is just showing total rather than total - free. + +Thu Apr 27 2006 - wnl (3.6) + Added patches for linux-style sort shortcuts and for Unixware + support in configure (patch 1474427). Fixed sunos5 to do slow start + and to ensure cpucount is set (patch 1477386). Added pagination + routines to display.c and modified show_help to use it, since the + help screen is now longer than 24 lines. Applied patch for unixware + support that adds check for mas library (patch #1474423). Solaris + cpu percent now reflects a percentage of the entire server, rather + than a single cpu (bug 1478138). + +Mon Mar 27 2006 - wnl (3.6) + The production release of version 3.6. Fixed a minor scaling + bug in the decosf1 module. Support for MacOS X is officially + withdrawn although the macosx module is still part of the + distribution. Hopefully this is a temporary situation. + Documentation updated. + + +Wed Feb 15 2006 - wnl (3.6beta5) + Minor changes to eliminate warnings from the Sun Studio compiler. + These were mostly sloppy argument declarations. I also added + message.h to provide an interface file for just the message + related functions of display.c. + +Mon Dec 26 2005 - wnl (3.6beta4) + Added new netbsd module, courtesy of Simon Burge. + Fixed a few bugs in SVR4 module and added its use to + configure.ac, thanks to Sanchet Dighe. Also ensured that the + novpath Makefile was in the distribution. + Fixed portability problem in display.c + + +Mon Oct 24 2005 - wnl (3.6beta3) + Set up a color tagging mechanism in color.c to allow for the + dynamic creation of tag names to contol color highlighting. + These names are partially derived from the tags used to label + memory and swap information on the screen, thus are driven by + the machine module itself. Added -T option to list color + highlighting information. Help screen now includes the actual + list of sort order names. Incorporated some minor fixes to + the main code from the Freebsd source tree. Fixed bug #1324582. + Freebsd 5: removed WCPU column and added THR column. Display + for freebsd 4 and earlier unchanged since they don't track + threads in the kernel. Added LICENSE file to distribution. + +Wed Oct 12 2005 - wnl (3.6beta2) + Major overhaul to display.c. All lines of the display are + directly tracked and controlled via display_write and its + companion display_fmt. Added support for complete control + of ANSI color on the screen: this will be used in the future + to allow for full use of color everywhere on the screen. + Signal handling code now uses sigaction on all systems that + support it. Restored the freebsd module and did away with + freebsd4, and upgraded freebsd module to support 5.x. + Fix bug #1306099 (wio(wait) timer ignored on OSF1). + +Fri Sep 23 2005 - wnl (3.6beta1) + Fixed bugs #1266341 (compilation errors with gcc 4.x), + #1156464 (cpu% field for sunos), #1156243 (compilation + errors on AIX). Applied patches #1217855 (Solaris 10 + xarch flag). Overhaul of sunos5 module, making code more + efficient and easier to follow. Got rid of need for MEMTYPE + type in utils.h. Changed all memory statistics data in the + module specification from an int to a long to better support + 64-bit systems with lots of memory. Moved all unused modules + out of the distribution (I will add them back in as needed). + Moved freebsd module to freebsd4 as it won't work with 5.x + (a new module will be necessary). Added support to configure + for makes that don't understand VPATH. Updated documentation: + man page, FAQ, README, INSTALL. + +Mon Jan 24 2005 - wnl (3.6alpha10) + Updated aix43 module with ANSI function declarations and fixed + declaration of get_system_info. Configure now uses irixsgi + module for irix6* systems. Updates to the following modules: + irixsgi, sunos5. Fixed null pointer bug in color.c. Removed + some useless code and definitions in display.c + + +Sun Nov 28 2004 - wnl (3.6alpha9) + Replace AIX 5 module with alternate (bug 1056565). + Fixed vulnerability in use of snprintf. + +Fri Oct 22 2004 - wnl (3.6alpha8) + Support for linux 2.6, added more stuff to memory and swap lines. + Updated linuxthr module, which is only useful on 2.4 and earlier. + Added some color support back in (feature request 930588), but + still need to add it back to the per-process display. Added + OSF 5 support (untested). + Fixed bug 1017951 (invalid process count argument not caught) + +Tue Apr 20 2004 - wnl (3.6alpha7) + Added 64 bit support for AIX. + +Thu Apr 15 2004 - wnl (3.6alpha6) + Included fixes for decosf1 pid size and updated module. Also + added osf1 to list of recognized operating systems in configure.ac. + +Tue Mar 30 2004 - wnl (3.6alpha5) + Minor bug fixes and some code rearrangement. Changes to install + rule. Added several more platforms including: aix 4.2 thru 5, + MacOS 10, Dec OSF, HPUX 7 thru 11. Fixed the core dumping bug + in linux. Code cleanup, including sigdesc.h (by changing + sigconv.awk). Startup error messages are displayed on the + first screen rather than beforehand (no more pause). Cleaned + up interrupt handling to avoid a race condition. Eliminated + top.local.h. REMOVED Configure!!! + +Mon Mar 22 2004 - wnl (3.6alpha1) + Now using gnu autoconf. Eliminated the need for CFLAGS and LIBS + tags in the module source files. Autoconf tries to figure all + that out now. Machine module interface now uses flags to determine + if module supports sorting, selective display of idle processes, + viewing full commands. Added display of uptime for modules that + support it. Added display of full command lines for modules that + support it. 3.5 modules must be changed a bit to work for 3.6: + ORDER is no longer defined, and the module must fill in the + appropriate fields in struct statics to get the extra features. + Added a extenstion interface to allow for putting extra stuff + on the screen -- this is still half baked and not documented. + +Mon Feb 23 2004 - wnl (3.5) + Turned rc1 in to version 3.5. Only changes were to the FAQ. + +Mon Feb 2 2004 - wnl (3.5rc1) + Changed format_k (utils.c) to use MEMTYPE for its parameter. + On most systems this is a long, but if the module defines + USE_SIZE_T, this is set to be a size_t. The sunos5 module + now defines it, so that it will work correctly on 64-bit + machines. New "linuxthr" module for rolling up processes + that are really threads. Configure autodetects when running + on a 64-bit Solaris machine. + +Tue Dec 16 2003 - wnl (3.5beta13) + Improved linux module. For Solaris, changed "THR" column + heading to "LWP" since that's what they really are. + Thu Mar 30 2000 - wnl (3.5beta12) Updated modules: m_aix41.c, m_aix43.c, m_mtxinu.c, m_sco5.c, and m_ultrix4.c. diff --git a/Configure b/Configure deleted file mode 100755 index e760044043dd..000000000000 --- a/Configure +++ /dev/null @@ -1,565 +0,0 @@ -#!/bin/csh -f -# -# Configuration script for top. -# -# Use with version 3.0 and higher. -# -set PRIME = "/usr/games/primes" -set vars = (module LoadMax topn NominalTopn delay owner group mode random \ - TableSize bindir mandir manext mansty \ - Cmdshell Cmdcc Cmdawk Cmdinstall cdefs) -set fastrack = 0 -set yesno = (no yes) - -onintr byebye - -# make sure that getans is there and ready -if (! -e getans) then - echo 'This package is not complete. The shell file "getans" is missing.' - exit 10 -endif -chmod +x getans - -if ($#argv > 0) then -# fast track configuration - set fastrack = 1 -else -cat <<'EOF' -Configuration for top, version 3.5 - -One moment.... -'EOF' -endif - -# collect file names and module names -ls machine/m_*.c >$$.f -ls machine/m_*.man >$$.m -sed -e 's@^machine/m_@@' -e 's/.c$//' $$.f >$$.n - -# build Make.desc -sed -e 's@\.c@.desc\\@' $$.f | sed -e '$s/\\//' >$$.a -sed -e "/^DESCS/r $$.a" Make.desc.X >Make.desc - -# build desc files and SYNOPSIS as needed -make -f Make.desc >/dev/null -if ($status != 0) then - echo "Unable to build the synopsis." - echo 'Make sure the command "make" is on your path and try' - echo 'running Configure again.' - exit 1 -endif - -if (-e .defaults) then - echo "" - echo "Reading configuration from last time..." - source .defaults - set nodefaults = 0 - if ($fastrack == 1) then - set module = $1 - endif -else - if ($fastrack == 1) then - echo "No previous configuration was found." - set fastrack = 0 - set module = $1 - else - set module = "" - endif - set LoadMax = 5.0 - set topn = 15 - set NominalTopn = 18 - set delay = 5 - set TableSize = 0 - set bindir = /usr/local/bin - set mandir = /usr/man/manl - set manext = l - set mansty = man - set nodefaults = 1 - set Cmdshell = /bin/sh - set Cmdawk = awk - set Cmdinstall = ./install - set Cmdcc = cc - set cdefs = -O -endif -echo "" - -if ($fastrack == 1) then - grep -s $module $$.n >/dev/null - if ($status != 0) then - echo "$module is not recognized. To see a list of available modules" - echo 'run "Configure" with no arguments.' - rm -f $$.[fmna] - exit 1 - endif - set random1 = `expr $random + 1` - cat <<EOF -Using these settings: - Bourne Shell $Cmdshell - C compiler $Cmdcc - Compiler options $cdefs - Awk command $Cmdawk - Install command $Cmdinstall - - Module $module - LoadMax $LoadMax - Default TOPN $topn - Nominal TOPN $NominalTopn - Default Delay $delay -Random passwd access $yesno[$random1] - Table Size $TableSize - Owner $owner - Group Owner $group - Mode $mode - bin directory $bindir - man directory $mandir - man extension $manext - man style $mansty - -EOF - goto fast -endif - -cat <<'EOF' -You will be asked a series of questions. Each question will have a -default answer enclosed in brackets, such as "[5.0]". In most cases, -the default answer will work well. To use that value, merely press -return. - -'EOF' - -# display synopses - -getmod: -cat <<'EOF' - -The following machine-dependent modules are available: -'EOF' -awk -F: ' { printf "%-10s %s\n", $1, $2 }' SYNOPSIS -echo '' -./getans "What module is appropriate for this machine? " string "$module" .$$ -set module = `cat .$$` - -if ("$module" == "") then - echo "Please specify a valid module name." - goto getmod -endif - -# is it a valid one? -grep -s "$module" $$.n >/dev/null -if ($status != 0) then - echo "That is not a recognized module name." - goto getmod -endif - -# display a full description -sed -e '1,/DESCRIPTION:/d' -e '/^$/,$d' machine/m_${module}.desc - -# verify it -echo "" -./getans "Is this what you want to use?" yesno 1 .$$ -if (`cat .$$` == 0) then - goto getmod -endif -endif - -cat <<'EOF' - -First we need to find out a little bit about the executables needed to -compile top. - -'EOF' -./getans "What is the full path name for the Bourne shell" file "$Cmdshell" .$$ -set Cmdshell = `cat .$$` - -cat <<'EOF' - -Please supply the name of the appropriate command. It need not be a -full path name, but the named command does need to exist somewhere on -the current path. - -'EOF' -./getans "AWK Interpreter" path "$Cmdawk" .$$ -set Cmdawk = `cat .$$` -./getans "C Compiler" path "$Cmdcc" .$$ -set Cmdcc = `cat .$$` - -cat <<'EOF' - -The installer command needs to understand Berkeley-esque arguments: -"-o" for owner, "-g" for group, and "-m" for mode. A shell script -called "install" is distributed with top and is suitable for use by -top. You can specify a different program here if you like, or use -the shell script (the default). - -'EOF' -./getans "Installer" path "$Cmdinstall" .$$ -set Cmdinstall = `cat .$$` - -cat <<EOF - -What other options should be used with the $Cmdcc command (use "none" to -specify no options)? -EOF -./getans "Compiler options" string "$cdefs" .$$ -set cdefs = `cat .$$` -if ("$cdefs" == "none") then - set cdefs = "" -endif - -cat <<'EOF' - -Now you need to answer some questions concerning the configuration of -top itself. - -The space command forces an immediate update. Sometimes, on loaded -systems, this update will take a significant period of time (because all -the output is buffered). So, if the short-term load average is above -"LoadMax", then top will put the cursor home immediately after the space -is pressed before the next update is attempted. This serves as a visual -acknowledgement of the command. "LoadMax" should always be specified as a -floating point number. - -'EOF' -./getans "LoadMax" number "$LoadMax" .$$ -set LoadMax = `cat .$$` - -cat <<'EOF' - -"Default TOPN" is the default number of processes to show. This is the -number that will be used when the user does not specify the number of -processes to show. If you want "all" (or infinity) as the default, use -the value "-1". - -'EOF' - -./getans "Default TOPN" neginteger "$topn" .$$ -set topn = `cat .$$` - -cat <<'EOF' - -"Nominal_TOPN" is used as the default TOPN when Default_TOPN is Infinity -and the output is a dumb terminal. If we didn't do this, then -installations who use a default TOPN of Infinity will get every process in -the system when running top on a dumb terminal (or redirected to a file). -Note that Nominal_TOPN is a default: it can still be overridden on the -command line, even with the value "infinity". - -'EOF' - -./getans "Nominal TOPN" integer "$NominalTopn" .$$ -set NominalTopn = `cat .$$` - -cat <<'EOF' - -Default Delay is the default number of seconds to wait between screen -updates. - -'EOF' - -./getans "Default Delay" integer "$delay" .$$ -set delay = `cat .$$` - -echo "" - -set rand = 0 -if (-e /etc/nsswitch.conf) then - set rand = `grep '^passwd:.*nis' /etc/nsswitch.conf | wc -l` - if ($rand > 1) then - set rand = 1 - endif -else - ypwhich >&/dev/null - if ($status == 0 || -e /etc/passwd.dir || -e /etc/pwd.db) then - set rand = 1 - endif -endif - -if ($rand == 1) then - echo "It looks like you have a passwd file that can be accessed at random." - set pr = 'Do you want top to take advantage of this' -else - echo "It looks like you have conventional passwd file access. Top can take" - echo "advantage of a random access passwd mechanism if such exists. Do" - echo "you want top to assume that accesses to the file /etc/passwd are done" - set pr = 'with random access rather than sequential' -endif - -if ($nodefaults == 1) then - set random = $rand -endif - -./getans "${pr}?" yesno $random .$$ -set random = `cat .$$` - -echo "" -echo "Compiling prime.c" -$Cmdcc $cdefs -o prime prime.c -lm -if ($status != 0) then - echo "Oh well." - rm -f prime -endif - -echo "" - -ypcat passwd.byname >&/tmp/$$.a -if ($status == 0) then - set cnt = `wc -l </tmp/$$.a` - set mapfile = "NIS map" -else - rm /tmp/$$.a - niscat passwd.org_dir >&/tmp/$$.a - if ($status == 0) then - set cnt = `wc -l </tmp/$$.a` - set mapfile = "NISPLUS map" - else - set cnt = `wc -l </etc/passwd` - set mapfile = "file" - endif -endif -rm /tmp/$$.a -set double = `expr $cnt \* 2` -echo "I found $cnt entries in your passwd $mapfile. Top hashes the username to" -echo "uid mappings as it goes along and it needs a good guess on the size of" -echo "that hash table. This number should be the next highest prime number" -echo "after $double." -echo "" -if (-e prime) then - set pr = `./prime $double` - echo "I have calculated that to be $pr." -else if (-e $PRIME) then - set pr = `$PRIME $double | head -1` - echo "I have calculated that to be $pr." -else - set pr = $double - echo "I cannot calculate that prime number, so you will need to provide it for me." -endif - -if ($TableSize == 0) then - set TableSize = $pr -endif - -./getans "Enter the hash table size" integer "$TableSize" .$$ -set TableSize = `cat .$$` - -echo "" - -# !!! I need to fix this: /dev/kmem might not exist on some machines !!! - -# determine the right way to invoke ls to get full output -set ls = "ls -l" -if (`$ls getans | wc -w` < 9) then - set ls = "ls -lg" -endif - -set t_owner = root -set t_group = `$ls -d /usr/bin | awk ' { print $4 }'` -if (-e /proc) then - cat <<EOF -I see /proc out there. Many Unix variants provide the /proc file -system as a mechanism to get to a process's address space. This -directory is typically only accessible by root. However, there are a -few systems (such as DG/UX) on which this directory exists, but isn't -used. - -EOF - if (-r /proc/0/psinfo) then - set t_mode = 2711 - set mode = 2711 - set t_group = sys - set group = sys - cat <<EOF -It looks like this system is running Solaris 2.6 or greater. If this -is the case, then top can function just fine installed set group id to -sys. It does not need to be installed set-uid to root. - -EOF - else - set t_mode = 4711 - set mode = 4711 - cat <<EOF -I'm going to assume that top needs to run setuid to root, but you -should double check and use mode 2755 (set group id) if top doesn't -really need root access. If you are running SunOS 5.0 through SunOS -5.5.1 (that's Solaris 2.0 through Solaris 2.5.1) then you will need to -install top setuid root (owner root and mode 4711). In SunOS 5.6 -and higher top only requires set group id sys permissions. - -EOF - endif -else if (-e /dev/kmem) then - $ls /dev/kmem >/tmp/$$.b - grep '^....r..r..' /tmp/$$.b >&/dev/null - if ($status == 1) then - grep '^....r..-..' /tmp/$$.b >&/dev/null - if ($status == 0) then - set t_group = `awk ' { print $4 }' /tmp/$$.b` - set t_mode = 2755 - echo "It looks like only group $t_group can read the memory devices." - else - set t_mode = 4755 - echo "It looks like only root can read the memory devices." - endif - else - set t_mode = 755 - echo "It looks like anybody can read the memory devices." - endif -else - echo "It looks like there are no memory device special files." - set t_mode = 755 -endif -if ($nodefaults) then - set owner = $t_owner - set group = $t_group - set mode = $t_mode -endif -echo "Tell me how to set the following when top is installed:" -./getans "Owner" user "$owner" .$$ -set owner = `cat .$$` -./getans "Group owner" group "$group" .$$ -set group = `cat .$$` -./getans "Mode" integer "$mode" .$$ -set mode = `cat .$$` -rm -f /tmp/$$.b - -echo "" -./getans "Install the executable in this directory" file "$bindir" .$$ -set bindir = `cat .$$` - -echo "" -./getans "Install the manual page in this directory" file "$mandir" .$$ -set mandir = `cat .$$` - -echo "" -./getans "Install the manual page with this extension" string "$manext" .$$ -set manext = `cat .$$` - -echo "" -./getans "Install the manual page as 'man' or 'catman'" string "$mansty" .$$ -set mansty = `cat .$$` - -echo "" -echo "We are done with the questions." - -# Some Unix environments are so poor that their csh doesn't even support -# the "eval" builtin. Check for this before relying on its use to save -# the current configuration. -/bin/csh -fc "eval echo foo" >&/dev/null -if ($status == 1) then - echo "Can't save configuration (nonfatal)" -else - echo "Saving configuration..." -# save settings to use as defaults the next time - rm -f .defaults - touch .defaults - foreach v ($vars) - set tmp = `eval echo \$$v` - echo set $v = "'$tmp'" >>.defaults - end -endif - -fast: - -# clean up -rm -f $$.[fmna] - -# set the link for machine.c -rm -f machine.c machine.o -ln -s machine/m_${module}.c machine.c - -# get definitions out of the module file -set libs = `grep LIBS: machine/m_${module}.desc | sed -e 's/^.[^:]*: *//'` -set cflgs = `grep CFLAGS: machine/m_${module}.desc | sed -e 's/^.[^:]*: *//'` -set tcap = `grep TERMCAP: machine/m_${module}.desc | sed -e 's/^.[^:]*: *//'` -set math = `grep MATH: machine/m_${module}.desc | sed -e 's/^.[^:]*: *//'` - -# get osrev defition, if we can -set uname="" -if (-e /usr/bin/uname) then - set uname=/usr/bin/uname -else if (-e /bin/uname) then - set uname=/bin/uname -endif - -if ("$uname" != "") then -# different versions of tr can't agree on the way to specify ranges, so -# we will have to give the range explicitly.....sigh. - set osrev="-DOSREV=`$uname -r | tr -cd ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`" -else - set osrev="" -endif - -# default for tcap (termcap) -if ("$tcap" == "") then - set tcap="-ltermcap" -else if ("$tcap" == "none") then - set tcap="" -endif - -# allow for the module to override or remove -lm -if ("$math" == "") then - set math="-lm" -else if ("$math" == "none") then - set math="" -endif - -if ( { grep -s SIGKILL /usr/include/signal.h } ) then - set signal="/usr/include/signal.h" -else - set signal="/usr/include/sys/signal.h" -endif - - -echo "Building Makefile..." -sed -e "s|%topn%|$topn|" \ - -e "s|%delay%|$delay|" \ - -e "s|%owner%|$owner|" \ - -e "s|%group%|$group|" \ - -e "s|%mode%|$mode|" \ - -e "s|%bindir%|$bindir|" \ - -e "s|%mandir%|$mandir|" \ - -e "s|%manext%|$manext|" \ - -e "s|%mansty%|$mansty|" \ - -e "s|%tablesize%|$TableSize|" \ - -e "s|%libs%|$libs|" \ - -e "s|%cflgs%|$cflgs|" \ - -e "s|%termcap%|$tcap|" \ - -e "s|%math%|$math|" \ - -e "s|%cdefs%|$cdefs|" \ - -e "s|%signal%|$signal|" \ - -e "s|%cc%|$Cmdcc|" \ - -e "s|%awk%|$Cmdawk|" \ - -e "s|%install%|$Cmdinstall|" \ - -e "s|%shell%|$Cmdshell|" \ - -e "s|%osrev%|$osrev|" \ - Makefile.X >Makefile - -echo "Building top.local.h..." -sed -e "s|%LoadMax%|$LoadMax|" \ - -e "s|%TableSize%|$TableSize|" \ - -e "s|%NominalTopn%|$NominalTopn|" \ - -e "s|%topn%|$topn|" \ - -e "s|%delay%|$delay|" \ - -e "s|%random%|$random|" \ - top.local.H >top.local.h - -echo "Building top.1..." -sed -e "s|%topn%|$topn|" \ - -e "s|%delay%|$delay|" \ - top.X >top.1 -if (-e machine/m_${module}.man ) then - cat machine/m_${module}.man >>top.1 -endif - -# clean up -rm -f .$$ - -echo 'Doing a "make clean".' -make clean - -echo 'To create the executable, type "make".' -echo 'To install the executable, type "make install".' -exit 0 - -byebye: -rm -f .$$ $$.[fmna] /tmp/$$.[ab] -exit 1 diff --git a/DISCLAIMER b/DISCLAIMER deleted file mode 100644 index 796d7a24c604..000000000000 --- a/DISCLAIMER +++ /dev/null @@ -1,31 +0,0 @@ -DISCLAIMER - -"top" is distributed free of charge. It should not be considered an -official product of Group sys Consulting. William LeFebvre supports -"top" in his spare time and as time permits. - -NO WARRANTY: - -BECAUSE "top" IS DISTRIBUTED FREE OF CHARGE, THERE IS ABSOLUTELY NO -WARRANTY PROVIDED, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING, GROUP SYS CONSULTING, ARGONNE -NATIONAL LABORATORY, NORTHWESTERN UNIVERSITY, WILLIAM N. LeFEBVRE -AND/OR OTHER PARTIES PROVIDE "top" "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -PROGRAM IS WITH YOU. SHOULD THE "top" PROGRAM PROVE DEFECTIVE, YOU -ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -IN NO EVENT WILL GROUP SYS CONSULTING, ARGONNE NATIONAL LABORATORY, -NORTHWESTERN UNIVERSITY, WILLIAM N. LeFEBVRE, AND/OR ANY OTHER PARTY -WHO MAY MODIFY AND REDISTRIBUTE "top", BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL -OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE -(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED -INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE -PROGRAM TO OPERATE WITH OTHER PROGRAMS) THE PROGRAM, EVEN IF YOU HAVE -BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY -ANY OTHER PARTY. - -So there! @@ -1,264 +1,340 @@ - TOP - Version 3.5 - Beta Release 11 + TOP + Version 3.8beta1 - William LeFebvre - with much help from others + William LeFebvre + with much help from others + Frequently Asked Questions and their Answers -FREQUENTLY ASKED QUESTIONS AND THEIR ANSWERS -This FAQ is broken out in to several topics. + GENERAL -GENERAL + 1. What is top? - 1. "Where do I get the latest version of top?" + Top provies the user with a regularly updated display showing + information about the system and its top cpu-using processes. Think + of it as a full-screen "ps" output that gets updated at regular + intervals. -The official site for top is "ftp.groupsys.com" in the directory -"/pub/top". It is also available from the following mirror sites: -"pharos.dgim.doc.ca" in /packages/top, "uiarchive.uiuc.edu" in -/pub/packages/top, "sunsite.auc.dk" in /pub/unix/top. European -users should consider using the Denmark (dk) site. - - 2. "Is there a web page for top?" + 2. Where do I get the latest version of top? -Yes. Point your browser at http://www.groupsys.com/top. It includes -all documentation, a nice interactive display which describes the -various components of the output of top, web-based retrieval of the -package, year 2000 information, and pointers to the mailing list. + The official site for top is "ftp.unixtop.org" in the directory + "/pub/top". Top is also a SourceForge project, and the most recent + releases are available on any of the SourceForge mirrors. The + SourceForge project page is at + http://sourceforge.net/projects/unixtop. - 3. "Is there a mailing list for top?" + 3. Is there a web page for top? -The official list for announcements is "top-announce@groupsys.com". -This list is managed by "majordomo@groupsys.com". Announcements of -importance to all top users will be sent to this list, including new -releases, availability of beta test versions, emergency revisions and -patches, etc. Anyone is welcome to join top-announce. This is a -read-only list. The list of subscribers will not (intentionally) be -made available, and postings to the list are limited. + Yes. Point your browser at http://www.unixtop.org. It includes all + documentation, a nice interactive display which describes the various + components of the output of top, web-based retrieval of the package, + year 2000 information, and other neat stuff. -In addition, there is a top developers mailing list that is used by -beta testers and other people who help me port the program to various -machines. Membership to this list is solely at my discretion. If you -feel qualified to act as a beta tester, or if you are doing development -work on top (such as porting to a new platform), you may submit a -request by sending a message to "top-spinners-request@groupsys.com" -containing the word "subscribe". I will contact you within a few days, -as my schedule permits. + 4. Is there a mailing list or on-line bulletin board for top? - 4. "What about Year 2000 compliance"? + There is a mailing list used for general announcements regarding top, + including new releases. This mailing list is available to sourceforge + members and can be accessed from the unixtop sourceforge project + page. Visit SourceForge and search for the project "unixtop", then + click on "mailing lists". There are also on-line forums available + through SourceForge where members can post questions and comments. -Top should not experience any problems with the transition to the year -2000. A full statement concerning top and the year 2000 can be found -in the file "Y2K" included with the distribution. + 5. What about Year 2000 compliance? + Top did not experience any problems with the transition to the year + 2000. A full statement concerning top and the year 2000 can be found + in the file "Y2K" included with the distribution. - 5. "Why does it take so long for a new version of top to go through the - beta test process?" + 6. Will there be another major release of top? Will there be a top + version 4? -This is completely my fault. I have just not had the time to give top -the attention it deserves. I thank everyone for their patience, and I -hope that with the recent changes in the direction of my career that I -can spend more time on this. + I have some great ideas for the next major release of top, and I very + much want to make those ideas a reality. What I don't have much of + these days is free time. But I will keep poking at it and I hope to + have top version 4.0 ready by the fall of 2006. - 6. "Top is not written in ANSI C. Do you ever plan to change that?" + 7. Does top really support multi-processor systems? -Top predates ANSI C by about 5 years. Yeah, it'll get "fixed" eventually. -Probably in 3.6. + On platforms that support multiple processors, top is able to detect + and correctly summarize the information about those processors. What + top does not do is break down the cpu states summary (the third line + of the display) by cpu. Instead it collects the cpu state information + from all processors and combines them in to a single line. Some + vendors include a modified version of top that presents this + information for each cpu. Top 3.7 may have this functionality but it + is not present in the standard top 3.6 release. + 8. Is top under CVS control? Can I access the sources via SourceForge + CVS or Subversion? -CONFIGURING + I maintain top using subversion, not CVS. Although I utilize my own + private subversion repository, it is regularly mirrored in to the + SourceForge Subversion repository. You can access the SourceForge + repository here: https://svn.unixtop.org/unixtop/top-3. - 7. "Configure said that it saw /proc and is recommending that I install top - setuid root. Is there any way around this? Is it safe?" -There is no way around it. Complain to POSIX. Every effort has been made -to make top a secure setuid program. However, we cannot guarantee that -there are no security problems associated with this configuration. The -places where top is most vulnerable are the builtin kill and renice -commands. There is no internal top command that causes top to start a shell -as a subprocess. Some SVR4 systems may contain a bug that enables a user to -renice his own processes downward (to lower nice values that are more -favorable for the process). This problem has been fixed for the Solaris 2.x -modules, but may still exist in others. We will hopefully fix this up in -the next release. + COMPILING - 8. "Why is Configure a c-shell script? I thought c-shell scripts were - evil?" + 9. We just upgraded our operating system to a new version and top broke. + What should we do? -They are. :-) I'll probably be rewriting the Configure script for the -next release, or switching to something like Gnu configure. + Recompile it. Top is very sensitive to changes in internal kernel + data structures. It is not uncommon for a new version of the + operating system to include changes to kernel data structures. -COMPILING + RUNNING - 9. "We just upgraded our operating system to a new version and top broke. - What should we do?" +10. I just finished compiling top and it works fine for root, but when I + try to run it as a regular user it either complains about files it + can't open or it doesn't display all the information it should. Did I + do something wrong? -Recompile it. Top is very sensitive to changes in internal kernel data -structures. It is not uncommon for a new version of the operating system to -include changes to kernel data structures. + Well, you're just not done. On many operating systems today, access + to many of the kernel memory devices and other system files is + restricted to either root or a particular group. The configure script + figures this out (usually) and makes sure that the "install" rule in + the Makefile will install top so that anyone can run it successfully. + However, you have to *install* it first. Do this with the command + "make install". +11. Top is (not) displaying idle processes and I don't (do) want it to. -RUNNING + This default has only changed about a dozen times, and I finally got + tired of people whining about it. Go read the manual page for the + current version and pay special attention to the description of the + "TOP" environment variable. -10. "I just finished compiling top and it works fine for root, but when - I try to run it as a regular user it either complains about files - it can't open or it doesn't display all the information it should. - Did I do something wrong?" +12. We have so much memory in our machine that the memory status display + (the fourth line) ends up being longer than 80 characters. This + completely messes up top's output. Is there a patch? -Well, you're just not done. On many operating systems today, access to -many of the kernel memory devices and other system files is restricted to -either root or a particular group. The Configure script figures this out -(usually) and makes sure that the "intsall" rule in the Makefile will -install top so that anyone can run it successfully. However, you have to -*install* it first. Do this with the command "make install". + Most modules have been changed to use new memory formatting functions + which will display large values in terms of megabytes instead of + kilobytes. This should fix all occurences of this problem. Also note + that newer versions of top can use columns beyond 79, and understand + window resizes. So you can always make your window wider. -11. "Top is (not) displaying idle processes and I don't (do) want it to." +13. I tried to compile top with gcc and it doesn't work. I get + compilation errors in the include files, or I get an executable that + dumps core, or top displays incorrect numbers in some of the + displays. What's wrong? -This default has only changed about a dozen times, and I finally got tired -of people whining about it. Go read the manual page for the current version -and pay special attention to the description of the "TOP" environment -variable. + Gnu CC likes very much to use its own include files. Not being a gcc + expert, I can't explain why it does this. But I can tell you that if + you upgrade your operating system (say from Solaris 2.6 to Solaris + 2.7) after installing gcc, then the include files that gcc uses will + be incorrect, especially those found in the "sys" directory. Your + choices are: (1) rebuild and reinstall the "standard" include files + for gcc (look for scripts in the distribution called "fixincludes" + and "fixinc.svr4"), (2) compile machine.c with + "CFLAGS=-I/usr/include" then make the rest of the object files + normally, or (3) use a different compiler. -12. "We have so much memory in our machine that the memory status display - (the fourth line) ends up being longer than 80 characters. This - completely messes up top's output. Is there a patch?" +14. The cpu state percentages are all wrong, indicating that my machine + is using 95% system time when it is clearly idle. What's wrong? -Most modules have been changed to use new memory formatting functions which -will display large values in terms of megabytes instead of kilobytes. This -should fix all occurences of this problem. If you encounter a system where -this large memory display overflow is still occurring, please let me know -(send mail to <wnl@groupsys.com>). Also note that newer versions of top can -use columns beyond 79, and understand window resizes. So you can always -make your window bigger. + This can happen if you compiled with gcc using the wrong include + files. See the previous question. -13. "I tried to compile top with gcc and it doesn't work. I get - compilation errors in the include files, or I get an executable that - dumps core, or top displays incorrect numbers in some of the displays. - What's wrong?" -Gnu CC likes very much to use its own include files. Not being a gcc -expert, I can't explain why it does this. But I can tell you that if -you upgrade your operating system (say from Solaris 2.4 to Solaris -2.5) after installing gcc, then the include files that gcc uses will -be incorrect, especially those found in the "sys" directory. Your -choices are: (1) rebuild and reinstall the "standard" include files -for gcc (look for scripts in the distribution called "fixincludes" and -"fixinc.svr4"), (2) compile machine.c with "CFLAGS=-I/usr/include" -then make the rest of the object files normally, or (3) use "cc". -Solaris 2.6 users should also consult FAQ #20. + FREEBSD PROBLEMS -14. "The cpu state percentages are all wrong, indicating that my machine is - using 95% system time when it is clearly idle. What's wrong?" +15. This version of top does not show individual threads with the "t" or + "H" commands. Instead it says "command not available." Why? -This can happen if you compiled with gcc using the wrong include files. -See the previous question. + Previous versions of top attempted to support the display of + individual threads under FreeBSD through the use of the "t" command. + However, the FreeBSD kernel does not supply sufficient or correct + information on the individual threads within a process. So the data + that was being displayed was incorrect and misleading. Therefore, top + version 3.8 disables the use of this command to prevent the display + of incorrect information. FreeBSD 8.0 will correctly report + per-thread information and top version 3.8 supports the use of the + "t" command for version 8.0. +16. The "f" command (to display full command lines for the processes) + does not work and instead says "command not available". Why? + + The current version of top is able to use sysctl to retrieve almost + all of the information it needs without having to open /dev/kmem. The + one piece of information not available via sysctl is the full command + line of each argument. If you run top as a regular user and it cannot + open /dev/kmem (in other words, it is not installed set-gid to the + kmem group) then it will disable the "f" command. Make sure the top + binary is installed with a group ownership of "kmem" and with the + set-gid bit on if you want the "f" command to work properly. + + + MACOSX PROBLEMS + +17. I tried to configure top on my Mac OSX system and I got an error + claiming "macosx not supported". What up? + + Since I don't have full time root access to a Mac OSX system I cannot + provide effective support for the platform. MacOSX uses Mach, and it + is very difficult to extract accurate system and process information + from the system. It takes a lot of trial and error, along with root + access. I have included the most up-to-date version of the macosx + module in the distribution, but I do not claim that it works. If you + want to try to use it, you can configure with "./configure + --with-module=macosx". + + + SUNOS PROBLEMS + +18. I tried compiling top under SunOS version 4.1.x and it got compile + time errors or run time errors. Is there a patch? + + If you try compiling top in a "System V environment" under SunOS + (that is, /usr/5bin is before /usr/bin on your path) then the + compilation may fail. This is mostly due to the fact that top thinks + its being compiled on a System V machine when it really isn't. The + only solution is to put /usr/bin and /usr/ucb before /usr/5bin on + your path and try again. + + + SOLARIS PROBLEMS + + + NOTE: the most common source of problems with top under Solaris is + the result of compiling it with the wrong front end. Make sure that + /usr/ucb is not on your path before attempting to compile top under + Solaris. + +19. Is there somewhere I can get a pre-compiled package? + + Yes. Although I don't provide pre-compiled binaries, you can get a + Sun-style package from www.sunfreeware.com. + +20. Under Solaris 2, when I type "make", the system says "language + optional software package not installed." What's going on? + + You tried to compile with /usr/ucb/cc. Make sure /usr/ucb is not on + your path. Furthermore, you do not have a Sun compiler installed on + your system. You need a compiler to make top. Either Sun's C compiler + or the Gnu C compiler will work fine. + +21. Under Solaris 2, when I run top as root it only shows root processes, + or it only shows processes with a PID less than 1000. It refuses to + show anything else. What do I do? + + You probably compiled it with /usr/ucb/cc instead of the real C + compiler. /usr/ucb/cc is a cc front end that compiles programs in BSD + source-level compatability mode. You do not want that. Make sure that + /usr/ucb is not on your path and try compiling top again. + +22. Under Solaris 2, I compiled top using what I am sure is the correct + compiler but when I try to run it it complains about missing dynamic + libraries. What is wrong? + + Check to see if you have LD_LIBRARY_PATH defined in your shell. If + you do, make sure that /usr/ucblib is not on the path anywhere. Then + try compiling top again. + +23. Under Solaris 2, when I try to run top it complains that it can't + open the library "libucb.so.1". So I changed the LIBS line in + m_sunos5.c to include -R/usr/ucblib to make sure that the dynamic + linker will look there when top runs. I figured this was just an + oversight. Was I right? + + No, you were not right. As distributed, top requires no alterations + for successful compilation and operations under any release of + Solaris 2. You probably compiled top with /usr/ucb/cc instead of the + real C compiler. See FAQ 22 for more details. + +24. On my 64-bit system some processes show up with incorrect information + (such as zero memory). + + If you are running a 64-bit system, then you need to make sure that + you are running the 64-bit top binary. Top's configure script + attempts to detect 64-bit systems, and will automatically generate + both 32-bit and 64-bit binaries on such systems. If you use or + install the 32-bit binary on a 64-bit system top will still run but + will not produce the correct results. This will also happen if you + configure your distribution on a 32-bit system then compile with that + configuration on a 64-bit system. You must configure and compile on + the same system. For Sparc systems the 32-bit binary will be created + in the subdirectory "sparcv7" and the 64-bit binary will be created + in the subdirectory "sparcv9". For Intel systems the directories will + be "i386" (32-bit) and "amd64" (64-bit). In all cases a copy of + /usr/lib/isaexec is made in the main directory and called "top". This + program will choose the correct binary to run from one of these + subdirectories. See isaexec(3c) for more details. + +25. Can I install both 32-bit and 64-bit binaries on a central file + server and have machines which mount it automatically use the correct + one? + + Yes. If you configure and compile on a 64-bit system, top's configure + script and makefile will automatically create both 32-bit and 64-bit + binaries. The "install" rule in the makefile will install these + binaries in subdirectories of /usr/local/bin appropriate to the + architecture (sparcv7/sparcv9 or i386/amd64) then create a copy of + /usr/lib/isaexec named "top" in /usr/local/bin to ensure that the + appropriate is run when a user types "top". If you make sure that you + configure and compile on a 64-bit system, then "make install" will do + the right thing. + +26. This version of top show less available swap space than previous + versions. Why does it no longer match the output of the swap summary + produced with "swap -s"? + + Starting with version 3.6 of top, the amount of swap space reported + by top has been changed to reflect only disk-based swap space. The + swap summary produced with "swap -s" also includes memory-based swap + space. This changed was made for several reasons. It makes the + display under Solaris more like those of other operating systems. The + display is more what users expect (except those used to previous + versions of top). Most importantly, "swap -s" gets its data via an + undocumented system interface. Now that top no longer displays that + data it can use publically documented and maintained system + interfaces to retrieve its data. + + + SVR4-DERIVED PROBLEMS + +27. When I run top on my SVR4-derived operating system, it displays all + the system information at the top but does not display any process + information (or only displays process information for my own + processes). Yet when I run it as root, everything works fine. What's + wrong? + + Your system probably uses the pseudo file system "/proc", which is by + default only accessible by root. Top needs to be installed setuid + root on such systems if it is going to function correctly for normal + users. + + + SVR42 PROBLEMS + +28. The memory display doesn't work right. Why? + + This is a known bug with the svr42 module. The problem has been + traced down to a potential bug in the "mem" driver. The author of the + svr42 module is working on a fix. + + + STILL STUCK + +29. I'm still stuck. To whom do I report problems with top? + + The most common problems are caused by top's sensitivity to internal + kernel data structures. So make sure that you are using the right + include files, and make sure that you test out top on the same + machine where you compiled it. Sun's BSD Source Compatability Mode is + also a common culprit. Make sure you aren't using either /usr/ucb/cc + or any of the libraries in /usr/ucblib. Finally, make sure you are + using the correct module. If there does not appear to be one + appropriate for your computer, then top probably will not work on + your system. + + If after reading all of this file and checking everything you can you + are still stuck, then please use SourceForge to submit a support + request or a bug. Top is supported by the SourceForge project named + "unixtop". On SourceForge you will find defect tracking, a mailing + list, and on-line forums. You can also contact the author through + SourceForge. -SUNOS PROBLEMS - -15. "I tried compiling top under SunOS version 4.1.x and it got compile time - errors. Is there a patch?" - -If you try compiling top in a "System V environment" under SunOS (that is, -/usr/5bin is before /usr/bin on your path) then the compilation may fail. -This is mostly due to the fact that top thinks its being compiled on a -System V machine when it really isn't. The only solution is to put /usr/bin -and /usr/ucb before /usr/5bin on your path and try again. - - -SVR4-derived PROBLEMS - -16. "When I run top on my SVR4-derived operating system, it displays all - the system information at the top but does not display any process - information (or only displayes process information for my own - processes). Yet when I run it as root, everything works fine." - -Your system probably uses the pseudo file system "/proc", which is by -default only accessible by root. Top needs to be installed setuid root on -such systems if it is going to function correctly for normal users. - - -SOLARIS PROBLEMS - -17. "Under Solaris 2, when I run top as root it only shows root processes, - or it only shows processes with a PID less than 1000. It refuses to - show anything else. What do I do?" - -You probably compiled it with /usr/ucb/cc instead of the real C compiler. -/usr/ucb/cc is a cc front end that compiles programs in BSD source-level -compatability mode. You do not want that. Make sure that /usr/ucb is not -on your path and try compiling top again. - -18. "Under Solaris 2, I compiled top using what I am sure is the correct - compiler but when I try to run it it complains about missing dynamic - libraries. What is wrong?" - -Check to see if you have LD_LIBRARY_PATH defined in your shell. If you do, -make sure that /usr/ucblib is not on the path anywhere. Then try compiling -top again. - -19. "Under Solaris 2, when I try to run top it complains that it can't open - the library "libucb.so.1". So I changed the LIBS line in m_sunos5.c - to include -R/usr/ucblib to make sure that the dynamic linker will look - there when top runs. I figured this was just an oversight. Was I - right?" - -No, you were not right. As distributed, top requires NO alterations -for successful compilation and operations under any release of Solaris -2. You probably compiled top with /usr/ucb/cc instead of the real C -compiler. See FAQ #10 for more details. - -20. "When I try to compile top under Solaris 2.6 using gcc I get compile - time errors. There appear to be problems with the include files, - such as 'u_rlimit has incomplete type' and/or 'u_saved_rlimit has - incomplete type'. I've already run fixinc.svr4 as per FAQ #13. - Why didn't that fix it?" - -Only top versions 3.5 and later are compatible with Solaris 2.6. Make -sure you are using the most up-to-date version. Earlier beta release -copies of version 3.5 had additional problems when compiled with gcc. -Retrieve the official version 3.5 (non-beta) release from one of the -sites listed in FAQ #1 or FAQ #2. - - -SCO PROBLEMS - -21. "When I try to run Configure, it complains about a syntax error." - -Some versions of SCO's csh do not understand the syntax "$<". Earlier -releases of top depended on this syntax to read input from the installer's -terminal during the installation process. Version 3.5 fixes this. - - -SVR42 PROBLEMS - -22. "The memory display doesn't work right. Why?" - -This is a known bug with the svr42 module. The problem has been traced down -to a potential bug in the "mem" driver. The author of the svr42 module is -working on a fix. - - -STILL STUCK - -23. I'm still stuck. To whom do I report problems with top?" - -The most common problems are caused by top's sensitivity to internal kernel -data structures. So make sure that you are using the right include files, -and make sure that you test out top on the same machine where you compiled -it. Sun's BSD Source Compatability Mode is also a common culprit. Make -sure you aren't using either /usr/ucb/cc or any of the libraries in -/usr/ucblib. Finally, make sure you are using the correct module. If there -does not appear to be one appropriate for your computer, then top probably -will not work on your system. - -If after reading all of this file and checking everything you can you are -still stuck, then send mail to "wnl@groupsys.com". I will answer your mail -when I have time. Please bear with me in that regard! If it looks like the -problem is machine-specific, I will forward the report along to the module's -author. If you would like to converse directly with the module author, the -authors' names are listed at the beginning of the module .c file in the -"machine" directory. @@ -1,166 +1,54 @@ TOP - Version 3.5 + Version 3.8beta1 William LeFebvre and a cast of many INSTALLATION -Configuration and installation of top is very straightforward. After -unpacking the sources, run the script "Configure". It will present you -with a series of questions, all of which should be explained in the -presentation. After you have answered all the questions, "Configure" will -perform all the necessary configuration. Once this is finished, type -"make install". Make will compile the sources then install the resulting -executable and manual page in the appropriate places. +Configuration and installation of top is easy. Top version 3.6 +comes with a configure script generated by gnu autoconf. After +unpacking the tar file, simply run "./configure". The script will +automatically perform a series of checks on the system and determine +what settings are appropriate for the Makefile and certain include +files. Once configure completes, simply type "make install" and +top will be compiled and installed. By default, the installation +location is /usr/local/bin. You can change the destination location +with the --prefix option to configure. -The most difficult step in the configuration is the choice of an -appropriate machine-specific module. The Configure script gives you a -list of choices complete with brief descriptions of when each choice is -appropriate. Each module is contained in a separate c file in the -directory "machine". The module contains all of the machine-specific code -that makes top work correctly on the architecture in question. All of the -code in the top-level directory is machine-independent (or at least -strives to be). Hints for some module choices that are not obvious are -given at the end of this file. +In addition to the standard options, top's configure script supports +the following: -The first comment in each c file in that directory contains the synopsis -AND a detailed description of the machines for which that module is -appropriate. It also contains a list of authors for that module. If you -are really stumped in this choice, use grep to find your machine -manufacturer's name or operating system name in machine/*.c. If you still -can't find one that is appropriate, then chances are very good that one -hasn't been written yet. If that is the case, then you are out of luck. + --with-module=name -HANDLING MULTIPLE ARCHITECTURES + Force the use of a particular module. Modules are located + in the subdirectory "machine". A module's name is derived + from the file's basename without the leading "m_". -If you need to recompile top for a different architecture (that is, using -a different module) you need to reconfigure top. A short cut is available -to make this a little easier. If all of your previous answers to the -configuration questions (except for the module name of course) are -adequate for the new architecture, then you can just use the command -"Configure <modulename>". The configuration script will reconfigure top -using the new module and all the answers you gave last time. It will -finish with a "make clean". Once that completes, type "make install" -and make will compile the sources and do the installation. + --with-ext=name -HANDLING MULTIPLE OS VERSIONS + Compile with the extension "name", found in the subdirectory + "ext". At the present time, there are no extensions in the + standard distribution. -By far the most frequently received bug report for top is something like -this: "We just upgraded our operating system to version 99.9.9.9 and top -broke. What should we do?" The simple answer is "recompile". + --enable-debug + --disable-debug -Top is very sensitive to changes in internal kernel data structures -(especially the proc and user structures). Some operating systems -(especially SunOS) are notorious for changing these structure in every -minor release of the OS. This means that a top executable made under one -version of the OS will not always work correctly (if even at all) under -another version. This is just one of those tough facts of life. There is -really no way around it. + Default off. Include debugging output in the compilation, + which can be seen with the -D switch. -To make life even worse, some operating systems (SunOS again) will use -slightly different proc and user structures on different models. For -example, "top" built on a SparcStation 2 will not run correctly on a -SparcStation 10, even if they are both running SunOS 4.1.3. These -unfortunate circumstances make maintaining top very difficult, especially -in an environment that runs several different versions of the same -operating system. + --enable-color + --disable-color -But there is hope. If your operating system has a properly functioning -"uname" command then you can handle this problem rather gracefully. -Included in the distribution is a shell file called "metatop". All this -shell file does is: + Default on. Include code that allows for the use of color + in the output display. Use --disable-color if you do not + want this feature compiled in to the code. The configure + script also recognizes the spelling "colour". - exec top-`uname -m`-`uname -r` "$@" - -So when you run this script, it execs a filename that is unique to your -specific machine architecture and your OS revision number. - -To use "metatop", do the following: - - . on any machine, run Configure and choose the module that is - appropriate for the machine - . for all machines which use the same module: - . group machines according to machine architecture AND OS - revision number (i.e.: sun4-4.1.1, sun4c-4.1.1, sun4c-4.1.2, - sun4-4.1.3, sun4c-4.1.3, sun4m-4.1.3, ...) - . for each group, choose one machine from that group and on it - run "make clean; make installmeta". - - -The "installmeta" rule in the makefile will insure that top is compiled, -install the shell file "metatop" as "top", then install the executable -"top" with a name appropriate to the machine architecture and OS revision. - - -HINTS FOR CHOOSING THE CORRECT MODULE: - -SOLARIS 2.x - -All versions of Solaris will now work with the module sunos5. Version -specific modules (such as sunos54) no longer exist. - - -SUNOS 4.x AND MULTIPROCESSOR ARCHITECTURES - -First, we need to be speaking the same language: - -sun4 a regular sparc sun 4 architecture machine (sparc station 1, - sparc station 2, IPC, SLC, etc.) - -sun4m a multiprocessor sparc (Sparc 10, 4/670, 4/690) - -I intended to write the sunos4 module so that an executable compiled on a -sun4m machine would work correctly on a sun4 machine. Unfortunately my -experiments indicate that this cannot be done. It turns out that the user -structure is so different between these two architectures that nothing -short of a serious hack will make the same executable work correctly on -both machines. I recommend that you use the separate module "sunos4mp" -when making an executable for a sun4m architecture, and use "sunos4" when -making an executable for sun4 or sun4c architectures. - -DIGITAL UNIX V4.0 - -This is the successor to DECOSF/1. Use the module decosf1. - -SOLBOURNE OPERATING SYSTEM (OS/MP) - -If you are running OS/MP version 4.1A, then use the module "osmp4.1a". - -If you are running a version of OS/MP OLDER than 4.1A (that is, one -of its predecessors), use the module "sunos4". - -If you are running OS/MP 4.1B or LATER, use the module "sunos4mp". - -HP/UX OPERATING SYSTEM - -The module hpux8 works on all version 8 systems. Some say that it works -with version 9 as well, but one user did send me a separate module for -version 9. This module has only been tested on series 800 machines. I -would recommend the following for those running version 9: try hpux9 and -if it doesn't work then try hpux8. If neither work, then send mail to me -and/or the modules' authors. Another note: we have a model 730 supposedly -running version 9.01. The module hpux9 did not compile successfully, but -the module hpux8 worked fine. The module hpux10 works on all revisions of -HP/UX 10 except 10.10, where HP removed the definition of the proc structure -from the system include files. - -NET/2 386BSD SYSTEMS - -If your version of the operating system has patchkit 2.4 installed, -then you will need to modify machine/m_386bsd.c and uncomment the -definition of PATCHED_KVM. This patchkit makes what more than a few -people believe to be a wholly unnecessary patch to the way the kvm -routines work. - -A/UX SYSTEMS - -There is a module for A/UX 3.0 and 3.1. Whether or not it works for -any other version is not known. Proceed at your own risk. - -Although AUX does not generally have a renice systemcall, it can be -implemented by tweeking kernel memory. The flag IMPLEMENT_SETPRIORITY -controls the inclusion of this code. It is off be default. While -such a simple hack should not be difficult to get right, USE THIS -FEATURE AT YOUR OWN RISK! + --enable-kill + --disable-kill + Default on. Include code that allows for renicing and sending + signals to processes from within top (the 'kill' and 'renice' + commands). Use --disable-kill if you do not want this feature + compiled in to the code. diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000000..3b210dc1041d --- /dev/null +++ b/LICENSE @@ -0,0 +1,30 @@ +Copyright (c) 1984 through 2008, William LeFebvre +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + + * Neither the name of William LeFebvre nor the names of other +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Make.desc.X b/Make.desc.X deleted file mode 100644 index 6fcb79e2778a..000000000000 --- a/Make.desc.X +++ /dev/null @@ -1,24 +0,0 @@ -# Makefile for .desc files - -# This makefile is the prototype for "Make.desc", which is used by -# top's Configure script to build .desc files and the SYNOPSIS file. -# Configure then uses these files to ask appropriate questions. - -# Written by William LeFebvre, Group sys Consulting -# (formerly of Northwestern University and Rice University) - -# DO NOT EDIT "Make.desc"!!! Make changes to "Make.desc.X", -# then "make veryclean", then run "Configure". - -# The list of .desc files will be inserted after this next line: -DESCS=\ - -.SUFFIXES: .desc - -.c.desc: - sed -e '/^$$/,$$d' -e 's,^[/ *]*,,' $< > $@ - -all: SYNOPSIS - -SYNOPSIS: $(DESCS) - grep SYNOPSIS: $(DESCS) | sed -e 's@^machine/m_@@' -e 's@.desc:.[^:]*: *@:@' >SYNOPSIS diff --git a/Makefile.X b/Makefile.X deleted file mode 100644 index a9bfe65b820a..000000000000 --- a/Makefile.X +++ /dev/null @@ -1,117 +0,0 @@ -# Makefile for "top", a top 10 process display for Unix -# -# This makefile is for top, version 3 -# -# Written by William LeFebvre, Group sys Consulting -# (formerly of Northwestern University and Rice University) - -# DO NOT EDIT "Makefile"!!!! Make changes to "Makefile.X" and rerun -# Configure. - -# Executables (these should be obvious): - -SHELL = %shell% -CC = %cc% -AWK = %awk% -INSTALL = %install% - -# installation information: -# OWNER - name (or uid) for the installed executable's owner -# GROUP - group name (or gid) for the installed executable's group -# MODE - mode for the installed executable (should start with a 0) -# BINDIR - directory where the executable should live -# MANDIR - directory where the manual page should live -# MANEXT - installed man pages end in .$(MANEXT) -# MANSTY - "man" or "catman" depending on what's to be installed -# SIGNAL - <signal.h> or <sys/signal.h>; the one with signal definitions -# TROFF - most appropriate troff command - -OWNER = %owner% -GROUP = %group% -MODE = %mode% -BINDIR = %bindir% -MANDIR = %mandir% -MANEXT = %manext% -MANSTY = %mansty% -SIGNAL = %signal% - -# Values for the two defaults in "top": -# TOPN - default number of processes to display -# DELAY - default delay between updates -# -# set TOPN to -1 to indicate infinity (so that top will display as many -# as the screen will hold). - -TOPN = %topn% -DELAY = %delay% - -CFILES = top.c commands.c display.c screen.c username.c \ - utils.c version.c getopt.c machine.c -OBJS = top.o commands.o display.o screen.o username.o \ - utils.o version.o getopt.o machine.o - -CDEFS = %cdefs% -LIBS = %libs% -TERMCAP = %termcap% -MATH = %math% - -CFLAGS = %cflgs% $(CDEFS) -LINTFLAGS = -x $(CDEFS) - -all: Makefile top.local.h top - -Makefile: Makefile.X - @echo 'You need to run the script "Configure" before running "make".' - exit 10 - -top.local.h: top.local.H - @echo 'You need to run the script "Configure" before running "make".' - exit 10 - -top: $(OBJS) - rm -f top - $(CC) $(CDEFS) -o top $(OBJS) $(TERMCAP) $(MATH) $(LIBS) - -lint: sigdesc.h - $(LINT) $(LINTFLAGS) $(CFILES) - -# include file dependencies -top.o: boolean.h display.h screen.h top.h top.local.h utils.h machine.h -commands.o: boolean.h sigdesc.h top.h utils.h -display.o: boolean.h display.h layout.h screen.h top.h top.local.h utils.h -screen.o: boolean.h screen.h -utils.o: top.h -version.o: top.h patchlevel.h -username.o: top.local.h utils.h - -# when compiling machine.c, include os revision definition -machine.o: machine.c top.h machine.h utils.h - $(CC) "%osrev%" $(CFLAGS) -c machine.c - -# automatically built include file -sigdesc.h: sigconv.awk $(SIGNAL) - $(AWK) -f sigconv.awk $(SIGNAL) >sigdesc.h - -clean: - rm -f *.o top core core.* sigdesc.h - -veryclean: clean - rm -f Make.desc machine/*.desc .defaults top.tar SYNOPSIS Makefile top.local.h top.1 machine.c prime - -install: top top.1 install-top install-$(MANSTY) - -install-top: - $(INSTALL) -o $(OWNER) -m $(MODE) -g $(GROUP) top $(BINDIR) - -install-man: - $(INSTALL) top.1 $(MANDIR)/top.$(MANEXT) - -install-catman: - tbl top.1 | nroff -man > $(MANDIR)/top.$(MANEXT) - -installmeta: top top.1 - $(INSTALL) -o $(OWNER) -m 755 -g $(GROUP) metatop $(BINDIR)/top - @echo $(INSTALL) -o $(OWNER) -m $(MODE) -g $(GROUP) top $(BINDIR)/top-`uname -m`-`uname -r` - @$(INSTALL) -o $(OWNER) -m $(MODE) -g $(GROUP) \ - top $(BINDIR)/top-`uname -m`-`uname -r` - $(INSTALL) top.1 $(MANDIR)/top.$(MANEXT) diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 000000000000..ac97b3560f5c --- /dev/null +++ b/Makefile.in @@ -0,0 +1,92 @@ +# Makefile +# +# This makefile was generated by configure from a Makefile.in definition. + +PROGRAM=top +INC=boolean.h color.h commands.h config.h display.h globalstate.h hash.h \ + loadavg.h machine.h message.h os.h screen.h sigdesc.h top.h username.h \ + utils.h version.h +SRC=color.c commands.c display.c hash.c screen.c top.c username.c utils.c version.c @SRC@ +OBJ=color.o commands.o display.o hash.o screen.o top.o username.o utils.o version.o @OBJ@ +MANPAGE=top.1 +CLEAN_SRC=sigdesc.h +CLEAN_EXTRA=@CLEAN_EXTRA@ + +srcdir=@srcdir@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +mandir=@mandir@ +datarootdir=@datarootdir@ +VPATH=@srcdir@ + +PACKAGE_NAME=@PACKAGE_NAME@ +SIGNAL=@SIGNAL_H@ +ARCHFLAG=@ARCHFLAG@ +AWK=@AWK@ +CC=@CC@ +CFLAGS=$(DEFS) $(DEFAULT_INCLUDES) $(CFLAGSONLY) $(ARCHFLAG) +CFLAGSONLY=@CFLAGS@ +CPPFLAGS=@CPPFLAGS@ +DEBUG= +DEFS=@DEFS@ $(DEBUG) +ISAEXEC=@ISAEXEC@ +LDFLAGS=@LDFLAGS@ +LIBS=@LIBS@ +MODULE_CFLAGS=@MODULE_CFLAGS@ + +INSTALL=@INSTALL@ +INSTALL_PROGRAM=@INSTALL_PROGRAM@ +INSTALL_DATA=@INSTALL_DATA@ +INSTALL_OPTS_PROG=@INSTALL_OPTS_PROG@ +INSTALL_OPTS_DATA= + +DEFAULT_INCLUDES = -I. -I$(srcdir) + +BINARY = $@ +COMPILE = $(CC) $(CFLAGS) $(CPPFLAGS) +LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $(BINARY) + + +@FIRST_RULE@ + +$(PROGRAM): $(OBJ) + $(LINK) $(OBJ) $(LIBS) + +# explicit dependency for the module appropriate to this machine +m_@MODULE@.o: $(srcdir)/machine/m_@MODULE@.c + $(COMPILE) $(MODULE_CFLAGS) -o $@ -c $(srcdir)/machine/m_@MODULE@.c + +sigdesc.h: $(srcdir)/sigconv.awk $(SIGNAL) + $(AWK) -f $(srcdir)/sigconv.awk $(SIGNAL) >sigdesc.h + +@INSTALL_RULE@ + +install-man: $(MANPAGE) + mkdir -p $(DESTDIR)$(mandir)/man1 + $(INSTALL_DATA) $(INSTALL_OPTS_DATA) \ + $(MANPAGE) $(DESTDIR)$(mandir)/man1/$(MANPAGE) + +clean: + -rm -f $(PROGRAM) $(OBJ) $(CLEAN_SRC) $(CLEAN_EXTRA) + +distclean: clean + -rm -f Makefile config.status config.cache config.log config.h + +configure: configure.ac + autoheader + autoconf + +# Include file dependencies +color.o: os.h config.h message.h color.h +commands.o: os.h config.h sigdesc.h top.h machine.h globalstate.h \ + boolean.h commands.h display.h utils.h version.h +display.o: os.h config.h top.h machine.h screen.h layout.h display.h \ + boolean.h utils.h color.h +screen.o: os.h config.h top.h screen.h boolean.h +top.o: os.h config.h top.h machine.h globalstate.h commands.h display.h \ + screen.h boolean.h username.h utils.h version.h color.h +username.o: os.h config.h top.h utils.h hash.h +utils.o: os.h config.h top.h utils.h +version.o: config.h top.h +m_@MODULE@.o: top.h machine.h utils.h loadavg.h @@ -3,8 +3,6 @@ Instructions for porting top to other architectures. This is still a preliminary document. Suggestions for improvement are most welcome. -My address is now "wnl@groupsys.com". - Before you embark on a port, please send me a mail message telling me what platform you are porting top to. There are three reasons for this: (1) I may already have a port, (2) module naming needs to be @@ -163,3 +161,69 @@ change in one of the existing files, please contact me so that we can discuss the details. I want to keep such changes as general as possible. +-------- + +Changes were made to the module interface between 3.5 and 3.6. Here are +the changes that need to be made to port a 3.5 module to 3.6: + +The array that stores memory statistics and is passed back in the system +information structure as "memory" must now be an array of (signed) longs. +This was done to more easily accomodate systems that have gigabytes of +memory. Since the numbers are supposed to be kilobytes, a long can still +represent up to 2 terabytes. Look for "int memory_stats[X]" (where "X" +is some arbitrary number) and change it to "long memory_stats[X]". If +the module support reporting swap information on a separate line, then +its "swap_stats" array also needs to be an array of longs. + +The argument to proc_owner should be an int, as in "int pid". When it is +used in proc_owner it should be cast as necessary. Many operating systems +will require it to be cast to a pid_t before being compared to the appropriate +element in the proc structure. + +In the function format_next_process, the last argument in the main call +to sprintf is the string that contains the command for the process. +Make sure that this last argument is enclosed in a call to "printable". +For example: "printable(MPP(pp, p_comm))". + +The third argument to "get_process_info" needs to be changed to an integer, +typically "int compare_index". The call to qsort in get_process_info may +be guarded by "if (compare != NULL)". If it is, remove the if statement. + +The other changes to get_process_info depends on whether or not the module +supports multiple sort orders. + +To support multiple keys: + +Create an array int (*proc_compares[])() and assign to it the list of +comparison functions, NULL terminated. For example: + +int (*proc_compares[])() = { + compare_cpu, + compare_size, + compare_res, + compare_time, + NULL }; + +In get_process_info there is a call to qsort which uses one of the +functions in proc_compares. It should be changed so that its fourth +argument is "proc_compares[compare_index]". + +If the module contains the function "proc_compare", it should be removed. + +There should also be a NULL-terminated array of strings which list the names +for the sort keys, for example: + +char *ordernames[] = +{"cpu", "size", "res", "time", NULL}; + +To indicate that this module supports multiple sort keys, add the following +line in machine_init: + + statics->order_names = ordernames; + +If there is no support for multiple keys: + +Leave statics->order_names alone and call the comparison function of +your choice in get_process_info, ignoring the third argument. + + @@ -1,5 +1,5 @@ TOP - Version 3.5 + Version 3.8beta1 William LeFebvre and a cast of dozens @@ -21,46 +21,47 @@ Version 3 has many bug fixes from version 2.5, and it has also been reorganized in a major way to make it easy to port to other platforms. All system dependent code is now contained in one file. -Top now includes a configuration script called "Configure". It helps -the installer choose the correct parameters for this particular -installation. This script MUST be run before attempting to compile top. - -Top requires read access to the memory files "/dev/kmem" and "/dev/mem" -as well as the system image "/vmunix". Some installations have these -files protected from general access. These sites would have to install -this program in the same way that programs such as "ps" are installed. -In addition, on those Unix variants that support the proc filesystem -(such as SVR4 and Solaris 2), top requires read access to all the files -in /proc: typically dictating that top be installed setuid to root. +Starting with version 3.6, top includes a "configure" script generated +by Gnu's autoconf. This script MUST be run before attempting to +compile top. It will explore the system and generate approriate +contents for Makefile, config.h, and top.1. + +On some systems, top requires read access to the memory files +"/dev/kmem" and "/dev/mem" as well as the system's kernel image. Most +installations have these files protected from general access. These +sites would have to install this program in the same way that programs +such as "ps" are installed. On most systems with a /proc file system, +top will try to read everything it can from /proc, but may need extra +permissions to do so. The configure script will determine the +permissions needed by the top binary, and a "make install" as root +will get the binary installed correctly. Sometimes this requires that +the binary be installed with set-group-id privileges and, in rare +cases, set-user-id to root. CAVEAT: version 3 of top has internal commands that kill and renice processes. Although I have taken steps to insure that top makes appropriate checks with these commands, I cannot guarantee that these -internal commands are totally secure. IF YOU INSTALL top as a SETUID -program, you do so AT YOUR OWN RISK! I realize that some operating -systems will require top to run setuid, and I will do everything I can -to make sure that top is a secure setuid program. - -Configure will ask you to input values for certain parameters. Before -each parameter, Configure will display a description of what the -parameter does. Read the description and choose an appropriate value. -Sometimes a default will appear in brackets. Typing just return will -choose the default. - -System support now takes the form of "modules". Adding support for -a different architecture requires only adding a module. Configure -asks which module to use when it is configuring top. See the file -"Porting" for a description of how to write your own module. +internal commands are totally secure. IF YOU INSTALL top SET-USER-ID +TO ROOT, YOU DO SO AT YOUR OWN RISK! I realize that some operating +systems will require top to run setuid root, and I will do everything +I can to make sure that top is a secure setuid program. + +System support now takes the form of "modules". Adding support for a +different architecture requires only adding a module. These modules +are contained in the subdirectory "machine". The "configure" script +automatically determines which module is approproate. However, it may +not be able to determine what the correct module is. This can happen +either because it doesn't know about the system or there is no module +to support the system. In the former case, if you know which module +to use, you can force "configure" to choose a particular module with +the option "--with-module". For example, if you want to force the use +of the svr4 module (which appears as "machine/m_svr4.c") then use +"configure --with-module=svr4" to generate the correct Makefile. See +the file "Porting" for a description of how to write your own module. To compile and install "top", read the file "INSTALL" and follow the directions and advice contained therein. -Once you have created a binary for one particular type of machine, you -can reconfigure for another type with "./Configure modulename" where -"modulename" is replaced with the appropriate module name. All other -parameter values are kept the same. Note that in some cases this may -not be appropriate. - If you make any kind of change to "top" that you feel would be beneficial to others who use this program, or if you find and fix a bug, please send me the change. @@ -69,33 +70,50 @@ Be sure to read the FAQ enclosed with the distrubution. It contains answers to the most commonly asked questions about the configuration, installation, and operation of top. +COLOR + +Version 3.6 incorporated the idea of using ANSI color sequences to +enhance information on the screen. By default, no color is used. But +you can configure the use of color through the environment variable +TOPCOLORS (or, for compatibility, TOPCOLOURS). The interface is +identical to the one first implemented by chris@spang.uk.eu.org, but +the implementation is entirely different. The option -C can be used +to diable the feature entirely. + +Any information at the top of the screen can be enhanced with color. +However, due to implementation difficulties, the per-process area +cannot be color-enhanced. A complete description of color support can +be found in the man page. References for ANSI color codes can be +found all over the Internet, but if you want a handy reference, look +in color.h. + AVAILABILITY -The latest version of "top" is now being made available via anonymous -FTP from the host "ftp.groupsys.com" in the directory "/pub/top". -Additional modules will be made available in the directory -"/pub/top/m". The site "eecs.nwu.edu" will continue to house copies -of the distribution as well. +Note that top is now a sourceforge project! Its project name is +"unixtop" and you can access its project page here: + +http://sourceforge.net/projects/unixtop -Here are HTML links for the four best "top" archive sites: +On the project page you can find more information and access the +official bug and feature request trackers. If you find a bug, +want to request a feature, or need help, please submit a request +to the appropriate tracker on sourceforge. Thank you. -<A HREF="ftp://ftp.groupsys.com/pub/top">Top archive (groupsys.com)</A> -<A HREF="ftp://eecs.nwu.edu/pub/top">Top archive (eecs.nwu.edu)</A> -<A HREF="ftp://pharos.dgim.doc.ca/packages/top"> Top mirror (dgim.doc.ca)</A> -<A HREF="ftp://uiarchive.uiuc.edu/pub/packages/top/">Top mirror (uiuc.edu)</A> +Subversion access is also provided by Sourceforge. If Subversion is +installed on your system you can check out the project with the +following command: -New releases will be posted to comp.sources.unix as they become -available. Sites which arhive that newsgroup will also contain copies -of the distribution. + svn co https://svn.sourceforge.net/svnroot/unixtop unixtop -Announcements about availability will be made to the mailing list -"top-announce@groupsys.com". This is an open list maintained by -majordomo. To join the list, send a message containing the word -"subscribe" to "top-announce-request@groupsys.com". Addresses of -subscribers to this list are kept confidential and will never be used -for any purpose other than as recipients of announements concerning -this software. +There is also a web site dedicated to the project, and it is here: + +http://www.unixtop.org + +The latest version of "top" is available as a download through +sourceforge. Start here to access the downloadable files: + +http://sourceforge.net/project/showfiles.php?group_id=72892 KNOWN PROBLEMS: @@ -115,6 +133,16 @@ make sure the include files you are using are up to date BEFORE sending me a bug report. Look in the gcc source distribution for the shell script "fixincludes". +MacOS X + +Since I don't have full time root access to a MacOS X system I cannot +provide effective support for the platform. MacOS X uses Mach, and it +is very difficult to extract accurate system and process information +from the system. It takes a lot of trial and error, along with root +access. I have included the most up-to-date version of the macosx module +in the distribution, but I do not claim that it works. If you want to +try to use it, you can configure with "./configure --with-module=macosx". + HP/UX 10.10 In their infinite wisdom, the folks at HP have decided that mere mortals @@ -127,31 +155,6 @@ information. I have no immediate solution for this problem, but hope to obtain a sufficiently complete definition of "struct proc" at some point in the near future. Stay tuned. -DIGITAL UNIX 4.0 (DECOSF/1 V4.0) - -A user has reported that idle processes are not displayed regardless -of the flags used when invoking top. We have not had time to track -this problem down. - -DECOSF/1 V3.0 - -There is a bug either in the module, in utils.c, or in DEC's optimizer that -is tickled by the decosf1 module when compiled under V3.0 (and perhaps -earlier versions). Top compiled using DEC's compiler with optimization -will consistently produce a segmentation fault (in format_next_process -while calling sprintf). To work around this problem, either compile top -with gcc or turn off optimization (compile without -O). We think that -one of the bugs fixed in utils.c fixed this problem as well, but we are -not certain. - - -System V R 4.2 - -Load average and memory displays do not work. The problem has been -traced down to a potential bug in the "mem" driver. The author -of the svr42 module is working on a fix. - - GRATITUDE @@ -159,34 +162,30 @@ My perpetual thanks to all the people who have helped me support top on so many platforms. Without these people, top would not be what it is. Here is a partial list of contributors and other individuals. - Robert Boucher <boucher@sofkin.ca> - Marc Cohen <marc@aai.com> - David Cutter <dpc@grail.com> - Casper Dik <Casper.Dik@Sun.COM> - Charles Hedrick <hedrick@geneva.rutgers.edu> - Andrew Herbert <andrew@werple.apana.org.au> - Jeff Janvrin <jeff.janvrin@columbiasc.ncr.com> - Torsten Kasch <torsten@techfak.uni-bielefeld.de> - Petri Kutvonen <kutvonen@cs.helsinki.fi> - William L. Jones <jones@chpc> - Tim Pugh <tpugh@oce.orst.edu> - Steve Scherf <scherf@swdc.stratus.com> - Phillip Wu <pwu01@qantek.com.au> + Robert Boucher, Marc Cohen, David Cutter, Casper Dik, + Charles Hedrick, Andrew Herbert, Jeff Janvrin, Torsten Kasch, + Petri Kutvonen, William L. Jones, Tim Pugh, Steve Scherf, + Phillip Wu (My apologies if I missed anyone.) +LICENSE + +Top is distributed free of charge under the same terms as the BSD +license. For an official statement, please refer to the file "LICENSE" +which should be included with the source distribution. + + AUTHOR - William LeFebvre - Group sys Consulting - wnl@groupsys.com +If you wish to contact me, please send a message to the sourceforge +username "wnl". + William LeFebvre U.S. Mail address: William LeFebvre - Group sys Consulting 11585 Jones Bridge Road - Suite 420-139 - Alpharetta, GA 30022 - (770) 813-3224 + Suite 420 PMB 139 + Alpharetta, GA 30202 @@ -22,5 +22,5 @@ top. THERE IS ABSOLUTELY NO WARRANTY PROVIDED WITH THIS SOFTWARE. -Please see the contents of the file "DISCLAIMER" for further +Please see the contents of the file "LICENSE" for further information. diff --git a/ap_snprintf.c b/ap_snprintf.c new file mode 100644 index 000000000000..f9ba3500f27a --- /dev/null +++ b/ap_snprintf.c @@ -0,0 +1,1193 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This code is based on, and used with the permission of, the + * SIO stdio-replacement strx_* functions by Panos Tsirigotis + * <panos@alumni.cs.colorado.edu> for xinetd. + */ + +#include "config.h" +#include <stdio.h> +#include <ctype.h> +#include <sys/types.h> +#include <stdarg.h> +#include <string.h> +#include <stdlib.h> +#include <math.h> +#include <netinet/in.h> + +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +typedef struct { + char *curpos; + char *endpos; +} ap_vformatter_buff; + + +#define API_EXPORT(type) type +#define API_EXPORT_NONSTD(type) type + +#define ap_isalnum(c) (isalnum(((unsigned char)(c)))) +#define ap_isalpha(c) (isalpha(((unsigned char)(c)))) +#define ap_iscntrl(c) (iscntrl(((unsigned char)(c)))) +#define ap_isdigit(c) (isdigit(((unsigned char)(c)))) +#define ap_isgraph(c) (isgraph(((unsigned char)(c)))) +#define ap_islower(c) (islower(((unsigned char)(c)))) +#define ap_isprint(c) (isprint(((unsigned char)(c)))) +#define ap_ispunct(c) (ispunct(((unsigned char)(c)))) +#define ap_isspace(c) (isspace(((unsigned char)(c)))) +#define ap_isupper(c) (isupper(((unsigned char)(c)))) +#define ap_isxdigit(c) (isxdigit(((unsigned char)(c)))) +#define ap_tolower(c) (tolower(((unsigned char)(c)))) +#define ap_toupper(c) (toupper(((unsigned char)(c)))) + + +typedef enum { + NO = 0, YES = 1 +} boolean_e; + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef AP_LONGEST_LONG +#define AP_LONGEST_LONG long +#endif +#define NUL '\0' +#define WIDE_INT long +#define WIDEST_INT AP_LONGEST_LONG + +typedef WIDE_INT wide_int; +typedef unsigned WIDE_INT u_wide_int; +typedef WIDEST_INT widest_int; +#ifdef __TANDEM +/* Although Tandem supports "long long" there is no unsigned variant. */ +typedef unsigned long u_widest_int; +#else +typedef unsigned WIDEST_INT u_widest_int; +#endif +typedef int bool_int; + +#define S_NULL "(null)" +#define S_NULL_LEN 6 + +#define FLOAT_DIGITS 6 +#define EXPONENT_LENGTH 10 + +/* + * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions + * + * XXX: this is a magic number; do not decrease it + */ +#define NUM_BUF_SIZE 512 + +/* + * cvt.c - IEEE floating point formatting routines for FreeBSD + * from GNU libc-4.6.27. Modified to be thread safe. + */ + +/* + * ap_ecvt converts to decimal + * the number of digits is specified by ndigit + * decpt is set to the position of the decimal point + * sign is set to 0 for positive, 1 for negative + */ + +#define NDIG 80 + +/* buf must have at least NDIG bytes */ +static char *ap_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag, char *buf) +{ + register int r2; + double fi, fj; + register char *p, *p1; + + if (ndigits >= NDIG - 1) + ndigits = NDIG - 2; + r2 = 0; + *sign = 0; + p = &buf[0]; + if (arg < 0) { + *sign = 1; + arg = -arg; + } + arg = modf(arg, &fi); + p1 = &buf[NDIG]; + /* + * Do integer part + */ + if (fi != 0) { + p1 = &buf[NDIG]; + while (p1 > &buf[0] && fi != 0) { + fj = modf(fi / 10, &fi); + *--p1 = (int) ((fj + .03) * 10) + '0'; + r2++; + } + while (p1 < &buf[NDIG]) + *p++ = *p1++; + } + else if (arg > 0) { + while ((fj = arg * 10) < 1) { + arg = fj; + r2--; + } + } + p1 = &buf[ndigits]; + if (eflag == 0) + p1 += r2; + *decpt = r2; + if (p1 < &buf[0]) { + buf[0] = '\0'; + return (buf); + } + while (p <= p1 && p < &buf[NDIG]) { + arg *= 10; + arg = modf(arg, &fj); + *p++ = (int) fj + '0'; + } + if (p1 >= &buf[NDIG]) { + buf[NDIG - 1] = '\0'; + return (buf); + } + p = p1; + *p1 += 5; + while (*p1 > '9') { + *p1 = '0'; + if (p1 > buf) + ++ * --p1; + else { + *p1 = '1'; + (*decpt)++; + if (eflag == 0) { + if (p > buf) + *p = '0'; + p++; + } + } + } + *p = '\0'; + return (buf); +} + +static char *ap_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf) +{ + return (ap_cvt(arg, ndigits, decpt, sign, 1, buf)); +} + +static char *ap_fcvt(double arg, int ndigits, int *decpt, int *sign, char *buf) +{ + return (ap_cvt(arg, ndigits, decpt, sign, 0, buf)); +} + +/* + * ap_gcvt - Floating output conversion to + * minimal length string + */ + +static char *ap_gcvt(double number, int ndigit, char *buf, boolean_e altform) +{ + int sign, decpt; + register char *p1, *p2; + register int i; + char buf1[NDIG]; + + p1 = ap_ecvt(number, ndigit, &decpt, &sign, buf1); + p2 = buf; + if (sign) + *p2++ = '-'; + for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--) + ndigit--; + if ((decpt >= 0 && decpt - ndigit > 4) + || (decpt < 0 && decpt < -3)) { /* use E-style */ + decpt--; + *p2++ = *p1++; + *p2++ = '.'; + for (i = 1; i < ndigit; i++) + *p2++ = *p1++; + *p2++ = 'e'; + if (decpt < 0) { + decpt = -decpt; + *p2++ = '-'; + } + else + *p2++ = '+'; + if (decpt / 100 > 0) + *p2++ = decpt / 100 + '0'; + if (decpt / 10 > 0) + *p2++ = (decpt % 100) / 10 + '0'; + *p2++ = decpt % 10 + '0'; + } + else { + if (decpt <= 0) { + if (*p1 != '0') + *p2++ = '.'; + while (decpt < 0) { + decpt++; + *p2++ = '0'; + } + } + for (i = 1; i <= ndigit; i++) { + *p2++ = *p1++; + if (i == decpt) + *p2++ = '.'; + } + if (ndigit < decpt) { + while (ndigit++ < decpt) + *p2++ = '0'; + *p2++ = '.'; + } + } + if (p2[-1] == '.' && !altform) + p2--; + *p2 = '\0'; + return (buf); +} + +/* + * The INS_CHAR macro inserts a character in the buffer and writes + * the buffer back to disk if necessary + * It uses the char pointers sp and bep: + * sp points to the next available character in the buffer + * bep points to the end-of-buffer+1 + * While using this macro, note that the nextb pointer is NOT updated. + * + * NOTE: Evaluation of the c argument should not have any side-effects + */ +#define INS_CHAR(c, sp, bep, cc) \ + { \ + if (sp >= bep) { \ + vbuff->curpos = sp; \ + if (flush_func(vbuff)) \ + return -1; \ + sp = vbuff->curpos; \ + bep = vbuff->endpos; \ + } \ + *sp++ = (c); \ + cc++; \ + } + +#define NUM( c ) ( c - '0' ) + +#define STR_TO_DEC( str, num ) \ + num = NUM( *str++ ) ; \ + while ( ap_isdigit( *str ) ) \ + { \ + num *= 10 ; \ + num += NUM( *str++ ) ; \ + } + +/* + * This macro does zero padding so that the precision + * requirement is satisfied. The padding is done by + * adding '0's to the left of the string that is going + * to be printed. We don't allow precision to be large + * enough that we continue past the start of s. + * + * NOTE: this makes use of the magic info that s is + * always based on num_buf with a size of NUM_BUF_SIZE. + */ +#define FIX_PRECISION( adjust, precision, s, s_len ) \ + if ( adjust ) { \ + int p = precision < NUM_BUF_SIZE - 1 ? precision : NUM_BUF_SIZE - 1; \ + while ( s_len < p ) \ + { \ + *--s = '0' ; \ + s_len++ ; \ + } \ + } + +/* + * Macro that does padding. The padding is done by printing + * the character ch. + */ +#define PAD( width, len, ch ) do \ + { \ + INS_CHAR( ch, sp, bep, cc ) ; \ + width-- ; \ + } \ + while ( width > len ) + +/* + * Prefix the character ch to the string str + * Increase length + * Set the has_prefix flag + */ +#define PREFIX( str, length, ch ) *--str = ch ; length++ ; has_prefix = YES + + +/* + * Convert num to its decimal format. + * Return value: + * - a pointer to a string containing the number (no sign) + * - len contains the length of the string + * - is_negative is set to TRUE or FALSE depending on the sign + * of the number (always set to FALSE if is_unsigned is TRUE) + * + * The caller provides a buffer for the string: that is the buf_end argument + * which is a pointer to the END of the buffer + 1 (i.e. if the buffer + * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) + * + * Note: we have 2 versions. One is used when we need to use quads + * (conv_10_quad), the other when we don't (conv_10). We're assuming the + * latter is faster. + */ +static char *conv_10(register wide_int num, register bool_int is_unsigned, + register bool_int *is_negative, char *buf_end, + register int *len) +{ + register char *p = buf_end; + register u_wide_int magnitude; + + if (is_unsigned) { + magnitude = (u_wide_int) num; + *is_negative = FALSE; + } + else { + *is_negative = (num < 0); + + /* + * On a 2's complement machine, negating the most negative integer + * results in a number that cannot be represented as a signed integer. + * Here is what we do to obtain the number's magnitude: + * a. add 1 to the number + * b. negate it (becomes positive) + * c. convert it to unsigned + * d. add 1 + */ + if (*is_negative) { + wide_int t = num + 1; + + magnitude = ((u_wide_int) -t) + 1; + } + else + magnitude = (u_wide_int) num; + } + + /* + * We use a do-while loop so that we write at least 1 digit + */ + do { + register u_wide_int new_magnitude = magnitude / 10; + + *--p = (char) (magnitude - new_magnitude * 10 + '0'); + magnitude = new_magnitude; + } + while (magnitude); + + *len = buf_end - p; + return (p); +} + +static char *conv_10_quad(widest_int num, register bool_int is_unsigned, + register bool_int *is_negative, char *buf_end, + register int *len) +{ + register char *p = buf_end; + u_widest_int magnitude; + + /* + * We see if we can use the faster non-quad version by checking the + * number against the largest long value it can be. If <=, we + * punt to the quicker version. + */ + if ((num <= ULONG_MAX && is_unsigned) || (num <= LONG_MAX && !is_unsigned)) + return(conv_10( (wide_int)num, is_unsigned, is_negative, + buf_end, len)); + + if (is_unsigned) { + magnitude = (u_widest_int) num; + *is_negative = FALSE; + } + else { + *is_negative = (num < 0); + + /* + * On a 2's complement machine, negating the most negative integer + * results in a number that cannot be represented as a signed integer. + * Here is what we do to obtain the number's magnitude: + * a. add 1 to the number + * b. negate it (becomes positive) + * c. convert it to unsigned + * d. add 1 + */ + if (*is_negative) { + widest_int t = num + 1; + + magnitude = ((u_widest_int) -t) + 1; + } + else + magnitude = (u_widest_int) num; + } + + /* + * We use a do-while loop so that we write at least 1 digit + */ + do { + u_widest_int new_magnitude = magnitude / 10; + + *--p = (char) (magnitude - new_magnitude * 10 + '0'); + magnitude = new_magnitude; + } + while (magnitude); + + *len = buf_end - p; + return (p); +} + + + +static char *conv_in_addr(struct in_addr *ia, char *buf_end, int *len) +{ + unsigned addr = ntohl(ia->s_addr); + char *p = buf_end; + bool_int is_negative; + int sub_len; + + p = conv_10((addr & 0x000000FF) , TRUE, &is_negative, p, &sub_len); + *--p = '.'; + p = conv_10((addr & 0x0000FF00) >> 8, TRUE, &is_negative, p, &sub_len); + *--p = '.'; + p = conv_10((addr & 0x00FF0000) >> 16, TRUE, &is_negative, p, &sub_len); + *--p = '.'; + p = conv_10((addr & 0xFF000000) >> 24, TRUE, &is_negative, p, &sub_len); + + *len = buf_end - p; + return (p); +} + + + +static char *conv_sockaddr_in(struct sockaddr_in *si, char *buf_end, int *len) +{ + char *p = buf_end; + bool_int is_negative; + int sub_len; + + p = conv_10(ntohs(si->sin_port), TRUE, &is_negative, p, &sub_len); + *--p = ':'; + p = conv_in_addr(&si->sin_addr, p, &sub_len); + + *len = buf_end - p; + return (p); +} + + + +/* + * Convert a floating point number to a string formats 'f', 'e' or 'E'. + * The result is placed in buf, and len denotes the length of the string + * The sign is returned in the is_negative argument (and is not placed + * in buf). + */ +static char *conv_fp(register char format, register double num, + boolean_e add_dp, int precision, bool_int *is_negative, + char *buf, int *len) +{ + register char *s = buf; + register char *p; + int decimal_point; + char buf1[NDIG]; + + if (format == 'f') + p = ap_fcvt(num, precision, &decimal_point, is_negative, buf1); + else /* either e or E format */ + p = ap_ecvt(num, precision + 1, &decimal_point, is_negative, buf1); + + /* + * Check for Infinity and NaN + */ + if (ap_isalpha(*p)) { + *len = strlen(strcpy(buf, p)); + *is_negative = FALSE; + return (buf); + } + + if (format == 'f') { + if (decimal_point <= 0) { + *s++ = '0'; + if (precision > 0) { + *s++ = '.'; + while (decimal_point++ < 0) + *s++ = '0'; + } + else if (add_dp) + *s++ = '.'; + } + else { + while (decimal_point-- > 0) + *s++ = *p++; + if (precision > 0 || add_dp) + *s++ = '.'; + } + } + else { + *s++ = *p++; + if (precision > 0 || add_dp) + *s++ = '.'; + } + + /* + * copy the rest of p, the NUL is NOT copied + */ + while (*p) + *s++ = *p++; + + if (format != 'f') { + char temp[EXPONENT_LENGTH]; /* for exponent conversion */ + int t_len; + bool_int exponent_is_negative; + + *s++ = format; /* either e or E */ + decimal_point--; + if (decimal_point != 0) { + p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative, + &temp[EXPONENT_LENGTH], &t_len); + *s++ = exponent_is_negative ? '-' : '+'; + + /* + * Make sure the exponent has at least 2 digits + */ + if (t_len == 1) + *s++ = '0'; + while (t_len--) + *s++ = *p++; + } + else { + *s++ = '+'; + *s++ = '0'; + *s++ = '0'; + } + } + + *len = s - buf; + return (buf); +} + + +/* + * Convert num to a base X number where X is a power of 2. nbits determines X. + * For example, if nbits is 3, we do base 8 conversion + * Return value: + * a pointer to a string containing the number + * + * The caller provides a buffer for the string: that is the buf_end argument + * which is a pointer to the END of the buffer + 1 (i.e. if the buffer + * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) + * + * As with conv_10, we have a faster version which is used when + * the number isn't quad size. + */ +static char *conv_p2(register u_wide_int num, register int nbits, + char format, char *buf_end, register int *len) +{ + register int mask = (1 << nbits) - 1; + register char *p = buf_end; + static const char low_digits[] = "0123456789abcdef"; + static const char upper_digits[] = "0123456789ABCDEF"; + register const char *digits = (format == 'X') ? upper_digits : low_digits; + + do { + *--p = digits[num & mask]; + num >>= nbits; + } + while (num); + + *len = buf_end - p; + return (p); +} + +static char *conv_p2_quad(u_widest_int num, register int nbits, + char format, char *buf_end, register int *len) +{ + register int mask = (1 << nbits) - 1; + register char *p = buf_end; + static const char low_digits[] = "0123456789abcdef"; + static const char upper_digits[] = "0123456789ABCDEF"; + register const char *digits = (format == 'X') ? upper_digits : low_digits; + + if (num <= ULONG_MAX) + return(conv_p2( (u_wide_int)num, nbits, format, buf_end, len)); + + do { + *--p = digits[num & mask]; + num >>= nbits; + } + while (num); + + *len = buf_end - p; + return (p); +} + + +/* + * Do format conversion placing the output in buffer + */ +API_EXPORT(int) ap_vformatter(int (*flush_func)(ap_vformatter_buff *), + ap_vformatter_buff *vbuff, const char *fmt, va_list ap) +{ + register char *sp; + register char *bep; + register int cc = 0; + register int i; + + register char *s = NULL; + char *q; + int s_len; + + register int min_width = 0; + int precision = 0; + enum { + LEFT, RIGHT + } adjust; + char pad_char; + char prefix_char; + + double fp_num; + widest_int i_quad = (widest_int) 0; + u_widest_int ui_quad; + wide_int i_num = (wide_int) 0; + u_wide_int ui_num; + + char num_buf[NUM_BUF_SIZE]; + char char_buf[2]; /* for printing %% and %<unknown> */ + + enum var_type_enum { + IS_QUAD, IS_LONG, IS_SHORT, IS_INT + }; + enum var_type_enum var_type = IS_INT; + + /* + * Flag variables + */ + boolean_e alternate_form; + boolean_e print_sign; + boolean_e print_blank; + boolean_e adjust_precision; + boolean_e adjust_width; + bool_int is_negative; + + sp = vbuff->curpos; + bep = vbuff->endpos; + + while (*fmt) { + if (*fmt != '%') { + INS_CHAR(*fmt, sp, bep, cc); + } + else { + /* + * Default variable settings + */ + adjust = RIGHT; + alternate_form = print_sign = print_blank = NO; + pad_char = ' '; + prefix_char = NUL; + + fmt++; + + /* + * Try to avoid checking for flags, width or precision + */ + if (!ap_islower(*fmt)) { + /* + * Recognize flags: -, #, BLANK, + + */ + for (;; fmt++) { + if (*fmt == '-') + adjust = LEFT; + else if (*fmt == '+') + print_sign = YES; + else if (*fmt == '#') + alternate_form = YES; + else if (*fmt == ' ') + print_blank = YES; + else if (*fmt == '0') + pad_char = '0'; + else + break; + } + + /* + * Check if a width was specified + */ + if (ap_isdigit(*fmt)) { + STR_TO_DEC(fmt, min_width); + adjust_width = YES; + } + else if (*fmt == '*') { + min_width = va_arg(ap, int); + fmt++; + adjust_width = YES; + if (min_width < 0) { + adjust = LEFT; + min_width = -min_width; + } + } + else + adjust_width = NO; + + /* + * Check if a precision was specified + */ + if (*fmt == '.') { + adjust_precision = YES; + fmt++; + if (ap_isdigit(*fmt)) { + STR_TO_DEC(fmt, precision); + } + else if (*fmt == '*') { + precision = va_arg(ap, int); + fmt++; + if (precision < 0) + precision = 0; + } + else + precision = 0; + } + else + adjust_precision = NO; + } + else + adjust_precision = adjust_width = NO; + + /* + * Modifier check + */ + if (*fmt == 'q') { + var_type = IS_QUAD; + fmt++; + } + else if (*fmt == 'l') { + var_type = IS_LONG; + fmt++; + } + else if (*fmt == 'h') { + var_type = IS_SHORT; + fmt++; + } + else { + var_type = IS_INT; + } + + /* + * Argument extraction and printing. + * First we determine the argument type. + * Then, we convert the argument to a string. + * On exit from the switch, s points to the string that + * must be printed, s_len has the length of the string + * The precision requirements, if any, are reflected in s_len. + * + * NOTE: pad_char may be set to '0' because of the 0 flag. + * It is reset to ' ' by non-numeric formats + */ + switch (*fmt) { + case 'u': + if (var_type == IS_QUAD) { + i_quad = va_arg(ap, u_widest_int); + s = conv_10_quad(i_quad, 1, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + i_num = (wide_int) va_arg(ap, u_wide_int); + else if (var_type == IS_SHORT) + i_num = (wide_int) (unsigned short) va_arg(ap, unsigned int); + else + i_num = (wide_int) va_arg(ap, unsigned int); + s = conv_10(i_num, 1, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + FIX_PRECISION(adjust_precision, precision, s, s_len); + break; + + case 'd': + case 'i': + if (var_type == IS_QUAD) { + i_quad = va_arg(ap, widest_int); + s = conv_10_quad(i_quad, 0, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + i_num = (wide_int) va_arg(ap, wide_int); + else if (var_type == IS_SHORT) + i_num = (wide_int) (short) va_arg(ap, int); + else + i_num = (wide_int) va_arg(ap, int); + s = conv_10(i_num, 0, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + FIX_PRECISION(adjust_precision, precision, s, s_len); + + if (is_negative) + prefix_char = '-'; + else if (print_sign) + prefix_char = '+'; + else if (print_blank) + prefix_char = ' '; + break; + + + case 'o': + if (var_type == IS_QUAD) { + ui_quad = va_arg(ap, u_widest_int); + s = conv_p2_quad(ui_quad, 3, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + else if (var_type == IS_SHORT) + ui_num = (u_wide_int) (unsigned short) va_arg(ap, unsigned int); + else + ui_num = (u_wide_int) va_arg(ap, unsigned int); + s = conv_p2(ui_num, 3, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + FIX_PRECISION(adjust_precision, precision, s, s_len); + if (alternate_form && *s != '0') { + *--s = '0'; + s_len++; + } + break; + + + case 'x': + case 'X': + if (var_type == IS_QUAD) { + ui_quad = va_arg(ap, u_widest_int); + s = conv_p2_quad(ui_quad, 4, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + else if (var_type == IS_SHORT) + ui_num = (u_wide_int) (unsigned short) va_arg(ap, unsigned int); + else + ui_num = (u_wide_int) va_arg(ap, unsigned int); + s = conv_p2(ui_num, 4, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + FIX_PRECISION(adjust_precision, precision, s, s_len); + if (alternate_form && i_num != 0) { + *--s = *fmt; /* 'x' or 'X' */ + *--s = '0'; + s_len += 2; + } + break; + + + case 's': + s = va_arg(ap, char *); + if (s != NULL) { + s_len = strlen(s); + if (adjust_precision && precision < s_len) + s_len = precision; + } + else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + break; + + + case 'f': + case 'e': + case 'E': + fp_num = va_arg(ap, double); + /* + * * We use &num_buf[ 1 ], so that we have room for the sign + */ +#ifdef HAVE_ISNAN + if (isnan(fp_num)) { + s = "nan"; + s_len = 3; + } + else +#endif +#ifdef HAVE_ISINF + if (isinf(fp_num)) { + s = "inf"; + s_len = 3; + } + else +#endif + { + s = conv_fp(*fmt, fp_num, alternate_form, + (adjust_precision == NO) ? FLOAT_DIGITS : precision, + &is_negative, &num_buf[1], &s_len); + if (is_negative) + prefix_char = '-'; + else if (print_sign) + prefix_char = '+'; + else if (print_blank) + prefix_char = ' '; + } + break; + + + case 'g': + case 'G': + if (adjust_precision == NO) + precision = FLOAT_DIGITS; + else if (precision == 0) + precision = 1; + /* + * * We use &num_buf[ 1 ], so that we have room for the sign + */ + s = ap_gcvt(va_arg(ap, double), precision, &num_buf[1], + alternate_form); + if (*s == '-') + prefix_char = *s++; + else if (print_sign) + prefix_char = '+'; + else if (print_blank) + prefix_char = ' '; + + s_len = strlen(s); + + if (alternate_form && (q = strchr(s, '.')) == NULL) { + s[s_len++] = '.'; + s[s_len] = '\0'; /* delimit for following strchr() */ + } + if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL) + *q = 'E'; + break; + + + case 'c': + char_buf[0] = (char) (va_arg(ap, int)); + s = &char_buf[0]; + s_len = 1; + pad_char = ' '; + break; + + + case '%': + char_buf[0] = '%'; + s = &char_buf[0]; + s_len = 1; + pad_char = ' '; + break; + + + case 'n': + if (var_type == IS_QUAD) + *(va_arg(ap, widest_int *)) = cc; + else if (var_type == IS_LONG) + *(va_arg(ap, long *)) = cc; + else if (var_type == IS_SHORT) + *(va_arg(ap, short *)) = cc; + else + *(va_arg(ap, int *)) = cc; + break; + + /* + * This is where we extend the printf format, with a second + * type specifier + */ + case 'p': + switch(*++fmt) { + /* + * If the pointer size is equal to or smaller than the size + * of the largest unsigned int, we convert the pointer to a + * hex number, otherwise we print "%p" to indicate that we + * don't handle "%p". + */ + case 'p': +#ifdef AP_VOID_P_IS_QUAD + if (sizeof(void *) <= sizeof(u_widest_int)) { + ui_quad = (u_widest_int) va_arg(ap, void *); + s = conv_p2_quad(ui_quad, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + } +#else + if (sizeof(void *) <= sizeof(u_wide_int)) { + ui_num = (u_wide_int) va_arg(ap, void *); + s = conv_p2(ui_num, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + } +#endif + else { + s = "%p"; + s_len = 2; + prefix_char = NUL; + } + pad_char = ' '; + break; + + /* print a struct sockaddr_in as a.b.c.d:port */ + case 'I': + { + struct sockaddr_in *si; + + si = va_arg(ap, struct sockaddr_in *); + if (si != NULL) { + s = conv_sockaddr_in(si, &num_buf[NUM_BUF_SIZE], &s_len); + if (adjust_precision && precision < s_len) + s_len = precision; + } + else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + } + break; + + /* print a struct in_addr as a.b.c.d */ + case 'A': + { + struct in_addr *ia; + + ia = va_arg(ap, struct in_addr *); + if (ia != NULL) { + s = conv_in_addr(ia, &num_buf[NUM_BUF_SIZE], &s_len); + if (adjust_precision && precision < s_len) + s_len = precision; + } + else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + } + break; + + case NUL: + /* if %p ends the string, oh well ignore it */ + continue; + + default: + s = "bogus %p"; + s_len = 8; + prefix_char = NUL; + break; + } + break; + + case NUL: + /* + * The last character of the format string was %. + * We ignore it. + */ + continue; + + + /* + * The default case is for unrecognized %'s. + * We print %<char> to help the user identify what + * option is not understood. + * This is also useful in case the user wants to pass + * the output of format_converter to another function + * that understands some other %<char> (like syslog). + * Note that we can't point s inside fmt because the + * unknown <char> could be preceded by width etc. + */ + default: + char_buf[0] = '%'; + char_buf[1] = *fmt; + s = char_buf; + s_len = 2; + pad_char = ' '; + break; + } + + if (prefix_char != NUL && s != S_NULL && s != char_buf) { + *--s = prefix_char; + s_len++; + } + + if (adjust_width && adjust == RIGHT && min_width > s_len) { + if (pad_char == '0' && prefix_char != NUL) { + INS_CHAR(*s, sp, bep, cc); + s++; + s_len--; + min_width--; + } + PAD(min_width, s_len, pad_char); + } + + /* + * Print the string s. + */ + for (i = s_len; i != 0; i--) { + INS_CHAR(*s, sp, bep, cc); + s++; + } + + if (adjust_width && adjust == LEFT && min_width > s_len) + PAD(min_width, s_len, pad_char); + } + fmt++; + } + vbuff->curpos = sp; + + return cc; +} + + +static int snprintf_flush(ap_vformatter_buff *vbuff) +{ + /* if the buffer fills we have to abort immediately, there is no way + * to "flush" an ap_snprintf... there's nowhere to flush it to. + */ + return -1; +} + + +API_EXPORT_NONSTD(int) ap_snprintf(char *buf, size_t len, const char *format,...) +{ + int cc; + va_list ap; + ap_vformatter_buff vbuff; + + if (len == 0) + return 0; + + /* save one byte for nul terminator */ + vbuff.curpos = buf; + vbuff.endpos = buf + len - 1; + va_start(ap, format); + cc = ap_vformatter(snprintf_flush, &vbuff, format, ap); + va_end(ap); + *vbuff.curpos = '\0'; + return (cc == -1) ? len : cc; +} + + +API_EXPORT(int) ap_vsnprintf(char *buf, size_t len, const char *format, + va_list ap) +{ + int cc; + ap_vformatter_buff vbuff; + + if (len == 0) + return 0; + + /* save one byte for nul terminator */ + vbuff.curpos = buf; + vbuff.endpos = buf + len - 1; + cc = ap_vformatter(snprintf_flush, &vbuff, format, ap); + *vbuff.curpos = '\0'; + return (cc == -1) ? len : cc; +} diff --git a/color.c b/color.c new file mode 100644 index 000000000000..c681082505b8 --- /dev/null +++ b/color.c @@ -0,0 +1,376 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Top users/processes display for Unix + * Version 3 + */ + +/* + * This file handles color definitions and access for augmenting + * the output with ansi color sequences. + * + * The definition of a color setting is as follows, separated by + * colons: + * + * tag=minimum,maximum#code + * + * "tag" is the name of the value to display with color. + * + * "minimum" and "maximum" are positive integer values defining a range: + * when the value is within this range it will be shown with the + * specified color. A missing value indicates that no check should be + * made (i.e.: ",25" is n <= 25; "25,50" is 25 <= n <= 50; and "50," + * is 50 <= n). + * + * "code" is the ansi sequence that defines the color to use with the + * escape sequence "[m". Semi-colons are allowed in this string to + * combine attributes. + */ + +#include "os.h" +#include "display.h" +#include "message.h" +#include "color.h" +#include "utils.h" + +typedef struct color_entry { + char *tag; + int min; + int max; + char color; + struct color_entry *next; + struct color_entry *tagnext; +} color_entry; + +static color_entry *entries = NULL; + +static color_entry **bytag = NULL; +static char **bytag_names = NULL; +static int totaltags = 0; +static int tagcnt = 0; +static int color_off = 0; + +static char **color_ansi = NULL; +static int num_color_ansi = 0; +static int max_color_ansi = 0; + +static int +color_slot(char *str) + +{ + int i; + + for (i = 0; i < num_color_ansi; i++) + { + if (strcmp(color_ansi[i], str) == 0) + { + return i; + } + } + + /* need a new slot */ + if (num_color_ansi >= max_color_ansi) + { + max_color_ansi += COLOR_ANSI_SLOTS; + color_ansi = (char **)realloc(color_ansi, max_color_ansi * sizeof(char *)); + } + color_ansi[num_color_ansi] = strdup(str); + return num_color_ansi++; +} + +/* + * int color_env_parse(char *env) + * + * Parse a color specification "env" (such as one found in the environment) and + * add them to the list of entries. Always returns 0. Should only be called + * once. + */ + +int +color_env_parse(char *env) + +{ + char *p; + char *min; + char *max; + char *str; + int len; + color_entry *ce; + + /* initialization */ + color_ansi = (char **)malloc(COLOR_ANSI_SLOTS * sizeof(char *)); + max_color_ansi = COLOR_ANSI_SLOTS; + + /* color slot 0 is always "0" */ + color_slot("0"); + + if (env != NULL) + { + p = strtok(env, ":"); + while (p != NULL) + { + if ((min = strchr(p, '=')) != NULL && + (max = strchr(min, ',')) != NULL && + (str = strchr(max, '#')) != NULL) + { + ce = (color_entry *)malloc(sizeof(color_entry)); + len = min - p; + ce->tag = (char *)malloc(len + 1); + strncpy(ce->tag, p, len); + ce->tag[len] = '\0'; + ce->min = atoi(++min); + ce->max = atoi(++max); + ce->color = color_slot(++str); + ce->next = entries; + entries = ce; + } + else + { + if (min != NULL) + { + len = min - p; + } + else + { + len = strlen(p); + } + message_error(" %.*s: bad color entry", len, p); + } + p = strtok(NULL, ":"); + } + } + return 0; +} + +/* + * int color_tag(char *tag) + * + * Declare "tag" as a color tag. Return a tag index to use when testing + * a value against the tests for this tag. Should not be called before + * color_env_parse. + */ + +int +color_tag(char *tag) + +{ + color_entry *entryp; + color_entry *tp; + + /* check for absurd arguments */ + if (tag == NULL || *tag == '\0') + { + return -1; + } + + dprintf("color_tag(%s)\n", tag); + + /* initial allocation */ + if (bytag == NULL) + { + totaltags = 10; + bytag = (color_entry **)malloc(totaltags * sizeof(color_entry *)); + bytag_names = (char **)malloc(totaltags * sizeof(char *)); + } + + /* if we dont have enough room then reallocate */ + if (tagcnt >= totaltags) + { + totaltags *= 2; + bytag = (color_entry **)realloc(bytag, totaltags * sizeof(color_entry *)); + bytag_names = (char **)realloc(bytag_names, totaltags * sizeof(char *)); + } + + /* initialize scan */ + entryp = entries; + tp = NULL; + + /* look for tag in the list of entries */ + while (entryp != NULL) + { + if (strcmp(entryp->tag, tag) == 0) + { + entryp->tagnext = tp; + tp = entryp; + } + entryp = entryp->next; + } + + /* we track names in the array bytag */ + bytag[tagcnt] = tp; + bytag_names[tagcnt] = strdup(tag); + + /* return this index number as a reference */ + dprintf("color_tag: returns %d\n", tagcnt); + return (tagcnt++); +} + +/* + * int color_test(int tagidx, int value) + * + * Test "value" against tests for tag "tagidx", a number previously returned + * by color_tag. Return the correct color number to use when highlighting. + * If there is no match, return 0 (color 0). + */ + +int +color_test(int tagidx, int value) + +{ + color_entry *ce; + + /* sanity check */ + if (tagidx < 0 || tagidx >= tagcnt || color_off) + { + return 0; + } + + ce = bytag[tagidx]; + + while (ce != NULL) + { + if ((!ce->min || ce->min <= value) && + (!ce->max || ce->max >= value)) + { + return ce->color; + } + ce = ce->tagnext; + } + + return 0; +} + +/* + * char *color_setstr(int color) + * + * Return ANSI string to set the terminal for color number "color". + */ + +char * +color_setstr(int color) + +{ + static char v[32]; + + v[0] = '\0'; + if (color >= 0 && color < num_color_ansi) + { + snprintf(v, sizeof(v), "\033[%sm", color_ansi[color]); + } + return v; +} + +void +color_dump(FILE *f) + +{ + color_entry *ep; + int i; + int col; + int len; + + fputs("These color tags are available:", f); + col = 81; + for (i = 0; i < tagcnt; i++) + { + len = strlen(bytag_names[i]) + 1; + if (len + col > 79) + { + fputs("\n ", f); + col = 2; + } + fprintf(f, " %s", bytag_names[i]); + col += len; + } + + fputs("\n\nTop color settings:\n", f); + + for (i = 0; i < tagcnt; i++) + { + ep = bytag[i]; + while (ep != NULL) + { + fprintf(f, " %s (%d-", ep->tag, ep->min); + if (ep->max != 0) + { + fprintf(f, "%d", ep->max); + } + fprintf(f, "): ansi color %s, %sSample Text", + color_ansi[(int)ep->color], + color_setstr(ep->color)); + fprintf(f, "%s\n", color_setstr(0)); + ep = ep -> tagnext; + } + } +} + +void +color_debug(FILE *f) + +{ + color_entry *ep; + int i; + + fprintf(f, "color debug dump\n"); + ep = entries; + while (ep != NULL) + { + fprintf(f, "%s(%d,%d): slot %d, ansi %s, %sSample Text", + ep->tag, ep->min, ep->max, ep->color, color_ansi[(int)ep->color], + color_setstr(ep->color)); + fprintf(f, "%s\n", color_setstr(0)); + ep = ep -> next; + } + + fprintf(f, "\ntags:"); + for (i = 0; i < tagcnt; i++) + { + fprintf(f, " %s", bytag_names[i]); + } + fprintf(f, "\n"); +} + +int +color_activate(int i) + +{ + if (i == -1) + { + color_off = !color_off; + } + else + { + color_off = !i; + } + return color_off; +} diff --git a/color.h b/color.h new file mode 100644 index 000000000000..9a210a295959 --- /dev/null +++ b/color.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Top - a top users display for Unix + * + * Definition of the color interface. + */ + +#ifndef _COLOR_H_ +#define _COLOR_H_ + +#define COLOR_ANSI_SLOTS 20 + +int color_env_parse(char *env); +int color_tag(char *tag); +int color_test(int tagidx, int value); +char *color_setstr(int color); +void color_dump(FILE *f); +int color_activate(int i); + + +/* + * These color tag names are currently in use + * (or reserved for future use): + * + * cpu, size, res, time, 1min, 5min, 15min, host + */ + +/* + * Valid ANSI values for colors are: + * + * 0 Reset all attributes + * 1 Bright + * 2 Dim + * 4 Underscore + * 5 Blink + * 7 Reverse + * 8 Hidden + * + * Foreground Colours + * 30 Black + * 31 Red + * 32 Green + * 33 Yellow + * 34 Blue + * 35 Magenta + * 36 Cyan + * 37 White + * + * Background Colours + * 40 Black + * 41 Red + * 42 Green + * 43 Yellow + * 44 Blue + * 45 Magenta + * 46 Cyan + * 47 White + */ + +#endif /*_COLOR_H_ */ diff --git a/commands.c b/commands.c index a852a4752b57..e93fb54646c1 100644 --- a/commands.c +++ b/commands.c @@ -1,12 +1,38 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * Top users/processes display for Unix * Version 3 - * - * This program may be freely redistributed, - * but this entire comment MUST remain intact. - * - * Copyright (c) 1984, 1989, William LeFebvre, Rice University - * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University */ /* @@ -19,134 +45,51 @@ #include "os.h" #include <ctype.h> #include <signal.h> +#include <stdarg.h> +#include <unistd.h> +#include <color.h> #include <errno.h> -#include <sys/time.h> +#ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> +#endif + +#if defined(HAVE_DECL_SYS_SIGLIST) & defined(HAVE_STRCASECMP) +#define USE_SYS_SIGLIST +#endif +#ifdef USE_SYS_SIGLIST +extern const char * const sys_siglist[]; +extern const char * const sys_signame[]; +#else #include "sigdesc.h" /* generated automatically */ +#endif #include "top.h" +#include "machine.h" +#include "globalstate.h" #include "boolean.h" +#include "color.h" +#include "commands.h" +#include "display.h" +#include "screen.h" +#include "username.h" #include "utils.h" +#include "version.h" extern int errno; extern char *copyright; -/* imported from screen.c */ -extern int overstrike; - -int err_compar(); -char *err_string(); - -/* - * show_help() - display the help screen; invoked in response to - * either 'h' or '?'. - */ - -show_help() - -{ - printf("Top version %s, %s\n", version_string(), copyright); - fputs("\n\n\ -A top users display for Unix\n\ -\n\ -These single-character commands are available:\n\ -\n\ -^L - redraw screen\n\ -q - quit\n\ -h or ? - help; show this text\n", stdout); - - /* not all commands are availalbe with overstrike terminals */ - if (overstrike) - { - fputs("\n\ -Other commands are also available, but this terminal is not\n\ -sophisticated enough to handle those commands gracefully.\n\n", stdout); - } - else - { - fputs("\ -d - change number of displays to show\n\ -e - list errors generated by last \"kill\" or \"renice\" command\n\ -i - toggle the displaying of idle processes\n\ -I - same as 'i'\n\ -k - kill processes; send a signal to a list of processes\n\ -n or # - change number of processes to display\n", stdout); -#ifdef ORDER - fputs("\ -o - specify sort order (size, res, cpu, time)\n", stdout); -#endif - fputs("\ -r - renice a process\n\ -s - change number of seconds to delay between updates\n\ -u - display processes for only one user (+ selects all users)\n\ -\n\ -\n", stdout); - } -} - -/* - * Utility routines that help with some of the commands. - */ - -char *next_field(str) - -register char *str; - -{ - if ((str = strchr(str, ' ')) == NULL) - { - return(NULL); - } - *str = '\0'; - while (*++str == ' ') /* loop */; - - /* if there is nothing left of the string, return NULL */ - /* This fix is dedicated to Greg Earle */ - return(*str == '\0' ? NULL : str); -} - -scanint(str, intp) - -char *str; -int *intp; - -{ - register int val = 0; - register char ch; - - /* if there is nothing left of the string, flag it as an error */ - /* This fix is dedicated to Greg Earle */ - if (*str == '\0') - { - return(-1); - } - - while ((ch = *str++) != '\0') - { - if (isdigit(ch)) - { - val = val * 10 + (ch - '0'); - } - else if (isspace(ch)) - { - break; - } - else - { - return(-1); - } - } - *intp = val; - return(0); -} +typedef struct command { + int ch; + int (*cmd_func)(globalstate *); + char *help; +} command; /* * Some of the commands make system calls that could generate errors. * These errors are collected up in an array of structures for later * contemplation and display. Such routines return a string containing an - * error message, or NULL if no errors occurred. The next few routines are - * for manipulating and displaying these errors. We need an upper limit on + * error message, or NULL if no errors occurred. We need an upper limit on * the number of errors, so we arbitrarily choose 20. */ @@ -160,96 +103,43 @@ struct errs /* structure for a system-call error */ static struct errs errs[ERRMAX]; static int errcnt; -static char *err_toomany = " too many errors occurred"; -static char *err_listem = - " Many errors occurred. Press `e' to display the list of errors."; /* These macros get used to reset and log the errors */ #define ERR_RESET errcnt = 0 -#define ERROR(p, e) if (errcnt >= ERRMAX) \ - { \ - return(err_toomany); \ - } \ - else \ +#define ERROR(p, e) if (errcnt < ERRMAX) \ { \ errs[errcnt].arg = (p); \ errs[errcnt++].errnum = (e); \ } /* - * err_string() - return an appropriate error string. This is what the - * command will return for displaying. If no errors were logged, then - * return NULL. The maximum length of the error string is defined by - * "STRMAX". + * err_compar(p1, p2) - comparison routine used by "qsort" + * for sorting errors. */ -#define STRMAX 80 - -char *err_string() +int +err_compar(const void *p1, const void *p2) { - register struct errs *errp; - register int cnt = 0; - register int first = Yes; - register int currerr = -1; - int stringlen; /* characters still available in "string" */ - static char string[STRMAX]; - - /* if there are no errors, return NULL */ - if (errcnt == 0) - { - return(NULL); - } - - /* sort the errors */ - qsort((char *)errs, errcnt, sizeof(struct errs), err_compar); - - /* need a space at the front of the error string */ - string[0] = ' '; - string[1] = '\0'; - stringlen = STRMAX - 2; + register int result; - /* loop thru the sorted list, building an error string */ - while (cnt < errcnt) + if ((result = ((struct errs *)p1)->errnum - + ((struct errs *)p2)->errnum) == 0) { - errp = &(errs[cnt++]); - if (errp->errnum != currerr) - { - if (currerr != -1) - { - if ((stringlen = str_adderr(string, stringlen, currerr)) < 2) - { - return(err_listem); - } - (void) strcat(string, "; "); /* we know there's more */ - } - currerr = errp->errnum; - first = Yes; - } - if ((stringlen = str_addarg(string, stringlen, errp->arg, first)) ==0) - { - return(err_listem); - } - first = No; + return(strcmp(((struct errs *)p1)->arg, + ((struct errs *)p2)->arg)); } - - /* add final message */ - stringlen = str_adderr(string, stringlen, currerr); - - /* return the error string */ - return(stringlen == 0 ? err_listem : string); + return(result); } /* * str_adderr(str, len, err) - add an explanation of error "err" to - * the string "str". + * the string "str" without overflowing length "len". return + * number of characters remaining in str, or 0 if overflowed. */ -str_adderr(str, len, err) - -char *str; -int len; -int err; +int +str_adderr(char *str, int len, int err) { register char *msg; @@ -268,16 +158,14 @@ int err; /* * str_addarg(str, len, arg, first) - add the string argument "arg" to - * the string "str". This is the first in the group when "first" - * is set (indicating that a comma should NOT be added to the front). + * the string "str" without overflowing length "len". This is the + * first in the group when "first" is set (indicating that a comma + * should NOT be added to the front). Return number of characters + * remaining in str, or 0 if overflowed. */ -str_addarg(str, len, arg, first) - -char *str; -int len; -char *arg; -int first; +int +str_addarg(char *str, int len, char *arg, int first) { register int arglen; @@ -300,28 +188,139 @@ int first; } /* - * err_compar(p1, p2) - comparison routine used by "qsort" - * for sorting errors. + * void err_string() + * + * Use message_error to log errors in the errs array. This function + * will combine identical errors to make the message short, but if + * there is more than one type of error it will call message_error + * for each one. */ -err_compar(p1, p2) +#define STRMAX 80 -register struct errs *p1, *p2; +void +err_string() { - register int result; + register struct errs *errp; + register int cnt = 0; + register int first = Yes; + register int currerr = -1; + int stringlen = 0; /* characters still available in "string" */ + char string[STRMAX]; - if ((result = p1->errnum - p2->errnum) == 0) + /* if there are no errors, our job is easy */ + if (errcnt == 0) { - return(strcmp(p1->arg, p2->arg)); + return; } - return(result); + + /* sort the errors */ + qsort((char *)errs, errcnt, sizeof(struct errs), err_compar); + + /* initialize the buffer (probably not necessary) */ + string[0] = '\0'; + stringlen = STRMAX - 1; + + /* loop thru the sorted list, logging errors */ + while (cnt < errcnt) + { + /* point to the current error */ + errp = &(errs[cnt++]); + + /* note that on overflow "stringlen" will become 0 and all + subsequent calls to str_addarg or str_adderr will return 0 */ + + /* if the error number is different then add the error string */ + if (errp->errnum != currerr) + { + if (currerr != -1) + { + /* add error string and log the error */ + stringlen = str_adderr(string, stringlen, currerr); + message_error(" %s", string); + + } + /* reset the buffer */ + string[0] = '\0'; + stringlen = STRMAX - 1; + + /* move to next error num */ + currerr = errp->errnum; + first = Yes; + } + + /* add this arg */ + stringlen = str_addarg(string, stringlen, errp->arg, first); + first = No; + } + + /* add final message */ + stringlen = str_adderr(string, stringlen, currerr); + + /* write the error string */ + message_error(" %s", string); +} + +/* + * Utility routines that help with some of the commands. + */ + +char * +next_field(char *str) + + +{ + if ((str = strchr(str, ' ')) == NULL) + { + return(NULL); + } + *str = '\0'; + while (*++str == ' ') /* loop */; + + /* if there is nothing left of the string, return NULL */ + /* This fix is dedicated to Greg Earle */ + return(*str == '\0' ? NULL : str); +} + +int +scanint(char *str, int *intp) + +{ + register int val = 0; + register int ch; + + /* if there is nothing left of the string, flag it as an error */ + /* This fix is dedicated to Greg Earle */ + if (*str == '\0') + { + return(-1); + } + + while ((ch = *str++) != '\0') + { + if (isdigit(ch)) + { + val = val * 10 + (ch - '0'); + } + else if (isspace(ch)) + { + break; + } + else + { + return(-1); + } + } + *intp = val; + return(0); } /* * error_count() - return the number of errors currently logged. */ +int error_count() { @@ -332,6 +331,7 @@ error_count() * show_errors() - display on stdout the current log of errors. */ +void show_errors() { @@ -352,16 +352,18 @@ show_errors() * command does; invoked in response to 'k'. */ -char *kill_procs(str) - -char *str; +void +kill_procs(char *str) { register char *nptr; int signum = SIGTERM; /* default */ int procnum; - struct sigdesc *sigp; int uid; + int owner; +#ifndef USE_SYS_SIGLIST + struct sigdesc *sigp; +#endif /* reset error array */ ERR_RESET; @@ -370,30 +372,51 @@ char *str; uid = getuid(); /* skip over leading white space */ - while (isspace(*str)) str++; + while (isspace((int)*str)) str++; if (str[0] == '-') { /* explicit signal specified */ if ((nptr = next_field(str)) == NULL) { - return(" kill: no processes specified"); + message_error(" kill: no processes specified"); + return; } - if (isdigit(str[1])) + str++; + if (isdigit((int)str[0])) { - (void) scanint(str + 1, &signum); + (void) scanint(str, &signum); if (signum <= 0 || signum >= NSIG) { - return(" invalid signal number"); + message_error(" kill: invalid signal number"); + return; } } else { /* translate the name into a number */ +#ifdef USE_SYS_SIGLIST + for (signum = 1; signum < NSIG; signum++) + { + if (strcasecmp(sys_signame[signum], str) == 0) + { + break; + } + } + if (signum == NSIG) + { + message_error(" kill: bad signal name"); + return; + } +#else for (sigp = sigdesc; sigp->name != NULL; sigp++) { - if (strcmp(sigp->name, str + 1) == 0) +#ifdef HAVE_STRCASECMP + if (strcasecmp(sigp->name, str) == 0) +#else + if (strcmp(sigp->name, str) == 0) +#endif { signum = sigp->number; break; @@ -403,8 +426,10 @@ char *str; /* was it ever found */ if (sigp->name == NULL) { - return(" bad signal name"); + message_error(" kill: bad signal name"); + return; } +#endif } /* put the new pointer in place */ str = nptr; @@ -420,9 +445,10 @@ char *str; else { /* check process owner if we're not root */ - if (uid && (uid != proc_owner(procnum))) + owner = proc_owner(procnum); + if (uid && (uid != owner)) { - ERROR(str, EACCES); + ERROR(str, owner == -1 ? ESRCH : EACCES); } /* go in for the kill */ else if (kill(procnum, signum) == -1) @@ -433,8 +459,8 @@ char *str; } } while ((str = next_field(str)) != NULL); - /* return appropriate error string */ - return(err_string()); + /* process errors */ + err_string(); } /* @@ -442,9 +468,8 @@ char *str; * "renice" command does; invoked in response to 'r'. */ -char *renice_procs(str) - -char *str; +void +renice_procs(char *str) { register char negate; @@ -475,16 +500,17 @@ char *str; /* check for validity */ if (procnum == -1 || prio < PRIO_MIN || prio > PRIO_MAX) { - return(" bad priority value"); + message_error(" renice: bad priority value"); } #endif /* move to the first process number */ if ((str = next_field(str)) == NULL) { - return(" no processes specified"); + message_error(" remice: no processes specified"); } +#ifdef HAVE_SETPRIORITY /* loop thru the process numbers, renicing each one */ do { @@ -503,8 +529,506 @@ char *str; ERROR(str, errno); } } while ((str = next_field(str)) != NULL); + err_string(); +#else + message_error(" renice operation not supported"); +#endif +} - /* return appropriate error string */ - return(err_string()); +/* COMMAND ROUTINES */ + +/* + * Each command routine is called by command_process and is passed a + * pointer to the current global state. Command routines are free + * to change anything in the global state, although changes to the + * statics structure are discouraged. Whatever a command routine + * returns will be returned by command_process. + */ + +void +cmd_quit(globalstate *gstate) + +{ + quit(EX_OK); + /*NOTREACHED*/ +} + +int +cmd_update(globalstate *gstate) + +{ + /* go home for visual feedback */ + screen_home(); + fflush(stdout); + message_expire(); + return CMD_REFRESH; +} + +int +cmd_redraw(globalstate *gstate) + +{ + gstate->fulldraw = Yes; + return CMD_REFRESH; +} + +int +cmd_color(globalstate *gstate) + +{ + gstate->use_color = color_activate(-1); + gstate->fulldraw = Yes; + return CMD_REFRESH; +} + +int +cmd_number(globalstate *gstate) + +{ + int newval; + char tmpbuf[20]; + + message_prompt("Number of processes to show: "); + newval = readline(tmpbuf, 8, Yes); + if (newval > -1) + { + if (newval > gstate->max_topn) + { + message_error(" This terminal can only display %d processes", + gstate->max_topn); + } + + if (newval == 0) + { + /* inhibit the header */ + display_header(No); + } + + else if (gstate->topn == 0) + { + display_header(Yes); + } + + gstate->topn = newval; + } + return CMD_REFRESH; +} + +int +cmd_delay(globalstate *gstate) + +{ + int newval; + char tmpbuf[20]; + + message_prompt("Seconds to delay: "); + if ((newval = readline(tmpbuf, 8, Yes)) > -1) + { + if ((gstate->delay = newval) == 0 && getuid() != 0) + { + gstate->delay = 1; + } + } + return CMD_REFRESH; +} + +int +cmd_idle(globalstate *gstate) + +{ + gstate->pselect.idle = !gstate->pselect.idle; + message_error(" %sisplaying idle processes.", + gstate->pselect.idle ? "D" : "Not d"); + return CMD_REFRESH; +} + +int +cmd_displays(globalstate *gstate) + +{ + int i; + char tmpbuf[20]; + + message_prompt("Displays to show (currently %s): ", + gstate->displays == -1 ? "infinite" : + itoa(gstate->displays)); + + if ((i = readline(tmpbuf, 10, Yes)) > 0) + { + gstate->displays = i; + } + else if (i == 0) + { + quit(EX_OK); + /*NOTREACHED*/ + } + return CMD_OK; +} + +int +cmd_cmdline(globalstate *gstate) + +{ + if (gstate->statics->flags.fullcmds) + { + gstate->pselect.fullcmd = !gstate->pselect.fullcmd; + message_error(" %sisplaying full command lines.", + gstate->pselect.fullcmd ? "D" : "Not d"); + return CMD_REFRESH; + } + message_error(" Full command display not supported."); + return CMD_OK; } +int +cmd_order(globalstate *gstate) + +{ + char tmpbuf[MAX_COLS]; + int i; + + if (gstate->statics->order_names != NULL) + { + message_prompt("Column to sort: "); + if (readline(tmpbuf, sizeof(tmpbuf), No) > 0) + { + if ((i = string_index(tmpbuf, gstate->statics->order_names)) == -1) + { + message_error(" Sort order \"%s\" not recognized", tmpbuf); + } + else + { + gstate->order_index = i; + return CMD_REFRESH; + } + } + } + return CMD_OK; +} + +int +cmd_order_x(globalstate *gstate, char *name, ...) + +{ + va_list ap; + char *p; + char **names; + int i; + + names = gstate->statics->order_names; + if (names != NULL) + { + if ((i = string_index(name, names)) == -1) + { + /* check the alternate list */ + va_start(ap, name); + p = va_arg(ap, char *); + while (p != NULL) + { + if ((i = string_index(p, names)) != -1) + { + gstate->order_index = i; + return CMD_REFRESH; + } + p = va_arg(ap, char *); + } + message_error(" Sort order not recognized"); + } + else + { + gstate->order_index = i; + return CMD_REFRESH; + } + } + return CMD_OK; +} + +int +cmd_order_cpu(globalstate *gstate) + +{ + return cmd_order_x(gstate, "cpu", NULL); +} + +int +cmd_order_pid(globalstate *gstate) + +{ + return cmd_order_x(gstate, "pid", NULL); +} + +int +cmd_order_mem(globalstate *gstate) + +{ + return cmd_order_x(gstate, "mem", "size", NULL); +} + +int +cmd_order_time(globalstate *gstate) + +{ + return cmd_order_x(gstate, "time"); +} + +#ifdef ENABLE_KILL + +int +cmd_kill(globalstate *gstate) + +{ + char tmpbuf[MAX_COLS]; + + message_prompt_plain("kill "); + if (readline(tmpbuf, sizeof(tmpbuf), No) > 0) + { + kill_procs(tmpbuf); + } + return CMD_OK; +} + +int +cmd_renice(globalstate *gstate) + +{ + char tmpbuf[MAX_COLS]; + + message_prompt_plain("renice "); + if (readline(tmpbuf, sizeof(tmpbuf), No) > 0) + { + renice_procs(tmpbuf); + } + return CMD_OK; +} + +#endif + +int +cmd_user(globalstate *gstate) + +{ + char linebuf[MAX_COLS]; + int i; + int ret = CMD_OK; + + message_prompt("Username to show: "); + if (readline(linebuf, sizeof(linebuf), No) > 0) + { + if (linebuf[0] == '+' && + linebuf[1] == '\0') + { + gstate->pselect.uid = -1; + ret = CMD_REFRESH; + } + else if ((i = userid(linebuf)) == -1) + { + message_error(" %s: unknown user", linebuf); + } + else + { + gstate->pselect.uid = i; + ret = CMD_REFRESH; + } + } + return ret; +} + +int +cmd_command(globalstate *gstate) + +{ + char linebuf[MAX_COLS]; + + if (gstate->pselect.command != NULL) + { + free(gstate->pselect.command); + gstate->pselect.command = NULL; + } + + message_prompt("Command to show: "); + if (readline(linebuf, sizeof(linebuf), No) > 0) + { + if (linebuf[0] != '\0') + { + gstate->pselect.command = strdup(linebuf); + } + } + return CMD_REFRESH; +} + +int +cmd_useruid(globalstate *gstate) + +{ + gstate->pselect.usernames = !gstate->pselect.usernames; + display_header(2); + return CMD_REFRESH; +} + +int +cmd_mode(globalstate *gstate) + +{ + if (gstate->statics->modemax <= 1) + { + return CMD_NA; + } + gstate->pselect.mode = (gstate->pselect.mode + 1) % gstate->statics->modemax; + display_header(2); + return CMD_REFRESH; +} + +int +cmd_system(globalstate *gstate) + +{ + gstate->pselect.system = !gstate->pselect.system; + display_header(2); + return CMD_REFRESH; +} + +int +cmd_threads(globalstate *gstate) + +{ + if (gstate->statics->flags.threads) + { + gstate->pselect.threads = !gstate->pselect.threads; + display_header(2); + return CMD_REFRESH; + } + return CMD_NA; +} + +/* forward reference for cmd_help, as it needs to see the command_table */ +int cmd_help(globalstate *gstate); + +/* command table */ +command command_table[] = { + { '\014', cmd_redraw, "redraw screen" }, + { ' ', cmd_update, "update screen" }, + { '?', cmd_help, "help; show this text" }, + { 'h', cmd_help, NULL }, + { 'C', cmd_color, "toggle the use of color" }, + { 'H', cmd_threads, "toggle the display of individual threads" }, + { 't', cmd_threads, NULL }, + { 'M', cmd_order_mem, "sort by memory usage" }, + { 'N', cmd_order_pid, "sort by process id" }, + { 'P', cmd_order_cpu, "sort by CPU usage" }, + { 'S', cmd_system, "toggle the display of system processes" }, + { 'T', cmd_order_time, "sort by CPU time" }, + { 'U', cmd_useruid, "toggle the display of usernames or uids" }, + { 'c', cmd_command, "display processes by command name" }, + { 'd', cmd_displays, "change number of displays to show" }, + { 'f', cmd_cmdline, "toggle the display of full command paths" }, + { 'i', cmd_idle, "toggle the displaying of idle processes" }, + { 'I', cmd_idle, NULL }, +#ifdef ENABLE_KILL + { 'k', cmd_kill, "kill processes; send a signal to a list of processes" }, +#endif + { 'm', cmd_mode, "toggle between display modes" }, + { 'n', cmd_number, "change number of processes to display" }, + { '#', cmd_number, NULL }, + { 'o', cmd_order, "specify sort order (see below)" }, + { 'q', (int (*)(globalstate *))cmd_quit, "quit" }, +#ifdef ENABLE_KILL + { 'r', cmd_renice, "renice a process" }, +#endif + { 's', cmd_delay, "change number of seconds to delay between updates" }, + { 'u', cmd_user, "display processes for only one user (+ selects all users)" }, + { '\0', NULL, NULL }, +}; + +int +cmd_help(globalstate *gstate) + +{ + command *c; + char buf[12]; + char *p; + char *help; + + display_pagerstart(); + + display_pager("Top version %s, %s\n", version_string(), copyright); + display_pager("Platform module: %s\n\n", MODULE); + display_pager("A top users display for Unix\n\n"); + display_pager("These single-character commands are available:\n\n"); + + c = command_table; + while (c->cmd_func != NULL) + { + /* skip null help strings */ + if ((help = c->help) == NULL) + { + continue; + } + + /* translate character in to something readable */ + if (c->ch < ' ') + { + buf[0] = '^'; + buf[1] = c->ch + '@'; + buf[2] = '\0'; + } + else if (c->ch == ' ') + { + strcpy(buf, "<sp>"); + } + else + { + buf[0] = c->ch; + buf[1] = '\0'; + } + + /* if the next command is the same, fold them onto one line */ + if ((c+1)->cmd_func == c->cmd_func) + { + strcat(buf, " or "); + p = buf + strlen(buf); + *p++ = (c+1)->ch; + *p = '\0'; + c++; + } + + display_pager("%-7s - %s\n", buf, help); + c++; + } + + display_pager("\nNot all commands are available on all systems.\n\n"); + display_pager("Available sort orders: %s\n", gstate->order_namelist); + display_pagerend(); + gstate->fulldraw = Yes; + return CMD_REFRESH; +} + +/* + * int command_process(globalstate *gstate, int cmd) + * + * Process the single-character command "cmd". The global state may + * be modified by the command to alter the output. Returns CMD_ERROR + * if there was a serious error that requires an immediate exit, CMD_OK + * to indicate success, CMD_REFRESH to indicate that the screen needs + * to be refreshed immediately, CMD_UNKNOWN when the command is not known, + * and CMD_NA when the command is not available. Error messages for + * CMD_NA and CMD_UNKNOWN must be handled by the caller. + */ + +int +command_process(globalstate *gstate, int cmd) + +{ + command *c; + + c = command_table; + while (c->cmd_func != NULL) + { + if (c->ch == cmd) + { + return (c->cmd_func)(gstate); + } + c++; + } + + return CMD_UNKNOWN; +} diff --git a/commands.h b/commands.h new file mode 100644 index 000000000000..cf98c8ddbe7a --- /dev/null +++ b/commands.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* call specifications for commands.c */ + +int command_process(globalstate *gstate, int cmd); + +/* returns from command routines */ +#define CMD_ERROR -1 +#define CMD_OK 0 +#define CMD_REFRESH 1 +#define CMD_UNKNOWN 2 +#define CMD_NA 3 diff --git a/config.default.makeinstall b/config.default.makeinstall new file mode 100644 index 000000000000..e3f9475b1875 --- /dev/null +++ b/config.default.makeinstall @@ -0,0 +1,5 @@ +# Standard install rule +install: $(PROGRAM) install-man + mkdir -p $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) $(INSTALL_OPTS_PROG) \ + $(PROGRAM) $(DESTDIR)$(bindir)/$(PROGRAM) diff --git a/config.guess b/config.guess new file mode 100755 index 000000000000..0e30d56e94e0 --- /dev/null +++ b/config.guess @@ -0,0 +1,1407 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-07-02' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner <per@bothner.com>. +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha*:OpenVMS:*:*) + echo alpha-hp-vms + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*|*:GNU/FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <features.h> + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + # GNU/FreeBSD systems have a "k" prefix to indicate we are using + # FreeBSD's kernel, but not the complete OS. + case ${LIBC} in gnu) kernel_only='k' ;; esac + echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <features.h> + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include <sys/param.h> +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + ftp://ftp.gnu.org/pub/gnu/config/ + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 000000000000..d095dbc9facd --- /dev/null +++ b/config.h.in @@ -0,0 +1,256 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Support for debugging output */ +#undef DEBUG + +/* Default delay */ +#undef DEFAULT_DELAY + +/* Default number of processes to display */ +#undef DEFAULT_TOPN + +/* Enable color */ +#undef ENABLE_COLOR + +/* Enable dual architecture */ +#undef ENABLE_DUALARCH + +/* Enable kill and renice */ +#undef ENABLE_KILL + +/* Supports C99 style variadic macros */ +#undef HAVE_C99_VARIADIC_MACROS + +/* Define to 1 if you have the <curses.h> header file. */ +#undef HAVE_CURSES_H + +/* Define to 1 if you have the declaration of `sys_errlist', and to 0 if you + don't. */ +#undef HAVE_DECL_SYS_ERRLIST + +/* Define to 1 if you have the declaration of `sys_signame', and to 0 if you + don't. */ +#undef HAVE_DECL_SYS_SIGNAME + +/* Define to 1 if you have the declaration of `tgetent', and to 0 if you + don't. */ +#undef HAVE_DECL_TGETENT + +/* Define to 1 if you have the declaration of `tgetflag', and to 0 if you + don't. */ +#undef HAVE_DECL_TGETFLAG + +/* Define to 1 if you have the declaration of `tgetnum', and to 0 if you + don't. */ +#undef HAVE_DECL_TGETNUM + +/* Define to 1 if you have the declaration of `tgetstr', and to 0 if you + don't. */ +#undef HAVE_DECL_TGETSTR + +/* Define to 1 if you have the declaration of `tgoto', and to 0 if you don't. + */ +#undef HAVE_DECL_TGOTO + +/* Define to 1 if you have the declaration of `tputs', and to 0 if you don't. + */ +#undef HAVE_DECL_TPUTS + +/* Platform module */ +#undef HAVE_FORMAT_PROCESS_HEADER + +/* Define to 1 if you have the `getopt' function. */ +#undef HAVE_GETOPT + +/* Define to 1 if you have the <getopt.h> header file. */ +#undef HAVE_GETOPT_H + +/* Define to 1 if you have the `getopt_long' function. */ +#undef HAVE_GETOPT_LONG + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Supports gnu style variadic macros */ +#undef HAVE_GNU_VARIADIC_MACROS + +/* Define to 1 if the system has the type `id_t'. */ +#undef HAVE_ID_T + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `elf' library (-lelf). */ +#undef HAVE_LIBELF + +/* Define to 1 if you have the `kstat' library (-lkstat). */ +#undef HAVE_LIBKSTAT + +/* Define to 1 if you have the `kvm' library (-lkvm). */ +#undef HAVE_LIBKVM + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the `mach' library (-lmach). */ +#undef HAVE_LIBMACH + +/* Define to 1 if you have the `mas' library (-lmas). */ +#undef HAVE_LIBMAS + +/* Define to 1 if you have the `perfstat' library (-lperfstat). */ +#undef HAVE_LIBPERFSTAT + +/* Define to 1 if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if the system has the type `lwpid_t'. */ +#undef HAVE_LWPID_T + +/* Define to 1 if you have the <math.h> header file. */ +#undef HAVE_MATH_H + +/* Define to 1 if you have the `memcpy' function. */ +#undef HAVE_MEMCPY + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if the system has the type `pid_t'. */ +#undef HAVE_PID_T + +/* Define to 1 if you have the `setbuffer' function. */ +#undef HAVE_SETBUFFER + +/* Define to 1 if you have the `setpriority' function. */ +#undef HAVE_SETPRIORITY + +/* Define to 1 if you have the `setvbuf' function. */ +#undef HAVE_SETVBUF + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the `sighold' function. */ +#undef HAVE_SIGHOLD + +/* Define to 1 if you have the `sigprocmask' function. */ +#undef HAVE_SIGPROCMASK + +/* Define to 1 if you have the `sigrelse' function. */ +#undef HAVE_SIGRELSE + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the <stdarg.h> header file. */ +#undef HAVE_STDARG_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `sysconf' function. */ +#undef HAVE_SYSCONF + +/* Define to 1 if you have the <sysexits.h> header file. */ +#undef HAVE_SYSEXITS_H + +/* Define to 1 if you have the <sys/resource.h> header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <sys/utsname.h> header file. */ +#undef HAVE_SYS_UTSNAME_H + +/* Define to 1 if you have the <termcap.h> header file. */ +#undef HAVE_TERMCAP_H + +/* Define to 1 if you have the <term.h> header file. */ +#undef HAVE_TERM_H + +/* Define to 1 if the system has the type `time_t'. */ +#undef HAVE_TIME_T + +/* Define to 1 if the system has the type `uid_t'. */ +#undef HAVE_UID_T + +/* Define to 1 if you have the `uname' function. */ +#undef HAVE_UNAME + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Platform module */ +#undef MODULE + +/* Default number of processes to display on non-terminals when topn is all */ +#undef NOMINAL_TOPN + +/* Define the major OS revision number. */ +#undef OSMAJOR + +/* Define the OS revision. */ +#undef OSREV + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ +#undef TIME_WITH_SYS_TIME + +/* Define as the type for the argument to the putc function of tputs ('int' or + 'char') */ +#undef TPUTS_PUTC_ARGTYPE + +/* Define the system hardware platform */ +#undef UNAME_HARDWARE + +/* Include code that utilizes extensions */ +#undef WITH_EXT diff --git a/config.sub b/config.sub new file mode 100755 index 000000000000..9d7f73390549 --- /dev/null +++ b/config.sub @@ -0,0 +1,1504 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-07-04' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | kfreebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | amd64-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 000000000000..f2a53985f3bb --- /dev/null +++ b/configure @@ -0,0 +1,7969 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61 for top 3.8beta1. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 </dev/null 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME='top' +PACKAGE_TARNAME='top' +PACKAGE_VERSION='3.8beta1' +PACKAGE_STRING='top 3.8beta1' +PACKAGE_BUGREPORT='' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +target +target_cpu +target_vendor +target_os +DEFAULT_TOPN +NOMINAL_TOPN +DEFAULT_DELAY +ENABLE_KILL +MAKE +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +AWK +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +ISAINFO +ISAEXEC +UNAME +CPP +GREP +EGREP +SIGNAL_H +HAVE_GETOPT_LONG +SRC +OBJ +CLEAN_EXTRA +ARCHFLAG +MODULE +MODULE_CFLAGS +INSTALL_OPTS_PROG +LIBOBJS +LTLIBOBJS' +ac_subst_files='FIRST_RULE +INSTALL_RULE +MAN_SUPPLEMENT' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures top 3.8beta1 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/top] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of top 3.8beta1:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-debug enable support for debugging output + --disable-kill disable kill and renice commands + --disable-color disable the use of color + --disable-colour synonym for --disable-color + --enable-dualarch enable or disable a dual architecture (32-bit and + 64-bit) compile + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-module=NAME use the platform module NAME + --with-ext=EXT use the extension EXT + --with-default-topn=N use N as the default for number of processes + --with-nominal-topn=N use N as the default number of processes for + non-terminals + --with-default-delay=SEC + use a default delay of SEC seconds + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +top configure 3.8beta1 +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by top $as_me 3.8beta1, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# AX_CHECK_VARIADIC_MACROS... +# ----- + + +# AC_CHECK_CFLAG... +# ----- +# AC_CHECK_CFLAG + +echo "Configuring $PACKAGE_STRING" + +ac_config_headers="$ac_config_headers config.h" + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6; } +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 +echo "$as_me: error: invalid value of canonical target" >&2;} + { (exit 1); exit 1; }; };; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +# options processing + +# Check whether --with-module was given. +if test "${with_module+set}" = set; then + withval=$with_module; if test ! -f machine/m_$withval.c; + then { { echo "$as_me:$LINENO: error: No such module $withval" >&5 +echo "$as_me: error: No such module $withval" >&2;} + { (exit 1); exit 1; }; }; fi +fi + + + +# Check whether --with-ext was given. +if test "${with_ext+set}" = set; then + withval=$with_ext; if test -f ext/$withval.c; then + +cat >>confdefs.h <<\_ACEOF +#define WITH_EXT 1 +_ACEOF + + SRC="$SRC ext/$withval.c" + OBJ="$OBJ $withval.o" + else + { { echo "$as_me:$LINENO: error: No such extension $withval" >&5 +echo "$as_me: error: No such extension $withval" >&2;} + { (exit 1); exit 1; }; } + fi +fi + + +DEFAULT_TOPN=30 + +# Check whether --with-default-topn was given. +if test "${with_default_topn+set}" = set; then + withval=$with_default_topn; if test x"$with_default_topn" = xall; then + DEFAULT_TOPN="-1" + elif test x`echo $with_default_topn | tr -d '0-9+-'` = x; then + DEFAULT_TOPN=$with_default_topn + fi +fi + + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_TOPN $DEFAULT_TOPN +_ACEOF + + + +NOMINAL_TOPN=40 + +# Check whether --with-nominal-topn was given. +if test "${with_nominal_topn+set}" = set; then + withval=$with_nominal_topn; if test x"$with_nominal_topn" = xall; then + NOMINAL_TOPN="-1" + elif test x`echo $with_nominal_topn | tr -d '0-9+-'` = x; then + NOMINAL_TOPN=$with_nominal_topn + fi +fi + + +cat >>confdefs.h <<_ACEOF +#define NOMINAL_TOPN $NOMINAL_TOPN +_ACEOF + + + +DEFAULT_DELAY=5 + +# Check whether --with-default-delay was given. +if test "${with_default_delay+set}" = set; then + withval=$with_default_delay; if test x`echo $with_default_delay | tr -d '0-9+-'` = x; then + DEFAULT_DELAY=$with_default_delay + fi +fi + + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_DELAY $DEFAULT_DELAY +_ACEOF + + + +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then + enableval=$enable_debug; +fi + +if test "x$enable_debug" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define DEBUG 1 +_ACEOF + +fi + +ENABLE_KILL=0 +# Check whether --enable-kill was given. +if test "${enable_kill+set}" = set; then + enableval=$enable_kill; +fi + +if test x$enable_kill != xno; then + +cat >>confdefs.h <<\_ACEOF +#define ENABLE_KILL 1 +_ACEOF + + ENABLE_KILL=1 +fi + + + +# Check whether --enable-color was given. +if test "${enable_color+set}" = set; then + enableval=$enable_color; +fi + +# Check whether --enable-colour was given. +if test "${enable_colour+set}" = set; then + enableval=$enable_colour; +fi + +if test x$enable_color != xno -a x$enable_colour != xno; then + +cat >>confdefs.h <<\_ACEOF +#define ENABLE_COLOR 1 +_ACEOF + +fi + +# Check whether --enable-dualarch was given. +if test "${enable_dualarch+set}" = set; then + enableval=$enable_dualarch; +fi + + +# check for needed programs +for ac_prog in make +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_MAKE+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$MAKE"; then + ac_cv_prog_MAKE="$MAKE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MAKE="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +MAKE=$ac_cv_prog_MAKE +if test -n "$MAKE"; then + { echo "$as_me:$LINENO: result: $MAKE" >&5 +echo "${ECHO_T}$MAKE" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$MAKE" && break +done + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test "$ac_cv_c_compiler_gnu" = "yes"; then + ax_cv_c_compiler_vendor="gnu" +else + + +{ echo "$as_me:$LINENO: checking for C compiler vendor" >&5 +echo $ECHO_N "checking for C compiler vendor... $ECHO_C" >&6; } +if test "${ax_cv_c_compiler_vendor+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ax_cv_c_compiler_vendor=unknown + # note: don't check for gcc first since some other compilers define __GNUC__ + for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ pathscale:__PATHCC__,__PATHSCALE__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do + vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + +#if !($vencpp) + thisisanerror; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ax_cv_c_compiler_vendor=`echo $ventest | cut -d: -f1`; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done + +fi +{ echo "$as_me:$LINENO: result: $ax_cv_c_compiler_vendor" >&5 +echo "${ECHO_T}$ax_cv_c_compiler_vendor" >&6; } + +fi +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +for ac_prog in isainfo +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_ISAINFO+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $ISAINFO in + [\\/]* | ?:[\\/]*) + ac_cv_path_ISAINFO="$ISAINFO" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ISAINFO="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +ISAINFO=$ac_cv_path_ISAINFO +if test -n "$ISAINFO"; then + { echo "$as_me:$LINENO: result: $ISAINFO" >&5 +echo "${ECHO_T}$ISAINFO" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ISAINFO" && break +done + +for ac_prog in isaexec +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_ISAEXEC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $ISAEXEC in + [\\/]* | ?:[\\/]*) + ac_cv_path_ISAEXEC="$ISAEXEC" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/lib:/lib" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ISAEXEC="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +ISAEXEC=$ac_cv_path_ISAEXEC +if test -n "$ISAEXEC"; then + { echo "$as_me:$LINENO: result: $ISAEXEC" >&5 +echo "${ECHO_T}$ISAEXEC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ISAEXEC" && break +done + +for ac_prog in uname +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_UNAME+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $UNAME in + [\\/]* | ?:[\\/]*) + ac_cv_path_UNAME="$UNAME" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_UNAME="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +UNAME=$ac_cv_path_UNAME +if test -n "$UNAME"; then + { echo "$as_me:$LINENO: result: $UNAME" >&5 +echo "${ECHO_T}$UNAME" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$UNAME" && break +done + + + +# system checks require uname +if test "$UNAME"; then + # we make the version number available as a C preprocessor definition + { echo "$as_me:$LINENO: checking OS revision number" >&5 +echo $ECHO_N "checking OS revision number... $ECHO_C" >&6; } + osrev=`$UNAME -r | tr -cd ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789` + + if test "$osrev" != "unknown" ; then + +cat >>confdefs.h <<_ACEOF +#define OSREV $osrev +_ACEOF + + osmajor=`$UNAME -r | sed 's/^\([0-9]*\).*$/\1/'` + if test -n "$osmajor"; then + +cat >>confdefs.h <<_ACEOF +#define OSMAJOR $osmajor +_ACEOF + + fi + else + cat >>confdefs.h <<\_ACEOF +#define OSREV "" +_ACEOF + + fi + { echo "$as_me:$LINENO: result: $osrev" >&5 +echo "${ECHO_T}$osrev" >&6; } + + # we make the non-canonicalized hardware type available + { echo "$as_me:$LINENO: checking hardware platform" >&5 +echo $ECHO_N "checking hardware platform... $ECHO_C" >&6; } + UNAME_HARDWARE=`$UNAME -m` + if test "$UNAME_HARDWARE" != "unknown"; then + +cat >>confdefs.h <<_ACEOF +#define UNAME_HARDWARE "$UNAME_HARDWARE" +_ACEOF + + fi + { echo "$as_me:$LINENO: result: $UNAME_HARDWARE" >&5 +echo "${ECHO_T}$UNAME_HARDWARE" >&6; } +fi + +# checks for libraries + +{ echo "$as_me:$LINENO: checking for elf32_getphdr in -lelf" >&5 +echo $ECHO_N "checking for elf32_getphdr in -lelf... $ECHO_C" >&6; } +if test "${ac_cv_lib_elf_elf32_getphdr+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lelf $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char elf32_getphdr (); +int +main () +{ +return elf32_getphdr (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_elf_elf32_getphdr=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_elf_elf32_getphdr=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_elf_elf32_getphdr" >&5 +echo "${ECHO_T}$ac_cv_lib_elf_elf32_getphdr" >&6; } +if test $ac_cv_lib_elf_elf32_getphdr = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBELF 1 +_ACEOF + + LIBS="-lelf $LIBS" + +fi + + +{ echo "$as_me:$LINENO: checking for kstat_open in -lkstat" >&5 +echo $ECHO_N "checking for kstat_open in -lkstat... $ECHO_C" >&6; } +if test "${ac_cv_lib_kstat_kstat_open+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lkstat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char kstat_open (); +int +main () +{ +return kstat_open (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_kstat_kstat_open=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_kstat_kstat_open=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_kstat_kstat_open" >&5 +echo "${ECHO_T}$ac_cv_lib_kstat_kstat_open" >&6; } +if test $ac_cv_lib_kstat_kstat_open = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBKSTAT 1 +_ACEOF + + LIBS="-lkstat $LIBS" + +fi + + +{ echo "$as_me:$LINENO: checking for kvm_open in -lkvm" >&5 +echo $ECHO_N "checking for kvm_open in -lkvm... $ECHO_C" >&6; } +if test "${ac_cv_lib_kvm_kvm_open+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lkvm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char kvm_open (); +int +main () +{ +return kvm_open (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_kvm_kvm_open=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_kvm_kvm_open=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_kvm_kvm_open" >&5 +echo "${ECHO_T}$ac_cv_lib_kvm_kvm_open" >&6; } +if test $ac_cv_lib_kvm_kvm_open = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBKVM 1 +_ACEOF + + LIBS="-lkvm $LIBS" + +fi + +# -lmld -lmach + +{ echo "$as_me:$LINENO: checking for vm_statistics in -lmach" >&5 +echo $ECHO_N "checking for vm_statistics in -lmach... $ECHO_C" >&6; } +if test "${ac_cv_lib_mach_vm_statistics+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lmach $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char vm_statistics (); +int +main () +{ +return vm_statistics (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_mach_vm_statistics=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_mach_vm_statistics=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_mach_vm_statistics" >&5 +echo "${ECHO_T}$ac_cv_lib_mach_vm_statistics" >&6; } +if test $ac_cv_lib_mach_vm_statistics = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBMACH 1 +_ACEOF + + LIBS="-lmach $LIBS" + +fi + +{ echo "$as_me:$LINENO: checking for library containing tgetent" >&5 +echo $ECHO_N "checking for library containing tgetent... $ECHO_C" >&6; } +if test "${ac_cv_search_tgetent+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +for ac_lib in '' termcap curses ncurses; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_tgetent=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_tgetent+set}" = set; then + break +fi +done +if test "${ac_cv_search_tgetent+set}" = set; then + : +else + ac_cv_search_tgetent=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_tgetent" >&5 +echo "${ECHO_T}$ac_cv_search_tgetent" >&6; } +ac_res=$ac_cv_search_tgetent +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +{ echo "$as_me:$LINENO: checking for exp in -lm" >&5 +echo $ECHO_N "checking for exp in -lm... $ECHO_C" >&6; } +if test "${ac_cv_lib_m_exp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char exp (); +int +main () +{ +return exp (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_m_exp=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_m_exp=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_exp" >&5 +echo "${ECHO_T}$ac_cv_lib_m_exp" >&6; } +if test $ac_cv_lib_m_exp = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi + + +# check for libraries required by extension +extlibs="" +if test -n "$with_ext" -a -f "${srcdir}/ext/$with_ext.libs"; then + { echo "$as_me:$LINENO: checking for libraries needed by extensions" >&5 +echo $ECHO_N "checking for libraries needed by extensions... $ECHO_C" >&6; } + for lib in `cat "${srcdir}/ext/$with_ext.libs"` + do + saveLIBS=$LIBS + LIBS="$LIBS -l$lib" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +exit(0); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + extlibs="$extlibs -l$lib" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$saveLIBS + done + { echo "$as_me:$LINENO: result: $extlibs" >&5 +echo "${ECHO_T}$extlibs" >&6; } + LIBS="$LIBS$extlibs" +fi + +# checks for header files +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + + + + + + +for ac_header in curses.h getopt.h limits.h math.h stdarg.h sysexits.h termcap.h unistd.h sys/resource.h sys/time.h sys/utsname.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in term.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if HAVE_CURSES_H +#include <curses.h> +#endif + + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_time=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for a good signal.h" >&5 +echo $ECHO_N "checking for a good signal.h... $ECHO_C" >&6; } +SIGNAL_H="no" +for f in /usr/include/signal.h /usr/include/sys/signal.h /usr/include/sys/iso/signal_iso.h /usr/include/bits/signum.h; do + if grep SIGKILL $f >/dev/null 2>&1; then + SIGNAL_H=$f + break + fi +done +{ echo "$as_me:$LINENO: result: $SIGNAL_H" >&5 +echo "${ECHO_T}$SIGNAL_H" >&6; } +if test "$SIGNAL_H" = "no"; then + SIGNAL_H="/dev/null" +fi + + +# checks for typedefs, structures, and compiler characteristics. +{ echo "$as_me:$LINENO: checking for variadic macros" >&5 +echo $ECHO_N "checking for variadic macros... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define a(x, ...) (x, __VA_ARGS__) +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ax_cv_c99_variadic=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ax_cv_c99_variadic=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#define a(x...) (x) +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ax_cv_gnu_variadic=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ax_cv_gnu_variadic=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +_result="" +if test "$ax_cv_c99_variadic" = "yes"; then + _result=" c99" + +cat >>confdefs.h <<\_ACEOF +#define HAVE_C99_VARIADIC_MACROS 1 +_ACEOF + +fi +if test "$ax_cv_gnu_variadic" = "yes"; then + _result="$_result gnu" + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GNU_VARIADIC_MACROS 1 +_ACEOF + +fi +if test "x$_result" = x; then + _result="no" +fi +{ echo "$as_me:$LINENO: result: $_result" >&5 +echo "${ECHO_T}$_result" >&6; } + +{ echo "$as_me:$LINENO: checking whether sys_errlist is declared" >&5 +echo $ECHO_N "checking whether sys_errlist is declared... $ECHO_C" >&6; } +if test "${ac_cv_have_decl_sys_errlist+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +#ifndef sys_errlist + (void) sys_errlist; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_have_decl_sys_errlist=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_have_decl_sys_errlist=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_have_decl_sys_errlist" >&5 +echo "${ECHO_T}$ac_cv_have_decl_sys_errlist" >&6; } +if test $ac_cv_have_decl_sys_errlist = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SYS_ERRLIST 1 +_ACEOF + + +else + cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SYS_ERRLIST 0 +_ACEOF + + +fi + + +{ echo "$as_me:$LINENO: checking whether sys_signame is declared" >&5 +echo $ECHO_N "checking whether sys_signame is declared... $ECHO_C" >&6; } +if test "${ac_cv_have_decl_sys_signame+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <signal.h> +/* NetBSD declares sys_siglist in unistd.h. */ +#if HAVE_UNISTD_H +# include <unistd.h> +#endif + + +int +main () +{ +#ifndef sys_signame + (void) sys_signame; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_have_decl_sys_signame=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_have_decl_sys_signame=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_have_decl_sys_signame" >&5 +echo "${ECHO_T}$ac_cv_have_decl_sys_signame" >&6; } +if test $ac_cv_have_decl_sys_signame = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SYS_SIGNAME 1 +_ACEOF + + +else + cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SYS_SIGNAME 0 +_ACEOF + + +fi + + +{ echo "$as_me:$LINENO: checking whether tputs is declared" >&5 +echo $ECHO_N "checking whether tputs is declared... $ECHO_C" >&6; } +if test "${ac_cv_have_decl_tputs+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if HAVE_CURSES_H && HAVE_TERM_H +#include <curses.h> +#include <term.h> +#else +#if HAVE_TERMCAP_H +#include <termcap.h> +#else +#if HAVE_CURSES_H +#include <curses.h> +#endif +#endif +#endif + + +int +main () +{ +#ifndef tputs + (void) tputs; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_have_decl_tputs=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_have_decl_tputs=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_have_decl_tputs" >&5 +echo "${ECHO_T}$ac_cv_have_decl_tputs" >&6; } +if test $ac_cv_have_decl_tputs = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TPUTS 1 +_ACEOF + + +else + cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TPUTS 0 +_ACEOF + + +fi +{ echo "$as_me:$LINENO: checking whether tgoto is declared" >&5 +echo $ECHO_N "checking whether tgoto is declared... $ECHO_C" >&6; } +if test "${ac_cv_have_decl_tgoto+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if HAVE_CURSES_H && HAVE_TERM_H +#include <curses.h> +#include <term.h> +#else +#if HAVE_TERMCAP_H +#include <termcap.h> +#else +#if HAVE_CURSES_H +#include <curses.h> +#endif +#endif +#endif + + +int +main () +{ +#ifndef tgoto + (void) tgoto; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_have_decl_tgoto=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_have_decl_tgoto=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_have_decl_tgoto" >&5 +echo "${ECHO_T}$ac_cv_have_decl_tgoto" >&6; } +if test $ac_cv_have_decl_tgoto = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TGOTO 1 +_ACEOF + + +else + cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TGOTO 0 +_ACEOF + + +fi +{ echo "$as_me:$LINENO: checking whether tgetent is declared" >&5 +echo $ECHO_N "checking whether tgetent is declared... $ECHO_C" >&6; } +if test "${ac_cv_have_decl_tgetent+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if HAVE_CURSES_H && HAVE_TERM_H +#include <curses.h> +#include <term.h> +#else +#if HAVE_TERMCAP_H +#include <termcap.h> +#else +#if HAVE_CURSES_H +#include <curses.h> +#endif +#endif +#endif + + +int +main () +{ +#ifndef tgetent + (void) tgetent; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_have_decl_tgetent=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_have_decl_tgetent=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_have_decl_tgetent" >&5 +echo "${ECHO_T}$ac_cv_have_decl_tgetent" >&6; } +if test $ac_cv_have_decl_tgetent = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TGETENT 1 +_ACEOF + + +else + cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TGETENT 0 +_ACEOF + + +fi +{ echo "$as_me:$LINENO: checking whether tgetflag is declared" >&5 +echo $ECHO_N "checking whether tgetflag is declared... $ECHO_C" >&6; } +if test "${ac_cv_have_decl_tgetflag+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if HAVE_CURSES_H && HAVE_TERM_H +#include <curses.h> +#include <term.h> +#else +#if HAVE_TERMCAP_H +#include <termcap.h> +#else +#if HAVE_CURSES_H +#include <curses.h> +#endif +#endif +#endif + + +int +main () +{ +#ifndef tgetflag + (void) tgetflag; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_have_decl_tgetflag=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_have_decl_tgetflag=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_have_decl_tgetflag" >&5 +echo "${ECHO_T}$ac_cv_have_decl_tgetflag" >&6; } +if test $ac_cv_have_decl_tgetflag = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TGETFLAG 1 +_ACEOF + + +else + cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TGETFLAG 0 +_ACEOF + + +fi +{ echo "$as_me:$LINENO: checking whether tgetnum is declared" >&5 +echo $ECHO_N "checking whether tgetnum is declared... $ECHO_C" >&6; } +if test "${ac_cv_have_decl_tgetnum+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if HAVE_CURSES_H && HAVE_TERM_H +#include <curses.h> +#include <term.h> +#else +#if HAVE_TERMCAP_H +#include <termcap.h> +#else +#if HAVE_CURSES_H +#include <curses.h> +#endif +#endif +#endif + + +int +main () +{ +#ifndef tgetnum + (void) tgetnum; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_have_decl_tgetnum=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_have_decl_tgetnum=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_have_decl_tgetnum" >&5 +echo "${ECHO_T}$ac_cv_have_decl_tgetnum" >&6; } +if test $ac_cv_have_decl_tgetnum = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TGETNUM 1 +_ACEOF + + +else + cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TGETNUM 0 +_ACEOF + + +fi +{ echo "$as_me:$LINENO: checking whether tgetstr is declared" >&5 +echo $ECHO_N "checking whether tgetstr is declared... $ECHO_C" >&6; } +if test "${ac_cv_have_decl_tgetstr+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if HAVE_CURSES_H && HAVE_TERM_H +#include <curses.h> +#include <term.h> +#else +#if HAVE_TERMCAP_H +#include <termcap.h> +#else +#if HAVE_CURSES_H +#include <curses.h> +#endif +#endif +#endif + + +int +main () +{ +#ifndef tgetstr + (void) tgetstr; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_have_decl_tgetstr=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_have_decl_tgetstr=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_have_decl_tgetstr" >&5 +echo "${ECHO_T}$ac_cv_have_decl_tgetstr" >&6; } +if test $ac_cv_have_decl_tgetstr = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TGETSTR 1 +_ACEOF + + +else + cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TGETSTR 0 +_ACEOF + + +fi + + + +# The third argument to tputs is a putc-like function that takes an +# argument. On most systems that argument is an int, but on some it +# is a char. Determine which. +{ echo "$as_me:$LINENO: checking argument type of tputs putc function" >&5 +echo $ECHO_N "checking argument type of tputs putc function... $ECHO_C" >&6; } +_savedwerror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef HAVE_TERMCAP_H +#include <termcap.h> +#endif +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#ifdef HAVE_TERM_H +#include <term.h> +#endif +int f(char i) { } +int +main () +{ +tputs("a", 1, f); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_tputs_putc="char" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_tputs_putc="int" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_cv_type_tputs_putc" >&5 +echo "${ECHO_T}$ac_cv_type_tputs_putc" >&6; } + +cat >>confdefs.h <<_ACEOF +#define TPUTS_PUTC_ARGTYPE $ac_cv_type_tputs_putc +_ACEOF + +ac_c_werror_flag=$_savedwerror_flag + +# Determine presence of needed types +{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <sys/types.h> +#include <signal.h> + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_signal=int +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_signal=void +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +{ echo "$as_me:$LINENO: checking for id_t" >&5 +echo $ECHO_N "checking for id_t... $ECHO_C" >&6; } +if test "${ac_cv_type_id_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef id_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_id_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_id_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_id_t" >&5 +echo "${ECHO_T}$ac_cv_type_id_t" >&6; } +if test $ac_cv_type_id_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_ID_T 1 +_ACEOF + + +fi +{ echo "$as_me:$LINENO: checking for lwpid_t" >&5 +echo $ECHO_N "checking for lwpid_t... $ECHO_C" >&6; } +if test "${ac_cv_type_lwpid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef lwpid_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_lwpid_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_lwpid_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_lwpid_t" >&5 +echo "${ECHO_T}$ac_cv_type_lwpid_t" >&6; } +if test $ac_cv_type_lwpid_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_LWPID_T 1 +_ACEOF + + +fi +{ echo "$as_me:$LINENO: checking for pid_t" >&5 +echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } +if test "${ac_cv_type_pid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef pid_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_pid_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_pid_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 +echo "${ECHO_T}$ac_cv_type_pid_t" >&6; } +if test $ac_cv_type_pid_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_PID_T 1 +_ACEOF + + +fi +{ echo "$as_me:$LINENO: checking for time_t" >&5 +echo $ECHO_N "checking for time_t... $ECHO_C" >&6; } +if test "${ac_cv_type_time_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef time_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_time_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_time_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_time_t" >&5 +echo "${ECHO_T}$ac_cv_type_time_t" >&6; } +if test $ac_cv_type_time_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_TIME_T 1 +_ACEOF + + +fi +{ echo "$as_me:$LINENO: checking for uid_t" >&5 +echo $ECHO_N "checking for uid_t... $ECHO_C" >&6; } +if test "${ac_cv_type_uid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef uid_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_uid_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_uid_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 +echo "${ECHO_T}$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_UID_T 1 +_ACEOF + + +fi + + +# Checks for library functions. + + + + + + + + + + + + + + + + + + +for ac_func in getopt getopt_long gettimeofday memcpy setbuffer setpriority setvbuf strcasecmp strchr strerror snprintf sighold sigrelse sigaction sigprocmask sysconf uname vsnprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# this is needed in the man page +if test "x$ac_cv_func_getopt_long" = "xyes"; then + HAVE_GETOPT_LONG=1 +else + HAVE_GETOPT_LONG=0 +fi + + +# if we dont have snprintf/vsnprint then we need to compile the alternate +if test "x$ac_cv_func_snprintf" != "xyes" -o "x$ac_cv_func_vsnprintf" != "xyes"; then + SRC="$SRC ap_snprintf.c" + OBJ="$OBJ ap_snprintf.o" +fi + + +# determine correct user, group, and mode +# these can be overridden later if need be +{ echo "$as_me:$LINENO: checking for correct ls options" >&5 +echo $ECHO_N "checking for correct ls options... $ECHO_C" >&6; } +lslong="ls -l" +if test `$lslong -d . | wc -w` -lt 9; then + lslong="ls -lg" +fi +{ echo "$as_me:$LINENO: result: $lslong" >&5 +echo "${ECHO_T}$lslong" >&6; } + + +# determine correct module +{ echo "$as_me:$LINENO: checking for a platform module" >&5 +echo $ECHO_N "checking for a platform module... $ECHO_C" >&6; } +if test "$with_module"; then + MODULE=$with_module +else + case $target_os in + aix4.2*) MODULE=aix43;; + aix4.3*) MODULE=aix43;; + aix5*) MODULE=aix5;; + dec-osf*) MODULE=decosf1;; + osf1*) MODULE=decosf1;; + osf4*) MODULE=decosf1;; + osf5*) MODULE=decosf1;; + freebsd*) MODULE=freebsd; USE_KMEM=1; USE_FPH=1;; + hpux7*) MODULE=hpux7;; + hpux8*) MODULE=hpux8;; + hpux9*) MODULE=hpux9;; + hpux10*) MODULE=hpux10;; + hpux11*) MODULE=hpux10;; + irix5*) MODULE=irix5;; + irix6*) MODULE=irixsgi;; + linux*) MODULE=linux; USE_FPH=1; SET_MODE=755;; + netbsd*) MODULE=netbsd; SET_MODE=755;; + solaris2*) MODULE=sunos5; USE_FPH=1; SET_MODE=755;; + sunos4*) MODULE=sunos4;; + sysv4*) MODULE=svr4;; + sysv5*) MODULE=svr5;; + darwin*) + echo "macosx" + echo "The macosx module is untested. Use at your own risk." + echo "If you really want to use this module, please run configure as follows:" + echo " ./configure --with-module=macosx" + { { echo "$as_me:$LINENO: error: macosx module unsupported" >&5 +echo "$as_me: error: macosx module unsupported" >&2;} + { (exit 1); exit 1; }; };; + *) echo "none" + echo "Configure doesn't recognize this system and doesn't know" + echo "what module to assign to it. Help the cause and run the" + echo "following command to let the maintainers know about this" + echo "deficiency! Thanks. Just cut and paste the following:" +echo "uname -a | mail -s $target_os bill@lefebvre.org" + echo "" + { { echo "$as_me:$LINENO: error: System type $target_os unrecognized" >&5 +echo "$as_me: error: System type $target_os unrecognized" >&2;} + { (exit 1); exit 1; }; } + esac +fi +{ echo "$as_me:$LINENO: result: $MODULE" >&5 +echo "${ECHO_T}$MODULE" >&6; } +SRC="$SRC machine/m_$MODULE.c" +OBJ="$OBJ m_$MODULE.o" +CLEAN_EXTRA="" + + + + +cat >>confdefs.h <<_ACEOF +#define MODULE "$MODULE" +_ACEOF + + +FIRST_RULE=/dev/null +INSTALL_RULE=config.default.makeinstall + +# extra things that need to be done for certain systems +# also handle setup for 64-bit detection +bits="default" +case $MODULE in + aix5) + +{ echo "$as_me:$LINENO: checking for perfstat_cpu_total in -lperfstat" >&5 +echo $ECHO_N "checking for perfstat_cpu_total in -lperfstat... $ECHO_C" >&6; } +if test "${ac_cv_lib_perfstat_perfstat_cpu_total+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lperfstat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char perfstat_cpu_total (); +int +main () +{ +return perfstat_cpu_total (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_perfstat_perfstat_cpu_total=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_perfstat_perfstat_cpu_total=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_perfstat_perfstat_cpu_total" >&5 +echo "${ECHO_T}$ac_cv_lib_perfstat_perfstat_cpu_total" >&6; } +if test $ac_cv_lib_perfstat_perfstat_cpu_total = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPERFSTAT 1 +_ACEOF + + LIBS="-lperfstat $LIBS" + +fi + + if test -f /usr/sbin/bootinfo; then + bits="`/usr/sbin/bootinfo -K`" + extra_flag="-q64" + fi + ;; + svr5) + # -lmas + +{ echo "$as_me:$LINENO: checking for mas_open in -lmas" >&5 +echo $ECHO_N "checking for mas_open in -lmas... $ECHO_C" >&6; } +if test "${ac_cv_lib_mas_mas_open+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lmas $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char mas_open (); +int +main () +{ +return mas_open (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_mas_mas_open=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_mas_mas_open=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_mas_mas_open" >&5 +echo "${ECHO_T}$ac_cv_lib_mas_mas_open" >&6; } +if test $ac_cv_lib_mas_mas_open = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBMAS 1 +_ACEOF + + LIBS="-lmas $LIBS" + +fi + + ;; + sunos5) + if test "$ISAINFO"; then + bits="`$ISAINFO -b`" + if test "$target_cpu" = "sparc"; then + extra_flag="-xarch=v9" + else + extra_flag="-xarch=amd64" + fi + fi + ;; +esac + +# USE_FPH means the module has format_process_header +if test -n "$USE_FPH"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_FORMAT_PROCESS_HEADER 1 +_ACEOF + +fi + +# if we are 64-bit, try to turn on the appropriate flags +{ echo "$as_me:$LINENO: checking address space size" >&5 +echo $ECHO_N "checking address space size... $ECHO_C" >&6; } +ARCHFLAG="" +if test "$bits" = "64"; then + { echo "$as_me:$LINENO: result: 64" >&5 +echo "${ECHO_T}64" >&6; } + if test "$ax_cv_c_compiler_vendor" = "gnu"; then + extra_flag="-m64" + fi +# Make sure our compiler accepts the flag we want to use + { echo "$as_me:$LINENO: checking whether compiler accepts $extra_flag" >&5 +echo $ECHO_N "checking whether compiler accepts $extra_flag... $ECHO_C" >&6; } +as_ac_Flag=`echo "ac_cv_cflag_$extra_flag" | $as_tr_sh` +_savedcflags=$CFLAGS +_savedwerror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +CFLAGS=$CFLAGS" $extra_flag" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_Flag=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Flag=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Flag'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Flag'}'`" >&6; } +CFLAGS=$_savedcflags +ac_c_werror_flag=$_savedwerror_flag +if test `eval echo '${'$as_ac_Flag'}'` = yes; then + ARCHFLAG="$extra_flag" +else + enable_dualarch="no" +fi + +else + { echo "$as_me:$LINENO: result: $bits" >&5 +echo "${ECHO_T}$bits" >&6; } +fi + + +# Dual architecture handling: for now this is only enabled on Solaris. +# Config options can explicitly enable or disable dualarch. Otherwise, +# dualarch is only enabled when we are on a 64-bit system. +if test "$MODULE" = "sunos5"; then + { echo "$as_me:$LINENO: checking for dual architecture compilation" >&5 +echo $ECHO_N "checking for dual architecture compilation... $ECHO_C" >&6; } + if test "x$enable_dualarch" = x; then +# we must make the determination implicitly + if test "$bits" = "64"; then + enable_dualarch="yes" + else + enable_dualarch="no" + fi + fi + if test "x$enable_dualarch" = "xyes"; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + if test "$target_cpu" = "sparc"; then + FIRST_RULE="config.sparcv9.make" + INSTALL_RULE="config.sparcv9.makeinstall" + CLEAN_EXTRA="$CLEAN_EXTRA sparcv7/* sparcv9/*" + mkdir -p sparcv7 sparcv9 + else + FIRST_RULE="config.amd64.make" + INSTALL_RULE="config.amd64.makeinstall" + CLEAN_EXTRA="$CLEAN_EXTRA i386/* amd64/*" + mkdir -p i386 amd64 + fi + else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + fi +fi + +if test x$enable_dualarch = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define ENABLE_DUALARCH 1 +_ACEOF + +fi + + + + +{ echo "$as_me:$LINENO: checking for installation settings" >&5 +echo $ECHO_N "checking for installation settings... $ECHO_C" >&6; } +# calculate appropriate settings +OWNER="" +GROUP="" +MODE="" +if test ! -n "$USE_KMEM" -a -d /proc; then +# make sure we are installed so that we can read /proc + rm -f conftest.txt + if test -r /proc/0/psinfo; then +# system uses solaris-style /proc + $lslong /proc/0/psinfo >conftest.txt + elif test -r /proc/1/stat; then +# linux-style /proc? + $lslong /proc/1/stat >conftest.txt + else + echo "-r--r--r-- 1 bin bin 32 Jan 1 12:00 /foo" >conftest.txt + fi + +# set permissions so that we can read stuff in /proc + if grep '^.......r..' conftest.txt >/dev/null; then +# world readable + MODE=755 + elif grep '^....r.....' conftest.txt >/dev/null; then +# group readable + MODE=2711 + GROUP=`awk ' { print $4 }'` + else +# probably only readable by root + MODE=4711 + OWNER=`awk ' { print $3 }'` + fi + +elif test -c /dev/kmem; then + $lslong -L /dev/kmem >conftest.txt + if grep '^....r..r..' conftest.txt >/dev/null; then + MODE=755 + elif grep '^....r..-..' conftest.txt >/dev/null; then + MODE=2755 + GROUP=`$AWK ' { print $4 }' conftest.txt` + fi +else + MODE=755 +fi +rm -f conftest.txt +# let module settings override what we calculated +OWNER=${SET_OWNER:-$OWNER} +GROUP=${SET_GROUP:-$GROUP} +MODE=${SET_MODE:-$MODE} + +# set only those things that require it +result="" +INSTALL_OPTS_PROG="" +if test x$OWNER != x; then + result="${result}owner=$OWNER, " + INSTALL_OPTS_PROG="$INSTALL_OPTS_PROG -o $OWNER" +fi +if test x$GROUP != x; then + result="${result}group=$GROUP, " + INSTALL_OPTS_PROG="$INSTALL_OPTS_PROG -g $GROUP" +fi +result="${result}mode=$MODE" +INSTALL_OPTS_PROG="$INSTALL_OPTS_PROG -m $MODE" + +{ echo "$as_me:$LINENO: result: $result" >&5 +echo "${ECHO_T}$result" >&6; } + +# add extra cflags if the compiler accepts them +{ echo "$as_me:$LINENO: checking CFLAGS for maximum warnings" >&5 +echo $ECHO_N "checking CFLAGS for maximum warnings... $ECHO_C" >&6; } +if test "${ac_cv_cflags_warn_all+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_cflags_warn_all="no, unknown" + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ac_save_CFLAGS="$CFLAGS" +for ac_arg in "-pedantic % -Wall" "-xstrconst % -v" "-std1 % -verbose -w0 -warnprotos" "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" "-ansi -ansiE % -fullwarn" "+ESlit % +w1" "-Xc % -pvctl,fullmsg" "-h conform % -h msglevel 2" # +do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_cflags_warn_all=`echo $ac_arg | sed -e 's,.*% *,,'` ; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done + CFLAGS="$ac_save_CFLAGS" + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cflags_warn_all" >&5 +echo "${ECHO_T}$ac_cv_cflags_warn_all" >&6; } +case ".$ac_cv_cflags_warn_all" in + .ok|.ok,*) ;; + .|.no|.no,*) + ;; + *) + if echo " $CFLAGS " | grep " $ac_cv_cflags_warn_all " 2>&1 >/dev/null + then { (echo "$as_me:$LINENO: : CFLAGS does contain \$ac_cv_cflags_warn_all") >&5 + (: CFLAGS does contain $ac_cv_cflags_warn_all) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + else { (echo "$as_me:$LINENO: : CFLAGS=\"\$CFLAGS \$ac_cv_cflags_warn_all\"") >&5 + (: CFLAGS="$CFLAGS $ac_cv_cflags_warn_all") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + CFLAGS="$CFLAGS $ac_cv_cflags_warn_all" + fi + ;; +esac + +MODULE_CFLAGS="" +if test "$ax_cv_c_compiler_vendor" = "gnu"; then + { echo "$as_me:$LINENO: checking MODULE_CFLAGS for gcc -fno-strict-aliasing" >&5 +echo $ECHO_N "checking MODULE_CFLAGS for gcc -fno-strict-aliasing... $ECHO_C" >&6; } +if test "${ac_cv_cflags_gcc_option__fno_strict_aliasing+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_cflags_gcc_option__fno_strict_aliasing="no, unknown" + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ac_save_CFLAGS="$CFLAGS" +for ac_arg in "-pedantic -Werror % -fno-strict-aliasing" "-pedantic % -fno-strict-aliasing %% no, obsolete" # +do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_cflags_gcc_option__fno_strict_aliasing=`echo $ac_arg | sed -e 's,.*% *,,'` ; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done + CFLAGS="$ac_save_CFLAGS" + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cflags_gcc_option__fno_strict_aliasing" >&5 +echo "${ECHO_T}$ac_cv_cflags_gcc_option__fno_strict_aliasing" >&6; } +case ".$ac_cv_cflags_gcc_option__fno_strict_aliasing" in + .ok|.ok,*) ;; + .|.no|.no,*) ;; + *) + if echo " $MODULE_CFLAGS " | grep " $ac_cv_cflags_gcc_option__fno_strict_aliasing " 2>&1 >/dev/null + then { (echo "$as_me:$LINENO: : MODULE_CFLAGS does contain \$ac_cv_cflags_gcc_option__fno_strict_aliasing") >&5 + (: MODULE_CFLAGS does contain $ac_cv_cflags_gcc_option__fno_strict_aliasing) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + else { (echo "$as_me:$LINENO: : MODULE_CFLAGS=\"\$MODULE_CFLAGS \$ac_cv_cflags_gcc_option__fno_strict_aliasing\"") >&5 + (: MODULE_CFLAGS="$MODULE_CFLAGS $ac_cv_cflags_gcc_option__fno_strict_aliasing") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + MODULE_CFLAGS="$MODULE_CFLAGS $ac_cv_cflags_gcc_option__fno_strict_aliasing" + fi + ;; +esac + + if test "$target_cpu" = "alpha"; then + { echo "$as_me:$LINENO: checking CFLAGS for gcc -mfp-trap-mode=sui -mtrap-precision=i" >&5 +echo $ECHO_N "checking CFLAGS for gcc -mfp-trap-mode=sui -mtrap-precision=i... $ECHO_C" >&6; } +if test "${ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i="no, unknown" + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ac_save_CFLAGS="$CFLAGS" +for ac_arg in "-pedantic -Werror % -mfp-trap-mode=sui -mtrap-precision=i" "-pedantic % -mfp-trap-mode=sui -mtrap-precision=i %% no, obsolete" # +do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i=`echo $ac_arg | sed -e 's,.*% *,,'` ; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done + CFLAGS="$ac_save_CFLAGS" + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i" >&5 +echo "${ECHO_T}$ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i" >&6; } +case ".$ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i" in + .ok|.ok,*) ;; + .|.no|.no,*) ;; + *) + if echo " $CFLAGS " | grep " $ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i " 2>&1 >/dev/null + then { (echo "$as_me:$LINENO: : CFLAGS does contain \$ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i") >&5 + (: CFLAGS does contain $ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + else { (echo "$as_me:$LINENO: : CFLAGS=\"\$CFLAGS \$ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i\"") >&5 + (: CFLAGS="$CFLAGS $ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + CFLAGS="$CFLAGS $ac_cv_cflags_gcc_option__mfp_trap_mode_sui__mtrap_precision_i" + fi + ;; +esac + + fi +fi + +# Define man page supplement +MAN_SUPPLEMENT=machine/m_$MODULE.man + + +# Extra things we want substituted + + + + +# wrapup + +ac_config_files="$ac_config_files Makefile top.1" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by top $as_me 3.8beta1, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to <bug-autoconf@gnu.org>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +top config.status 3.8beta1 +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "top.1") CONFIG_FILES="$CONFIG_FILES top.1" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + +# Create sed commands to just substitute file output variables. + +# Remaining file output variables are in a fragment that also has non-file +# output varibles. + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +target!$target$ac_delim +target_cpu!$target_cpu$ac_delim +target_vendor!$target_vendor$ac_delim +target_os!$target_os$ac_delim +DEFAULT_TOPN!$DEFAULT_TOPN$ac_delim +NOMINAL_TOPN!$NOMINAL_TOPN$ac_delim +DEFAULT_DELAY!$DEFAULT_DELAY$ac_delim +ENABLE_KILL!$ENABLE_KILL$ac_delim +MAKE!$MAKE$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +AWK!$AWK$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +ISAINFO!$ISAINFO$ac_delim +ISAEXEC!$ISAEXEC$ac_delim +UNAME!$UNAME$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +SIGNAL_H!$SIGNAL_H$ac_delim +HAVE_GETOPT_LONG!$HAVE_GETOPT_LONG$ac_delim +SRC!$SRC$ac_delim +OBJ!$OBJ$ac_delim +CLEAN_EXTRA!$CLEAN_EXTRA$ac_delim +ARCHFLAG!$ARCHFLAG$ac_delim +MODULE!$MODULE$ac_delim +MODULE_CFLAGS!$MODULE_CFLAGS$ac_delim +INSTALL_OPTS_PROG!$INSTALL_OPTS_PROG$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 82; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +/^[ ]*@FIRST_RULE@[ ]*$/{ +r $FIRST_RULE +d +} +/^[ ]*@INSTALL_RULE@[ ]*$/{ +r $INSTALL_RULE +d +} +/^[ ]*@MAN_SUPPLEMENT@[ ]*$/{ +r $MAN_SUPPLEMENT +d +} +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS <conf$$subs.sed +rm -f conf$$subs.sed +cat >>$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" + ;; + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000000..c7fc28fafcce --- /dev/null +++ b/configure.ac @@ -0,0 +1,529 @@ +# configure.ac +AC_INIT(top, 3.8beta1) + +# AX_CHECK_VARIADIC_MACROS... +# ----- +AC_DEFUN([AX_CHECK_VARIADIC_MACROS], +[AC_MSG_CHECKING([for variadic macros]) +AC_COMPILE_IFELSE(AC_LANG_PROGRAM( +[#define a(x, ...) (x, __VA_ARGS__)], []), + [AS_VAR_SET(ax_cv_c99_variadic, yes)], + [AS_VAR_SET(ax_cv_c99_variadic, no)]) +AC_COMPILE_IFELSE(AC_LANG_PROGRAM( +[#define a(x...) (x)], []), + [AS_VAR_SET(ax_cv_gnu_variadic, yes)], + [AS_VAR_SET(ax_cv_gnu_variadic, no)]) +_result="" +if test "$ax_cv_c99_variadic" = "yes"; then + _result=" c99" + AC_DEFINE(HAVE_C99_VARIADIC_MACROS, 1, [Supports C99 style variadic macros]) +fi +if test "$ax_cv_gnu_variadic" = "yes"; then + _result="$_result gnu" + AC_DEFINE(HAVE_GNU_VARIADIC_MACROS, 1, [Supports gnu style variadic macros]) +fi +if test "x$_result" = x; then + _result="no" +fi +AC_MSG_RESULT($_result) +]) + +# AC_CHECK_CFLAG... +# ----- +AC_DEFUN([AC_CHECK_CFLAG], +[AC_MSG_CHECKING([whether compiler accepts $1]) +AS_VAR_PUSHDEF([ac_Flag], [ac_cv_cflag_$1])dnl +_savedcflags=$CFLAGS +_savedwerror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +CFLAGS=$CFLAGS" $1" +AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [AS_VAR_SET(ac_Flag, yes)], + [AS_VAR_SET(ac_Flag, no)]) +AC_MSG_RESULT([AS_VAR_GET(ac_Flag)]) +CFLAGS=$_savedcflags +ac_c_werror_flag=$_savedwerror_flag +AS_IF([test AS_VAR_GET(ac_Flag) = yes], [$2], [$3])[]dnl +AS_VAR_POPDEF([ac_Flag])dnl +])# AC_CHECK_CFLAG + +echo "Configuring $PACKAGE_STRING" + +AC_CONFIG_HEADER([config.h]) +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +# options processing +AC_ARG_WITH(module, AC_HELP_STRING([--with-module=NAME], + [use the platform module NAME]), + [if test ! -f machine/m_$withval.c; + then AC_MSG_ERROR([No such module $withval]); fi]) + +AC_ARG_WITH(ext, AC_HELP_STRING([--with-ext=EXT], + [use the extension EXT]), + [if test -f ext/$withval.c; then + AC_DEFINE(WITH_EXT, 1, [Include code that utilizes extensions]) + SRC="$SRC ext/$withval.c" + OBJ="$OBJ $withval.o" + else + AC_MSG_ERROR([No such extension $withval]) + fi]) + +DEFAULT_TOPN=30 +AC_ARG_WITH(default-topn, AC_HELP_STRING([--with-default-topn=N], + [use N as the default for number of processes]), + [if test x"$with_default_topn" = xall; then + DEFAULT_TOPN="-1" + elif test x`echo $with_default_topn | tr -d '[0-9+-]'` = x; then + DEFAULT_TOPN=$with_default_topn + fi]) +AC_DEFINE_UNQUOTED(DEFAULT_TOPN, $DEFAULT_TOPN, [Default number of processes to display]) +AC_SUBST(DEFAULT_TOPN) + +NOMINAL_TOPN=40 +AC_ARG_WITH(nominal-topn, AC_HELP_STRING([--with-nominal-topn=N], + [use N as the default number of processes for non-terminals]), + [if test x"$with_nominal_topn" = xall; then + NOMINAL_TOPN="-1" + elif test x`echo $with_nominal_topn | tr -d '[0-9+-]'` = x; then + NOMINAL_TOPN=$with_nominal_topn + fi]) +AC_DEFINE_UNQUOTED(NOMINAL_TOPN, $NOMINAL_TOPN, [Default number of processes to display on non-terminals when topn is all]) +AC_SUBST(NOMINAL_TOPN) + +DEFAULT_DELAY=5 +AC_ARG_WITH(default-delay, AC_HELP_STRING([--with-default-delay=SEC], + [use a default delay of SEC seconds]), + [if test x`echo $with_default_delay | tr -d '[0-9+-]'` = x; then + DEFAULT_DELAY=$with_default_delay + fi]) +AC_DEFINE_UNQUOTED(DEFAULT_DELAY, $DEFAULT_DELAY, [Default delay]) +AC_SUBST(DEFAULT_DELAY) + +AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], + [enable support for debugging output])) +if test "x$enable_debug" = xyes; then + AC_DEFINE(DEBUG, 1, [Support for debugging output]) +fi + +ENABLE_KILL=0 +AC_ARG_ENABLE(kill, AC_HELP_STRING([--disable-kill], + [disable kill and renice commands])) +if test x$enable_kill != xno; then + AC_DEFINE(ENABLE_KILL, 1, [Enable kill and renice]) + ENABLE_KILL=1 +fi +AC_SUBST(ENABLE_KILL) + + +AC_ARG_ENABLE(color, AC_HELP_STRING([--disable-color], + [disable the use of color])) +AC_ARG_ENABLE(colour, AC_HELP_STRING([--disable-colour], + [synonym for --disable-color])) +if test x$enable_color != xno -a x$enable_colour != xno; then + AC_DEFINE(ENABLE_COLOR, 1, [Enable color]) +fi + +AC_ARG_ENABLE(dualarch, AC_HELP_STRING([--enable-dualarch], + [enable or disable a dual architecture (32-bit and 64-bit) compile])) + +# check for needed programs +AC_CHECK_PROGS(MAKE, make) +AC_PROG_CC +if test "$ac_cv_c_compiler_gnu" = "yes"; then + ax_cv_c_compiler_vendor="gnu" +else + AX_COMPILER_VENDOR +fi +AC_PROG_AWK +AC_PROG_INSTALL +AC_PATH_PROGS(ISAINFO, isainfo) +AC_PATH_PROGS(ISAEXEC, isaexec, , [$PATH:/usr/lib:/lib]) +AC_PATH_PROGS(UNAME, uname) +AC_SUBST(ISAEXEC) + +# system checks require uname +if test "$UNAME"; then + # we make the version number available as a C preprocessor definition + AC_MSG_CHECKING(OS revision number) + osrev=`$UNAME -r | tr -cd ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789` + + if test "$osrev" != "unknown" ; then + AC_DEFINE_UNQUOTED(OSREV, $osrev, [Define the OS revision.]) + osmajor=`$UNAME -r | sed 's/^\([[0-9]]*\).*$/\1/'` + if test -n "$osmajor"; then + AC_DEFINE_UNQUOTED(OSMAJOR, $osmajor, [Define the major OS revision number.]) + fi + else + AC_DEFINE(OSREV, "") + fi + AC_MSG_RESULT($osrev) + + # we make the non-canonicalized hardware type available + AC_MSG_CHECKING(hardware platform) + UNAME_HARDWARE=`$UNAME -m` + if test "$UNAME_HARDWARE" != "unknown"; then + AC_DEFINE_UNQUOTED(UNAME_HARDWARE, "$UNAME_HARDWARE", [Define the system hardware platform]) + fi + AC_MSG_RESULT($UNAME_HARDWARE) +fi + +# checks for libraries +AC_CHECK_LIB(elf, elf32_getphdr) +AC_CHECK_LIB(kstat, kstat_open) +AC_CHECK_LIB(kvm, kvm_open) +# -lmld -lmach +AC_CHECK_LIB(mach, vm_statistics) +AC_SEARCH_LIBS(tgetent, termcap curses ncurses) +AC_CHECK_LIB(m, exp) + +# check for libraries required by extension +extlibs="" +if test -n "$with_ext" -a -f "${srcdir}/ext/$with_ext.libs"; then + AC_MSG_CHECKING(for libraries needed by extensions) + for lib in `cat "${srcdir}/ext/$with_ext.libs"` + do + saveLIBS=$LIBS + LIBS="$LIBS -l$lib" + AC_TRY_LINK(, [exit(0);], [extlibs="$extlibs -l$lib"], ) + LIBS=$saveLIBS + done + AC_MSG_RESULT($extlibs) + LIBS="$LIBS$extlibs" +fi + +# checks for header files +AC_HEADER_STDC +AC_CHECK_HEADERS([curses.h getopt.h limits.h math.h stdarg.h sysexits.h termcap.h unistd.h sys/resource.h sys/time.h sys/utsname.h]) +AC_CHECK_HEADERS([term.h],,, +[#if HAVE_CURSES_H +#include <curses.h> +#endif +]) +AC_HEADER_TIME +AC_MSG_CHECKING(for a good signal.h) +SIGNAL_H="no" +for f in /usr/include/signal.h /usr/include/sys/signal.h /usr/include/sys/iso/signal_iso.h /usr/include/bits/signum.h; do + if grep SIGKILL $f >/dev/null 2>&1; then + SIGNAL_H=$f + break + fi +done +AC_MSG_RESULT($SIGNAL_H) +if test "$SIGNAL_H" = "no"; then + SIGNAL_H="/dev/null" +fi +AC_SUBST(SIGNAL_H) + +# checks for typedefs, structures, and compiler characteristics. +AX_CHECK_VARIADIC_MACROS +AC_CHECK_DECLS([sys_errlist]) +AC_CHECK_DECLS([sys_signame],,, +[#include <signal.h> +/* NetBSD declares sys_siglist in unistd.h. */ +#if HAVE_UNISTD_H +# include <unistd.h> +#endif +]) +AC_CHECK_DECLS([tputs, tgoto, tgetent, tgetflag, tgetnum, tgetstr],,, +[#if HAVE_CURSES_H && HAVE_TERM_H +#include <curses.h> +#include <term.h> +#else +#if HAVE_TERMCAP_H +#include <termcap.h> +#else +#if HAVE_CURSES_H +#include <curses.h> +#endif +#endif +#endif +]) + +# The third argument to tputs is a putc-like function that takes an +# argument. On most systems that argument is an int, but on some it +# is a char. Determine which. +AC_MSG_CHECKING([argument type of tputs putc function]) +_savedwerror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +AC_COMPILE_IFELSE( +[AC_LANG_PROGRAM([#ifdef HAVE_TERMCAP_H +#include <termcap.h> +#endif +#ifdef HAVE_CURSES_H +#include <curses.h> +#endif +#ifdef HAVE_TERM_H +#include <term.h> +#endif +int f(char i) { }], +[tputs("a", 1, f);])], + [ac_cv_type_tputs_putc="char"], + [ac_cv_type_tputs_putc="int"]) +AC_MSG_RESULT($ac_cv_type_tputs_putc) +AC_DEFINE_UNQUOTED(TPUTS_PUTC_ARGTYPE, $ac_cv_type_tputs_putc, + [Define as the type for the argument to the +putc function of tputs ('int' or 'char')]) +ac_c_werror_flag=$_savedwerror_flag + +# Determine presence of needed types +AC_TYPE_SIGNAL +AC_CHECK_TYPES([id_t, lwpid_t, pid_t, time_t, uid_t]) + +# Checks for library functions. +AC_CHECK_FUNCS([getopt getopt_long gettimeofday memcpy setbuffer setpriority setvbuf strcasecmp strchr strerror snprintf sighold sigrelse sigaction sigprocmask sysconf uname vsnprintf]) + +# this is needed in the man page +if test "x$ac_cv_func_getopt_long" = "xyes"; then + HAVE_GETOPT_LONG=1 +else + HAVE_GETOPT_LONG=0 +fi +AC_SUBST(HAVE_GETOPT_LONG) + +# if we dont have snprintf/vsnprint then we need to compile the alternate +if test "x$ac_cv_func_snprintf" != "xyes" -o "x$ac_cv_func_vsnprintf" != "xyes"; then + SRC="$SRC ap_snprintf.c" + OBJ="$OBJ ap_snprintf.o" +fi + + +# determine correct user, group, and mode +# these can be overridden later if need be +AC_MSG_CHECKING(for correct ls options) +lslong="ls -l" +if test `$lslong -d . | wc -w` -lt 9; then + lslong="ls -lg" +fi +AC_MSG_RESULT($lslong) + + +# determine correct module +AC_MSG_CHECKING(for a platform module) +if test "$with_module"; then + MODULE=$with_module +else + case $target_os in + aix4.2*) MODULE=aix43;; + aix4.3*) MODULE=aix43;; + aix5*) MODULE=aix5;; + dec-osf*) MODULE=decosf1;; + osf1*) MODULE=decosf1;; + osf4*) MODULE=decosf1;; + osf5*) MODULE=decosf1;; + freebsd*) MODULE=freebsd; USE_KMEM=1; USE_FPH=1;; + hpux7*) MODULE=hpux7;; + hpux8*) MODULE=hpux8;; + hpux9*) MODULE=hpux9;; + hpux10*) MODULE=hpux10;; + hpux11*) MODULE=hpux10;; + irix5*) MODULE=irix5;; + irix6*) MODULE=irixsgi;; + linux*) MODULE=linux; USE_FPH=1; SET_MODE=755;; + netbsd*) MODULE=netbsd; SET_MODE=755;; + solaris2*) MODULE=sunos5; USE_FPH=1; SET_MODE=755;; + sunos4*) MODULE=sunos4;; + sysv4*) MODULE=svr4;; + sysv5*) MODULE=svr5;; + darwin*) + echo "macosx" + echo "The macosx module is untested. Use at your own risk." + echo "If you really want to use this module, please run configure as follows:" + echo " ./configure --with-module=macosx" + AC_MSG_ERROR([macosx module unsupported]);; + *) echo "none" + echo "Configure doesn't recognize this system and doesn't know" + echo "what module to assign to it. Help the cause and run the" + echo "following command to let the maintainers know about this" + echo "deficiency! Thanks. Just cut and paste the following:" +echo "uname -a | mail -s $target_os bill@lefebvre.org" + echo "" + AC_MSG_ERROR([System type $target_os unrecognized]) + esac +fi +AC_MSG_RESULT($MODULE) +SRC="$SRC machine/m_$MODULE.c" +OBJ="$OBJ m_$MODULE.o" +CLEAN_EXTRA="" +AC_SUBST(SRC) +AC_SUBST(OBJ) +AC_SUBST(CLEAN_EXTRA) +AC_DEFINE_UNQUOTED(MODULE, "$MODULE", [Platform module]) + +FIRST_RULE=/dev/null +INSTALL_RULE=config.default.makeinstall + +# extra things that need to be done for certain systems +# also handle setup for 64-bit detection +bits="default" +case $MODULE in + aix5) + AC_CHECK_LIB(perfstat, perfstat_cpu_total) + if test -f /usr/sbin/bootinfo; then + bits="`/usr/sbin/bootinfo -K`" + extra_flag="-q64" + fi + ;; + svr5) + # -lmas + AC_CHECK_LIB(mas, mas_open) + ;; + sunos5) + if test "$ISAINFO"; then + bits="`$ISAINFO -b`" + if test "$target_cpu" = "sparc"; then + extra_flag="-xarch=v9" + else + extra_flag="-xarch=amd64" + fi + fi + ;; +esac + +# USE_FPH means the module has format_process_header +if test -n "$USE_FPH"; then + AC_DEFINE(HAVE_FORMAT_PROCESS_HEADER, 1, [Platform module]) +fi + +# if we are 64-bit, try to turn on the appropriate flags +AC_MSG_CHECKING(address space size) +ARCHFLAG="" +if test "$bits" = "64"; then + AC_MSG_RESULT(64) + if test "$ax_cv_c_compiler_vendor" = "gnu"; then + extra_flag="-m64" + fi +# Make sure our compiler accepts the flag we want to use + AC_CHECK_CFLAG($extra_flag, [ARCHFLAG="$extra_flag"], + [enable_dualarch="no"]) +else + AC_MSG_RESULT($bits) +fi +AC_SUBST(ARCHFLAG) + +# Dual architecture handling: for now this is only enabled on Solaris. +# Config options can explicitly enable or disable dualarch. Otherwise, +# dualarch is only enabled when we are on a 64-bit system. +if test "$MODULE" = "sunos5"; then + AC_MSG_CHECKING(for dual architecture compilation) + if test "x$enable_dualarch" = x; then +# we must make the determination implicitly + if test "$bits" = "64"; then + enable_dualarch="yes" + else + enable_dualarch="no" + fi + fi + if test "x$enable_dualarch" = "xyes"; then + AC_MSG_RESULT(yes) + if test "$target_cpu" = "sparc"; then + FIRST_RULE="config.sparcv9.make" + INSTALL_RULE="config.sparcv9.makeinstall" + CLEAN_EXTRA="$CLEAN_EXTRA sparcv7/* sparcv9/*" + mkdir -p sparcv7 sparcv9 + else + FIRST_RULE="config.amd64.make" + INSTALL_RULE="config.amd64.makeinstall" + CLEAN_EXTRA="$CLEAN_EXTRA i386/* amd64/*" + mkdir -p i386 amd64 + fi + else + AC_MSG_RESULT(no) + fi +fi + +if test x$enable_dualarch = xyes; then + AC_DEFINE(ENABLE_DUALARCH, 1, [Enable dual architecture]) +fi + +AC_SUBST_FILE(FIRST_RULE) +AC_SUBST_FILE(INSTALL_RULE) + +AC_MSG_CHECKING(for installation settings) +# calculate appropriate settings +OWNER="" +GROUP="" +MODE="" +if test ! -n "$USE_KMEM" -a -d /proc; then +# make sure we are installed so that we can read /proc + rm -f conftest.txt + if test -r /proc/0/psinfo; then +# system uses solaris-style /proc + $lslong /proc/0/psinfo >conftest.txt + elif test -r /proc/1/stat; then +# linux-style /proc? + $lslong /proc/1/stat >conftest.txt + else + echo "-r--r--r-- 1 bin bin 32 Jan 1 12:00 /foo" >conftest.txt + fi + +# set permissions so that we can read stuff in /proc + if grep '^.......r..' conftest.txt >/dev/null; then +# world readable + MODE=755 + elif grep '^....r.....' conftest.txt >/dev/null; then +# group readable + MODE=2711 + GROUP=`awk ' { print $4 }'` + else +# probably only readable by root + MODE=4711 + OWNER=`awk ' { print $3 }'` + fi + +elif test -c /dev/kmem; then + $lslong -L /dev/kmem >conftest.txt + if grep '^....r..r..' conftest.txt >/dev/null; then + MODE=755 + elif grep '^....r..-..' conftest.txt >/dev/null; then + MODE=2755 + GROUP=`$AWK ' { print $4 }' conftest.txt` + fi +else + MODE=755 +fi +rm -f conftest.txt +# let module settings override what we calculated +OWNER=${SET_OWNER:-$OWNER} +GROUP=${SET_GROUP:-$GROUP} +MODE=${SET_MODE:-$MODE} + +# set only those things that require it +result="" +INSTALL_OPTS_PROG="" +if test x$OWNER != x; then + result="${result}owner=$OWNER, " + INSTALL_OPTS_PROG="$INSTALL_OPTS_PROG -o $OWNER" +fi +if test x$GROUP != x; then + result="${result}group=$GROUP, " + INSTALL_OPTS_PROG="$INSTALL_OPTS_PROG -g $GROUP" +fi +result="${result}mode=$MODE" +INSTALL_OPTS_PROG="$INSTALL_OPTS_PROG -m $MODE" + +AC_MSG_RESULT($result) + +# add extra cflags if the compiler accepts them +AX_CFLAGS_WARN_ALL +MODULE_CFLAGS="" +if test "$ax_cv_c_compiler_vendor" = "gnu"; then + AX_CFLAGS_GCC_OPTION([-fno-strict-aliasing], [MODULE_CFLAGS]) + if test "$target_cpu" = "alpha"; then + AX_CFLAGS_GCC_OPTION([-mfp-trap-mode=sui -mtrap-precision=i]) + fi +fi + +# Define man page supplement +MAN_SUPPLEMENT=machine/m_$MODULE.man +AC_SUBST_FILE(MAN_SUPPLEMENT) + +# Extra things we want substituted +AC_SUBST(MODULE) +AC_SUBST(MODULE_CFLAGS) +AC_SUBST(INSTALL_OPTS_PROG) + +# wrapup + +AC_CONFIG_FILES(Makefile top.1) +AC_OUTPUT diff --git a/display.c b/display.c index 13cecc00ca22..2330ca422ec3 100644 --- a/display.c +++ b/display.c @@ -1,12 +1,38 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * Top users/processes display for Unix * Version 3 - * - * This program may be freely redistributed, - * but this entire comment MUST remain intact. - * - * Copyright (c) 1984, 1989, William LeFebvre, Rice University - * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University */ /* @@ -21,80 +47,631 @@ * In this way, those routines can be safely used on terminals that * have minimal (or nonexistant) terminal capabilities. * - * The routines are called in this order: *_loadave, i_timeofday, - * *_procstates, *_cpustates, *_memory, *_message, *_header, - * *_process, u_endscreen. + * The routines should be called in this order: *_loadave, *_uptime, + * i_timeofday, *_procstates, *_cpustates, *_memory, *_swap, + * *_message, *_header, *_process, *_endscreen. */ #include "os.h" #include <ctype.h> -#include <time.h> +#include <stdarg.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <unistd.h> +#include "top.h" +#include "machine.h" #include "screen.h" /* interface to screen package */ #include "layout.h" /* defines for screen position layout */ #include "display.h" -#include "top.h" -#include "top.local.h" #include "boolean.h" -#include "machine.h" /* we should eliminate this!!! */ #include "utils.h" -#ifdef DEBUG -FILE *debug; +#ifdef ENABLE_COLOR +#include "color.h" #endif +#define CURSOR_COST 8 + +#define MESSAGE_DISPLAY_TIME 5 + /* imported from screen.c */ extern int overstrike; -static int lmpid = 0; -static int last_hi = 0; /* used in u_process and u_endscreen */ -static int lastline = 0; +static int lmpid = -1; static int display_width = MAX_COLS; -#define lineindex(l) ((l)*display_width) - -char *printable(); - -/* things initialized by display_init and used thruout */ - -/* buffer of proc information lines for display updating */ -char *screenbuf = NULL; +/* cursor positions of key points on the screen are maintained here */ +/* layout.h has static definitions, but we may change our minds on some + of the positions as we make decisions about what needs to be displayed */ + +static int x_lastpid = X_LASTPID; +static int y_lastpid = Y_LASTPID; +static int x_loadave = X_LOADAVE; +static int y_loadave = Y_LOADAVE; +static int x_minibar = X_MINIBAR; +static int y_minibar = Y_MINIBAR; +static int x_uptime = X_UPTIME; +static int y_uptime = Y_UPTIME; +static int x_procstate = X_PROCSTATE; +static int y_procstate = Y_PROCSTATE; +static int x_cpustates = X_CPUSTATES; +static int y_cpustates = Y_CPUSTATES; +static int x_kernel = X_KERNEL; +static int y_kernel = Y_KERNEL; +static int x_mem = X_MEM; +static int y_mem = Y_MEM; +static int x_swap = X_SWAP; +static int y_swap = Y_SWAP; +static int y_message = Y_MESSAGE; +static int x_header = X_HEADER; +static int y_header = Y_HEADER; +static int x_idlecursor = X_IDLECURSOR; +static int y_idlecursor = Y_IDLECURSOR; +static int y_procs = Y_PROCS; + +/* buffer and colormask that describes the content of the screen */ +/* these are singly dimensioned arrays -- the row boundaries are + determined on the fly. +*/ +static char *screenbuf = NULL; +static char *colorbuf = NULL; +static char scratchbuf[MAX_COLS]; +static int bufsize = 0; + +/* lineindex tells us where the beginning of a line is in the buffer */ +#define lineindex(l) ((l)*MAX_COLS) + +/* screen's cursor */ +static int curr_x, curr_y; +static int curr_color; + +/* virtual cursor */ +static int virt_x, virt_y; static char **procstate_names; static char **cpustate_names; static char **memory_names; +static char **swap_names; +static char **kernel_names; static int num_procstates; static int num_cpustates; static int num_memory; +static int num_swap; +static int num_kernel; static int *lprocstates; static int *lcpustates; -static int *lmemory; static int *cpustate_columns; static int cpustate_total_length; -static enum { OFF, ON, ERASE } header_status = ON; +static int header_status = Yes; + +/* pending messages are stored in a circular buffer, where message_first + is the next one to display, and message_last is the last one + in the buffer. Counters wrap around at MAX_MESSAGES. The buffer is + empty when message_first == message_last and full when + message_last + 1 == message_first. The pointer message_current holds + the message currently being displayed, or "" if there is none. +*/ +#define MAX_MESSAGES 16 +static char *message_buf[MAX_MESSAGES]; +static int message_first = 0; +static int message_last = 0; +static struct timeval message_time = {0, 0}; +static char *message_current = NULL; +static int message_length = 0; +static int message_hold = 1; +static int message_barrier = No; + +#ifdef ENABLE_COLOR +static int load_cidx[3]; +static int header_cidx; +static int *cpustate_cidx; +static int *memory_cidx; +static int *swap_cidx; +static int *kernel_cidx; +#else +#define memory_cidx NULL +#define swap_cidx NULL +#define kernel_cidx NULL +#endif + + +/* internal support routines */ + +/* + * static int string_count(char **pp) + * + * Pointer "pp" points to an array of string pointers, which is + * terminated by a NULL. Return the number of string pointers in + * this array. + */ + +static int +string_count(char **pp) + +{ + register int cnt = 0; + + if (pp != NULL) + { + while (*pp++ != NULL) + { + cnt++; + } + } + return(cnt); +} + +void +display_clear() + +{ + dprintf("display_clear\n"); + screen_clear(); + memzero(screenbuf, bufsize); + memzero(colorbuf, bufsize); + curr_x = curr_y = 0; +} + +/* + * void display_move(int x, int y) + * + * Efficiently move the cursor to x, y. This assumes the cursor is + * currently located at curr_x, curr_y, and will only use cursor + * addressing when it is less expensive than overstriking what's + * already on the screen. + */ + +void +display_move(int x, int y) + +{ + char buff[128]; + char *p; + char *bufp; + char *colorp; + int cnt = 0; + int color = curr_color; + + dprintf("display_move(%d, %d): curr_x %d, curr_y %d\n", x, y, curr_x, curr_y); + + /* are we in a position to do this without cursor addressing? */ + if (curr_y < y || (curr_y == y && curr_x <= x)) + { + /* start buffering up what it would take to move there by rewriting + what's on the screen */ + cnt = CURSOR_COST; + p = buff; + + /* one newline for every line */ + while (cnt > 0 && curr_y < y) + { +#ifdef ENABLE_COLOR + if (color != 0) + { + p = strcpyend(p, color_setstr(0)); + color = 0; + cnt -= 5; + } +#endif + *p++ = '\n'; + curr_y++; + curr_x = 0; + cnt--; + } + + /* write whats in the screenbuf */ + bufp = &screenbuf[lineindex(curr_y) + curr_x]; + colorp = &colorbuf[lineindex(curr_y) + curr_x]; + while (cnt > 0 && curr_x < x) + { +#ifdef ENABLE_COLOR + if (color != *colorp) + { + color = *colorp; + p = strcpyend(p, color_setstr(color)); + cnt -= 5; + } +#endif + if ((*p = *bufp) == '\0') + { + /* somwhere on screen we haven't been before */ + *p = *bufp = ' '; + } + p++; + bufp++; + colorp++; + curr_x++; + cnt--; + } + } + + /* move the cursor */ + if (cnt > 0) + { + /* screen rewrite is cheaper */ + *p = '\0'; + fputs(buff, stdout); + curr_color = color; + } + else + { + screen_move(x, y); + } -static int string_count(); -static void summary_format(); -static void line_update(); + /* update our position */ + curr_x = x; + curr_y = y; +} -int display_resize() +/* + * display_write(int x, int y, int newcolor, int eol, char *new) + * + * Optimized write to the display. This writes characters to the + * screen in a way that optimizes the number of characters actually + * sent, by comparing what is being written to what is already on + * the screen (according to screenbuf and colorbuf). The string to + * write is "new", the first character of "new" should appear at + * screen position x, y. If x is -1 then "new" begins wherever the + * cursor is currently positioned. The string is written with color + * "newcolor". If "eol" is true then the remainder of the line is + * cleared. It is expected that "new" will have no newlines and no + * escape sequences. + */ + +void +display_write(int x, int y, int newcolor, int eol, char *new) { - register int lines; + char *bufp; + char *colorp; + int ch; + int diff; + + dprintf("display_write(%d, %d, %d, %d, \"%s\")\n", + x, y, newcolor, eol, new); - /* first, deallocate any previous buffer that may have been there */ - if (screenbuf != NULL) + /* dumb terminal handling here */ + if (!smart_terminal) { - free(screenbuf); + if (x != -1) + { + /* make sure we are on the right line */ + while (curr_y < y) + { + putchar('\n'); + curr_y++; + curr_x = 0; + } + + /* make sure we are on the right column */ + while (curr_x < x) + { + putchar(' '); + curr_x++; + } + } + + /* write */ + fputs(new, stdout); + curr_x += strlen(new); + + return; } + /* adjust for "here" */ + if (x == -1) + { + x = virt_x; + y = virt_y; + } + else + { + virt_x = x; + virt_y = y; + } + + /* a pointer to where we start */ + bufp = &screenbuf[lineindex(y) + x]; + colorp = &colorbuf[lineindex(y) + x]; + + /* main loop */ + while ((ch = *new++) != '\0') + { + /* if either character or color are different, an update is needed */ + /* but only when the screen is wide enough */ + if (x < display_width && (ch != *bufp || newcolor != *colorp)) + { + /* check cursor */ + if (y != curr_y || x != curr_x) + { + /* have to move the cursor */ + display_move(x, y); + } + + /* write character */ +#ifdef ENABLE_COLOR + if (curr_color != newcolor) + { + fputs(color_setstr(newcolor), stdout); + curr_color = newcolor; + } +#endif + putchar(ch); + *bufp = ch; + *colorp = curr_color; + curr_x++; + } + + /* move */ + x++; + virt_x++; + bufp++; + colorp++; + } + + /* eol handling */ + if (eol && *bufp != '\0') + { + dprintf("display_write: clear-eol (bufp = \"%s\")\n", bufp); + /* make sure we are color 0 */ +#ifdef ENABLE_COLOR + if (curr_color != 0) + { + fputs(color_setstr(0), stdout); + curr_color = 0; + } +#endif + + /* make sure we are at the end */ + if (x != curr_x || y != curr_y) + { + screen_move(x, y); + curr_x = x; + curr_y = y; + } + + /* clear to end */ + screen_cleareol(strlen(bufp)); + + /* clear out whats left of this line's buffer */ + diff = display_width - x; + if (diff > 0) + { + memzero(bufp, diff); + memzero(colorp, diff); + } + } +} + +void +display_fmt(int x, int y, int newcolor, int eol, char *fmt, ...) + +{ + va_list argp; + + va_start(argp, fmt); + + vsnprintf(scratchbuf, MAX_COLS, fmt, argp); + display_write(x, y, newcolor, eol, scratchbuf); +} + +void +display_cte() + +{ + int len; + int y; + char *p; + int need_clear = 0; + + /* is there anything out there that needs to be cleared? */ + p = &screenbuf[lineindex(virt_y) + virt_x]; + if (*p != '\0') + { + need_clear = 1; + } + else + { + /* this line is clear, what about the rest? */ + y = virt_y; + while (++y < screen_length) + { + if (screenbuf[lineindex(y)] != '\0') + { + need_clear = 1; + break; + } + } + } + + if (need_clear) + { + dprintf("display_cte: clearing\n"); + + /* we will need this later */ + len = lineindex(virt_y) + virt_x; + + /* move to x and y, then clear to end */ + display_move(virt_x, virt_y); + if (!screen_cte()) + { + /* screen has no clear to end, so do it by hand */ + p = &screenbuf[len]; + len = strlen(p); + if (len > 0) + { + screen_cleareol(len); + } + while (++virt_y < screen_length) + { + display_move(0, virt_y); + p = &screenbuf[lineindex(virt_y)]; + len = strlen(p); + if (len > 0) + { + screen_cleareol(len); + } + } + } + + /* clear the screenbuf */ + memzero(&screenbuf[len], bufsize - len); + memzero(&colorbuf[len], bufsize - len); + } +} + +static void +summary_format(int x, int y, int *numbers, char **names, int *cidx) + +{ + register int num; + register char *thisname; + register char *lastname = NULL; + register int color; + + /* format each number followed by its string */ + while ((thisname = *names++) != NULL) + { + /* get the number to format */ + num = *numbers++; + color = 0; + + /* display only non-zero numbers */ + if (num != 0) + { + /* write the previous name */ + if (lastname != NULL) + { + display_write(-1, -1, 0, 0, lastname); + } + +#ifdef ENABLE_COLOR + if (cidx != NULL) + { + /* choose a color */ + color = color_test(*cidx++, num); + } +#endif + + /* write this number if positive */ + if (num > 0) + { + display_write(x, y, color, 0, itoa(num)); + } + + /* defer writing this name */ + lastname = thisname; + + /* next iteration will not start at x, y */ + x = y = -1; + } + } + + /* if the last string has a separator on the end, it has to be + written with care */ + if (lastname != NULL) + { + if ((num = strlen(lastname)) > 1 && + lastname[num-2] == ',' && lastname[num-1] == ' ') + { + display_fmt(-1, -1, 0, 1, "%.*s", num-2, lastname); + } + else + { + display_write(-1, -1, 0, 1, lastname); + } + } +} + +static void +summary_format_memory(int x, int y, long *numbers, char **names, int *cidx) + +{ + register long num; + register int color; + register char *thisname; + register char *lastname = NULL; + + /* format each number followed by its string */ + while ((thisname = *names++) != NULL) + { + /* get the number to format */ + num = *numbers++; + color = 0; + + /* display only non-zero numbers */ + if (num != 0) + { + /* write the previous name */ + if (lastname != NULL) + { + display_write(-1, -1, 0, 0, lastname); + } + + /* defer writing this name */ + lastname = thisname; + +#ifdef ENABLE_COLOR + /* choose a color */ + color = color_test(*cidx++, num); +#endif + + /* is this number in kilobytes? */ + if (thisname[0] == 'K') + { + display_write(x, y, color, 0, format_k(num)); + lastname++; + } + else + { + display_write(x, y, color, 0, itoa((int)num)); + } + + /* next iteration will not start at x, y */ + x = y = -1; + } + } + + /* if the last string has a separator on the end, it has to be + written with care */ + if (lastname != NULL) + { + if ((num = strlen(lastname)) > 1 && + lastname[num-2] == ',' && lastname[num-1] == ' ') + { + display_fmt(-1, -1, 0, 1, "%.*s", num-2, lastname); + } + else + { + display_write(-1, -1, 0, 1, lastname); + } + } +} + +/* + * int display_resize() + * + * Reallocate buffer space needed by the display package to accomodate + * a new screen size. Must be called whenever the screen's size has + * changed. Returns the number of lines available for displaying + * processes or -1 if there was a problem allocating space. + */ + +int +display_resize() + +{ + register int top_lines; + register int newsize; + /* calculate the current dimensions */ /* if operating in "dumb" mode, we only need one line */ - lines = smart_terminal ? screen_length - Header_lines : 1; + top_lines = smart_terminal ? screen_length : 1; /* we don't want more than MAX_COLS columns, since the machine-dependent modules make static allocations based on MAX_COLS and we don't want @@ -105,48 +682,123 @@ int display_resize() display_width = MAX_COLS - 1; } - /* now, allocate space for the screen buffer */ - screenbuf = (char *)malloc(lines * display_width); - if (screenbuf == (char *)NULL) + /* see how much space we need */ + newsize = top_lines * (MAX_COLS + 1); + + /* reallocate only if we need more than we already have */ + if (newsize > bufsize) + { + /* deallocate any previous buffer that may have been there */ + if (screenbuf != NULL) + { + free(screenbuf); + } + if (colorbuf != NULL) + { + free(colorbuf); + } + + /* allocate space for the screen and color buffers */ + bufsize = newsize; + screenbuf = (char *)calloc(bufsize, sizeof(char)); + colorbuf = (char *)calloc(bufsize, sizeof(char)); + if (screenbuf == NULL || colorbuf == NULL) + { + /* oops! */ + return(-1); + } + } + else { - /* oops! */ - return(-1); + /* just clear them out */ + memzero(screenbuf, bufsize); + memzero(colorbuf, bufsize); } + /* adjust total lines on screen to lines available for procs */ + top_lines -= y_procs; + /* return number of lines available */ /* for dumb terminals, pretend like we can show any amount */ - return(smart_terminal ? lines : Largest); + return(smart_terminal ? top_lines : Largest); +} + +int +display_lines() + +{ + return(smart_terminal ? screen_length : Largest); +} + +int +display_columns() + +{ + return(display_width); } -int display_init(statics) +/* + * int display_init(struct statics *statics) + * + * Initialize the display system based on information in the statics + * structure. Returns the number of lines available for displaying + * processes or -1 if there was an error. + */ -struct statics *statics; +int +display_init(struct statics *statics) { - register int lines; + register int top_lines; register char **pp; + register char *p; register int *ip; register int i; + /* certain things may influence the screen layout, + so look at those first */ + + /* a kernel line shifts parts of the display down */ + kernel_names = statics->kernel_names; + if ((num_kernel = string_count(kernel_names)) > 0) + { + /* adjust screen placements */ + y_mem++; + y_swap++; + y_message++; + y_header++; + y_idlecursor++; + y_procs++; + } + + /* a swap line shifts parts of the display down one */ + swap_names = statics->swap_names; + if ((num_swap = string_count(swap_names)) > 0) + { + /* adjust screen placements */ + y_message++; + y_header++; + y_idlecursor++; + y_procs++; + } + /* call resize to do the dirty work */ - lines = display_resize(); + top_lines = display_resize(); /* only do the rest if we need to */ - if (lines > -1) + if (top_lines > -1) { /* save pointers and allocate space for names */ procstate_names = statics->procstate_names; num_procstates = string_count(procstate_names); - lprocstates = (int *)malloc(num_procstates * sizeof(int)); + lprocstates = (int *)calloc(num_procstates, sizeof(int)); cpustate_names = statics->cpustate_names; num_cpustates = string_count(cpustate_names); - lcpustates = (int *)malloc(num_cpustates * sizeof(int)); - cpustate_columns = (int *)malloc(num_cpustates * sizeof(int)); - + lcpustates = (int *)calloc(num_cpustates, sizeof(int)); + cpustate_columns = (int *)calloc(num_cpustates, sizeof(int)); memory_names = statics->memory_names; num_memory = string_count(memory_names); - lmemory = (int *)malloc(num_memory * sizeof(int)); /* calculate starting columns where needed */ cpustate_total_length = 0; @@ -162,42 +814,108 @@ struct statics *statics; } } - /* return number of lines available */ - return(lines); +#ifdef ENABLE_COLOR + /* set up color tags for loadavg */ + load_cidx[0] = color_tag("1min"); + load_cidx[1] = color_tag("5min"); + load_cidx[2] = color_tag("15min"); + + /* find header color */ + header_cidx = color_tag("header"); + + /* color tags for cpu states */ + cpustate_cidx = (int *)malloc(num_cpustates * sizeof(int)); + i = 0; + p = strcpyend(scratchbuf, "cpu."); + while (i < num_cpustates) + { + strcpy(p, cpustate_names[i]); + cpustate_cidx[i++] = color_tag(scratchbuf); + } + + /* color tags for kernel */ + if (num_kernel > 0) + { + kernel_cidx = (int *)malloc(num_kernel * sizeof(int)); + i = 0; + p = strcpyend(scratchbuf, "kernel."); + while (i < num_kernel) + { + strcpy(p, homogenize(kernel_names[i]+1)); + kernel_cidx[i++] = color_tag(scratchbuf); + } + } + + /* color tags for memory */ + memory_cidx = (int *)malloc(num_memory * sizeof(int)); + i = 0; + p = strcpyend(scratchbuf, "memory."); + while (i < num_memory) + { + strcpy(p, homogenize(memory_names[i]+1)); + memory_cidx[i++] = color_tag(scratchbuf); + } + + /* color tags for swap */ + if (num_swap > 0) + { + swap_cidx = (int *)malloc(num_swap * sizeof(int)); + i = 0; + p = strcpyend(scratchbuf, "swap."); + while (i < num_swap) + { + strcpy(p, homogenize(swap_names[i]+1)); + swap_cidx[i++] = color_tag(scratchbuf); + } + } +#endif + + /* return number of lines available (or error) */ + return(top_lines); } -i_loadave(mpid, avenrun) +static void +pr_loadavg(double avg, int i) + +{ + int color = 0; + +#ifdef ENABLE_COLOR + color = color_test(load_cidx[i], (int)(avg * 100)); +#endif + display_fmt(x_loadave + X_LOADAVEWIDTH * i, y_loadave, color, 0, + avg < 10.0 ? " %5.2f" : " %5.1f", avg); + display_write(-1, -1, 0, 0, (i < 2 ? "," : ";")); +} -int mpid; -double *avenrun; +void +i_loadave(int mpid, double *avenrun) { register int i; - /* i_loadave also clears the screen, since it is first */ - clear(); - /* mpid == -1 implies this system doesn't have an _mpid */ if (mpid != -1) { - printf("last pid: %5d; ", mpid); + display_fmt(0, 0, 0, 0, + "last pid: %5d; load avg:", mpid); + x_loadave = X_LOADAVE; + } + else + { + display_write(0, 0, 0, 0, "load averages:"); + x_loadave = X_LOADAVE - X_LASTPIDWIDTH; } - - printf("load averages"); - for (i = 0; i < 3; i++) { - printf("%c %5.2f", - i == 0 ? ':' : ',', - avenrun[i]); + pr_loadavg(avenrun[i], i); } + lmpid = mpid; } -u_loadave(mpid, avenrun) - -int mpid; -double *avenrun; +void +u_loadave(int mpid, double *avenrun) { register int i; @@ -207,35 +925,80 @@ double *avenrun; /* change screen only when value has really changed */ if (mpid != lmpid) { - Move_to(x_lastpid, y_lastpid); - printf("%5d", mpid); + display_fmt(x_lastpid, y_lastpid, 0, 0, + "%5d", mpid); lmpid = mpid; } - - /* i remembers x coordinate to move to */ - i = x_loadave; } - else + + /* display new load averages */ + for (i = 0; i < 3; i++) { - i = x_loadave_nompid; + pr_loadavg(avenrun[i], i); } +} - /* move into position for load averages */ - Move_to(i, y_loadave); +static char minibar_buffer[64]; +#define MINIBAR_WIDTH 20 - /* display new load averages */ - /* we should optimize this and only display changes */ - for (i = 0; i < 3; i++) +void +i_minibar(int (*formatter)(char *, int)) +{ + (void)((*formatter)(minibar_buffer, MINIBAR_WIDTH)); + + display_write(x_minibar, y_minibar, 0, 0, minibar_buffer); +} + +void +u_minibar(int (*formatter)(char *, int)) +{ + (void)((*formatter)(minibar_buffer, MINIBAR_WIDTH)); + + display_write(x_minibar, y_minibar, 0, 0, minibar_buffer); +} + +static int uptime_days; +static int uptime_hours; +static int uptime_mins; +static int uptime_secs; + +void +i_uptime(time_t *bt, time_t *tod) + +{ + time_t uptime; + + if (*bt != -1) { - printf("%s%5.2f", - i == 0 ? "" : ", ", - avenrun[i]); + uptime = *tod - *bt; + uptime += 30; + uptime_days = uptime / 86400; + uptime %= 86400; + uptime_hours = uptime / 3600; + uptime %= 3600; + uptime_mins = uptime / 60; + uptime_secs = uptime % 60; + + /* + * Display the uptime. + */ + + display_fmt(x_uptime, y_uptime, 0, 0, + " up %d+%02d:%02d:%02d", + uptime_days, uptime_hours, uptime_mins, uptime_secs); } } -i_timeofday(tod) +void +u_uptime(time_t *bt, time_t *tod) + +{ + i_uptime(bt, tod); +} + -time_t *tod; +void +i_timeofday(time_t *tod) { /* @@ -243,100 +1006,80 @@ time_t *tod; * "ctime" always returns a string that looks like this: * * Sun Sep 16 01:03:52 1973 - * 012345678901234567890123 + * 012345678901234567890123 * 1 2 * * We want indices 11 thru 18 (length 8). */ - if (smart_terminal) - { - Move_to(screen_width - 8, 0); - } - else - { - fputs(" ", stdout); - } -#ifdef DEBUG + int x; + + /* where on the screen do we start? */ + x = (smart_terminal ? screen_width : 79) - 8; + + /* but don't bump in to uptime */ + if (x < x_uptime + 19) { - char *foo; - foo = ctime(tod); - fputs(foo, stdout); + x = x_uptime + 19; } -#endif - printf("%-8.8s\n", &(ctime(tod)[11])); - lastline = 1; + + /* display it */ + display_fmt(x, 0, 0, 1, "%-8.8s", &(ctime(tod)[11])); } static int ltotal = 0; -static char procstates_buffer[MAX_COLS]; +static int lthreads = 0; /* * *_procstates(total, brkdn, names) - print the process summary line - * - * Assumptions: cursor is at the beginning of the line on entry - * lastline is valid */ -i_procstates(total, brkdn) -int total; -int *brkdn; +void +i_procstates(int total, int *brkdn, int threads) { - register int i; - /* write current number of processes and remember the value */ - printf("%d processes:", total); + display_fmt(0, y_procstate, 0, 0, + "%d %s: ", total, threads ? "threads" : "processes"); ltotal = total; - /* put out enough spaces to get to column 15 */ - i = digits(total); - while (i++ < 4) - { - putchar(' '); - } + /* remember where the summary starts */ + x_procstate = virt_x; - /* format and print the process state summary */ - summary_format(procstates_buffer, brkdn, procstate_names); - fputs(procstates_buffer, stdout); + if (total > 0) + { + /* format and print the process state summary */ + summary_format(-1, -1, brkdn, procstate_names, NULL); - /* save the numbers for next time */ - memcpy(lprocstates, brkdn, num_procstates * sizeof(int)); + /* save the numbers for next time */ + memcpy(lprocstates, brkdn, num_procstates * sizeof(int)); + lthreads = threads; + } } -u_procstates(total, brkdn) - -int total; -int *brkdn; +void +u_procstates(int total, int *brkdn, int threads) { - static char new[MAX_COLS]; - register int i; + /* if threads state has changed, do a full update */ + if (lthreads != threads) + { + i_procstates(total, brkdn, threads); + return; + } /* update number of processes only if it has changed */ if (ltotal != total) { - /* move and overwrite */ -#if (x_procstate == 0) - Move_to(x_procstate, y_procstate); -#else - /* cursor is already there...no motion needed */ - /* assert(lastline == 1); */ -#endif - printf("%d", total); + display_fmt(0, y_procstate, 0, 0, + "%d", total); /* if number of digits differs, rewrite the label */ if (digits(total) != digits(ltotal)) { - fputs(" processes:", stdout); - /* put out enough spaces to get to column 15 */ - i = digits(total); - while (i++ < 4) - { - putchar(' '); - } - /* cursor may end up right where we want it!!! */ + display_fmt(-1, -1, 0, 0, " %s: ", threads ? "threads" : "processes"); + x_procstate = virt_x; } /* save new total */ @@ -344,26 +1087,22 @@ int *brkdn; } /* see if any of the state numbers has changed */ - if (memcmp(lprocstates, brkdn, num_procstates * sizeof(int)) != 0) + if (total > 0 && memcmp(lprocstates, brkdn, num_procstates * sizeof(int)) != 0) { /* format and update the line */ - summary_format(new, brkdn, procstate_names); - line_update(procstates_buffer, new, x_brkdn, y_brkdn); + summary_format(x_procstate, y_procstate, brkdn, procstate_names, NULL); memcpy(lprocstates, brkdn, num_procstates * sizeof(int)); } } /* * *_cpustates(states, names) - print the cpu state percentages - * - * Assumptions: cursor is on the PREVIOUS line */ -static int cpustates_column; - /* cpustates_tag() calculates the correct tag to use to label the line */ -char *cpustates_tag() +char * +cpustates_tag() { register char *use; @@ -382,24 +1121,30 @@ char *cpustates_tag() use = long_tag; } - /* set cpustates_column accordingly then return result */ - cpustates_column = strlen(use); + /* set x_cpustates accordingly then return result */ + x_cpustates = strlen(use); return(use); } -i_cpustates(states) - -register int *states; +void +i_cpustates(int *states) { - register int i = 0; - register int value; - register char **names = cpustate_names; - register char *thisname; + int value; + char **names; + char *thisname; + int *colp; + int color = 0; +#ifdef ENABLE_COLOR + int *cidx = cpustate_cidx; +#endif + + /* initialize */ + names = cpustate_names; + colp = cpustate_columns; - /* print tag and bump lastline */ - printf("\n%s", cpustates_tag()); - lastline++; + /* print tag */ + display_write(0, y_cpustates, 0, 0, cpustates_tag()); /* now walk thru the names and print the line */ while ((thisname = *names++) != NULL) @@ -407,33 +1152,45 @@ register int *states; if (*thisname != '\0') { /* retrieve the value and remember it */ - value = *states++; + value = *states; + +#ifdef ENABLE_COLOR + /* determine color number to use */ + color = color_test(*cidx++, value/10); +#endif /* if percentage is >= 1000, print it as 100% */ - printf((value >= 1000 ? "%s%4.0f%% %s" : "%s%4.1f%% %s"), - i++ == 0 ? "" : ", ", - ((float)value)/10., - thisname); + display_fmt(x_cpustates + *colp, y_cpustates, + color, 0, + (value >= 1000 ? "%4.0f%% %s%s" : "%4.1f%% %s%s"), + ((float)value)/10., + thisname, + *names != NULL ? ", " : ""); + } + /* increment */ + colp++; + states++; } /* copy over values into "last" array */ memcpy(lcpustates, states, num_cpustates * sizeof(int)); } -u_cpustates(states) - -register int *states; +void +u_cpustates(int *states) { - register int value; - register char **names = cpustate_names; - register char *thisname; - register int *lp; - register int *colp; + int value; + char **names = cpustate_names; + char *thisname; + int *lp; + int *colp; + int color = 0; +#ifdef ENABLE_COLOR + int *cidx = cpustate_cidx; +#endif - Move_to(cpustates_column, y_cpustates); - lastline = y_cpustates; lp = lcpustates; colp = cpustate_columns; @@ -445,20 +1202,26 @@ register int *states; /* did the value change since last time? */ if (*lp != *states) { - /* yes, move and change */ - Move_to(cpustates_column + *colp, y_cpustates); - lastline = y_cpustates; - + /* yes, change it */ /* retrieve value and remember it */ value = *states; +#ifdef ENABLE_COLOR + /* determine color number to use */ + color = color_test(*cidx, value/10); +#endif + /* if percentage is >= 1000, print it as 100% */ - printf((value >= 1000 ? "%4.0f" : "%4.1f"), - ((double)value)/10.); + display_fmt(x_cpustates + *colp, y_cpustates, color, 0, + (value >= 1000 ? "%4.0f" : "%4.1f"), + ((double)value)/10.); /* remember it for next time */ *lp = value; } +#ifdef ENABLE_COLOR + cidx++; +#endif } /* increment and move on */ @@ -468,6 +1231,7 @@ register int *states; } } +void z_cpustates() { @@ -476,15 +1240,15 @@ z_cpustates() register char *thisname; register int *lp; - /* show tag and bump lastline */ - printf("\n%s", cpustates_tag()); - lastline++; + /* print tag */ + display_write(0, y_cpustates, 0, 0, cpustates_tag()); while ((thisname = *names++) != NULL) { if (*thisname != '\0') { - printf("%s %% %s", i++ == 0 ? "" : ", ", thisname); + display_fmt(-1, -1, 0, 0, "%s %% %s", i++ == 0 ? "" : ", ", + thisname); } } @@ -498,37 +1262,90 @@ z_cpustates() } /* - * *_memory(stats) - print "Memory: " followed by the memory summary string + * *_kernel(stats) - print "Kernel: " followed by the kernel summary string * - * Assumptions: cursor is on "lastline" - * for i_memory ONLY: cursor is on the previous line + * Assumptions: cursor is on "lastline", the previous line */ -char memory_buffer[MAX_COLS]; +void +i_kernel(int *stats) + +{ + if (num_kernel > 0) + { + display_write(0, y_kernel, 0, 0, "Kernel: "); + + /* format and print the kernel summary */ + summary_format(x_kernel, y_kernel, stats, kernel_names, kernel_cidx); + } +} -i_memory(stats) +void +u_kernel(int *stats) -int *stats; +{ + if (num_kernel > 0) + { + /* format the new line */ + summary_format(x_kernel, y_kernel, stats, kernel_names, kernel_cidx); + } +} + +/* + * *_memory(stats) - print "Memory: " followed by the memory summary string + * + * Assumptions: cursor is on "lastline", the previous line + */ + +void +i_memory(long *stats) { - fputs("\nMemory: ", stdout); - lastline++; + display_write(0, y_mem, 0, 0, "Memory: "); /* format and print the memory summary */ - summary_format(memory_buffer, stats, memory_names); - fputs(memory_buffer, stdout); + summary_format_memory(x_mem, y_mem, stats, memory_names, memory_cidx); +} + +void +u_memory(long *stats) + +{ + /* format the new line */ + summary_format_memory(x_mem, y_mem, stats, memory_names, memory_cidx); } -u_memory(stats) +/* + * *_swap(stats) - print "Swap: " followed by the swap summary string + * + * Assumptions: cursor is on "lastline", the previous line + * + * These functions only print something when num_swap > 0 + */ -int *stats; +void +i_swap(long *stats) { - static char new[MAX_COLS]; + if (num_swap > 0) + { + /* print the tag */ + display_write(0, y_swap, 0, 0, "Swap: "); - /* format the new line */ - summary_format(new, stats, memory_names); - line_update(memory_buffer, new, x_mem, y_mem); + /* format and print the swap summary */ + summary_format_memory(x_swap, y_swap, stats, swap_names, swap_cidx); + } +} + +void +u_swap(long *stats) + +{ + if (num_swap > 0) + { + /* format the new line */ + summary_format_memory(x_swap, y_swap, stats, swap_names, swap_cidx); + } } /* @@ -542,39 +1359,89 @@ int *stats; /* * i_message is funny because it gets its message asynchronously (with - * respect to screen updates). + * respect to screen updates). Messages are taken out of the + * circular message_buf and displayed one at a time. */ -static char next_msg[MAX_COLS + 5]; -static int msglen = 0; -/* Invariant: msglen is always the length of the message currently displayed - on the screen (even when next_msg doesn't contain that message). */ - -i_message() +void +i_message(struct timeval *now) { - while (lastline < y_message) - { - fputc('\n', stdout); - lastline++; - } - if (next_msg[0] != '\0') + struct timeval my_now; + int i = 0; + + dprintf("i_message(%08x)\n", now); + + /* if now is NULL we have to get it ourselves */ + if (now == NULL) { - standout(next_msg); - msglen = strlen(next_msg); - next_msg[0] = '\0'; + time_get(&my_now); + now = &my_now; } - else if (msglen > 0) + + /* now that we have been called, messages no longer need to be held */ + message_hold = 0; + + dprintf("i_message: now %d, message_time %d\n", + now->tv_sec, message_time.tv_sec); + + if (smart_terminal) { - (void) clear_eol(msglen); - msglen = 0; + /* is it time to change the message? */ + if (timercmp(now, &message_time, > )) + { + /* yes, free the current message */ + dprintf("i_message: timer expired\n"); + if (message_current != NULL) + { + free(message_current); + message_current = NULL; + } + + /* is there a new message to be displayed? */ + if (message_first != message_last) + { + /* move index to next message */ + if (++message_first == MAX_MESSAGES) message_first = 0; + + /* make the next message the current one */ + message_current = message_buf[message_first]; + + /* show it */ + dprintf("i_message: showing \"%s\"\n", message_current); + display_move(0, y_message); + screen_standout(message_current); + i = strlen(message_current); + + /* set the expiration timer */ + message_time = *now; + message_time.tv_sec += MESSAGE_DISPLAY_TIME; + + /* clear the rest of the line */ + screen_cleareol(message_length - i); + putchar('\r'); + message_length = i; + } + else + { + /* just clear what was there before, if anything */ + if (message_length > 0) + { + display_move(0, y_message); + screen_cleareol(message_length); + putchar('\r'); + message_length = 0; + } + } + } } } -u_message() +void +u_message(struct timeval *now) { - i_message(); + i_message(now); } static int header_length; @@ -585,37 +1452,34 @@ static int header_length; * Assumptions: cursor is on the previous line and lastline is consistent */ -i_header(text) - -char *text; +void +i_header(char *text) { + int header_color = 0; + +#ifdef ENABLE_COLOR + header_color = color_test(header_cidx, 0); +#endif header_length = strlen(text); - if (header_status == ON) + if (header_status) { - putchar('\n'); - fputs(text, stdout); - lastline++; - } - else if (header_status == ERASE) - { - header_status = OFF; + display_write(x_header, y_header, header_color, 1, text); } } /*ARGSUSED*/ -u_header(text) - -char *text; /* ignored */ +void +u_header(char *text) { - if (header_status == ERASE) - { - putchar('\n'); - lastline++; - clear_eol(header_length); - header_status = OFF; - } + int header_color = 0; + +#ifdef ENABLE_COLOR + header_color = color_test(header_cidx, 0); +#endif + display_write(x_header, y_header, header_color, 1, + header_status ? text : ""); } /* @@ -624,135 +1488,53 @@ char *text; /* ignored */ * Assumptions: lastline is consistent */ -i_process(line, thisline) - -int line; -char *thisline; +void +i_process(int line, char *thisline) { - register char *p; - register char *base; - - /* make sure we are on the correct line */ - while (lastline < y_procs + line) - { - putchar('\n'); - lastline++; - } - /* truncate the line to conform to our current screen width */ thisline[display_width] = '\0'; /* write the line out */ - fputs(thisline, stdout); - - /* copy it in to our buffer */ - base = smart_terminal ? screenbuf + lineindex(line) : screenbuf; - p = strecpy(base, thisline); - - /* zero fill the rest of it */ - memzero(p, display_width - (p - base)); + display_write(0, y_procs + line, 0, 1, thisline); } -u_process(line, newline) - -int line; -char *newline; +void +u_process(int line, char *new_line) { - register char *optr; - register int screen_line = line + Header_lines; - register char *bufferline; - - /* remember a pointer to the current line in the screen buffer */ - bufferline = &screenbuf[lineindex(line)]; + i_process(line, new_line); +} - /* truncate the line to conform to our current screen width */ - newline[display_width] = '\0'; +void +i_endscreen() - /* is line higher than we went on the last display? */ - if (line >= last_hi) +{ + if (smart_terminal) { - /* yes, just ignore screenbuf and write it out directly */ - /* get positioned on the correct line */ - if (screen_line - lastline == 1) - { - putchar('\n'); - lastline++; - } - else - { - Move_to(0, screen_line); - lastline = screen_line; - } - - /* now write the line */ - fputs(newline, stdout); - - /* copy it in to the buffer */ - optr = strecpy(bufferline, newline); - - /* zero fill the rest of it */ - memzero(optr, display_width - (optr - bufferline)); + /* move the cursor to a pleasant place */ + display_move(x_idlecursor, y_idlecursor); } else { - line_update(bufferline, newline, 0, line + Header_lines); + /* separate this display from the next with some vertical room */ + fputs("\n\n", stdout); } + fflush(stdout); } -u_endscreen(hi) - -register int hi; +void +u_endscreen() { - register int screen_line = hi + Header_lines; - register int i; - if (smart_terminal) { - if (hi < last_hi) - { - /* need to blank the remainder of the screen */ - /* but only if there is any screen left below this line */ - if (lastline + 1 < screen_length) - { - /* efficiently move to the end of currently displayed info */ - if (screen_line - lastline < 5) - { - while (lastline < screen_line) - { - putchar('\n'); - lastline++; - } - } - else - { - Move_to(0, screen_line); - lastline = screen_line; - } - - if (clear_to_end) - { - /* we can do this the easy way */ - putcap(clear_to_end); - } - else - { - /* use clear_eol on each line */ - i = hi; - while ((void) clear_eol(strlen(&screenbuf[lineindex(i++)])), i < last_hi) - { - putchar('\n'); - } - } - } - } - last_hi = hi; + /* clear-to-end the display */ + display_cte(); /* move the cursor to a pleasant place */ - Move_to(x_idlecursor, y_idlecursor); - lastline = y_idlecursor; + display_move(x_idlecursor, y_idlecursor); + fflush(stdout); } else { @@ -761,82 +1543,244 @@ register int hi; } } -display_header(t) +void +display_header(int t) -int t; +{ + header_status = t != 0; +} + +void +message_mark() { - if (t) - { - header_status = ON; - } - else if (header_status == ON) - { - header_status = ERASE; - } + message_barrier = Yes; } -/*VARARGS2*/ -new_message(type, msgfmt, a1, a2, a3) +void +message_expire() -int type; -char *msgfmt; -caddr_t a1, a2, a3; +{ + message_time.tv_sec = 0; + message_time.tv_usec = 0; +} + +void +message_flush() { - register int i; + message_first = message_last; + message_time.tv_sec = 0; + message_time.tv_usec = 0; +} + +/* + * void new_message_v(char *msgfmt, va_list ap) + * + * Display a message in the message area. This function takes a va_list for + * the arguments. Safe to call before display_init. This function only + * queues a message for display, and allowed for multiple messages to be + * queued. The i_message function drains the queue and actually writes the + * messages on the display. + */ + + +void +new_message_v(char *msgfmt, va_list ap) + +{ + int i; + int empty; + char msg[MAX_COLS]; + + /* if message_barrier is active, remove all pending messages */ + if (message_barrier) + { + message_flush(); + message_barrier = No; + } /* first, format the message */ - (void) sprintf(next_msg, msgfmt, a1, a2, a3); + (void) vsnprintf(msg, sizeof(msg), msgfmt, ap); + + /* where in the buffer will it go? */ + i = message_last + 1; + if (i >= MAX_MESSAGES) i = 0; - if (msglen > 0) + /* make sure the buffer is not full */ + if (i != message_first) { - /* message there already -- can we clear it? */ - if (!overstrike) + /* insert it in to message_buf */ + message_buf[i] = strdup(msg); + dprintf("new_message_v: new message inserted in slot %d\n", i); + + /* remember if the buffer is empty and set the index */ + empty = message_last == message_first; + message_last = i; + + /* is message_buf otherwise empty and have we started displaying? */ + if (empty && !message_hold) { - /* yes -- write it and clear to end */ - i = strlen(next_msg); - if ((type & MT_delayed) == 0) - { - type & MT_standout ? standout(next_msg) : - fputs(next_msg, stdout); - (void) clear_eol(msglen - i); - msglen = i; - next_msg[0] = '\0'; - } + /* we can display the message now */ + i_message(NULL); } } - else +} + +/* + * void new_message(int type, char *msgfmt, ...) + * + * Display a message in the message area. It is safe to call this function + * before display_init. Messages logged before the display is drawn will be + * held and displayed later. + */ + +void +new_message(char *msgfmt, ...) + +{ + va_list ap; + + va_start(ap, msgfmt); + new_message_v(msgfmt, ap); + va_end(ap); +} + +/* + * void message_error(char *msgfmt, ...) + * + * Put an error message in the message area. It is safe to call this function + * before display_init. Messages logged before the display is drawn will be + * held and displayed later. + */ + +void +message_error(char *msgfmt, ...) + +{ + va_list ap; + + va_start(ap, msgfmt); + new_message_v(msgfmt, ap); + fflush(stdout); + va_end(ap); +} + +/* + * void message_clear() + * + * Clear message area and flush all pending messages. + */ + +void +message_clear() + +{ + /* remove any existing message */ + if (message_current != NULL) { - if ((type & MT_delayed) == 0) - { - type & MT_standout ? standout(next_msg) : fputs(next_msg, stdout); - msglen = strlen(next_msg); - next_msg[0] = '\0'; - } + display_move(0, y_message); + screen_cleareol(message_length); + free(message_current); + message_current = 0; } + + /* flush all pending messages */ + message_flush(); } -clear_message() +/* + * void message_prompt_v(int so, char *msgfmt, va_list ap) + * + * Place a prompt in the message area. A prompt is different from a + * message as follows: it is displayed immediately, overwriting any + * message that may already be there, it may be highlighted in standout + * mode (if "so" is true), the cursor is left to rest at the end of the + * prompt. This call causes all pending messages to be flushed. + */ + +void +message_prompt_v(int so, char *msgfmt, va_list ap) { - if (clear_eol(msglen) == 1) + char msg[MAX_COLS]; + int i; + + /* clear out the message buffer */ + message_flush(); + + /* format the message */ + i = vsnprintf(msg, sizeof(msg), msgfmt, ap); + + /* this goes over any existing message */ + display_move(0, y_message); + + /* clear the entire line */ + screen_cleareol(message_length); + + /* show the prompt */ + if (so) + { + screen_standout(msg); + } + else { - putchar('\r'); + fputs(msg, stdout); } + + /* make it all visible */ + fflush(stdout); + + /* even though we dont keep a copy of the prompt, track its length */ + message_length = i < MAX_COLS ? i : MAX_COLS; } -readline(buffer, size, numeric) +/* + * void message_prompt(char *msgfmt, ...) + * + * Place a prompt in the message area (see message_prompt_v). + */ -char *buffer; -int size; -int numeric; +void +message_prompt(char *msgfmt, ...) + +{ + va_list ap; + + va_start(ap, msgfmt); + message_prompt_v(Yes, msgfmt, ap); + va_end(ap); +} + +void +message_prompt_plain(char *msgfmt, ...) + +{ + va_list ap; + + va_start(ap, msgfmt); + message_prompt_v(No, msgfmt, ap); + va_end(ap); +} + +/* + * int readline(char *buffer, int size, int numeric) + * + * Read a line of input from the terminal. The line is placed in + * "buffer" not to exceed "size". If "numeric" is true then the input + * can only consist of digits. This routine handles all character + * editing while keeping the terminal in cbreak mode. If "numeric" + * is true then the number entered is returned. Otherwise the number + * of character read in to "buffer" is returned. + */ + +int +readline(char *buffer, int size, int numeric) { register char *ptr = buffer; register char ch; register char cnt = 0; - register char maxcnt = 0; /* allow room for null terminator */ size -= 1; @@ -844,8 +1788,8 @@ int numeric; /* read loop */ while ((fflush(stdout), read(0, ptr, 1) > 0)) { - /* newline means we are done */ - if ((ch = *ptr) == '\n') + /* newline or return means we are done */ + if ((ch = *ptr) == '\n' || ch == '\r') { break; } @@ -853,17 +1797,39 @@ int numeric; /* handle special editing characters */ if (ch == ch_kill) { - /* kill line -- account for overstriking */ - if (overstrike) - { - msglen += maxcnt; - } - /* return null string */ *buffer = '\0'; putchar('\r'); return(-1); } + else if (ch == ch_werase) + { + /* erase previous word */ + if (cnt <= 0) + { + /* none to erase! */ + putchar('\7'); + } + else + { + /* + * First: remove all spaces till the first-non-space + * Second: remove all non-spaces till the first-space + */ + while(cnt > 0 && ptr[-1] == ' ') + { + fputs("\b \b", stdout); + ptr--; + cnt--; + } + while(cnt > 0 && ptr[-1] != ' ') + { + fputs("\b \b", stdout); + ptr--; + cnt--; + } + } + } else if (ch == ch_erase) { /* erase previous character */ @@ -880,8 +1846,8 @@ int numeric; } } /* check for character validity and buffer overflow */ - else if (cnt == size || (numeric && !isdigit(ch)) || - !isprint(ch)) + else if (cnt == size || (numeric && !isdigit((int)ch)) || + !isprint((int)ch)) { /* not legal */ putchar('\7'); @@ -892,238 +1858,80 @@ int numeric; putchar(ch); ptr++; cnt++; - if (cnt > maxcnt) - { - maxcnt = cnt; - } } } /* all done -- null terminate the string */ *ptr = '\0'; - /* account for the extra characters in the message area */ - /* (if terminal overstrikes, remember the furthest they went) */ - msglen += overstrike ? maxcnt : cnt; + /* add response length to message_length */ + message_length += cnt; /* return either inputted number or string length */ putchar('\r'); return(cnt == 0 ? -1 : numeric ? atoi(buffer) : cnt); } -/* internal support routines */ - -static int string_count(pp) - -register char **pp; +void +display_pagerstart() { - register int cnt; - - cnt = 0; - while (*pp++ != NULL) - { - cnt++; - } - return(cnt); + display_clear(); } -static void summary_format(str, numbers, names) - -char *str; -int *numbers; -register char **names; +void +display_pagerend() { - register char *p; - register int num; - register char *thisname; - register int useM = No; - - /* format each number followed by its string */ - p = str; - while ((thisname = *names++) != NULL) - { - /* get the number to format */ - num = *numbers++; - - /* display only non-zero numbers */ - if (num > 0) - { - /* is this number in kilobytes? */ - if (thisname[0] == 'K') - { - /* yes: format it as a memory value */ - p = strecpy(p, format_k(num)); - - /* skip over the K, since it was included by format_k */ - p = strecpy(p, thisname+1); - } - else - { - p = strecpy(p, itoa(num)); - p = strecpy(p, thisname); - } - } + char ch; - /* ignore negative numbers, but display corresponding string */ - else if (num < 0) - { - p = strecpy(p, thisname); - } - } - - /* if the last two characters in the string are ", ", delete them */ - p -= 2; - if (p >= str && p[0] == ',' && p[1] == ' ') - { - *p = '\0'; - } + screen_standout("Hit any key to continue: "); + fflush(stdout); + (void) read(0, &ch, 1); } -static void line_update(old, new, start, line) - -register char *old; -register char *new; -int start; -int line; +void +display_pager(char *fmt, ...) { - register int ch; - register int diff; - register int newcol = start + 1; - register int lastcol = start; - char cursor_on_line = No; - char *current; - - /* compare the two strings and only rewrite what has changed */ - current = old; -#ifdef DEBUG - fprintf(debug, "line_update, starting at %d\n", start); - fputs(old, debug); - fputc('\n', debug); - fputs(new, debug); - fputs("\n-\n", debug); -#endif + va_list ap; + + int ch; + char readch; + char buffer[MAX_COLS]; + char *data; - /* start things off on the right foot */ - /* this is to make sure the invariants get set up right */ - if ((ch = *new++) != *old) + /* format into buffer */ + va_start(ap, fmt); + (void) vsnprintf(buffer, MAX_COLS, fmt, ap); + va_end(ap); + data = buffer; + + while ((ch = *data++) != '\0') { - if (line - lastline == 1 && start == 0) - { - putchar('\n'); - } - else - { - Move_to(start, line); - } - cursor_on_line = Yes; putchar(ch); - *old = ch; - lastcol = 1; - } - old++; - - /* - * main loop -- check each character. If the old and new aren't the - * same, then update the display. When the distance from the - * current cursor position to the new change is small enough, - * the characters that belong there are written to move the - * cursor over. - * - * Invariants: - * lastcol is the column where the cursor currently is sitting - * (always one beyond the end of the last mismatch). - */ - do /* yes, a do...while */ - { - if ((ch = *new++) != *old) + if (ch == '\n') { - /* new character is different from old */ - /* make sure the cursor is on top of this character */ - diff = newcol - lastcol; - if (diff > 0) + if (++curr_y >= screen_length - 1) { - /* some motion is required--figure out which is shorter */ - if (diff < 6 && cursor_on_line) + screen_standout("...More..."); + fflush(stdout); + (void) read(0, &readch, 1); + putchar('\r'); + switch(readch) { - /* overwrite old stuff--get it out of the old buffer */ - printf("%.*s", diff, ¤t[lastcol-start]); - } - else - { - /* use cursor addressing */ - Move_to(newcol, line); - cursor_on_line = Yes; - } - /* remember where the cursor is */ - lastcol = newcol + 1; - } - else - { - /* already there, update position */ - lastcol++; - } - - /* write what we need to */ - if (ch == '\0') - { - /* at the end--terminate with a clear-to-end-of-line */ - (void) clear_eol(strlen(old)); - } - else - { - /* write the new character */ - putchar(ch); - } - /* put the new character in the screen buffer */ - *old = ch; - } - - /* update working column and screen buffer pointer */ - newcol++; - old++; - - } while (ch != '\0'); - - /* zero out the rest of the line buffer -- MUST BE DONE! */ - diff = display_width - newcol; - if (diff > 0) - { - memzero(old, diff); - } - - /* remember where the current line is */ - if (cursor_on_line) - { - lastline = line; - } -} - -/* - * printable(str) - make the string pointed to by "str" into one that is - * printable (i.e.: all ascii), by converting all non-printable - * characters into '?'. Replacements are done in place and a pointer - * to the original buffer is returned. - */ - -char *printable(str) + case '\r': + case '\n': + curr_y--; + break; -char *str; - -{ - register char *ptr; - register char ch; + case 'q': + return; - ptr = str; - while ((ch = *ptr) != '\0') - { - if (!isprint(ch)) - { - *ptr = '?'; + default: + curr_y = 0; + } + } } - ptr++; } - return(str); } diff --git a/display.h b/display.h index 4bd7ce77e08c..a44a7bb41e1b 100644 --- a/display.h +++ b/display.h @@ -1,7 +1,84 @@ -/* constants needed for display.c */ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ -/* "type" argument for new_message function */ +/* interface declaration for display.c */ -#define MT_standout 1 -#define MT_delayed 2 +#ifndef _DISPLAY_H +#define _DISPLAY_H +#include "globalstate.h" + +void display_clear(); +int display_resize(); +int display_lines(); +int display_columns(); +int display_init(struct statics *statics); +void i_loadave(int mpid, double *avenrun); +void u_loadave(int mpid, double *avenrun); +void i_minibar(int (*formatter)(char *, int)); +void u_minibar(int (*formatter)(char *, int)); +void i_uptime(time_t *bt, time_t *tod); +void u_uptime(time_t *bt, time_t *tod); +void i_timeofday(time_t *tod); +void i_procstates(int total, int *brkdn, int threads); +void u_procstates(int total, int *brkdn, int threads); +void i_cpustates(int *states); +void u_cpustates(int *states); +void z_cpustates(); +void i_kernel(int *stats); +void u_kernel(int *stats); +void i_memory(long *stats); +void u_memory(long *stats); +void i_swap(long *stats); +void u_swap(long *stats); +void i_message(struct timeval *now); +void u_message(struct timeval *now); +void i_header(char *text); +void u_header(char *text); +void i_process(int line, char *thisline); +void u_process(int, char *); +void i_endscreen(); +void u_endscreen(); +void display_header(int t); +void new_message(char *msgfmt, ...); +void message_error(char *msgfmt, ...); +void message_mark(); +void message_clear(); +void message_expire(); +void message_prompt(char *msgfmt, ...); +void message_prompt_plain(char *msgfmt, ...); +int readline(char *buffer, int size, int numeric); +void display_pagerstart(); +void display_pagerend(); +void display_pager(char *fmt, ...); + +#endif diff --git a/getans b/getans deleted file mode 100755 index 1b741f7cb7c2..000000000000 --- a/getans +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/sh -# getans prompt type default results_filename -# type is one of -# number -# integer -# neginteger -# file default=default filename -# path -# yesno default=0,1 corres yes or no -# string (default) - -RAWPMPT=$1 -TYP=$2 -DFLT=$3 -OFNM=$4 - -ny0="no"; ny1="yes" -if [ ${TYP} = "yesno" ]; then - eval ny=\$ny${DFLT} - pmpt="${RAWPMPT} [$ny]: " -else - if [ -z "${DFLT}" ]; then - pmpt="${RAWPMPT}" - else - pmpt="${RAWPMPT} [${DFLT}]: " - fi -fi -if [ x"`echo -n`" = x-n ] -then - c=\\c -else - n=-n -fi - -while : -do - echo $n "$pmpt"$c - read input - case "$TYP" in - number) - tmp=`echo $input | tr -d 0123456789.` - if [ -n "$tmp" ]; then - echo "Invalid number. Please try again." - continue - fi - ;; - - integer) - tmp=`echo $input | tr -d 0123456789` - if [ -n "$tmp" ]; then - echo "Invalid integer. Please try again." - continue - fi - ;; - - neginteger) - if [ "x$input" != "x-1" ]; then - tmp=`echo $input | tr -d 0123456789` - if [ -n "$tmp" ]; then - echo "Invalid integer. Please try again." - continue - fi - fi - ;; - - file) - if [ -z "$input" ]; then - input=${DFLT} - fi - if [ ! -f "$input" -a ! -d "$input" ]; then - echo "The file $input does not exist. Please try again." - continue - fi - ;; - - path) - if [ -z "$input" ]; then - input="${DFLT}" - fi - if [ ! -f "$input" ]; then - path=`echo $PATH | sed -e s'/::/ . /g' -e 's/:/ /g'` - x= - for elt in $path; do - if [ -f "$elt/$input" ]; then x=1; break; fi - done - if [ -z "$x" ] ;then - echo "The command $input was not found. Please try again." - continue - fi - fi - ;; - - yesno) - if [ -z "$input" ]; then - input="${DFLT}" - else - case $input in - y | yes) - input=1 ;; - n | no) - input=0 ;; - *) - echo 'Please answer "yes" or "no".' - continue ;; - esac - fi - ;; - - *) ;; - esac - break -done - -if [ -z "$input" ]; then - input="${DFLT}" -fi - -echo $input > ${OFNM} @@ -1,4 +1,36 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * "getopt" routine customized for top. */ @@ -43,9 +75,8 @@ int optopt; char *optarg; int -getopt(argc, argv, opts) -int argc; -char **argv, *opts; +getopt(int argc, char **argv, char *opts) + { static int sp = 1; register int c; diff --git a/globalstate.h b/globalstate.h new file mode 100644 index 000000000000..fd1d21dea1ac --- /dev/null +++ b/globalstate.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * The global state of top is described in this structure. It is passed + * to routines that may need to examine or alter it. + */ + +#ifndef _GLOBALSTATE_H_ +#define _GLOBALSTATE_H_ + +#include "machine.h" + +typedef struct globalstate { + struct timeval now; + struct timeval refresh; + int fulldraw; + int topn; + int max_topn; + int delay; + int displays; + int order_index; + int show_cpustates; + int show_tags; + int show_usernames; + int use_color; + int smart_terminal; + int interactive; + char *header_text; + char *order_name; /* only used before call to machine_init */ + char *order_namelist; + char *(*get_userid)(int); + struct process_select pselect; + struct statics *statics; +} globalstate; + +#endif /* _GLOBALSTATE_H_ */ diff --git a/hash.c b/hash.c new file mode 100644 index 000000000000..f65fe9210562 --- /dev/null +++ b/hash.c @@ -0,0 +1,2001 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* hash.m4c */ + +/* The file hash.c is generated from hash.m4c via the preprocessor M4 */ + +/* + * Hash table functions: init, add, lookup, first, next, sizeinfo. + * This is a conventional "bucket hash". The key is hashed in to a number + * less than or equal to the number of buckets and the result is used + * to index in to the array of buckets. Each bucket is a linked list + * that contains all the key/value pairs which hashed to that index. + */ + +#include "config.h" + +#if STDC_HEADERS +#include <string.h> +#include <stdlib.h> +#define memzero(a, b) memset((a), 0, (b)) +#else /* !STDC_HEADERS */ +#ifdef HAVE_MEMCPY +#define memzero(a, b) memset((a), 0, (b)) +#else +#define memcpy(a, b, c) bcopy((b), (a), (c)) +#define memzero(a, b) bzero((a), (b)) +#define memcmp(a, b, c) bcmp((a), (b), (c)) +#endif /* HAVE_MEMCPY */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#else +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#endif +void *malloc(); +void free(); +char *strdup(); +#endif /* !STDC_HEADERS */ + +/* After all that there are still some systems that don't have NULL defined */ +#ifndef NULL +#define NULL 0 +#endif + +#ifdef HAVE_MATH_H +#include <math.h> +#endif + +#if !HAVE_PID_T +typedef long pid_t; +#endif +#if !HAVE_ID_T +typedef long id_t; +#endif + +#include "hash.h" + + + + + + +static int +next_prime(int x) + +{ + double i, j; + int f; + + i = x; + while (i++) + { + f=1; + for (j=2; j<i; j++) + { + if ((i/j)==floor(i/j)) + { + f=0; + break; + } + } + if (f) + { + return (int)i; + } + } + return 1; +} + +/* string hashes */ + +static int +string_hash(hash_table *ht, char *key) + +{ + unsigned long s = 0; + unsigned char ch; + int shifting = 24; + + while ((ch = (unsigned char)*key++) != '\0') + { + if (shifting == 0) + { + s = s + ch; + shifting = 24; + } + else + { + s = s + (ch << shifting); + shifting -= 8; + } + } + + return (s % ht->num_buckets); +} + +void ll_init(llist *q) + +{ + q->head = NULL; + q->count = 0; +} + +llistitem *ll_newitem(int size) + +{ + llistitem *qi; + + qi = (llistitem *)malloc(sizeof(llistitem) + size); + qi->datum = ((void *)qi + sizeof(llistitem)); + return qi; +} + +void ll_freeitem(llistitem *li) + +{ + free(li); +} + +void ll_add(llist *q, llistitem *new) + +{ + new->next = q->head; + q->head = new; + q->count++; +} + +void ll_extract(llist *q, llistitem *qi, llistitem *last) + +{ + if (last == NULL) + { + q->head = qi->next; + } + else + { + last->next = qi->next; + } + qi->next = NULL; + q->count--; +} + +#define LL_FIRST(q) ((q)->head) +llistitem * +ll_first(llist *q) + +{ + return q->head; +} + +#define LL_NEXT(q, qi) ((qi) != NULL ? (qi)->next : NULL) +llistitem * +ll_next(llist *q, llistitem *qi) + +{ + return (qi != NULL ? qi->next : NULL); +} + +#define LL_ISEMPTY(ll) ((ll)->count == 0) +int +ll_isempty(llist *ll) + +{ + return (ll->count == 0); +} + +/* + * hash_table *hash_create(int num) + * + * Creates a hash table structure with at least "num" buckets. + */ + +hash_table * +hash_create(int num) + +{ + hash_table *result; + bucket_t *b; + int bytes; + int i; + + /* create the resultant structure */ + result = (hash_table *)malloc(sizeof(hash_table)); + + /* adjust bucket count to be prime */ + num = next_prime(num); + + /* create the buckets */ + bytes = sizeof(bucket_t) * num; + result->buckets = b = (bucket_t *)malloc(bytes); + result->num_buckets = num; + + /* create each bucket as a linked list */ + i = num; + while (--i >= 0) + { + ll_init(&(b->list)); + b++; + } + + return result; +} + +/* + * unsigned int hash_count(hash_table *ht) + * + * Return total number of elements contained in hash table. + */ + +unsigned int +hash_count(hash_table *ht) + +{ + register int i = 0; + register int cnt = 0; + register bucket_t *bucket; + + bucket = ht->buckets; + while (i++ < ht->num_buckets) + { + cnt += bucket->list.count; + bucket++; + } + + return cnt; +} + +/* + * void hash_sizeinfo(unsigned int *sizes, int max, hash_table *ht) + * + * Fill in "sizes" with information about bucket lengths in hash + * table "max". + */ + +void +hash_sizeinfo(unsigned int *sizes, int max, hash_table *ht) + +{ + register int i; + register int idx; + register bucket_t *bucket; + + memzero(sizes, max * sizeof(unsigned int)); + + bucket = ht->buckets; + i = 0; + while (i++ < ht->num_buckets) + { + idx = bucket->list.count; + sizes[idx >= max ? max-1 : idx]++; + bucket++; + } +} + + + + + + + +/* + * void hash_add_uint(hash_table *ht, unsigned int key, void *value) + * + * Add an element to table "ht". The element is described by + * "key" and "value". Return NULL on success. If the key + * already exists in the table, then no action is taken and + * the data for the existing element is returned. + * Key type is unsigned int + */ + +void * +hash_add_uint(hash_table *ht, unsigned int key, void *value) + +{ + bucket_t *bucket; + hash_item_uint *hi; + hash_item_uint *h; + llist *ll; + llistitem *li; + llistitem *newli; + unsigned int k1; + + /* allocate the space we will need */ + newli = ll_newitem(sizeof(hash_item_uint)); + hi = (hash_item_uint *)newli->datum; + + /* fill in the values */ + hi->key = key; + hi->value = value; + + /* hash to the bucket */ + bucket = &(ht->buckets[(key % ht->num_buckets)]); + + /* walk the list to make sure we do not have a duplicate */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_uint *)li->datum; + k1 = h->key; + if (key == k1) + { + /* found one */ + break; + } + li = LL_NEXT(ll, li); + } + li = NULL; + + /* is there already one there? */ + if (li == NULL) + { + /* add the unique element to the buckets list */ + ll_add(&(bucket->list), newli); + return NULL; + } + else + { + /* free the stuff we just allocated */ + ll_freeitem(newli); + return ((hash_item_uint *)(li->datum))->value; + } +} + +/* + * void *hash_replace_uint(hash_table *ht, unsigned int key, void *value) + * + * Replace an existing value in the hash table with a new one and + * return the old value. If the key does not already exist in + * the hash table, add a new element and return NULL. + * Key type is unsigned int + */ + +void * +hash_replace_uint(hash_table *ht, unsigned int key, void *value) + +{ + bucket_t *bucket; + hash_item_uint *hi; + llist *ll; + llistitem *li; + void *result = NULL; + unsigned int k1; + + /* find the bucket */ + bucket = &(ht->buckets[(key % ht->num_buckets)]); + + /* walk the list until we find the existing item */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + hi = (hash_item_uint *)li->datum; + k1 = hi->key; + if (key == k1) + { + /* found it: now replace the value with the new one */ + result = hi->value; + hi->value = value; + break; + } + li = LL_NEXT(ll, li); + } + + /* if the element wasnt found, add it */ + if (result == NULL) + { + li = ll_newitem(sizeof(hash_item_uint)); + hi = (hash_item_uint *)li->datum; + hi->key = key; + hi->value = value; + ll_add(&(bucket->list), li); + } + + /* return the old value (so it can be freed) */ + return result; +} + +/* + * void *hash_lookup_uint(hash_table *ht, unsigned int key) + * + * Look up "key" in "ht" and return the associated value. If "key" + * is not found, return NULL. Key type is unsigned int + */ + +void * +hash_lookup_uint(hash_table *ht, unsigned int key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + hash_item_uint *h; + void *result; + unsigned int k1; + + result = NULL; + if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_uint *)li->datum; + k1 = h->key; + if (key == k1) + { + result = h->value; + break; + } + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * void *hash_remove_uint(hash_table *ht, unsigned int key) + * + * Remove the element associated with "key" from the hash table + * "ht". Return the value or NULL if the key was not found. + */ + +void * +hash_remove_uint(hash_table *ht, unsigned int key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + llistitem *lilast; + hash_item_uint *hi; + void *result; + unsigned int k1; + + result = NULL; + if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + lilast = NULL; + while (li != NULL) + { + hi = (hash_item_uint *)li->datum; + k1 = hi->key; + if (key == k1) + { + ll_extract(ll, li, lilast); + result = hi->value; + key = hi->key; + ; + ll_freeitem(li); + break; + } + lilast = li; + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * hash_item_uint *hash_first_uint(hash_table *ht, hash_pos *pos) + * + * First function to call when iterating through all items in the hash + * table. Returns the first item in "ht" and initializes "*pos" to track + * the current position. + */ + +hash_item_uint * +hash_first_uint(hash_table *ht, hash_pos *pos) + +{ + /* initialize pos for first item in first bucket */ + pos->num_buckets = ht->num_buckets; + pos->hash_bucket = ht->buckets; + pos->curr = 0; + pos->ll_last = NULL; + + /* find the first non-empty bucket */ + while(pos->hash_bucket->list.count == 0) + { + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + return NULL; + } + } + + /* set and return the first item */ + pos->ll_item = LL_FIRST(&(pos->hash_bucket->list)); + return (hash_item_uint *)pos->ll_item->datum; +} + + +/* + * hash_item_uint *hash_next_uint(hash_pos *pos) + * + * Return the next item in the hash table, using "pos" as a description + * of the present position in the hash table. "pos" also identifies the + * specific hash table. Return NULL if there are no more elements. + */ + +hash_item_uint * +hash_next_uint(hash_pos *pos) + +{ + llistitem *li; + + /* move item to last and check for NULL */ + if ((pos->ll_last = pos->ll_item) == NULL) + { + /* are we really at the end of the hash table? */ + if (pos->curr >= pos->num_buckets) + { + /* yes: return NULL */ + return NULL; + } + /* no: regrab first item in current bucket list (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + else + { + /* get the next item in the llist */ + li = LL_NEXT(&(pos->hash_bucket->list), pos->ll_item); + } + + /* if its NULL we have to find another bucket */ + while (li == NULL) + { + /* locate another bucket */ + pos->ll_last = NULL; + + /* move to the next one */ + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + /* at the end of the hash table */ + pos->ll_item = NULL; + return NULL; + } + + /* get the first element (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + + /* li is the next element to dish out */ + pos->ll_item = li; + return (hash_item_uint *)li->datum; +} + +/* + * void *hash_remove_pos_uint(hash_pos *pos) + * + * Remove the hash table entry pointed to by position marker "pos". + * The data from the entry is returned upon success, otherwise NULL. + */ + + +void * +hash_remove_pos_uint(hash_pos *pos) + +{ + llistitem *li; + void *ans; + hash_item_uint *hi; + unsigned int key; + + /* sanity checks */ + if (pos == NULL || pos->ll_last == pos->ll_item) + { + return NULL; + } + + /* at this point pos contains the item to remove (ll_item) + and its predecesor (ll_last) */ + /* extract the item from the llist */ + li = pos->ll_item; + ll_extract(&(pos->hash_bucket->list), li, pos->ll_last); + + /* retain the data */ + hi = (hash_item_uint *)li->datum; + ans = hi->value; + + /* free up the space */ + key = hi->key; + ; + ll_freeitem(li); + + /* back up to previous item */ + /* its okay for ll_item to be null: hash_next will detect it */ + pos->ll_item = pos->ll_last; + + return ans; +} + + + +/* + * void hash_add_pid(hash_table *ht, pid_t key, void *value) + * + * Add an element to table "ht". The element is described by + * "key" and "value". Return NULL on success. If the key + * already exists in the table, then no action is taken and + * the data for the existing element is returned. + * Key type is pid_t + */ + +void * +hash_add_pid(hash_table *ht, pid_t key, void *value) + +{ + bucket_t *bucket; + hash_item_pid *hi; + hash_item_pid *h; + llist *ll; + llistitem *li; + llistitem *newli; + pid_t k1; + + /* allocate the space we will need */ + newli = ll_newitem(sizeof(hash_item_pid)); + hi = (hash_item_pid *)newli->datum; + + /* fill in the values */ + hi->key = key; + hi->value = value; + + /* hash to the bucket */ + bucket = &(ht->buckets[(key % ht->num_buckets)]); + + /* walk the list to make sure we do not have a duplicate */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_pid *)li->datum; + k1 = h->key; + if (key == k1) + { + /* found one */ + break; + } + li = LL_NEXT(ll, li); + } + li = NULL; + + /* is there already one there? */ + if (li == NULL) + { + /* add the unique element to the buckets list */ + ll_add(&(bucket->list), newli); + return NULL; + } + else + { + /* free the stuff we just allocated */ + ll_freeitem(newli); + return ((hash_item_pid *)(li->datum))->value; + } +} + +/* + * void *hash_replace_pid(hash_table *ht, pid_t key, void *value) + * + * Replace an existing value in the hash table with a new one and + * return the old value. If the key does not already exist in + * the hash table, add a new element and return NULL. + * Key type is pid_t + */ + +void * +hash_replace_pid(hash_table *ht, pid_t key, void *value) + +{ + bucket_t *bucket; + hash_item_pid *hi; + llist *ll; + llistitem *li; + void *result = NULL; + pid_t k1; + + /* find the bucket */ + bucket = &(ht->buckets[(key % ht->num_buckets)]); + + /* walk the list until we find the existing item */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + hi = (hash_item_pid *)li->datum; + k1 = hi->key; + if (key == k1) + { + /* found it: now replace the value with the new one */ + result = hi->value; + hi->value = value; + break; + } + li = LL_NEXT(ll, li); + } + + /* if the element wasnt found, add it */ + if (result == NULL) + { + li = ll_newitem(sizeof(hash_item_pid)); + hi = (hash_item_pid *)li->datum; + hi->key = key; + hi->value = value; + ll_add(&(bucket->list), li); + } + + /* return the old value (so it can be freed) */ + return result; +} + +/* + * void *hash_lookup_pid(hash_table *ht, pid_t key) + * + * Look up "key" in "ht" and return the associated value. If "key" + * is not found, return NULL. Key type is pid_t + */ + +void * +hash_lookup_pid(hash_table *ht, pid_t key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + hash_item_pid *h; + void *result; + pid_t k1; + + result = NULL; + if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_pid *)li->datum; + k1 = h->key; + if (key == k1) + { + result = h->value; + break; + } + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * void *hash_remove_pid(hash_table *ht, pid_t key) + * + * Remove the element associated with "key" from the hash table + * "ht". Return the value or NULL if the key was not found. + */ + +void * +hash_remove_pid(hash_table *ht, pid_t key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + llistitem *lilast; + hash_item_pid *hi; + void *result; + pid_t k1; + + result = NULL; + if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + lilast = NULL; + while (li != NULL) + { + hi = (hash_item_pid *)li->datum; + k1 = hi->key; + if (key == k1) + { + ll_extract(ll, li, lilast); + result = hi->value; + key = hi->key; + ; + ll_freeitem(li); + break; + } + lilast = li; + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * hash_item_pid *hash_first_pid(hash_table *ht, hash_pos *pos) + * + * First function to call when iterating through all items in the hash + * table. Returns the first item in "ht" and initializes "*pos" to track + * the current position. + */ + +hash_item_pid * +hash_first_pid(hash_table *ht, hash_pos *pos) + +{ + /* initialize pos for first item in first bucket */ + pos->num_buckets = ht->num_buckets; + pos->hash_bucket = ht->buckets; + pos->curr = 0; + pos->ll_last = NULL; + + /* find the first non-empty bucket */ + while(pos->hash_bucket->list.count == 0) + { + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + return NULL; + } + } + + /* set and return the first item */ + pos->ll_item = LL_FIRST(&(pos->hash_bucket->list)); + return (hash_item_pid *)pos->ll_item->datum; +} + + +/* + * hash_item_pid *hash_next_pid(hash_pos *pos) + * + * Return the next item in the hash table, using "pos" as a description + * of the present position in the hash table. "pos" also identifies the + * specific hash table. Return NULL if there are no more elements. + */ + +hash_item_pid * +hash_next_pid(hash_pos *pos) + +{ + llistitem *li; + + /* move item to last and check for NULL */ + if ((pos->ll_last = pos->ll_item) == NULL) + { + /* are we really at the end of the hash table? */ + if (pos->curr >= pos->num_buckets) + { + /* yes: return NULL */ + return NULL; + } + /* no: regrab first item in current bucket list (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + else + { + /* get the next item in the llist */ + li = LL_NEXT(&(pos->hash_bucket->list), pos->ll_item); + } + + /* if its NULL we have to find another bucket */ + while (li == NULL) + { + /* locate another bucket */ + pos->ll_last = NULL; + + /* move to the next one */ + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + /* at the end of the hash table */ + pos->ll_item = NULL; + return NULL; + } + + /* get the first element (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + + /* li is the next element to dish out */ + pos->ll_item = li; + return (hash_item_pid *)li->datum; +} + +/* + * void *hash_remove_pos_pid(hash_pos *pos) + * + * Remove the hash table entry pointed to by position marker "pos". + * The data from the entry is returned upon success, otherwise NULL. + */ + + +void * +hash_remove_pos_pid(hash_pos *pos) + +{ + llistitem *li; + void *ans; + hash_item_pid *hi; + pid_t key; + + /* sanity checks */ + if (pos == NULL || pos->ll_last == pos->ll_item) + { + return NULL; + } + + /* at this point pos contains the item to remove (ll_item) + and its predecesor (ll_last) */ + /* extract the item from the llist */ + li = pos->ll_item; + ll_extract(&(pos->hash_bucket->list), li, pos->ll_last); + + /* retain the data */ + hi = (hash_item_pid *)li->datum; + ans = hi->value; + + /* free up the space */ + key = hi->key; + ; + ll_freeitem(li); + + /* back up to previous item */ + /* its okay for ll_item to be null: hash_next will detect it */ + pos->ll_item = pos->ll_last; + + return ans; +} + + + +/* + * void hash_add_string(hash_table *ht, char * key, void *value) + * + * Add an element to table "ht". The element is described by + * "key" and "value". Return NULL on success. If the key + * already exists in the table, then no action is taken and + * the data for the existing element is returned. + * Key type is char * + */ + +void * +hash_add_string(hash_table *ht, char * key, void *value) + +{ + bucket_t *bucket; + hash_item_string *hi; + hash_item_string *h; + llist *ll; + llistitem *li; + llistitem *newli; + char * k1; + + /* allocate the space we will need */ + newli = ll_newitem(sizeof(hash_item_string)); + hi = (hash_item_string *)newli->datum; + + /* fill in the values */ + hi->key = strdup(key); + hi->value = value; + + /* hash to the bucket */ + bucket = &(ht->buckets[string_hash(ht, key)]); + + /* walk the list to make sure we do not have a duplicate */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_string *)li->datum; + k1 = h->key; + if (strcmp(key, k1) == 0) + { + /* found one */ + break; + } + li = LL_NEXT(ll, li); + } + li = NULL; + + /* is there already one there? */ + if (li == NULL) + { + /* add the unique element to the buckets list */ + ll_add(&(bucket->list), newli); + return NULL; + } + else + { + /* free the stuff we just allocated */ + ll_freeitem(newli); + return ((hash_item_string *)(li->datum))->value; + } +} + +/* + * void *hash_replace_string(hash_table *ht, char * key, void *value) + * + * Replace an existing value in the hash table with a new one and + * return the old value. If the key does not already exist in + * the hash table, add a new element and return NULL. + * Key type is char * + */ + +void * +hash_replace_string(hash_table *ht, char * key, void *value) + +{ + bucket_t *bucket; + hash_item_string *hi; + llist *ll; + llistitem *li; + void *result = NULL; + char * k1; + + /* find the bucket */ + bucket = &(ht->buckets[string_hash(ht, key)]); + + /* walk the list until we find the existing item */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + hi = (hash_item_string *)li->datum; + k1 = hi->key; + if (strcmp(key, k1) == 0) + { + /* found it: now replace the value with the new one */ + result = hi->value; + hi->value = value; + break; + } + li = LL_NEXT(ll, li); + } + + /* if the element wasnt found, add it */ + if (result == NULL) + { + li = ll_newitem(sizeof(hash_item_string)); + hi = (hash_item_string *)li->datum; + hi->key = strdup(key); + hi->value = value; + ll_add(&(bucket->list), li); + } + + /* return the old value (so it can be freed) */ + return result; +} + +/* + * void *hash_lookup_string(hash_table *ht, char * key) + * + * Look up "key" in "ht" and return the associated value. If "key" + * is not found, return NULL. Key type is char * + */ + +void * +hash_lookup_string(hash_table *ht, char * key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + hash_item_string *h; + void *result; + char * k1; + + result = NULL; + if ((bucket = &(ht->buckets[string_hash(ht, key)])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_string *)li->datum; + k1 = h->key; + if (strcmp(key, k1) == 0) + { + result = h->value; + break; + } + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * void *hash_remove_string(hash_table *ht, char * key) + * + * Remove the element associated with "key" from the hash table + * "ht". Return the value or NULL if the key was not found. + */ + +void * +hash_remove_string(hash_table *ht, char * key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + llistitem *lilast; + hash_item_string *hi; + void *result; + char * k1; + + result = NULL; + if ((bucket = &(ht->buckets[string_hash(ht, key)])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + lilast = NULL; + while (li != NULL) + { + hi = (hash_item_string *)li->datum; + k1 = hi->key; + if (strcmp(key, k1) == 0) + { + ll_extract(ll, li, lilast); + result = hi->value; + key = hi->key; + free(key); + ll_freeitem(li); + break; + } + lilast = li; + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * hash_item_string *hash_first_string(hash_table *ht, hash_pos *pos) + * + * First function to call when iterating through all items in the hash + * table. Returns the first item in "ht" and initializes "*pos" to track + * the current position. + */ + +hash_item_string * +hash_first_string(hash_table *ht, hash_pos *pos) + +{ + /* initialize pos for first item in first bucket */ + pos->num_buckets = ht->num_buckets; + pos->hash_bucket = ht->buckets; + pos->curr = 0; + pos->ll_last = NULL; + + /* find the first non-empty bucket */ + while(pos->hash_bucket->list.count == 0) + { + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + return NULL; + } + } + + /* set and return the first item */ + pos->ll_item = LL_FIRST(&(pos->hash_bucket->list)); + return (hash_item_string *)pos->ll_item->datum; +} + + +/* + * hash_item_string *hash_next_string(hash_pos *pos) + * + * Return the next item in the hash table, using "pos" as a description + * of the present position in the hash table. "pos" also identifies the + * specific hash table. Return NULL if there are no more elements. + */ + +hash_item_string * +hash_next_string(hash_pos *pos) + +{ + llistitem *li; + + /* move item to last and check for NULL */ + if ((pos->ll_last = pos->ll_item) == NULL) + { + /* are we really at the end of the hash table? */ + if (pos->curr >= pos->num_buckets) + { + /* yes: return NULL */ + return NULL; + } + /* no: regrab first item in current bucket list (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + else + { + /* get the next item in the llist */ + li = LL_NEXT(&(pos->hash_bucket->list), pos->ll_item); + } + + /* if its NULL we have to find another bucket */ + while (li == NULL) + { + /* locate another bucket */ + pos->ll_last = NULL; + + /* move to the next one */ + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + /* at the end of the hash table */ + pos->ll_item = NULL; + return NULL; + } + + /* get the first element (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + + /* li is the next element to dish out */ + pos->ll_item = li; + return (hash_item_string *)li->datum; +} + +/* + * void *hash_remove_pos_string(hash_pos *pos) + * + * Remove the hash table entry pointed to by position marker "pos". + * The data from the entry is returned upon success, otherwise NULL. + */ + + +void * +hash_remove_pos_string(hash_pos *pos) + +{ + llistitem *li; + void *ans; + hash_item_string *hi; + char * key; + + /* sanity checks */ + if (pos == NULL || pos->ll_last == pos->ll_item) + { + return NULL; + } + + /* at this point pos contains the item to remove (ll_item) + and its predecesor (ll_last) */ + /* extract the item from the llist */ + li = pos->ll_item; + ll_extract(&(pos->hash_bucket->list), li, pos->ll_last); + + /* retain the data */ + hi = (hash_item_string *)li->datum; + ans = hi->value; + + /* free up the space */ + key = hi->key; + free(key); + ll_freeitem(li); + + /* back up to previous item */ + /* its okay for ll_item to be null: hash_next will detect it */ + pos->ll_item = pos->ll_last; + + return ans; +} + + + +/* + * void hash_add_pidthr(hash_table *ht, pidthr_t key, void *value) + * + * Add an element to table "ht". The element is described by + * "key" and "value". Return NULL on success. If the key + * already exists in the table, then no action is taken and + * the data for the existing element is returned. + * Key type is pidthr_t + */ + +void * +hash_add_pidthr(hash_table *ht, pidthr_t key, void *value) + +{ + bucket_t *bucket; + hash_item_pidthr *hi; + hash_item_pidthr *h; + llist *ll; + llistitem *li; + llistitem *newli; + pidthr_t k1; + + /* allocate the space we will need */ + newli = ll_newitem(sizeof(hash_item_pidthr)); + hi = (hash_item_pidthr *)newli->datum; + + /* fill in the values */ + hi->key = key; + hi->value = value; + + /* hash to the bucket */ + bucket = &(ht->buckets[((key.k_thr * 10000 + key.k_pid) % ht->num_buckets)]); + + /* walk the list to make sure we do not have a duplicate */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_pidthr *)li->datum; + k1 = h->key; + if ((key.k_pid == k1.k_pid && key.k_thr == k1.k_thr)) + { + /* found one */ + break; + } + li = LL_NEXT(ll, li); + } + li = NULL; + + /* is there already one there? */ + if (li == NULL) + { + /* add the unique element to the buckets list */ + ll_add(&(bucket->list), newli); + return NULL; + } + else + { + /* free the stuff we just allocated */ + ll_freeitem(newli); + return ((hash_item_pidthr *)(li->datum))->value; + } +} + +/* + * void *hash_replace_pidthr(hash_table *ht, pidthr_t key, void *value) + * + * Replace an existing value in the hash table with a new one and + * return the old value. If the key does not already exist in + * the hash table, add a new element and return NULL. + * Key type is pidthr_t + */ + +void * +hash_replace_pidthr(hash_table *ht, pidthr_t key, void *value) + +{ + bucket_t *bucket; + hash_item_pidthr *hi; + llist *ll; + llistitem *li; + void *result = NULL; + pidthr_t k1; + + /* find the bucket */ + bucket = &(ht->buckets[((key.k_thr * 10000 + key.k_pid) % ht->num_buckets)]); + + /* walk the list until we find the existing item */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + hi = (hash_item_pidthr *)li->datum; + k1 = hi->key; + if ((key.k_pid == k1.k_pid && key.k_thr == k1.k_thr)) + { + /* found it: now replace the value with the new one */ + result = hi->value; + hi->value = value; + break; + } + li = LL_NEXT(ll, li); + } + + /* if the element wasnt found, add it */ + if (result == NULL) + { + li = ll_newitem(sizeof(hash_item_pidthr)); + hi = (hash_item_pidthr *)li->datum; + hi->key = key; + hi->value = value; + ll_add(&(bucket->list), li); + } + + /* return the old value (so it can be freed) */ + return result; +} + +/* + * void *hash_lookup_pidthr(hash_table *ht, pidthr_t key) + * + * Look up "key" in "ht" and return the associated value. If "key" + * is not found, return NULL. Key type is pidthr_t + */ + +void * +hash_lookup_pidthr(hash_table *ht, pidthr_t key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + hash_item_pidthr *h; + void *result; + pidthr_t k1; + + result = NULL; + if ((bucket = &(ht->buckets[((key.k_thr * 10000 + key.k_pid) % ht->num_buckets)])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_pidthr *)li->datum; + k1 = h->key; + if ((key.k_pid == k1.k_pid && key.k_thr == k1.k_thr)) + { + result = h->value; + break; + } + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * void *hash_remove_pidthr(hash_table *ht, pidthr_t key) + * + * Remove the element associated with "key" from the hash table + * "ht". Return the value or NULL if the key was not found. + */ + +void * +hash_remove_pidthr(hash_table *ht, pidthr_t key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + llistitem *lilast; + hash_item_pidthr *hi; + void *result; + pidthr_t k1; + + result = NULL; + if ((bucket = &(ht->buckets[((key.k_thr * 10000 + key.k_pid) % ht->num_buckets)])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + lilast = NULL; + while (li != NULL) + { + hi = (hash_item_pidthr *)li->datum; + k1 = hi->key; + if ((key.k_pid == k1.k_pid && key.k_thr == k1.k_thr)) + { + ll_extract(ll, li, lilast); + result = hi->value; + key = hi->key; + ; + ll_freeitem(li); + break; + } + lilast = li; + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * hash_item_pidthr *hash_first_pidthr(hash_table *ht, hash_pos *pos) + * + * First function to call when iterating through all items in the hash + * table. Returns the first item in "ht" and initializes "*pos" to track + * the current position. + */ + +hash_item_pidthr * +hash_first_pidthr(hash_table *ht, hash_pos *pos) + +{ + /* initialize pos for first item in first bucket */ + pos->num_buckets = ht->num_buckets; + pos->hash_bucket = ht->buckets; + pos->curr = 0; + pos->ll_last = NULL; + + /* find the first non-empty bucket */ + while(pos->hash_bucket->list.count == 0) + { + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + return NULL; + } + } + + /* set and return the first item */ + pos->ll_item = LL_FIRST(&(pos->hash_bucket->list)); + return (hash_item_pidthr *)pos->ll_item->datum; +} + + +/* + * hash_item_pidthr *hash_next_pidthr(hash_pos *pos) + * + * Return the next item in the hash table, using "pos" as a description + * of the present position in the hash table. "pos" also identifies the + * specific hash table. Return NULL if there are no more elements. + */ + +hash_item_pidthr * +hash_next_pidthr(hash_pos *pos) + +{ + llistitem *li; + + /* move item to last and check for NULL */ + if ((pos->ll_last = pos->ll_item) == NULL) + { + /* are we really at the end of the hash table? */ + if (pos->curr >= pos->num_buckets) + { + /* yes: return NULL */ + return NULL; + } + /* no: regrab first item in current bucket list (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + else + { + /* get the next item in the llist */ + li = LL_NEXT(&(pos->hash_bucket->list), pos->ll_item); + } + + /* if its NULL we have to find another bucket */ + while (li == NULL) + { + /* locate another bucket */ + pos->ll_last = NULL; + + /* move to the next one */ + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + /* at the end of the hash table */ + pos->ll_item = NULL; + return NULL; + } + + /* get the first element (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + + /* li is the next element to dish out */ + pos->ll_item = li; + return (hash_item_pidthr *)li->datum; +} + +/* + * void *hash_remove_pos_pidthr(hash_pos *pos) + * + * Remove the hash table entry pointed to by position marker "pos". + * The data from the entry is returned upon success, otherwise NULL. + */ + + +void * +hash_remove_pos_pidthr(hash_pos *pos) + +{ + llistitem *li; + void *ans; + hash_item_pidthr *hi; + pidthr_t key; + + /* sanity checks */ + if (pos == NULL || pos->ll_last == pos->ll_item) + { + return NULL; + } + + /* at this point pos contains the item to remove (ll_item) + and its predecesor (ll_last) */ + /* extract the item from the llist */ + li = pos->ll_item; + ll_extract(&(pos->hash_bucket->list), li, pos->ll_last); + + /* retain the data */ + hi = (hash_item_pidthr *)li->datum; + ans = hi->value; + + /* free up the space */ + key = hi->key; + ; + ll_freeitem(li); + + /* back up to previous item */ + /* its okay for ll_item to be null: hash_next will detect it */ + pos->ll_item = pos->ll_last; + + return ans; +} + +#if HAVE_LWPID_T + + +/* + * void hash_add_lwpid(hash_table *ht, lwpid_t key, void *value) + * + * Add an element to table "ht". The element is described by + * "key" and "value". Return NULL on success. If the key + * already exists in the table, then no action is taken and + * the data for the existing element is returned. + * Key type is lwpid_t + */ + +void * +hash_add_lwpid(hash_table *ht, lwpid_t key, void *value) + +{ + bucket_t *bucket; + hash_item_lwpid *hi; + hash_item_lwpid *h; + llist *ll; + llistitem *li; + llistitem *newli; + lwpid_t k1; + + /* allocate the space we will need */ + newli = ll_newitem(sizeof(hash_item_lwpid)); + hi = (hash_item_lwpid *)newli->datum; + + /* fill in the values */ + hi->key = key; + hi->value = value; + + /* hash to the bucket */ + bucket = &(ht->buckets[(key % ht->num_buckets)]); + + /* walk the list to make sure we do not have a duplicate */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_lwpid *)li->datum; + k1 = h->key; + if (key == k1) + { + /* found one */ + break; + } + li = LL_NEXT(ll, li); + } + li = NULL; + + /* is there already one there? */ + if (li == NULL) + { + /* add the unique element to the buckets list */ + ll_add(&(bucket->list), newli); + return NULL; + } + else + { + /* free the stuff we just allocated */ + ll_freeitem(newli); + return ((hash_item_lwpid *)(li->datum))->value; + } +} + +/* + * void *hash_replace_lwpid(hash_table *ht, lwpid_t key, void *value) + * + * Replace an existing value in the hash table with a new one and + * return the old value. If the key does not already exist in + * the hash table, add a new element and return NULL. + * Key type is lwpid_t + */ + +void * +hash_replace_lwpid(hash_table *ht, lwpid_t key, void *value) + +{ + bucket_t *bucket; + hash_item_lwpid *hi; + llist *ll; + llistitem *li; + void *result = NULL; + lwpid_t k1; + + /* find the bucket */ + bucket = &(ht->buckets[(key % ht->num_buckets)]); + + /* walk the list until we find the existing item */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + hi = (hash_item_lwpid *)li->datum; + k1 = hi->key; + if (key == k1) + { + /* found it: now replace the value with the new one */ + result = hi->value; + hi->value = value; + break; + } + li = LL_NEXT(ll, li); + } + + /* if the element wasnt found, add it */ + if (result == NULL) + { + li = ll_newitem(sizeof(hash_item_lwpid)); + hi = (hash_item_lwpid *)li->datum; + hi->key = key; + hi->value = value; + ll_add(&(bucket->list), li); + } + + /* return the old value (so it can be freed) */ + return result; +} + +/* + * void *hash_lookup_lwpid(hash_table *ht, lwpid_t key) + * + * Look up "key" in "ht" and return the associated value. If "key" + * is not found, return NULL. Key type is lwpid_t + */ + +void * +hash_lookup_lwpid(hash_table *ht, lwpid_t key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + hash_item_lwpid *h; + void *result; + lwpid_t k1; + + result = NULL; + if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_lwpid *)li->datum; + k1 = h->key; + if (key == k1) + { + result = h->value; + break; + } + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * void *hash_remove_lwpid(hash_table *ht, lwpid_t key) + * + * Remove the element associated with "key" from the hash table + * "ht". Return the value or NULL if the key was not found. + */ + +void * +hash_remove_lwpid(hash_table *ht, lwpid_t key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + llistitem *lilast; + hash_item_lwpid *hi; + void *result; + lwpid_t k1; + + result = NULL; + if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + lilast = NULL; + while (li != NULL) + { + hi = (hash_item_lwpid *)li->datum; + k1 = hi->key; + if (key == k1) + { + ll_extract(ll, li, lilast); + result = hi->value; + key = hi->key; + ; + ll_freeitem(li); + break; + } + lilast = li; + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * hash_item_lwpid *hash_first_lwpid(hash_table *ht, hash_pos *pos) + * + * First function to call when iterating through all items in the hash + * table. Returns the first item in "ht" and initializes "*pos" to track + * the current position. + */ + +hash_item_lwpid * +hash_first_lwpid(hash_table *ht, hash_pos *pos) + +{ + /* initialize pos for first item in first bucket */ + pos->num_buckets = ht->num_buckets; + pos->hash_bucket = ht->buckets; + pos->curr = 0; + pos->ll_last = NULL; + + /* find the first non-empty bucket */ + while(pos->hash_bucket->list.count == 0) + { + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + return NULL; + } + } + + /* set and return the first item */ + pos->ll_item = LL_FIRST(&(pos->hash_bucket->list)); + return (hash_item_lwpid *)pos->ll_item->datum; +} + + +/* + * hash_item_lwpid *hash_next_lwpid(hash_pos *pos) + * + * Return the next item in the hash table, using "pos" as a description + * of the present position in the hash table. "pos" also identifies the + * specific hash table. Return NULL if there are no more elements. + */ + +hash_item_lwpid * +hash_next_lwpid(hash_pos *pos) + +{ + llistitem *li; + + /* move item to last and check for NULL */ + if ((pos->ll_last = pos->ll_item) == NULL) + { + /* are we really at the end of the hash table? */ + if (pos->curr >= pos->num_buckets) + { + /* yes: return NULL */ + return NULL; + } + /* no: regrab first item in current bucket list (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + else + { + /* get the next item in the llist */ + li = LL_NEXT(&(pos->hash_bucket->list), pos->ll_item); + } + + /* if its NULL we have to find another bucket */ + while (li == NULL) + { + /* locate another bucket */ + pos->ll_last = NULL; + + /* move to the next one */ + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + /* at the end of the hash table */ + pos->ll_item = NULL; + return NULL; + } + + /* get the first element (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + + /* li is the next element to dish out */ + pos->ll_item = li; + return (hash_item_lwpid *)li->datum; +} + +/* + * void *hash_remove_pos_lwpid(hash_pos *pos) + * + * Remove the hash table entry pointed to by position marker "pos". + * The data from the entry is returned upon success, otherwise NULL. + */ + + +void * +hash_remove_pos_lwpid(hash_pos *pos) + +{ + llistitem *li; + void *ans; + hash_item_lwpid *hi; + lwpid_t key; + + /* sanity checks */ + if (pos == NULL || pos->ll_last == pos->ll_item) + { + return NULL; + } + + /* at this point pos contains the item to remove (ll_item) + and its predecesor (ll_last) */ + /* extract the item from the llist */ + li = pos->ll_item; + ll_extract(&(pos->hash_bucket->list), li, pos->ll_last); + + /* retain the data */ + hi = (hash_item_lwpid *)li->datum; + ans = hi->value; + + /* free up the space */ + key = hi->key; + ; + ll_freeitem(li); + + /* back up to previous item */ + /* its okay for ll_item to be null: hash_next will detect it */ + pos->ll_item = pos->ll_last; + + return ans; +} + +#endif diff --git a/hash.h b/hash.h new file mode 100644 index 000000000000..44a121bc0f20 --- /dev/null +++ b/hash.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* hash.m4h */ + +/* Interface definition for hash.c */ + +/* The file hash.h is generated from hash.m4h via the preprocessor M4 */ + +#ifndef _HASH_H +#define _HASH_H + +#include <sys/types.h> + +typedef struct pidthr_t { + pid_t k_pid; + id_t k_thr; +} pidthr_t; + +typedef struct llistitem { + void *datum; + struct llistitem *next; +} llistitem; + +typedef struct llist { + llistitem *head; + unsigned int count; +} llist; + +typedef struct bucket { + llist list; +} bucket_t; + +typedef struct hash_table { + int num_buckets; + bucket_t *buckets; +} hash_table; + +typedef struct hash_pos { + int num_buckets; + int curr; + bucket_t *hash_bucket; + llistitem *ll_item; + llistitem *ll_last; +} hash_pos; + +hash_table *hash_create(int num); +void hash_sizeinfo(unsigned int *sizes, int max, hash_table *ht); + + + + +typedef struct hash_item_uint { + unsigned int key; + void *value; +} hash_item_uint; + +void *hash_add_uint(hash_table *ht, unsigned int key, void *value); +void *hash_replace_uint(hash_table *ht, unsigned int key, void *value); +void *hash_lookup_uint(hash_table *ht, unsigned int key); +void *hash_remove_uint(hash_table *ht, unsigned int key); +hash_item_uint *hash_first_uint(hash_table *ht, hash_pos *pos); +hash_item_uint *hash_next_uint(hash_pos *pos); +void *hash_remove_pos_uint(hash_pos *pos); + + +typedef struct hash_item_pid { + pid_t key; + void *value; +} hash_item_pid; + +void *hash_add_pid(hash_table *ht, pid_t key, void *value); +void *hash_replace_pid(hash_table *ht, pid_t key, void *value); +void *hash_lookup_pid(hash_table *ht, pid_t key); +void *hash_remove_pid(hash_table *ht, pid_t key); +hash_item_pid *hash_first_pid(hash_table *ht, hash_pos *pos); +hash_item_pid *hash_next_pid(hash_pos *pos); +void *hash_remove_pos_pid(hash_pos *pos); + + +typedef struct hash_item_string { + char * key; + void *value; +} hash_item_string; + +void *hash_add_string(hash_table *ht, char * key, void *value); +void *hash_replace_string(hash_table *ht, char * key, void *value); +void *hash_lookup_string(hash_table *ht, char * key); +void *hash_remove_string(hash_table *ht, char * key); +hash_item_string *hash_first_string(hash_table *ht, hash_pos *pos); +hash_item_string *hash_next_string(hash_pos *pos); +void *hash_remove_pos_string(hash_pos *pos); + + +typedef struct hash_item_pidthr { + pidthr_t key; + void *value; +} hash_item_pidthr; + +void *hash_add_pidthr(hash_table *ht, pidthr_t key, void *value); +void *hash_replace_pidthr(hash_table *ht, pidthr_t key, void *value); +void *hash_lookup_pidthr(hash_table *ht, pidthr_t key); +void *hash_remove_pidthr(hash_table *ht, pidthr_t key); +hash_item_pidthr *hash_first_pidthr(hash_table *ht, hash_pos *pos); +hash_item_pidthr *hash_next_pidthr(hash_pos *pos); +void *hash_remove_pos_pidthr(hash_pos *pos); + +#if HAVE_LWPID_T + +typedef struct hash_item_lwpid { + lwpid_t key; + void *value; +} hash_item_lwpid; + +void *hash_add_lwpid(hash_table *ht, lwpid_t key, void *value); +void *hash_replace_lwpid(hash_table *ht, lwpid_t key, void *value); +void *hash_lookup_lwpid(hash_table *ht, lwpid_t key); +void *hash_remove_lwpid(hash_table *ht, lwpid_t key); +hash_item_lwpid *hash_first_lwpid(hash_table *ht, hash_pos *pos); +hash_item_lwpid *hash_next_lwpid(hash_pos *pos); +void *hash_remove_pos_lwpid(hash_pos *pos); + +#endif + + +#endif diff --git a/hash.m4c b/hash.m4c new file mode 100755 index 000000000000..6e8a7365936d --- /dev/null +++ b/hash.m4c @@ -0,0 +1,666 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* hash.m4c */ + +/* The file hash.c is generated from hash.m4c via the preprocessor M4 */ + +/* + * Hash table functions: init, add, lookup, first, next, sizeinfo. + * This is a conventional "bucket hash". The key is hashed in to a number + * less than or equal to the number of buckets and the result is used + * to index in to the array of buckets. Each bucket is a linked list + * that contains all the key/value pairs which hashed to that index. + */ + +#include "config.h" + +#if STDC_HEADERS +#include <string.h> +#include <stdlib.h> +#define memzero(a, b) memset((a), 0, (b)) +#else /* !STDC_HEADERS */ +#ifdef HAVE_MEMCPY +#define memzero(a, b) memset((a), 0, (b)) +#else +#define memcpy(a, b, c) bcopy((b), (a), (c)) +#define memzero(a, b) bzero((a), (b)) +#define memcmp(a, b, c) bcmp((a), (b), (c)) +#endif /* HAVE_MEMCPY */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#else +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#endif +void *malloc(); +void free(); +char *strdup(); +#endif /* !STDC_HEADERS */ + +/* After all that there are still some systems that don't have NULL defined */ +#ifndef NULL +#define NULL 0 +#endif + +#ifdef HAVE_MATH_H +#include <math.h> +#endif + +#if !HAVE_PID_T +typedef long pid_t; +#endif +#if !HAVE_ID_T +typedef long id_t; +#endif + +#include "hash.h" + +dnl # The m4 code uses MALLOC, FREE, and STRDUP for dynamic allocation. +dnl # You can change what these get mapped to here: + +define(`MALLOC', `malloc($1)') +define(`FREE', `free($1)') +define(`STRDUP', `strdup($1)') + +static int +next_prime(int x) + +{ + double i, j; + int f; + + i = x; + while (i++) + { + f=1; + for (j=2; j<i; j++) + { + if ((i/j)==floor(i/j)) + { + f=0; + break; + } + } + if (f) + { + return (int)i; + } + } + return 1; +} + +/* string hashes */ + +static int +string_hash(hash_table *ht, char *key) + +{ + unsigned long s = 0; + unsigned char ch; + int shifting = 24; + + while ((ch = (unsigned char)*key++) != '\0') + { + if (shifting == 0) + { + s = s + ch; + shifting = 24; + } + else + { + s = s + (ch << shifting); + shifting -= 8; + } + } + + return (s % ht->num_buckets); +} + +void ll_init(llist *q) + +{ + q->head = NULL; + q->count = 0; +} + +llistitem *ll_newitem(int size) + +{ + llistitem *qi; + + qi = (llistitem *)MALLOC(sizeof(llistitem) + size); + qi->datum = ((void *)qi + sizeof(llistitem)); + return qi; +} + +void ll_freeitem(llistitem *li) + +{ + FREE(li); +} + +void ll_add(llist *q, llistitem *new) + +{ + new->next = q->head; + q->head = new; + q->count++; +} + +void ll_extract(llist *q, llistitem *qi, llistitem *last) + +{ + if (last == NULL) + { + q->head = qi->next; + } + else + { + last->next = qi->next; + } + qi->next = NULL; + q->count--; +} + +#define LL_FIRST(q) ((q)->head) +llistitem * +ll_first(llist *q) + +{ + return q->head; +} + +#define LL_NEXT(q, qi) ((qi) != NULL ? (qi)->next : NULL) +llistitem * +ll_next(llist *q, llistitem *qi) + +{ + return (qi != NULL ? qi->next : NULL); +} + +#define LL_ISEMPTY(ll) ((ll)->count == 0) +int +ll_isempty(llist *ll) + +{ + return (ll->count == 0); +} + +/* + * hash_table *hash_create(int num) + * + * Creates a hash table structure with at least "num" buckets. + */ + +hash_table * +hash_create(int num) + +{ + hash_table *result; + bucket_t *b; + int bytes; + int i; + + /* create the resultant structure */ + result = (hash_table *)MALLOC(sizeof(hash_table)); + + /* adjust bucket count to be prime */ + num = next_prime(num); + + /* create the buckets */ + bytes = sizeof(bucket_t) * num; + result->buckets = b = (bucket_t *)MALLOC(bytes); + result->num_buckets = num; + + /* create each bucket as a linked list */ + i = num; + while (--i >= 0) + { + ll_init(&(b->list)); + b++; + } + + return result; +} + +/* + * unsigned int hash_count(hash_table *ht) + * + * Return total number of elements contained in hash table. + */ + +unsigned int +hash_count(hash_table *ht) + +{ + register int i = 0; + register int cnt = 0; + register bucket_t *bucket; + + bucket = ht->buckets; + while (i++ < ht->num_buckets) + { + cnt += bucket->list.count; + bucket++; + } + + return cnt; +} + +/* + * void hash_sizeinfo(unsigned int *sizes, int max, hash_table *ht) + * + * Fill in "sizes" with information about bucket lengths in hash + * table "max". + */ + +void +hash_sizeinfo(unsigned int *sizes, int max, hash_table *ht) + +{ + register int i; + register int idx; + register bucket_t *bucket; + + memzero(sizes, max * sizeof(unsigned int)); + + bucket = ht->buckets; + i = 0; + while (i++ < ht->num_buckets) + { + idx = bucket->list.count; + sizes[idx >= max ? max-1 : idx]++; + bucket++; + } +} + +dnl # HASH_TABLE_TMPL(suffix, keytype, to_hash, to_cmp, to_alloc, to_free) +dnl # +dnl # This generates hash table functions suitable for keys +dnl # of type "keytype". The function names all end with "suffix". +dnl # "to_hash" is an expression that generates a hash index (this +dnl # expression can include key and ht). "to_cmp" is an expression +dnl # that compares "key" to "k1". "to_alloc" is an expression that +dnl # allocates space for "key", or empty if no allocation is needed. +dnl # "to_free" is an expression that frees "key", or empty if no +dnl # allocation is needed. + +define(`HASH_TABLE_TMPL', ` + +/* + * void hash_add_$1(hash_table *ht, $2 key, void *value) + * + * Add an element to table "ht". The element is described by + * "key" and "value". Return NULL on success. If the key + * already exists in the table, then no action is taken and + * the data for the existing element is returned. + * Key type is $2 + */ + +void * +hash_add_$1(hash_table *ht, $2 key, void *value) + +{ + bucket_t *bucket; + hash_item_$1 *hi; + hash_item_$1 *h; + llist *ll; + llistitem *li; + llistitem *newli; + $2 k1; + + /* allocate the space we will need */ + newli = ll_newitem(sizeof(hash_item_$1)); + hi = (hash_item_$1 *)newli->datum; + + /* fill in the values */ + hi->key = ifelse($5, , key, $5); + hi->value = value; + + /* hash to the bucket */ + bucket = &(ht->buckets[$3]); + + /* walk the list to make sure we do not have a duplicate */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_$1 *)li->datum; + k1 = h->key; + if ($4) + { + /* found one */ + break; + } + li = LL_NEXT(ll, li); + } + li = NULL; + + /* is there already one there? */ + if (li == NULL) + { + /* add the unique element to the buckets list */ + ll_add(&(bucket->list), newli); + return NULL; + } + else + { + /* free the stuff we just allocated */ + ll_freeitem(newli); + return ((hash_item_$1 *)(li->datum))->value; + } +} + +/* + * void *hash_replace_$1(hash_table *ht, $2 key, void *value) + * + * Replace an existing value in the hash table with a new one and + * return the old value. If the key does not already exist in + * the hash table, add a new element and return NULL. + * Key type is $2 + */ + +void * +hash_replace_$1(hash_table *ht, $2 key, void *value) + +{ + bucket_t *bucket; + hash_item_$1 *hi; + llist *ll; + llistitem *li; + void *result = NULL; + $2 k1; + + /* find the bucket */ + bucket = &(ht->buckets[$3]); + + /* walk the list until we find the existing item */ + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + hi = (hash_item_$1 *)li->datum; + k1 = hi->key; + if ($4) + { + /* found it: now replace the value with the new one */ + result = hi->value; + hi->value = value; + break; + } + li = LL_NEXT(ll, li); + } + + /* if the element wasnt found, add it */ + if (result == NULL) + { + li = ll_newitem(sizeof(hash_item_$1)); + hi = (hash_item_$1 *)li->datum; + hi->key = ifelse($5, , key, $5); + hi->value = value; + ll_add(&(bucket->list), li); + } + + /* return the old value (so it can be freed) */ + return result; +} + +/* + * void *hash_lookup_$1(hash_table *ht, $2 key) + * + * Look up "key" in "ht" and return the associated value. If "key" + * is not found, return NULL. Key type is $2 + */ + +void * +hash_lookup_$1(hash_table *ht, $2 key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + hash_item_$1 *h; + void *result; + $2 k1; + + result = NULL; + if ((bucket = &(ht->buckets[$3])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + while (li != NULL) + { + h = (hash_item_$1 *)li->datum; + k1 = h->key; + if ($4) + { + result = h->value; + break; + } + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * void *hash_remove_$1(hash_table *ht, $2 key) + * + * Remove the element associated with "key" from the hash table + * "ht". Return the value or NULL if the key was not found. + */ + +void * +hash_remove_$1(hash_table *ht, $2 key) + +{ + bucket_t *bucket; + llist *ll; + llistitem *li; + llistitem *lilast; + hash_item_$1 *hi; + void *result; + $2 k1; + + result = NULL; + if ((bucket = &(ht->buckets[$3])) != NULL) + { + ll = &(bucket->list); + li = LL_FIRST(ll); + lilast = NULL; + while (li != NULL) + { + hi = (hash_item_$1 *)li->datum; + k1 = hi->key; + if ($4) + { + ll_extract(ll, li, lilast); + result = hi->value; + key = hi->key; + $6; + ll_freeitem(li); + break; + } + lilast = li; + li = LL_NEXT(ll, li); + } + } + return result; +} + +/* + * hash_item_$1 *hash_first_$1(hash_table *ht, hash_pos *pos) + * + * First function to call when iterating through all items in the hash + * table. Returns the first item in "ht" and initializes "*pos" to track + * the current position. + */ + +hash_item_$1 * +hash_first_$1(hash_table *ht, hash_pos *pos) + +{ + /* initialize pos for first item in first bucket */ + pos->num_buckets = ht->num_buckets; + pos->hash_bucket = ht->buckets; + pos->curr = 0; + pos->ll_last = NULL; + + /* find the first non-empty bucket */ + while(pos->hash_bucket->list.count == 0) + { + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + return NULL; + } + } + + /* set and return the first item */ + pos->ll_item = LL_FIRST(&(pos->hash_bucket->list)); + return (hash_item_$1 *)pos->ll_item->datum; +} + + +/* + * hash_item_$1 *hash_next_$1(hash_pos *pos) + * + * Return the next item in the hash table, using "pos" as a description + * of the present position in the hash table. "pos" also identifies the + * specific hash table. Return NULL if there are no more elements. + */ + +hash_item_$1 * +hash_next_$1(hash_pos *pos) + +{ + llistitem *li; + + /* move item to last and check for NULL */ + if ((pos->ll_last = pos->ll_item) == NULL) + { + /* are we really at the end of the hash table? */ + if (pos->curr >= pos->num_buckets) + { + /* yes: return NULL */ + return NULL; + } + /* no: regrab first item in current bucket list (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + else + { + /* get the next item in the llist */ + li = LL_NEXT(&(pos->hash_bucket->list), pos->ll_item); + } + + /* if its NULL we have to find another bucket */ + while (li == NULL) + { + /* locate another bucket */ + pos->ll_last = NULL; + + /* move to the next one */ + pos->hash_bucket++; + if (++pos->curr >= pos->num_buckets) + { + /* at the end of the hash table */ + pos->ll_item = NULL; + return NULL; + } + + /* get the first element (might be NULL) */ + li = LL_FIRST(&(pos->hash_bucket->list)); + } + + /* li is the next element to dish out */ + pos->ll_item = li; + return (hash_item_$1 *)li->datum; +} + +/* + * void *hash_remove_pos_$1(hash_pos *pos) + * + * Remove the hash table entry pointed to by position marker "pos". + * The data from the entry is returned upon success, otherwise NULL. + */ + + +void * +hash_remove_pos_$1(hash_pos *pos) + +{ + llistitem *li; + void *ans; + hash_item_$1 *hi; + $2 key; + + /* sanity checks */ + if (pos == NULL || pos->ll_last == pos->ll_item) + { + return NULL; + } + + /* at this point pos contains the item to remove (ll_item) + and its predecesor (ll_last) */ + /* extract the item from the llist */ + li = pos->ll_item; + ll_extract(&(pos->hash_bucket->list), li, pos->ll_last); + + /* retain the data */ + hi = (hash_item_$1 *)li->datum; + ans = hi->value; + + /* free up the space */ + key = hi->key; + $6; + ll_freeitem(li); + + /* back up to previous item */ + /* its okay for ll_item to be null: hash_next will detect it */ + pos->ll_item = pos->ll_last; + + return ans; +} +') + +dnl # create hash talbe functions for unsigned int and for strings */ + +HASH_TABLE_TMPL(`uint', `unsigned int', `(key % ht->num_buckets)', `key == k1', ,) +HASH_TABLE_TMPL(`pid', `pid_t', `(key % ht->num_buckets)', `key == k1', ,) +HASH_TABLE_TMPL(`string', `char *', `string_hash(ht, key)', `strcmp(key, k1) == 0', `STRDUP(key)', `FREE(key)') +HASH_TABLE_TMPL(`pidthr', `pidthr_t', `((key.k_thr * 10000 + key.k_pid) % ht->num_buckets)', `(key.k_pid == k1.k_pid && key.k_thr == k1.k_thr)', ,) +#if HAVE_LWPID_T +HASH_TABLE_TMPL(`lwpid', `lwpid_t', `(key % ht->num_buckets)', `key == k1', ,) +#endif diff --git a/hash.m4h b/hash.m4h new file mode 100755 index 000000000000..63a386c1fd04 --- /dev/null +++ b/hash.m4h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* hash.m4h */ + +/* Interface definition for hash.c */ + +/* The file hash.h is generated from hash.m4h via the preprocessor M4 */ + +#ifndef _HASH_H +#define _HASH_H + +#include <sys/types.h> + +typedef struct pidthr_t { + pid_t k_pid; + id_t k_thr; +} pidthr_t; + +typedef struct llistitem { + void *datum; + struct llistitem *next; +} llistitem; + +typedef struct llist { + llistitem *head; + unsigned int count; +} llist; + +typedef struct bucket { + llist list; +} bucket_t; + +typedef struct hash_table { + int num_buckets; + bucket_t *buckets; +} hash_table; + +typedef struct hash_pos { + int num_buckets; + int curr; + bucket_t *hash_bucket; + llistitem *ll_item; + llistitem *ll_last; +} hash_pos; + +hash_table *hash_create(int num); +void hash_sizeinfo(unsigned int *sizes, int max, hash_table *ht); + +define(`HASH_TYPE_TMPL', ` +typedef struct hash_item_$1 { + $2 key; + void *value; +} hash_item_$1; + +void *hash_add_$1(hash_table *ht, $2 key, void *value); +void *hash_replace_$1(hash_table *ht, $2 key, void *value); +void *hash_lookup_$1(hash_table *ht, $2 key); +void *hash_remove_$1(hash_table *ht, $2 key); +hash_item_$1 *hash_first_$1(hash_table *ht, hash_pos *pos); +hash_item_$1 *hash_next_$1(hash_pos *pos); +void *hash_remove_pos_$1(hash_pos *pos); +') + +HASH_TYPE_TMPL(`uint', `unsigned int') +HASH_TYPE_TMPL(`pid', `pid_t') +HASH_TYPE_TMPL(`string', `char *') +HASH_TYPE_TMPL(`pidthr', `pidthr_t') +#if HAVE_LWPID_T +HASH_TYPE_TMPL(`lwpid', `lwpid_t') +#endif + + +#endif diff --git a/install-sh b/install-sh index d8b6283eaca1..398a88e14218 100755 --- a/install-sh +++ b/install-sh @@ -1,69 +1,251 @@ #!/bin/sh # -# this shell script is amazingly similar to the old and lamented -# BSD "install" command. It recognized the following options: +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). # -# -o target file owner -# -m target file mode -# -g target file group owner +# Copyright 1991 by the Massachusetts Institute of Technology # +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. # -# scan the options +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. # -while [ $# -gt 0 ]; do +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do case $1 in - -o) - owner=$2 - shift ; shift - ;; - - -m) - mode=$2 - shift; shift - ;; - - -g) - group=$2 - shift ; shift - ;; - - -*) - echo "install: unknown option $1" - exit - ;; - - *) - break - ;; + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; esac done -# -# we need two more: filename and destination -# -if [ $# -ne 2 ]; then - echo "Usage: install [ -o owner ] [ -m mode ] [ -g group ] file destination" - exit -fi -# -# first, copy -# -cp $1 $2 -# -# normalize the name -# -dest=$2 -if [ -d $2 ]; then - dest=$2/`basename $1` -fi -# -# do optional things -# -if [ "$owner" ]; then - chown $owner $dest + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + : fi -if [ "$group" ]; then - chgrp $group $dest + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + : + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + : + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + : + fi fi -if [ "$mode" ]; then - chmod $mode $dest + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' + ' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + : + fi + + pathcomp="${pathcomp}/" +done fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + : + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 @@ -1,27 +1,69 @@ /* - * Top - a top users display for Berkeley Unix + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Top - a top users display for Unix * - * This file defines the locations on tne screen for various parts of the - * display. These definitions are used by the routines in "display.c" for - * cursor addressing. + * This file defines the default locations on the screen for various parts + * of the display. These definitions are used by the routines in "display.c" + * for cursor addressing. */ -#define x_lastpid 10 -#define y_lastpid 0 -#define x_loadave 33 -#define x_loadave_nompid 15 -#define y_loadave 0 -#define x_procstate 0 -#define y_procstate 1 -#define x_brkdn 15 -#define y_brkdn 1 -#define x_mem 8 -#define y_mem 3 -#define y_message 4 -#define x_header 0 -#define y_header 5 -#define x_idlecursor 0 -#define y_idlecursor 4 -#define y_procs 6 +#define X_LASTPID 10 +#define Y_LASTPID 0 +#define X_LASTPIDWIDTH 13 +#define X_LOADAVE 27 +#define Y_LOADAVE 0 +#define X_LOADAVEWIDTH 7 +#define X_MINIBAR 50 +#define Y_MINIBAR 0 +#define X_UPTIME 48 +#define Y_UPTIME 0 +#define X_PROCSTATE 15 +#define Y_PROCSTATE 1 +#define X_BRKDN 15 +#define Y_BRKDN 1 +#define X_CPUSTATES 0 +#define Y_CPUSTATES 2 +#define X_KERNEL 8 +#define Y_KERNEL 3 +#define X_MEM 8 +#define Y_MEM 3 +#define X_SWAP 6 +#define Y_SWAP 4 +#define Y_MESSAGE 4 +#define X_HEADER 0 +#define Y_HEADER 5 +#define X_IDLECURSOR 0 +#define Y_IDLECURSOR 4 +#define Y_PROCS 6 -#define y_cpustates 2 diff --git a/loadavg.h b/loadavg.h index f49541e7d907..c73fc7d28d93 100644 --- a/loadavg.h +++ b/loadavg.h @@ -1,4 +1,36 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * Top - a top users display for Berkeley Unix * * Defines required to access load average figures. diff --git a/m-template b/m-template deleted file mode 100644 index 569b0e0fccd2..000000000000 --- a/m-template +++ /dev/null @@ -1,241 +0,0 @@ -/* - * top - a top users display for Unix - * - * THIS IS A TEMPLATE FILE FOR A MACHINE DEPENDENT (m_...c) FILE - * - * SYNOPSIS: one line description of machine this module works with - * - * DESCRIPTION: - * Detailed description of this machine dependent module. - * It can be multiple lines, but a blank comment line (one with only an - * asterisk) is considered to end it. Place here a complete list of - * the machines and OS versions that this module works on. - * - * LIBS: list of special libraries to include at link step (REMOVE THIS LINE IF NOT NEEDED) - * - * AUTHOR: your name and <your@internet.address> - */ - -#include "top.h" -#include "machine.h" - - -/* - * These definitions control the format of the per-process area - */ - -static char header[] = - " PID X PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND"; -/* 0123456 -- field to fill in starts at header+6 */ -#define UNAME_START 6 - -#define Proc_format \ - "%5d %-8.8s %3d %4d%6dK %4dK %-5s%4d:%02d %5.2f%% %5.2f%% %.14s" - -/* these are for detailing the process states */ - -int process_states[?]; -char *procstatenames[] = { - "", " sleeping, ", " ABANDONED, ", " running, ", " starting, ", - " zombie, ", " stopped, ", - NULL -}; - -/* these are for detailing the cpu states */ - -int cpu_states[?]; -char *cpustatenames[] = { - "user", "nice", "system", "idle", - NULL -}; - -/* these are for detailing the memory statistics */ - -int memory_stats[?]; -char *memorynames[] = { - "K available, ", "K in use, ", "K free, ", "K locked", NULL -}; - -/* useful externals */ -extern int errno; -extern char *sys_errlist[]; - -long lseek(); -long time(); -long percentages(); - -machine_init(statics) - -struct statics *statics; - -{ - return(0); -} - -char *format_header(uname_field) - -register char *uname_field; - -{ - register char *ptr; - - ptr = header + UNAME_START; - while (*uname_field != '\0') - { - *ptr++ = *uname_field++; - } - - return(header); -} - -get_system_info(si) - -struct system_info *si; - -{ -} - -static struct handle handle; - -caddr_t get_process_info(si, sel, compare) - -struct system_info *si; -struct process_select *sel; -int (*compare)(); - -{ - return((caddr_t)&handle); -} - -char fmt[128]; /* static area where result is built */ - -/* define what weighted cpu is. */ -#define weighted_cpu(pct, pp) ((pp)->p_time == 0 ? 0.0 : \ - ((pct) / (1.0 - exp((pp)->p_time * logcpu)))) - -char *format_next_process(handle, get_userid) - -caddr_t handle; -char *(*get_userid)(); - -{ - return(fmt); -} - -/* - * getkval(offset, ptr, size, refstr) - get a value out of the kernel. - * "offset" is the byte offset into the kernel for the desired value, - * "ptr" points to a buffer into which the value is retrieved, - * "size" is the size of the buffer (and the object to retrieve), - * "refstr" is a reference string used when printing error meessages, - * if "refstr" starts with a '!', then a failure on read will not - * be fatal (this may seem like a silly way to do things, but I - * really didn't want the overhead of another argument). - * - */ - -getkval(offset, ptr, size, refstr) - -unsigned long offset; -int *ptr; -int size; -char *refstr; - -{ - if (kvm_read(kd, offset, ptr, size) != size) - { - if (*refstr == '!') - { - return(0); - } - else - { - fprintf(stderr, "top: kvm_read for %s: %s\n", - refstr, sys_errlist[errno]); - quit(23); - } - } - return(1); -} - -/* comparison routine for qsort */ -/* NOTE: this is specific to the BSD proc structure, but it should - give you a good place to start. */ - -/* - * proc_compare - comparison function for "qsort" - * Compares the resource consumption of two processes using five - * distinct keys. The keys (in descending order of importance) are: - * percent cpu, cpu ticks, state, resident set size, total virtual - * memory usage. The process states are ordered as follows (from least - * to most important): WAIT, zombie, sleep, stop, start, run. The - * array declaration below maps a process state index into a number - * that reflects this ordering. - */ - -static unsigned char sorted_state[] = -{ - 0, /* not used */ - 3, /* sleep */ - 1, /* ABANDONED (WAIT) */ - 6, /* run */ - 5, /* start */ - 2, /* zombie */ - 4 /* stop */ -}; - -proc_compare(pp1, pp2) - -struct proc **pp1; -struct proc **pp2; - -{ - register struct proc *p1; - register struct proc *p2; - register int result; - register pctcpu lresult; - - /* remove one level of indirection */ - p1 = *pp1; - p2 = *pp2; - - /* compare percent cpu (pctcpu) */ - if ((lresult = p2->p_pctcpu - p1->p_pctcpu) == 0) - { - /* use cpticks to break the tie */ - if ((result = p2->p_cpticks - p1->p_cpticks) == 0) - { - /* use process state to break the tie */ - if ((result = sorted_state[p2->p_stat] - - sorted_state[p1->p_stat]) == 0) - { - /* use priority to break the tie */ - if ((result = p2->p_pri - p1->p_pri) == 0) - { - /* use resident set size (rssize) to break the tie */ - if ((result = p2->p_rssize - p1->p_rssize) == 0) - { - /* use total memory to break the tie */ - result = PROCSIZE(p2) - PROCSIZE(p1); - } - } - } - } - } - else - { - result = lresult < 0 ? -1 : 1; - } - - return(result); -} - -proc_owner(pid) - -int pid; - -{ - /* returns uid of owner of process pid */ - return(uid); -} - diff --git a/m_freebsd.c b/m_freebsd.c new file mode 100644 index 000000000000..e26bca7688bf --- /dev/null +++ b/m_freebsd.c @@ -0,0 +1,1780 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * top - a top users display for Unix + * + * SYNOPSIS: For FreeBSD 5.x, 6.x, 7.x, 8.x + * + * DESCRIPTION: + * Originally written for BSD4.4 system by Christos Zoulas. + * Ported to FreeBSD 2.x by Steven Wallace && Wolfram Schneider + * Order support hacked in from top-3.5beta6/machine/m_aix41.c + * by Monte Mitzelfelt + * Ported to FreeBSD 5.x and higher by William LeFebvre + * + * AUTHOR: Christos Zoulas <christos@ee.cornell.edu> + * Steven Wallace <swallace@freebsd.org> + * Wolfram Schneider <wosch@FreeBSD.org> + */ + + +#include <sys/time.h> +#include <sys/types.h> +#include <sys/signal.h> +#include <sys/param.h> + +#include "config.h" +#include <stdio.h> +#include <string.h> +#include <nlist.h> +#include <math.h> +#include <kvm.h> +#include <pwd.h> +#include <sys/errno.h> +#include <sys/sysctl.h> +#include <sys/dkstat.h> +#include <sys/file.h> +#include <sys/time.h> +#include <sys/proc.h> +#include <sys/user.h> +#include <sys/vmmeter.h> +#include <sys/resource.h> +#include <sys/rtprio.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +/* Swap */ +#include <stdlib.h> +#include <sys/conf.h> + +#include <osreldate.h> /* for changes in kernel structures */ + +#include "top.h" +#include "machine.h" +#include "utils.h" +#include "username.h" +#include "hash.h" +#include "display.h" + +extern char* printable __P((char *)); +int swapmode __P((int *retavail, int *retfree)); +static int smpmode; +static int namelength; + +/* + * Versions prior to 5.x do not track threads in kinfo_proc, so we + * simply do not display any information about them. + * Versions 5.x, 6.x, and 7.x track threads but the data reported + * as runtime for each thread is actually per-process and is just + * duplicated across all threads. It would be very wrong to show + * this data individually for each thread. Therefore we will show + * a THR column (number of threads) but not provide any sort of + * per-thread display. We distinguish between these three ways of + * handling threads as follows: HAS_THREADS indicates that the + * system has and tracks kernel threads (a THR column will appear + * in the display). HAS_SHOWTHREADS indicates that the system + * reports correct per-thread information and we will provide a + * per-thread display (the 'H' and 't' command) upon request. + * HAS_SHOWTHREADS implies HAS_THREADS. + */ + +/* HAS_THREADS for anything 5.x and up */ +#if OSMAJOR >= 5 +#define HAS_THREADS +#endif + +/* HAS_SHOWTHREADS for anything 8.x and up */ +#if OSMAJOR >=8 +#define HAS_SHOWTHREADS +#endif + +/* get_process_info passes back a handle. This is what it looks like: */ + +struct handle +{ + struct kinfo_proc **next_proc; /* points to next valid proc pointer */ + int remaining; /* number of pointers remaining */ +}; + +/* declarations for load_avg */ +#include "loadavg.h" + +/* + * Macros to access process information: + * In versions 4.x and earlier the kinfo_proc structure was a collection of + * substructures (kp_proc and kp_eproc). Starting with 5.0 kinfo_proc was + * redesigned and "flattene" so that most of the information was available + * in a single structure. We use macros to access the various types of + * information and define these macros according to the OS revision. The + * names PP, EP, and VP are due to the fact that information was originally + * contained in the different substructures. We retain these names in the + * code for backward compatibility. These macros use ANSI concatenation. + * PP: proc + * EP: extented proc + * VP: vm (virtual memory information) + * PRUID: Real uid + * RP: rusage + * PPCPU: where we store calculated cpu% data + * SPPTR: where we store pointer to extra calculated data + * SP: access to the extra calculated data pointed to by SPPTR + */ +#if OSMAJOR <= 4 +#define PP(pp, field) ((pp)->kp_proc . p_##field) +#define EP(pp, field) ((pp)->kp_eproc . e_##field) +#define VP(pp, field) ((pp)->kp_eproc.e_vm . vm_##field) +#define PRUID(pp) ((pp)->kp_eproc.e_pcred.p_ruid) +#else +#define PP(pp, field) ((pp)->ki_##field) +#define EP(pp, field) ((pp)->ki_##field) +#define VP(pp, field) ((pp)->ki_##field) +#define PRUID(pp) ((pp)->ki_ruid) +#define RP(pp, field) ((pp)->ki_rusage.ru_##field) +#define PPCPU(pp) ((pp)->ki_sparelongs[0]) +#define SPPTR(pp) ((pp)->ki_spareptrs[0]) +#define SP(pp, field) (((struct save_proc *)((pp)->ki_spareptrs[0]))->sp_##field) +#endif + +/* what we consider to be process size: */ +#if OSMAJOR <= 4 +#define PROCSIZE(pp) (VP((pp), map.size) / 1024) +#else +#define PROCSIZE(pp) (((pp)->ki_size) / 1024) +#endif + +/* calculate a per-second rate using milliseconds */ +#define per_second(n, msec) (((n) * 1000) / (msec)) + +/* process state names for the "STATE" column of the display */ +/* the extra nulls in the string "run" are for adding a slash and + the processor number when needed */ + +char *state_abbrev[] = +{ + "?", "START", "RUN", "SLEEP", "STOP", "ZOMB", "WAIT", "LOCK" +}; +#define NUM_STATES 8 + +/* kernel access */ +static kvm_t *kd; + +/* these are for dealing with sysctl-based data */ +#define MAXMIBLEN 8 +struct sysctl_mib { + char *name; + int mib[MAXMIBLEN]; + size_t miblen; +}; +static struct sysctl_mib mibs[] = { + { "vm.stats.sys.v_swtch" }, +#define V_SWTCH 0 + { "vm.stats.sys.v_trap" }, +#define V_TRAP 1 + { "vm.stats.sys.v_intr" }, +#define V_INTR 2 + { "vm.stats.sys.v_soft" }, +#define V_SOFT 3 + { "vm.stats.vm.v_forks" }, +#define V_FORKS 4 + { "vm.stats.vm.v_vforks" }, +#define V_VFORKS 5 + { "vm.stats.vm.v_rforks" }, +#define V_RFORKS 6 + { "vm.stats.vm.v_vm_faults" }, +#define V_VM_FAULTS 7 + { "vm.stats.vm.v_swapin" }, +#define V_SWAPIN 8 + { "vm.stats.vm.v_swapout" }, +#define V_SWAPOUT 9 + { "vm.stats.vm.v_tfree" }, +#define V_TFREE 10 + { "vm.stats.vm.v_vnodein" }, +#define V_VNODEIN 11 + { "vm.stats.vm.v_vnodeout" }, +#define V_VNODEOUT 12 + { "vm.stats.vm.v_active_count" }, +#define V_ACTIVE_COUNT 13 + { "vm.stats.vm.v_inactive_count" }, +#define V_INACTIVE_COUNT 14 + { "vm.stats.vm.v_wire_count" }, +#define V_WIRE_COUNT 15 + { "vm.stats.vm.v_cache_count" }, +#define V_CACHE_COUNT 16 + { "vm.stats.vm.v_free_count" }, +#define V_FREE_COUNT 17 + { "vm.stats.vm.v_swappgsin" }, +#define V_SWAPPGSIN 18 + { "vm.stats.vm.v_swappgsout" }, +#define V_SWAPPGSOUT 19 + { "vfs.bufspace" }, +#define VFS_BUFSPACE 20 + { "kern.cp_time" }, +#define K_CP_TIME 21 +#ifdef HAS_SHOWTHREADS + { "kern.proc.all" }, +#else + { "kern.proc.proc" }, +#endif +#define K_PROC 22 + { NULL } +}; + + +/* these are for calculating cpu state percentages */ + +static long cp_time[CPUSTATES]; +static long cp_old[CPUSTATES]; +static long cp_diff[CPUSTATES]; + +/* these are for detailing the process states */ + +int process_states[8]; +char *procstatenames[] = { + "", " starting, ", " running, ", " sleeping, ", " stopped, ", " zombie, ", + " waiting, ", " locked, ", + NULL +}; + +/* these are for detailing the cpu states */ + +int cpu_states[CPUSTATES]; +char *cpustatenames[] = { + "user", "nice", "system", "interrupt", "idle", NULL +}; + +/* these are for detailing the kernel information */ + +int kernel_stats[9]; +char *kernelnames[] = { + " ctxsw, ", " trap, ", " intr, ", " soft, ", " fork, ", + " flt, ", " pgin, ", " pgout, ", " fr", + NULL +}; + +/* these are for detailing the memory statistics */ + +long memory_stats[7]; +char *memorynames[] = { + "K Active, ", "K Inact, ", "K Wired, ", "K Cache, ", "K Buf, ", "K Free", + NULL +}; + +long swap_stats[7]; +char *swapnames[] = { +/* 0 1 2 3 4 5 */ + "K Total, ", "K Used, ", "K Free, ", "% Inuse, ", "K In, ", "K Out", + NULL +}; + + +/* + * pbase points to the array that holds the kinfo_proc structures. pref + * (pronounced p-ref) points to an array of kinfo_proc pointers and is where + * we build up a list of processes we wish to display. Both pbase and pref are + * potentially resized on every call to get_process_info. psize is the number + * of procs for which we currently have space allocated. pref_len is the number + * of valid pointers in pref (this is used by proc_owner). We start psize off + * at -1 to ensure that space gets allocated on the first call to + * get_process_info. + */ + +static int psize = -1; +static int pref_len; +static struct kinfo_proc *pbase = NULL; +static struct kinfo_proc **pref = NULL; + +/* this structure retains information from the proc array between samples */ +struct save_proc { + pid_t sp_pid; + u_int64_t sp_runtime; + long sp_vcsw; + long sp_ivcsw; + long sp_inblock; + long sp_oublock; + long sp_majflt; + long sp_totalio; + long sp_old_nvcsw; + long sp_old_nivcsw; + long sp_old_inblock; + long sp_old_oublock; + long sp_old_majflt; +}; +hash_table *procs; + +struct proc_field { + char *name; + int width; + int rjust; + int min_screenwidth; + int (*format)(char *, int, struct kinfo_proc *); +}; + +/* these are for getting the memory statistics */ + +static int pagesize; /* kept from getpagesize */ +static int pageshift; /* log base 2 of the pagesize */ + +/* define pagetok in terms of pageshift */ + +#define pagetok(size) ((size) << pageshift) + +/* things that we track between updates */ +static u_int ctxsws = 0; +static u_int traps = 0; +static u_int intrs = 0; +static u_int softs = 0; +static u_int64_t forks = 0; +static u_int pfaults; +static u_int pagein; +static u_int pageout; +static u_int tfreed; +static int swappgsin = -1; +static int swappgsout = -1; +extern struct timeval timeout; +static struct timeval lasttime = { 0, 0 }; +static long elapsed_time; +static long elapsed_msecs; + +/* things that we track during an update */ +static long total_io; +static int show_fullcmd; +static struct handle handle; +static int username_length; +static int show_usernames; +static int display_mode; +static int *display_fields; +#ifdef HAS_SHOWTHREADS +static int show_threads = 0; +#endif + + +/* sorting orders. first is default */ +char *ordernames[] = { + "cpu", "size", "res", "time", "pri", "io", "pid", NULL +}; + +/* compare routines */ +int proc_compare(), compare_size(), compare_res(), compare_time(), + compare_prio(), compare_io(), compare_pid(); + +int (*proc_compares[])() = { + proc_compare, + compare_size, + compare_res, + compare_time, + compare_prio, + compare_io, + compare_pid, + NULL +}; + +/* swap related calculations */ + +static int mib_swapinfo[16]; +static int *mib_swapinfo_idx; +static int mib_swapinfo_size = 0; + +void +swap_init() + +{ + size_t m; + + m = sizeof(mib_swapinfo) / sizeof(mib_swapinfo[0]); + if (sysctlnametomib("vm.swap_info", mib_swapinfo, &m) != -1) + { + mib_swapinfo_size = m + 1; + mib_swapinfo_idx = &(mib_swapinfo[m]); + } +} + +int +swap_getdata(long long *retavail, long long *retfree) + +{ + int n; + size_t size; + long long total = 0; + long long used = 0; + struct xswdev xsw; + + n = 0; + if (mib_swapinfo_size > 0) + { + *mib_swapinfo_idx = 0; + while (size = sizeof(xsw), + sysctl(mib_swapinfo, mib_swapinfo_size, &xsw, &size, NULL, 0) != -1) + { + dprintf("swap_getdata: swaparea %d: nblks %d, used %d\n", + n, xsw.xsw_nblks, xsw.xsw_used); + total += (long long)xsw.xsw_nblks; + used += (long long)xsw.xsw_used; + *mib_swapinfo_idx = ++n; + } + + *retavail = pagetok(total); + *retfree = pagetok(total) - pagetok(used); + + if (total > 0) + { + n = (int)((double)used * 100.0 / (double)total); + } + else + { + n = 0; + } + } + else + { + *retavail = 0; + *retfree = 0; + } + + dprintf("swap_getdata: avail %lld, free %lld, %d%%\n", + *retavail, *retfree, n); + return(n); +} + +/* + * getkval(offset, ptr, size) - get a value out of the kernel. + * "offset" is the byte offset into the kernel for the desired value, + * "ptr" points to a buffer into which the value is retrieved, + * "size" is the size of the buffer (and the object to retrieve). + * Return 0 on success, -1 on any kind of failure. + */ + +static int +getkval(unsigned long offset, int *ptr, int size) + +{ + if (kd != NULL) + { + if (kvm_read(kd, offset, (char *) ptr, size) == size) + { + return(0); + } + } + return(-1); +} + +int +get_sysctl_mibs() + +{ + struct sysctl_mib *mp; + size_t len; + + mp = mibs; + while (mp->name != NULL) + { + len = MAXMIBLEN; + if (sysctlnametomib(mp->name, mp->mib, &len) == -1) + { + message_error(" sysctlnametomib: %s", strerror(errno)); + return -1; + } + mp->miblen = len; + mp++; + } + return 0; +} + +int +get_sysctl(int idx, void *v, size_t l) + +{ + struct sysctl_mib *m; + size_t len; + + m = &(mibs[idx]); + len = l; + if (sysctl(m->mib, m->miblen, v, &len, NULL, 0) == -1) + { + message_error(" sysctl: %s", strerror(errno)); + return -1; + } + return len; +} + +size_t +get_sysctlsize(int idx) + +{ + size_t len; + struct sysctl_mib *m; + + m = &(mibs[idx]); + if (sysctl(m->mib, m->miblen, NULL, &len, NULL, 0) == -1) + { + message_error(" sysctl (size): %s", strerror(errno)); + len = 0; + } + return len; +} + +int +fmt_pid(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%6d", PP(pp, pid)); +} + +int +fmt_username(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%-*.*s", + username_length, username_length, username(PRUID(pp))); +} + +int +fmt_uid(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%6d", PRUID(pp)); +} + +int +fmt_thr(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%3d", PP(pp, numthreads)); +} + +int +fmt_pri(char *buf, int sz, struct kinfo_proc *pp) + +{ +#if OSMAJOR <= 4 + return snprintf(buf, sz, "%3d", PP(pp, priority)); +#else + return snprintf(buf, sz, "%3d", PP(pp, pri.pri_level)); +#endif +} + +int +fmt_nice(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%4d", PP(pp, nice) - NZERO); +} + +int +fmt_size(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%5s", format_k(PROCSIZE(pp))); +} + +int +fmt_res(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%5s", format_k(pagetok(VP(pp, rssize)))); +} + +int +fmt_state(char *buf, int sz, struct kinfo_proc *pp) + +{ + int state; + char status[16]; + + state = PP(pp, stat); + switch(state) + { + case SRUN: + if (smpmode && PP(pp, oncpu) != 0xff) + sprintf(status, "CPU%d", PP(pp, oncpu)); + else + strcpy(status, "RUN"); + break; + + case SSLEEP: + if (EP(pp, wmesg) != NULL) { + sprintf(status, "%.6s", EP(pp, wmesg)); + break; + } + /* fall through */ + default: + if (state >= 0 && state < NUM_STATES) + sprintf(status, "%.6s", state_abbrev[(unsigned char) state]); + else + sprintf(status, "?%-5d", state); + break; + } + + return snprintf(buf, sz, "%-6.6s", status); +} + +int +fmt_flags(char *buf, int sz, struct kinfo_proc *pp) + +{ + long flag; + char chrs[12]; + char *p; + + flag = PP(pp, flag); + p = chrs; + if (PP(pp, nice) < NZERO) + *p++ = '<'; + else if (PP(pp, nice) > NZERO) + *p++ = 'N'; + if (flag & P_TRACED) + *p++ = 'X'; + if (flag & P_WEXIT && PP(pp, stat) != SZOMB) + *p++ = 'E'; + if (flag & P_PPWAIT) + *p++ = 'V'; + if (flag & P_SYSTEM || PP(pp, lock) > 0) + *p++ = 'L'; + if (PP(pp, kiflag) & KI_SLEADER) + *p++ = 's'; + if (flag & P_CONTROLT) + *p++ = '+'; + if (flag & P_JAILED) + *p++ = 'J'; + *p = '\0'; + + return snprintf(buf, sz, "%-3.3s", chrs); +} + +int +fmt_c(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%1x", PP(pp, lastcpu)); +} + +int +fmt_time(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%6s", + format_time((PP(pp, runtime) + 500000) / 1000000)); +} + +int +fmt_cpu(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%5.2f%%", (double)PPCPU(pp) / 100.0); +} + +int +fmt_command(char *buf, int sz, struct kinfo_proc *pp) + +{ + int inmem; + char cmd[MAX_COLS]; + char *bufp; + struct pargs pargs; + int len; + +#if OSMAJOR <= 4 + inmem = (PP(pp, flag) & P_INMEM); +#else + inmem = (PP(pp, sflag) & PS_INMEM); +#endif + + if (show_fullcmd && inmem) + { + /* get the pargs structure */ + if (getkval((unsigned long)PP(pp, args), (int *)&pargs, sizeof(pargs)) != -1) + { + /* determine workable length */ + if ((len = pargs.ar_length) >= MAX_COLS) + { + len = MAX_COLS - 1; + } + + /* get the string from that */ + if (len > 0 && getkval((unsigned long)PP(pp, args) + + sizeof(pargs.ar_ref) + + sizeof(pargs.ar_length), + (int *)cmd, len) != -1) + { + /* successfull retrieval: now convert nulls in to spaces */ + bufp = cmd; + while (len-- > 0) + { + if (*bufp == '\0') + { + *bufp = ' '; + } + bufp++; + } + + /* null terminate cmd */ + *--bufp = '\0'; + + /* format cmd as our answer */ + return snprintf(buf, sz, "%s", cmd); + } + } + } + + /* for anything else we just display comm */ + return snprintf(buf, sz, inmem ? "%s" : "<%s>", printable(PP(pp, comm))); +} + +int +fmt_vcsw(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%6ld", per_second(SP(pp, vcsw), elapsed_msecs)); +} + +int +fmt_ivcsw(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%6ld", per_second(SP(pp, ivcsw), elapsed_msecs)); +} + +int +fmt_read(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%6ld", per_second(SP(pp, inblock), elapsed_msecs)); +} + +int +fmt_write(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%6ld", per_second(SP(pp, oublock), elapsed_msecs)); +} + +int +fmt_fault(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%6ld", per_second(SP(pp, majflt), elapsed_msecs)); +} + +int +fmt_iototal(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%6ld", per_second(SP(pp, totalio), elapsed_msecs)); +} + +int +fmt_iopct(char *buf, int sz, struct kinfo_proc *pp) + +{ + return snprintf(buf, sz, "%6.2f", (SP(pp, totalio) * 100.) / total_io); +} + + +struct proc_field proc_field[] = { + { "PID", 6, 1, 0, fmt_pid }, + { "USERNAME", 8, 0, 0, fmt_username }, +#define FIELD_USERNAME 1 + { "UID", 6, 1, 0, fmt_uid }, +#define FIELD_UID 2 + { "THR", 3, 1, 0, fmt_thr }, + { "PRI", 3, 1, 0, fmt_pri }, + { "NICE", 4, 1, 0, fmt_nice }, + { "SIZE", 5, 1, 0, fmt_size }, + { "RES", 5, 1, 0, fmt_res }, + { "STATE", 6, 0, 0, fmt_state }, + { "FLG", 3, 0, 84, fmt_flags }, + { "C", 1, 0, 0, fmt_c }, + { "TIME", 6, 1, 0, fmt_time }, + { "CPU", 6, 1, 0, fmt_cpu }, + { "COMMAND", 7, 0, 0, fmt_command }, + { "VCSW", 6, 1, 0, fmt_vcsw }, + { "IVCSW", 6, 1, 0, fmt_ivcsw }, + { "READ", 6, 1, 0, fmt_read }, + { "WRITE", 6, 1, 0, fmt_write }, + { "FAULT", 6, 1, 0, fmt_fault }, + { "TOTAL", 6, 1, 0, fmt_iototal }, + { "PERCENT", 7, 1, 0, fmt_iopct }, + { NULL, 0, 0, 0, NULL } +}; +#define MAX_FIELDS 24 + +static int mode0_display[MAX_FIELDS]; +static int mode0thr_display[MAX_FIELDS]; +static int mode1_display[MAX_FIELDS]; + +int +field_index(char *col) + +{ + struct proc_field *fp; + int i = 0; + + fp = proc_field; + while (fp->name != NULL) + { + if (strcmp(col, fp->name) == 0) + { + return i; + } + fp++; + i++; + } + + return -1; +} + +void +field_subst(int *fp, int old, int new) + +{ + while (*fp != -1) + { + if (*fp == old) + { + *fp = new; + } + fp++; + } +} + +int +machine_init(struct statics *statics) + +{ + int i = 0; + size_t len; + int *ip; + + struct timeval boottime; + + len = sizeof(smpmode); + if ((sysctlbyname("machdep.smp_active", &smpmode, &len, NULL, 0) < 0 && + sysctlbyname("smp.smp_active", &smpmode, &len, NULL, 0) < 0) || + len != sizeof(smpmode)) + { + smpmode = 0; + } + smpmode = smpmode != 0; + + /* kvm_open the active kernel: its okay if this fails */ + kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL); + + /* get boot time */ + len = sizeof(boottime); + if (sysctlbyname("kern.boottime", &boottime, &len, NULL, 0) == -1) + { + /* we have no boottime to report */ + boottime.tv_sec = -1; + } + + pbase = NULL; + pref = NULL; + + /* get the page size with "getpagesize" and calculate pageshift from it */ + i = pagesize = getpagesize(); + pageshift = 0; + while (i > 1) + { + pageshift++; + i >>= 1; + } + + /* translate sysctl paths to mibs for faster access */ + get_sysctl_mibs(); + + /* initialize swap stuff */ + swap_init(); + + /* create the hash table that remembers proc data */ + procs = hash_create(2039); + + /* we only need the amount of log(2)1024 for our conversion */ + pageshift -= LOG1024; + + /* fill in the statics information */ + statics->procstate_names = procstatenames; + statics->cpustate_names = cpustatenames; + statics->memory_names = memorynames; + statics->kernel_names = kernelnames; + statics->boottime = boottime.tv_sec; + statics->swap_names = swapnames; + statics->order_names = ordernames; + statics->flags.warmup = 1; + statics->modemax = 2; +#ifdef HAS_SHOWTHREADS + statics->flags.threads = 1; +#endif + + /* we need kvm descriptor in order to show full commands */ + statics->flags.fullcmds = kd != NULL; + + /* set up the display indices for mode0 */ + ip = mode0_display; + *ip++ = field_index("PID"); + *ip++ = field_index("USERNAME"); +#ifdef HAS_THREADS + *ip++ = field_index("THR"); +#endif + *ip++ = field_index("PRI"); + *ip++ = field_index("NICE"); + *ip++ = field_index("SIZE"); + *ip++ = field_index("RES"); + *ip++ = field_index("STATE"); + *ip++ = field_index("FLG"); + if (smpmode) + *ip++ = field_index("C"); + *ip++ = field_index("TIME"); + *ip++ = field_index("CPU"); + *ip++ = field_index("COMMAND"); + *ip = -1; + +#ifdef HAS_SHOWTHREADS + /* set up the display indices for mode0 showing threads */ + ip = mode0thr_display; + *ip++ = field_index("PID"); + *ip++ = field_index("USERNAME"); + *ip++ = field_index("PRI"); + *ip++ = field_index("NICE"); + *ip++ = field_index("SIZE"); + *ip++ = field_index("RES"); + *ip++ = field_index("STATE"); + *ip++ = field_index("FLG"); + if (smpmode) + *ip++ = field_index("C"); + *ip++ = field_index("TIME"); + *ip++ = field_index("CPU"); + *ip++ = field_index("COMMAND"); + *ip = -1; +#endif + + /* set up the display indices for mode1 */ + ip = mode1_display; + *ip++ = field_index("PID"); + *ip++ = field_index("USERNAME"); + *ip++ = field_index("VCSW"); + *ip++ = field_index("IVCSW"); + *ip++ = field_index("READ"); + *ip++ = field_index("WRITE"); + *ip++ = field_index("FAULT"); + *ip++ = field_index("TOTAL"); + *ip++ = field_index("PERCENT"); + *ip++ = field_index("COMMAND"); + *ip = -1; + + /* all done! */ + return(0); +} + +char *format_header(char *uname_field) + +{ + return ""; +} + +void +get_vm_sum(struct vmmeter *sum) + +{ +#define GET_VM_STAT(v, s) (void)get_sysctl(v, &(sum->s), sizeof(sum->s)) + + GET_VM_STAT(V_SWTCH, v_swtch); + GET_VM_STAT(V_TRAP, v_trap); + GET_VM_STAT(V_INTR, v_intr); + GET_VM_STAT(V_SOFT, v_soft); + GET_VM_STAT(V_VFORKS, v_vforks); + GET_VM_STAT(V_FORKS, v_forks); + GET_VM_STAT(V_RFORKS, v_rforks); + GET_VM_STAT(V_VM_FAULTS, v_vm_faults); + GET_VM_STAT(V_SWAPIN, v_swapin); + GET_VM_STAT(V_SWAPOUT, v_swapout); + GET_VM_STAT(V_TFREE, v_tfree); + GET_VM_STAT(V_VNODEIN, v_vnodein); + GET_VM_STAT(V_VNODEOUT, v_vnodeout); + GET_VM_STAT(V_ACTIVE_COUNT, v_active_count); + GET_VM_STAT(V_INACTIVE_COUNT, v_inactive_count); + GET_VM_STAT(V_WIRE_COUNT, v_wire_count); + GET_VM_STAT(V_CACHE_COUNT, v_cache_count); + GET_VM_STAT(V_FREE_COUNT, v_free_count); + GET_VM_STAT(V_SWAPPGSIN, v_swappgsin); + GET_VM_STAT(V_SWAPPGSOUT, v_swappgsout); +} + +void +get_system_info(struct system_info *si) + +{ + long total; + struct timeval thistime; + struct timeval timediff; + + /* timestamp and time difference */ + gettimeofday(&thistime, 0); + timersub(&thistime, &lasttime, &timediff); + elapsed_time = timediff.tv_sec * 1000000 + timediff.tv_usec; + elapsed_msecs = timediff.tv_sec * 1000 + timediff.tv_usec / 1000; + + /* get the load averages */ + if (getloadavg(si->load_avg, NUM_AVERAGES) == -1) + { + /* failed: fill in with zeroes */ + (void) memset(si->load_avg, 0, sizeof(si->load_avg)); + } + + /* get the cp_time array */ + (void)get_sysctl(K_CP_TIME, &cp_time, sizeof(cp_time)); + + /* convert cp_time counts to percentages */ + total = percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff); + + /* sum memory & swap statistics */ + { + struct vmmeter sum; + static unsigned int swap_delay = 0; + static long long swapavail = 0; + static long long swapfree = 0; + static int bufspace = 0; + + get_vm_sum(&sum); + + /* get bufspace */ + bufspace = 0; + (void) get_sysctl(VFS_BUFSPACE, &bufspace, sizeof(bufspace)); + + /* kernel stats */ + dprintf("kernel: swtch %d, trap %d, intr %d, soft %d, vforks %d\n", + sum.v_swtch, sum.v_trap, sum.v_intr, sum.v_soft, sum.v_vforks); + kernel_stats[0] = per_second(sum.v_swtch - ctxsws, elapsed_msecs); + kernel_stats[1] = per_second(sum.v_trap - traps, elapsed_msecs); + kernel_stats[2] = per_second(sum.v_intr - intrs, elapsed_msecs); + kernel_stats[3] = per_second(sum.v_soft - softs, elapsed_msecs); + kernel_stats[4] = per_second(sum.v_vforks + sum.v_forks + + sum.v_rforks - forks, elapsed_msecs); + kernel_stats[5] = per_second(sum.v_vm_faults - pfaults, elapsed_msecs); + kernel_stats[6] = per_second(sum.v_swapin + sum.v_vnodein - pagein, elapsed_msecs); + kernel_stats[7] = per_second(sum.v_swapout + sum.v_vnodeout - pageout, elapsed_msecs); + kernel_stats[8] = per_second(sum.v_tfree - tfreed, elapsed_msecs); + ctxsws = sum.v_swtch; + traps = sum.v_trap; + intrs = sum.v_intr; + softs = sum.v_soft; + forks = (u_int64_t)sum.v_vforks + sum.v_forks + sum.v_rforks; + pfaults = sum.v_vm_faults; + pagein = sum.v_swapin + sum.v_vnodein; + pageout = sum.v_swapout + sum.v_vnodeout; + tfreed = sum.v_tfree; + + /* convert memory stats to Kbytes */ + memory_stats[0] = pagetok(sum.v_active_count); + memory_stats[1] = pagetok(sum.v_inactive_count); + memory_stats[2] = pagetok(sum.v_wire_count); + memory_stats[3] = pagetok(sum.v_cache_count); + memory_stats[4] = bufspace / 1024; + memory_stats[5] = pagetok(sum.v_free_count); + memory_stats[6] = -1; + + /* first interval */ + if (swappgsin < 0) + { + swap_stats[4] = 0; + swap_stats[5] = 0; + } + + /* compute differences between old and new swap statistic */ + else + { + swap_stats[4] = pagetok(sum.v_swappgsin - swappgsin); + swap_stats[5] = pagetok(sum.v_swappgsout - swappgsout); + } + + swappgsin = sum.v_swappgsin; + swappgsout = sum.v_swappgsout; + + /* call CPU heavy swap_getdata() only for changes */ + if (swap_stats[4] > 0 || swap_stats[5] > 0 || swap_delay == 0) + { + swap_stats[3] = swap_getdata(&swapavail, &swapfree); + swap_stats[0] = swapavail; + swap_stats[1] = swapavail - swapfree; + swap_stats[2] = swapfree; + } + swap_delay = 1; + swap_stats[6] = -1; + } + + /* set arrays and strings */ + si->cpustates = cpu_states; + si->kernel = kernel_stats; + si->memory = memory_stats; + si->swap = swap_stats; + + si->last_pid = -1; + + lasttime = thistime; +} + +caddr_t +get_process_info(struct system_info *si, + struct process_select *sel, + int compare_index) + +{ + int i; + int total_procs; + int active_procs; + struct kinfo_proc **prefp; + struct kinfo_proc *pp; + struct kinfo_proc *prev_pp = NULL; + struct save_proc *savep; + long proc_io; + pid_t pid; + size_t size; + int nproc; + + /* these are copied out of sel for speed */ + int show_idle; + int show_self; + int show_system; + int show_uid; + char *show_command; + + /* get proc table size and give it a boost */ + nproc = (int)get_sysctlsize(K_PROC) / sizeof(struct kinfo_proc); + nproc += nproc >> 4; + size = nproc * sizeof(struct kinfo_proc); + dprintf("get_process_info: nproc %d, psize %d, size %d\n", nproc, psize, size); + + /* make sure we have enough space allocated */ + if (nproc > psize) + { + /* reallocate both pbase and pref */ + pbase = (struct kinfo_proc *)realloc(pbase, size); + pref = (struct kinfo_proc **)realloc(pref, + sizeof(struct kinfo_proc *) * nproc); + psize = nproc; + } + + /* make sure we got the space we asked for */ + if (pref == NULL || pbase == NULL) + { + /* abandon all hope */ + message_error(" Out of memory!"); + nproc = psize = 0; + si->p_total = 0; + si->p_active = 0; + return NULL; + } + + /* get all process information (threads, too) */ + if (size > 0) + { + nproc = get_sysctl(K_PROC, pbase, size); + if (nproc == -1) + { + nproc = 0; + } + else + { + nproc /= sizeof(struct kinfo_proc); + } + } + + /* get a pointer to the states summary array */ + si->procstates = process_states; + + /* set up flags which define what we are going to select */ + show_idle = sel->idle; + show_self = 0; + show_system = sel->system; + show_uid = sel->uid != -1; + show_fullcmd = sel->fullcmd; + show_command = sel->command; + show_usernames = sel->usernames; + display_mode = sel->mode; +#ifdef HAS_SHOWTHREADS + show_threads = sel->threads; +#endif + + /* count up process states and get pointers to interesting procs */ + total_procs = 0; + active_procs = 0; + total_io = 0; + memset((char *)process_states, 0, sizeof(process_states)); + prefp = pref; + for (pp = pbase, i = 0; i < nproc; pp++, i++) + { + /* + * Place pointers to each valid proc structure in pref[]. + * Process slots that are actually in use have a non-zero + * status field. Processes with P_SYSTEM set are system + * processes---these get ignored unless show_sysprocs is set. + */ + pid = PP(pp, pid); + if (PP(pp, stat) != 0) + { +#ifdef HAS_SHOWTHREADS + int is_thread; + lwpid_t tid; + + /* get thread id */ + tid = PP(pp, tid); + + /* is this just a thread? */ + is_thread = (prev_pp != NULL && PP(prev_pp, pid) == pid); + + /* count this process and its state */ + /* only count threads if we are showing them */ + if (show_threads || !is_thread) + { + total_procs++; + process_states[(unsigned char) PP(pp, stat)]++; + } + + /* grab old data from hash */ + if ((savep = hash_lookup_lwpid(procs, tid)) != NULL) + { + /* verify that this is not a new or different thread */ + /* (freebsd reuses thread ids fairly quickly) */ + /* pids must match and time can't have gone backwards */ + if (pid != savep->sp_pid || PP(pp, runtime) < savep->sp_runtime) + { + /* not the same thread -- reuse the save_proc structure */ + memset(savep, 0, sizeof(struct save_proc)); + savep->sp_pid = pid; + } + } + else + { + /* havent seen this one before */ + savep = (struct save_proc *)calloc(1, sizeof(struct save_proc)); + savep->sp_pid = pid; + hash_add_lwpid(procs, tid, savep); + } + +#else /* !HAS_SHOWTHREADS */ + total_procs++; + process_states[(unsigned char) PP(pp, stat)]++; + + /* grab old data from hash */ + if ((savep = hash_lookup_pid(procs, pid)) == NULL) + { + /* havent seen this one before */ + savep = (struct save_proc *)calloc(1, sizeof(struct save_proc)); + savep->sp_pid = pid; + hash_add_pid(procs, pid, savep); + } +#endif + + /* save the pointer to the sp struct */ + SPPTR(pp) = (void *)savep; + + /* calculate %cpu */ + PPCPU(pp) = ((PP(pp, runtime) - savep->sp_runtime) * 10000) / + elapsed_time; + dprintf("%d (%d): runtime %lld, saved_pid %d, saved_runtime %lld, elapsed_time %d, ppcpu %d\n", + pid, PP(pp, tid), PP(pp, runtime), savep->sp_pid, savep->sp_runtime, + elapsed_time, PPCPU(pp)); + + /* calculate io differences */ + proc_io = 0; + savep->sp_vcsw = (RP(pp, nvcsw) - savep->sp_old_nvcsw); + savep->sp_ivcsw = (RP(pp, nivcsw) - savep->sp_old_nivcsw); + proc_io += (savep->sp_inblock = (RP(pp, inblock) - savep->sp_old_inblock)); + proc_io += (savep->sp_oublock = (RP(pp, oublock) - savep->sp_old_oublock)); + proc_io += (savep->sp_majflt = (RP(pp, majflt) - savep->sp_old_majflt)); + total_io += proc_io; + savep->sp_totalio = proc_io; + + /* save data for next time */ + savep->sp_runtime = PP(pp, runtime); + savep->sp_old_nvcsw = RP(pp, nvcsw); + savep->sp_old_nivcsw = RP(pp, nivcsw); + savep->sp_old_inblock = RP(pp, inblock); + savep->sp_old_oublock = RP(pp, oublock); + savep->sp_old_majflt = RP(pp, majflt); + + /* is this one selected for viewing? */ + if ((PP(pp, stat) != SZOMB) && + (show_system || ((PP(pp, flag) & P_SYSTEM) == 0)) && + (show_idle || (PP(pp, pctcpu) != 0) || + (PP(pp, stat) == SRUN)) && + (!show_uid || PRUID(pp) == (uid_t)sel->uid) && + (show_command == NULL || + strcasestr(PP(pp, comm), show_command) != NULL)) + { +#ifdef HAS_SHOWTHREADS + /* yes, but make sure it isn't just a thread */ + if (show_threads || !is_thread) + { + /* we will be showing this thread */ + *prefp++ = pp; + active_procs++; + } + else + { + /* we will not be showing this thread, but we need to roll + up its cpu usage in to its process */ + PP(prev_pp, pctcpu) += PP(pp, pctcpu); + } +#else /* !HAS_SHOWTHREADS */ + /* we will be showing this process */ + *prefp++ = pp; + active_procs++; +#endif + } + prev_pp = pp; + } + } + + dprintf("total_io: %d\n", total_io); + if (total_io == 0) total_io = 1; + + /* if requested, sort the "interesting" processes */ + if (active_procs > 1) + { + qsort((char *)pref, active_procs, sizeof(struct kinfo_proc *), + proc_compares[compare_index]); + } + + /* remember active and total counts */ + si->p_total = total_procs; + si->p_active = pref_len = active_procs; + + /* pass back a handle */ + handle.next_proc = pref; + handle.remaining = active_procs; + return((caddr_t)&handle); +} + +static char p_header[MAX_COLS]; + +char * +format_process_header(struct process_select *sel, caddr_t handle, int count) + +{ + int cols; + int n; + int w; + char *p; + int *fi; + struct kinfo_proc **kip; + struct proc_field *fp; + + /* check for null handle */ + if (handle == NULL) + { + return(""); + } + + /* remember how many columns there are on the display */ + cols = display_columns(); + + /* mode & threads dictate format */ + fi = display_fields = + sel->mode == 0 ? + (sel->threads == 0 ? mode0_display : mode0thr_display) : + mode1_display; + + /* set username field correctly */ + if (!sel->usernames) + { + /* display uids */ + field_subst(fi, FIELD_USERNAME, FIELD_UID); + } + else + { + /* display usernames */ + field_subst(fi, FIELD_UID, FIELD_USERNAME); + + /* we also need to determine the longest username for column width */ + /* calculate namelength from first "count" processes */ + kip = ((struct handle *)handle)->next_proc; + n = ((struct handle *)handle)->remaining; + if (n > count) + n = count; + namelength = 0; + while (n-- > 0) + { + w = strlen(username(PRUID(*kip))); + if (w > namelength) namelength = w; + kip++; + } + dprintf("format_process_header: namelength %d\n", namelength); + + /* place it in bounds */ + if (namelength < 8) + { + namelength = 8; + } + + /* set the column width */ + proc_field[FIELD_USERNAME].width = username_length = namelength; + } + + /* walk thru fields and construct header */ + /* are we worried about overflow??? */ + p = p_header; + while (*fi != -1) + { + fp = &(proc_field[*fi++]); + if (fp->min_screenwidth <= cols) + { + p += sprintf(p, fp->rjust ? "%*s" : "%-*s", fp->width, fp->name); + *p++ = ' '; + } + } + *--p = '\0'; + + return p_header; +} + +static char fmt[MAX_COLS]; /* static area where result is built */ + +char * +format_next_process(caddr_t handle, char *(*get_userid)(int)) + +{ + struct kinfo_proc *pp; + struct handle *hp; + struct proc_field *fp; + int *fi; + int i; + int cols; + char *p; + int len; + int x; + + /* find and remember the next proc structure */ + hp = (struct handle *)handle; + pp = *(hp->next_proc++); + hp->remaining--; + + /* mode & threads dictate format */ + fi = display_fields; + + /* screen width is a consideration, too */ + cols = display_columns(); + + /* build output by field */ + p = fmt; + len = MAX_COLS; + while ((i = *fi++) != -1) + { + fp = &(proc_field[i]); + if (len > 0 && fp->min_screenwidth <= cols) + { + x = (*(fp->format))(p, len, pp); + if (x >= len) + { + dprintf("format_next_process: formatter overflow: x %d, len %d, p %08x => %08x, fmt %08x - %08x\n", + x, len, p, p + len, fmt, fmt + sizeof(fmt)); + p += len; + len = 0; + } + else + { + p += x; + *p++ = ' '; + len -= x + 1; + } + } + } + *--p = '\0'; + + /* return the result */ + return(fmt); +} + +/* comparison routines for qsort */ + +/* + * proc_compare - comparison function for "qsort" + * Compares the resource consumption of two processes using five + * distinct keys. The keys (in descending order of importance) are: + * percent cpu, cpu ticks, state, resident set size, total virtual + * memory usage. The process states are ordered as follows (from least + * to most important): WAIT, zombie, sleep, stop, start, run. The + * array declaration below maps a process state index into a number + * that reflects this ordering. + */ + +static unsigned char sorted_state[] = +{ + 0, /* not used */ + 3, /* sleep */ + 1, /* ABANDONED (WAIT) */ + 6, /* run */ + 5, /* start */ + 2, /* zombie */ + 4 /* stop */ +}; + + +#define ORDERKEY_PCTCPU \ + if (lresult = (long) PPCPU(p2) - (long) PPCPU(p1), \ + (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) + +#define ORDERKEY_CPTICKS \ + if ((result = PP(p2, runtime) > PP(p1, runtime) ? 1 : \ + PP(p2, runtime) < PP(p1, runtime) ? -1 : 0) == 0) + +#define ORDERKEY_STATE \ + if ((result = sorted_state[(unsigned char) PP(p2, stat)] - \ + sorted_state[(unsigned char) PP(p1, stat)]) == 0) + +#if OSMAJOR <= 4 +#define ORDERKEY_PRIO \ + if ((result = PP(p2, priority) - PP(p1, priority)) == 0) +#else +#define ORDERKEY_PRIO \ + if ((result = PP(p2, pri.pri_level) - PP(p1, pri.pri_level)) == 0) +#endif + +#define ORDERKEY_RSSIZE \ + if ((result = VP(p2, rssize) - VP(p1, rssize)) == 0) + +#define ORDERKEY_MEM \ + if ( (result = PROCSIZE(p2) - PROCSIZE(p1)) == 0 ) + +#define ORDERKEY_IO \ + if ( (result = SP(p2, totalio) - SP(p1, totalio)) == 0) + +#define ORDERKEY_PID \ + if ( (result = PP(p1, pid) - PP(p2, pid)) == 0) + +/* compare_cpu - the comparison function for sorting by cpu percentage */ + +int +proc_compare(struct proc **pp1, struct proc **pp2) + +{ + struct kinfo_proc *p1; + struct kinfo_proc *p2; + int result; + pctcpu lresult; + + /* remove one level of indirection */ + p1 = *(struct kinfo_proc **) pp1; + p2 = *(struct kinfo_proc **) pp2; + + ORDERKEY_PCTCPU + ORDERKEY_CPTICKS + ORDERKEY_STATE + ORDERKEY_PRIO + ORDERKEY_RSSIZE + ORDERKEY_MEM + ; + + return(result); +} + +/* compare_size - the comparison function for sorting by total memory usage */ + +int +compare_size(struct proc **pp1, struct proc **pp2) + +{ + struct kinfo_proc *p1; + struct kinfo_proc *p2; + int result; + pctcpu lresult; + + /* remove one level of indirection */ + p1 = *(struct kinfo_proc **) pp1; + p2 = *(struct kinfo_proc **) pp2; + + ORDERKEY_MEM + ORDERKEY_RSSIZE + ORDERKEY_PCTCPU + ORDERKEY_CPTICKS + ORDERKEY_STATE + ORDERKEY_PRIO + ; + + return(result); +} + +/* compare_res - the comparison function for sorting by resident set size */ + +int +compare_res(struct proc **pp1, struct proc **pp2) + +{ + struct kinfo_proc *p1; + struct kinfo_proc *p2; + int result; + pctcpu lresult; + + /* remove one level of indirection */ + p1 = *(struct kinfo_proc **) pp1; + p2 = *(struct kinfo_proc **) pp2; + + ORDERKEY_RSSIZE + ORDERKEY_MEM + ORDERKEY_PCTCPU + ORDERKEY_CPTICKS + ORDERKEY_STATE + ORDERKEY_PRIO + ; + + return(result); +} + +/* compare_time - the comparison function for sorting by total cpu time */ + +int +compare_time(struct proc **pp1, struct proc **pp2) + +{ + struct kinfo_proc *p1; + struct kinfo_proc *p2; + int result; + pctcpu lresult; + + /* remove one level of indirection */ + p1 = *(struct kinfo_proc **) pp1; + p2 = *(struct kinfo_proc **) pp2; + + ORDERKEY_CPTICKS + ORDERKEY_PCTCPU + ORDERKEY_STATE + ORDERKEY_PRIO + ORDERKEY_RSSIZE + ORDERKEY_MEM + ; + + return(result); + } + +/* compare_prio - the comparison function for sorting by priority */ + +int +compare_prio(struct proc **pp1, struct proc **pp2) + +{ + struct kinfo_proc *p1; + struct kinfo_proc *p2; + int result; + pctcpu lresult; + + /* remove one level of indirection */ + p1 = *(struct kinfo_proc **) pp1; + p2 = *(struct kinfo_proc **) pp2; + + ORDERKEY_PRIO + ORDERKEY_CPTICKS + ORDERKEY_PCTCPU + ORDERKEY_STATE + ORDERKEY_RSSIZE + ORDERKEY_MEM + ; + + return(result); +} + +/* compare_io - the comparison function for sorting by io count */ + +int +compare_io(struct proc **pp1, struct proc **pp2) + +{ + struct kinfo_proc *p1; + struct kinfo_proc *p2; + int result; + pctcpu lresult; + + /* remove one level of indirection */ + p1 = *(struct kinfo_proc **) pp1; + p2 = *(struct kinfo_proc **) pp2; + + ORDERKEY_IO + ORDERKEY_PCTCPU + ORDERKEY_CPTICKS + ORDERKEY_STATE + ORDERKEY_PRIO + ORDERKEY_RSSIZE + ORDERKEY_MEM + ; + + return(result); +} + +/* compare_pid - the comparison function for sorting by process id */ + +int +compare_pid(struct proc **pp1, struct proc **pp2) + +{ + struct kinfo_proc *p1; + struct kinfo_proc *p2; + int result; + + /* remove one level of indirection */ + p1 = *(struct kinfo_proc **) pp1; + p2 = *(struct kinfo_proc **) pp2; + + ORDERKEY_PID + ; + + return(result); +} + +/* + * proc_owner(pid) - returns the uid that owns process "pid", or -1 if + * the process does not exist. + * It is EXTREMLY IMPORTANT that this function work correctly. + * If top runs setuid root (as in SVR4), then this function + * is the only thing that stands in the way of a serious + * security problem. It validates requests for the "kill" + * and "renice" commands. + */ + +int +proc_owner(int pid) + +{ + int cnt; + struct kinfo_proc **prefp; + struct kinfo_proc *pp; + + prefp = pref; + cnt = pref_len; + while (--cnt >= 0) + { + pp = *prefp++; + if (PP(pp, pid) == (pid_t)pid) + { + return((int)PRUID(pp)); + } + } + return(-1); +} + diff --git a/m_freebsd.man b/m_freebsd.man new file mode 100644 index 000000000000..0acafea17f2a --- /dev/null +++ b/m_freebsd.man @@ -0,0 +1,134 @@ +.SH "FreeBSD NOTES" +Priorities are shown the same as they exist in process data structures, +ranging from 0 to 255. Note that this is not the same as the ps(1) +\*(lqpri\*(rq column, which subtracts 84 from each number before displaying +it. Priority numbers fall in to priority classes as follows: +.TP 15 +0 \- 63 +Interrupt threads +.TP 15 +64 \- 127 +Top half kernel threads +.TP 15 +128 \- 159 +Realtime user threads +.TP 15 +160 \- 223 +Time sharing user threads +.TP 15 +224 \- 255 +Idle user threads + +.SH "FreeBSD THREADS" +Starting with FreeBSD 8.0 the display of individual threads can be +toggled with the synonymous commands +.B t +and +.BR H. +Information about state, flags, CPU time and percent cpu are shown +for each individual thread. Other information is identical for all +threads in the same process. + +.SH "FreeBSD ALTERNATE DISPLAY" +FreeBSD supports an alternate process display which shows i/o +information. Since this information is tracked per process and not +per thread, the per-thread display is not supported in this mode. +All fields calculate the number of operations observed since the +last update and are displayed as a per-second rate. +The fields in this display are as follows: +.TP +.B VCSW +Voluntary context switches +.TP +.B IVCSW +Involuntary context switches +.TP +.B READ +Number of blocks read +.TP +.B WRITE +Number of blocks written +.TP +.B FAULT +Number of page faults +.TP +.B TOTAL +Total number of i/o operations +.TP +.B PERCENT +Percentage of total i/o attributed to this process. If no i/o occured +then this field is 0 for all processes. + +.SH "FreeBSD KERNEL SUMMARY" +All rates are shown per-second. +.TP +.B Ctx +Number of context switches. +.TP +.B Trap +Number of kernel traps. +.TP +.B Intr +Number of device interrupts. +.TP +.B Soft +Number of software interrupts. +.TP +.B Fork +Number of forks, vforks, and rforks. +.TP +.B Flt +Total number of page faults. +.TP +.B Pgin +Number of pages paged or swapped in to physical memory. +.TP +.B Pgout +Number of pages paged or swapped out from physical memory. +.TP +.B Fr +Total number of pages freed. +.SH "FreeBSD MEMORY SUMMARY" +Memory: 10M Act 1208K Inact 3220K Wired 132K Free 25% Swap, 2924Kin 2604Kout +.TP +.B K: +Kilobyte +.TP +.B M: +Megabyte +.TP +.B G: +Gigabyte +.TP +.B %: +1/100 + +.TP +.B Act: +number of pages active +.TP +.B Inact: +number of pages inactive +.TP +.B Wired: +number of pages wired down +.TP +.B Free: +number of pages free +.TP +.B Swap: +swap usage +.TP +.B Kin: +kilobytes swap pager pages paged in (last interval) +.TP +.B Kout: +kilobytes swap pager pages paged out (last interval) +.PP + +See /usr/include/sys/vmmeter.h and /sys/vm/vm_meter.c. +.PP +Contributors: Christos Zoulas, Steven Wallace, Wolfram Schneider, +Monte Mitzelfelt. +.PP +This module was retrofitted from FreeBSD 4.6.2 sources. diff --git a/machine.h b/machine.h index 0a356a4fa80d..f727d3b08418 100644 --- a/machine.h +++ b/machine.h @@ -1,20 +1,67 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * This file defines the interface between top and the machine-dependent * module. It is NOT machine dependent and should not need to be changed * for any specific machine. */ +#ifndef _MACHINE_H_ +#define _MACHINE_H_ + +#include "top.h" + /* - * the statics struct is filled in by machine_init + * The statics struct is filled in by machine_init. Fields marked as + * "optional" are not filled in by every module. */ struct statics { char **procstate_names; char **cpustate_names; char **memory_names; -#ifdef ORDER - char **order_names; -#endif + char **swap_names; /* optional */ + char **order_names; /* optional */ + char **top_color_names; /* optional */ + char **kernel_names; /* optional */ + time_t boottime; /* optional */ + int modemax; /* optional */ + struct { + unsigned int fullcmds : 1; + unsigned int idle : 1; + unsigned int warmup : 1; + unsigned int threads : 1; + } flags; }; /* @@ -35,7 +82,9 @@ struct system_info int P_ACTIVE; /* number of procs considered "active" */ int *procstates; int *cpustates; - int *memory; + int *kernel; + long *memory; + long *swap; }; /* cpu_states is an array of percentages * 10. For example, @@ -51,14 +100,23 @@ struct process_select { int idle; /* show idle processes */ int system; /* show system processes */ + int fullcmd; /* show full command */ + int usernames; /* show usernames */ int uid; /* only this uid (unless uid == -1) */ char *command; /* only this command (unless == NULL) */ + int mode; /* select display mode (0 is default) */ + int threads; /* show threads separately */ }; /* routines defined by the machine dependent module */ +int machine_init(struct statics *); +void get_system_info(struct system_info *); +caddr_t get_process_info(struct system_info *, struct process_select *, int); +char *format_header(char *); +char *format_next_process(caddr_t, char *(*)(int)); +int proc_owner(int); +#ifdef HAVE_FORMAT_PROCESS_HEADER -char *format_header(); -char *format_next_process(); - -/* non-int routines typically used by the machine dependent module */ -char *printable(); +#endif /* _MACHINE_H_ */ +char *format_process_header(struct process_select *sel, caddr_t handle, int count); +#endif diff --git a/message.h b/message.h new file mode 100644 index 000000000000..f8a50b2ce3c6 --- /dev/null +++ b/message.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* interface declaration for display messages */ +/* This is a small subset of the interface from display.c that + just contains the calls for displaying messages. Do not include + this and display.h at the same time. */ + +#ifndef _MESSAGE_H +#define _MESSAGE_H + +void error_message(char *msgfmt, ...); +void clear_message(); + +#endif /* _MESSAGE_H_ */ diff --git a/metatop b/metatop deleted file mode 100755 index 88a787c34f82..000000000000 --- a/metatop +++ /dev/null @@ -1,25 +0,0 @@ -#! /bin/sh -# -# Top is very sensitive to differences in the kernel, so much so that an -# executable created on one sub-architecture may not work on others. It -# is also quite common for a minor OS revision to require recompilation of -# top. Both of these problems are especially prevalent on Suns. For -# example, a top executable made under SunOS 4.1.1 will not run correctly -# under SunOS 4.1.2, and vice versa. "metatop" attempts to solve this -# problem by choosing one of several possible top executables to run then -# executing it. -# -# To use metatop your operating system needs to have the command "uname" -# as part of the standard OS release. MAKE SURE IT DOES before proceeding. -# It will try to execute the command "top-`uname -m`-`uname -r`" For -# example, on a sparcstation 1 running SunOS 4.1.1, it will try to run -# "top-sun4c-4.1.1". -# -# INSTALLATION is easy. Just compile top as normal. Then use the command -# "make metainstall" (on the same machine!) instead of the usual. "make" -# will insure that this shell script is installed correctly then will install -# the most recently made top executable with the correct name. Remember: -# you will need to "make clean" and "make metainstall" on every different -# combination of sub-architecture and OS version that you have. -# -exec $0-`uname -m`-`uname -r` "$@" @@ -1,38 +1,143 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + #include <sys/types.h> -#include <sys/param.h> /* This defines BSD */ -#if defined(BSD) && !defined(BSD4_4) && !defined(__osf__) -# include <stdio.h> -# include <strings.h> -# define strchr(a, b) index((a), (b)) -# define strrchr(a, b) rindex((a), (b)) -# define memcpy(a, b, c) bcopy((b), (a), (c)) -# define memzero(a, b) bzero((a), (b)) -# define memcmp(a, b, c) bcmp((a), (b), (c)) -#if defined(NeXT) - typedef void sigret_t; +#include <sys/param.h> +#include <stdio.h> + +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> #else - typedef int sigret_t; +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif #endif -/* system routines that don't return int */ +#if STDC_HEADERS +#include <string.h> +#include <stdlib.h> +#define setbuffer(f, b, s) setvbuf((f), (b), (b) ? _IOFBF : _IONBF, (s)) +#define memzero(a, b) memset((a), 0, (b)) +#else /* !STDC_HEADERS */ +#ifndef HAVE_STRCHR +#define strchr(a, b) index((a), (b)) +#define strrchr(a, b) rindex((a), (b)) +#endif /* HAVE_STRCHR */ +#ifdef HAVE_MEMCPY +#define memzero(a, b) memset((a), 0, (b)) +#else +#define memcpy(a, b, c) bcopy((b), (a), (c)) +#define memzero(a, b) bzero((a), (b)) +#define memcmp(a, b, c) bcmp((a), (b), (c)) +#endif /* HAVE_MEMCPY */ +#ifdef HAVE_STRINGS_H +#include <strings.h> +#else +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#endif char *getenv(); caddr_t malloc(); +#endif /* STDC_HEADERS */ -#else -# include <stdio.h> -# define setbuffer(f, b, s) setvbuf((f), (b), (b) ? _IOFBF : _IONBF, (s)) -# include <string.h> -# include <memory.h> -# include <stdlib.h> -# define memzero(a, b) memset((a), 0, (b)) - typedef void sigret_t; +/* If snprintf or vsnprintf aren't available, we substitute our own. + But we have to include stdarg in order to be able to define them. +*/ +#ifdef HAVE_STDARG_H +#include <stdarg.h> +#ifndef HAVE_SNPRINTF +int ap_snprintf(char *buf, size_t len, const char *format,...); +#define snprintf ap_snprintf +#endif +#ifndef HAVE_VSNPRINTF +int ap_vsnprintf(char *buf, size_t len, const char *format,va_list ap); +#define vsnprintf ap_vsnprintf +#endif #endif -/* some systems declare sys_errlist in stdio.h! */ -#if defined(__NetBSD__) || defined(__FreeBSD__) -#if !defined(__m68k__) -# if !defined(__NetBSD132__) -#define SYS_ERRLIST_DECLARED -# endif /* __NetBSD132__ */ +#if !HAVE_PID_T +typedef long pid_t; +#endif +#if !HAVE_TIME_T +typedef long time_t; #endif +#if !HAVE_UID_T +typedef long uid_t; +#endif + +#ifndef INT_MAX +#define INT_MAX (0x7fffffff) +#endif + +#ifndef UINT_MAX +#define UINT_MAX (0xffffffffU) +#endif + +/* we must have both sighold and sigrelse to use them */ +#if defined(HAVE_SIGHOLD) && !defined(HAVE_SIGRELSE) +#undef HAVE_SIGHOLD +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef HAVE_SYSEXITS_H +#include <sysexits.h> +#else +#define EX_OK 0 /* successful termination */ +#define EX_USAGE 64 /* command line usage error */ +#define EX_DATAERR 65 /* data format error */ +#define EX_NOINPUT 66 /* cannot open input */ +#define EX_NOUSER 67 /* addressee unknown */ +#define EX_NOHOST 68 /* host name unknown */ +#define EX_UNAVAILABLE 69 /* service unavailable */ +#define EX_SOFTWARE 70 /* internal software error */ +#define EX_OSERR 71 /* system error (e.g., can't fork) */ +#define EX_OSFILE 72 /* critical OS file missing */ +#define EX_CANTCREAT 73 /* can't create (user) output file */ +#define EX_IOERR 74 /* input/output error */ +#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#define EX_PROTOCOL 76 /* remote error in protocol */ +#define EX_NOPERM 77 /* permission denied */ +#define EX_CONFIG 78 /* configuration error */ #endif diff --git a/patchlevel.h b/patchlevel.h deleted file mode 100644 index 28db88951c1b..000000000000 --- a/patchlevel.h +++ /dev/null @@ -1,2 +0,0 @@ -#define PATCHLEVEL 5 -#define BETA "beta12" diff --git a/prime.c b/prime.c deleted file mode 100644 index b0d65424b5e0..000000000000 --- a/prime.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Prime number generator. It prints on stdout the next prime number - * higher than the number specified as argv[1]. - */ - -#include <stdio.h> -#include <math.h> - -main(argc, argv) - -int argc; -char *argv[]; - -{ - double i, j; - int f; - - if (argc < 2) - { - exit(1); - } - - i = atoi(argv[1]); - while (i++) - { - f=1; - for (j=2; j<i; j++) - { - if ((i/j)==floor(i/j)) - { - f=0; - break; - } - } - if (f) - { - printf("%.0f\n", i); - exit(0); - } - } -} @@ -1,12 +1,38 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * Top users/processes display for Unix * Version 3 - * - * This program may be freely redistributed, - * but this entire comment MUST remain intact. - * - * Copyright (c) 1984, 1989, William LeFebvre, Rice University - * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University */ /* This file contains the routines that interface to termcap and stty/gtty. @@ -21,20 +47,52 @@ #include "os.h" #include "top.h" +#if HAVE_CURSES_H && HAVE_TERM_H +#include <curses.h> +#include <term.h> +#else +#if HAVE_TERMCAP_H +#include <termcap.h> +#else +#if HAVE_CURSES_H +#include <curses.h> +#endif +#endif +#endif + +#if !HAVE_DECL_TPUTS +int tputs(const char *, int, int (*)(int)); +#endif +#if !HAVE_DECL_TGOTO +char *tgoto(const char *, int, int); +#endif +#if !HAVE_DECL_TGETENT +int tgetent(const char *, char *); +#endif +#if !HAVE_DECL_TGETFLAG +int tgetflag(const char *); +#endif +#if !HAVE_DECL_TGETNUM +int tgetnum(const char *); +#endif +#if !HAVE_DECL_TGETSTR +char *tgetstr(const char *, char **); +#endif + #include <sys/ioctl.h> #ifdef CBREAK # include <sgtty.h> -# define SGTTY +# define USE_SGTTY #else # ifdef TCGETA -# define TERMIO +# define USE_TERMIO # include <termio.h> # else -# define TERMIOS +# define USE_TERMIOS # include <termios.h> # endif #endif -#if defined(TERMIO) || defined(TERMIOS) +#if defined(USE_TERMIO) || defined(USE_TERMIOS) # ifndef TAB3 # ifdef OXTABS # define TAB3 OXTABS @@ -43,45 +101,46 @@ # endif # endif #endif + #include "screen.h" #include "boolean.h" -extern char *myname; +#define putcap(str) (void)((str) != NULL ? tputs(str, 1, putstdout) : 0) -int putstdout(); +extern char *myname; -int overstrike; -int screen_length; -int screen_width; char ch_erase; char ch_kill; +char ch_werase; char smart_terminal; +int screen_length; +int screen_width; + char PC; -char *tgetstr(); -char *tgoto(); -char termcap_buf[1024]; -char string_buffer[1024]; -char home[15]; -char lower_left[15]; -char *clear_line; -char *clear_screen; -char *clear_to_end; -char *cursor_motion; -char *start_standout; -char *end_standout; -char *terminal_init; -char *terminal_end; -short ospeed; - -#ifdef SGTTY + +static int tc_overstrike; +static char termcap_buf[1024]; +static char string_buffer[1024]; +static char home[15]; +static char lower_left[15]; +static char *tc_clear_line; +static char *tc_clear_screen; +static char *tc_clear_to_end; +static char *tc_cursor_motion; +static char *tc_start_standout; +static char *tc_end_standout; +static char *terminal_init; +static char *terminal_end; + +#ifdef USE_SGTTY static struct sgttyb old_settings; static struct sgttyb new_settings; #endif -#ifdef TERMIO +#ifdef USE_TERMIO static struct termio old_settings; static struct termio new_settings; #endif -#ifdef TERMIOS +#ifdef USE_TERMIOS static struct termios old_settings; static struct termios new_settings; #endif @@ -95,9 +154,61 @@ static int new_lword; #define STDOUT 1 #define STDERR 2 -init_termcap(interactive) +/* This has to be defined as a subroutine for tputs (instead of a macro) */ + +static int +putstdout(TPUTS_PUTC_ARGTYPE ch) -int interactive; +{ + return putchar((int)ch); +} + +void +screen_getsize() + +{ + +#ifdef TIOCGWINSZ + + struct winsize ws; + + if (ioctl (1, TIOCGWINSZ, &ws) != -1) + { + if (ws.ws_row != 0) + { + screen_length = ws.ws_row; + } + if (ws.ws_col != 0) + { + screen_width = ws.ws_col - 1; + } + } + +#else +#ifdef TIOCGSIZE + + struct ttysize ts; + + if (ioctl (1, TIOCGSIZE, &ts) != -1) + { + if (ts.ts_lines != 0) + { + screen_length = ts.ts_lines; + } + if (ts.ts_cols != 0) + { + screen_width = ts.ts_cols - 1; + } + } + +#endif /* TIOCGSIZE */ +#endif /* TIOCGWINSZ */ + + (void) strcpy(lower_left, tgoto(tc_cursor_motion, 0, screen_length - 1)); +} + +int +screen_readtermcap(int interactive) { char *bufptr; @@ -110,11 +221,11 @@ int interactive; screen_width = MAX_COLS; screen_length = 0; - if (!interactive) + if (interactive == No) { /* pretend we have a dumb terminal */ smart_terminal = No; - return; + return No; } /* assume we have a smart terminal until proven otherwise */ @@ -128,7 +239,7 @@ int interactive; if (term_name == NULL) { smart_terminal = No; - return; + return No; } /* now get the termcap entry */ @@ -146,21 +257,21 @@ int interactive; /* pretend it's dumb and proceed */ smart_terminal = No; - return; + return No; } /* "hardcopy" immediately indicates a very stupid terminal */ if (tgetflag("hc")) { smart_terminal = No; - return; + return No; } /* set up common terminal capabilities */ if ((screen_length = tgetnum("li")) <= 0) { screen_length = smart_terminal = 0; - return; + return No; } /* screen_width is a little different */ @@ -174,70 +285,73 @@ int interactive; } /* terminals that overstrike need special attention */ - overstrike = tgetflag("os"); + tc_overstrike = tgetflag("os"); /* initialize the pointer into the termcap string buffer */ bufptr = string_buffer; /* get "ce", clear to end */ - if (!overstrike) + if (!tc_overstrike) { - clear_line = tgetstr("ce", &bufptr); + tc_clear_line = tgetstr("ce", &bufptr); } /* get necessary capabilities */ - if ((clear_screen = tgetstr("cl", &bufptr)) == NULL || - (cursor_motion = tgetstr("cm", &bufptr)) == NULL) + if ((tc_clear_screen = tgetstr("cl", &bufptr)) == NULL || + (tc_cursor_motion = tgetstr("cm", &bufptr)) == NULL) { smart_terminal = No; - return; + return No; } /* get some more sophisticated stuff -- these are optional */ - clear_to_end = tgetstr("cd", &bufptr); + tc_clear_to_end = tgetstr("cd", &bufptr); terminal_init = tgetstr("ti", &bufptr); terminal_end = tgetstr("te", &bufptr); - start_standout = tgetstr("so", &bufptr); - end_standout = tgetstr("se", &bufptr); + tc_start_standout = tgetstr("so", &bufptr); + tc_end_standout = tgetstr("se", &bufptr); /* pad character */ PC = (PCptr = tgetstr("pc", &bufptr)) ? *PCptr : 0; /* set convenience strings */ - (void) strcpy(home, tgoto(cursor_motion, 0, 0)); - /* (lower_left is set in get_screensize) */ + (void) strcpy(home, tgoto(tc_cursor_motion, 0, 0)); + /* (lower_left is set in screen_getsize) */ /* get the actual screen size with an ioctl, if needed */ /* This may change screen_width and screen_length, and it always sets lower_left. */ - get_screensize(); + screen_getsize(); /* if stdout is not a terminal, pretend we are a dumb terminal */ -#ifdef SGTTY +#ifdef USE_SGTTY if (ioctl(STDOUT, TIOCGETP, &old_settings) == -1) { smart_terminal = No; } #endif -#ifdef TERMIO +#ifdef USE_TERMIO if (ioctl(STDOUT, TCGETA, &old_settings) == -1) { smart_terminal = No; } #endif -#ifdef TERMIOS +#ifdef USE_TERMIOS if (tcgetattr(STDOUT, &old_settings) == -1) { smart_terminal = No; } #endif + + return smart_terminal; } -init_screen() +void +screen_init() { /* get the old settings for safe keeping */ -#ifdef SGTTY +#ifdef USE_SGTTY if (ioctl(STDOUT, TIOCGETP, &old_settings) != -1) { /* copy the settings so we can modify them */ @@ -251,6 +365,7 @@ init_screen() /* remember the erase and kill characters */ ch_erase = old_settings.sg_erase; ch_kill = old_settings.sg_kill; + ch_werase = old_settings.sg_werase; #ifdef TOStop /* get the local mode word */ @@ -267,7 +382,7 @@ init_screen() putcap(terminal_init); } #endif -#ifdef TERMIO +#ifdef USE_TERMIO if (ioctl(STDOUT, TCGETA, &old_settings) != -1) { /* copy the settings so we can modify them */ @@ -281,8 +396,9 @@ init_screen() (void) ioctl(STDOUT, TCSETA, &new_settings); /* remember the erase and kill characters */ - ch_erase = old_settings.c_cc[VERASE]; - ch_kill = old_settings.c_cc[VKILL]; + ch_erase = old_settings.c_cc[VERASE]; + ch_kill = old_settings.c_cc[VKILL]; + ch_werase = old_settings.c_cc[VWERASE]; /* remember that it really is a terminal */ is_a_terminal = Yes; @@ -291,7 +407,7 @@ init_screen() putcap(terminal_init); } #endif -#ifdef TERMIOS +#ifdef USE_TERMIOS if (tcgetattr(STDOUT, &old_settings) != -1) { /* copy the settings so we can modify them */ @@ -305,8 +421,9 @@ init_screen() (void) tcsetattr(STDOUT, TCSADRAIN, &new_settings); /* remember the erase and kill characters */ - ch_erase = old_settings.c_cc[VERASE]; - ch_kill = old_settings.c_cc[VKILL]; + ch_erase = old_settings.c_cc[VERASE]; + ch_kill = old_settings.c_cc[VKILL]; + ch_werase = old_settings.c_cc[VWERASE]; /* remember that it really is a terminal */ is_a_terminal = Yes; @@ -323,14 +440,15 @@ init_screen() } } -end_screen() +void +screen_end() { /* move to the lower left, clear the line and send "te" */ if (smart_terminal) { putcap(lower_left); - putcap(clear_line); + putcap(tc_clear_line); fflush(stdout); putcap(terminal_end); } @@ -338,37 +456,38 @@ end_screen() /* if we have settings to reset, then do so */ if (is_a_terminal) { -#ifdef SGTTY +#ifdef USE_SGTTY (void) ioctl(STDOUT, TIOCSETP, &old_settings); #ifdef TOStop (void) ioctl(STDOUT, TIOCLSET, &old_lword); #endif #endif -#ifdef TERMIO +#ifdef USE_TERMIO (void) ioctl(STDOUT, TCSETA, &old_settings); #endif -#ifdef TERMIOS +#ifdef USE_TERMIOS (void) tcsetattr(STDOUT, TCSADRAIN, &old_settings); #endif } } -reinit_screen() +void +screen_reinit() { /* install our settings if it is a terminal */ if (is_a_terminal) { -#ifdef SGTTY +#ifdef USE_SGTTY (void) ioctl(STDOUT, TIOCSETP, &new_settings); #ifdef TOStop (void) ioctl(STDOUT, TIOCLSET, &new_lword); #endif #endif -#ifdef TERMIO +#ifdef USE_TERMIO (void) ioctl(STDOUT, TCSETA, &new_settings); #endif -#ifdef TERMIOS +#ifdef USE_TERMIOS (void) tcsetattr(STDOUT, TCSADRAIN, &new_settings); #endif } @@ -380,59 +499,22 @@ reinit_screen() } } -get_screensize() +void +screen_move(int x, int y) { - -#ifdef TIOCGWINSZ - - struct winsize ws; - - if (ioctl (1, TIOCGWINSZ, &ws) != -1) - { - if (ws.ws_row != 0) - { - screen_length = ws.ws_row; - } - if (ws.ws_col != 0) - { - screen_width = ws.ws_col - 1; - } - } - -#else -#ifdef TIOCGSIZE - - struct ttysize ts; - - if (ioctl (1, TIOCGSIZE, &ts) != -1) - { - if (ts.ts_lines != 0) - { - screen_length = ts.ts_lines; - } - if (ts.ts_cols != 0) - { - screen_width = ts.ts_cols - 1; - } - } - -#endif /* TIOCGSIZE */ -#endif /* TIOCGWINSZ */ - - (void) strcpy(lower_left, tgoto(cursor_motion, 0, screen_length - 1)); + tputs(tgoto(tc_cursor_motion, x, y), 1, putstdout); } -standout(msg) - -char *msg; +void +screen_standout(char *msg) { if (smart_terminal) { - putcap(start_standout); + putcap(tc_start_standout); fputs(msg, stdout); - putcap(end_standout); + putcap(tc_end_standout); } else { @@ -440,40 +522,64 @@ char *msg; } } -clear() +void +screen_clear() { if (smart_terminal) { - putcap(clear_screen); + putcap(tc_clear_screen); } } -clear_eol(len) +int +screen_cte() + +{ + if (smart_terminal) + { + if (tc_clear_to_end) + { + putcap(tc_clear_to_end); + return(Yes); + } + } + return(No); +} -int len; +void +screen_cleareol(int len) { - if (smart_terminal && !overstrike && len > 0) + int i; + + if (smart_terminal && !tc_overstrike && len > 0) { - if (clear_line) + if (tc_clear_line) { - putcap(clear_line); - return(0); + putcap(tc_clear_line); + return; } else { - while (len-- > 0) + i = 0; + while (i++ < 0) { putchar(' '); } - return(1); + i = 0; + while (i++ < 0) + { + putchar('\b'); + } + return; } } - return(-1); + return; } -go_home() +void +screen_home() { if (smart_terminal) @@ -482,13 +588,4 @@ go_home() } } -/* This has to be defined as a subroutine for tputs (instead of a macro) */ - -putstdout(ch) - -char ch; - -{ - putchar(ch); -} @@ -1,31 +1,65 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * top - a top users display for Unix 4.2 * * This file contains all the definitions necessary to use the hand-written * screen package in "screen.c" */ -#define TCputs(str) tputs(str, 1, putstdout) -#define putcap(str) (void)((str) != NULL ? TCputs(str) : 0) -#define Move_to(x, y) TCputs(tgoto(cursor_motion, x, y)) - -/* declare return values for termcap functions */ -char *tgetstr(); -char *tgoto(); +#ifndef _SCREEN_H_ +#define _SCREEN_H_ extern char ch_erase; /* set to the user's erase character */ -extern char ch_kill; /* set to the user's kill character */ +extern char ch_kill; /* set to the user's kill character */ +extern char ch_werase; /* set to the user's werase character */ extern char smart_terminal; /* set if the terminal has sufficient termcap capabilities for normal operation */ -/* These are some termcap strings for use outside of "screen.c" */ -extern char *cursor_motion; -extern char *clear_line; -extern char *clear_to_end; - /* rows and columns on the screen according to termcap */ extern int screen_length; extern int screen_width; -/* a function that puts a single character on stdout */ -int putstdout(); +void screen_getsize(); +int screen_readtermcap(int interactive); +void screen_init(); +void screen_end(); +void screen_reinit(); +void screen_move(int x, int y); +void screen_standout(char *msg); +void screen_clear(); +int screen_cte(); +void screen_cleareol(int len); +void screen_home(); + +#endif /* _SCREEN_H_ */ diff --git a/sigconv.awk b/sigconv.awk index 8c90d8dc749e..4f0ef608c5c2 100644 --- a/sigconv.awk +++ b/sigconv.awk @@ -1,3 +1,38 @@ +# Copyright (c) 1984 through 2008, William LeFebvre +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of William LeFebvre nor the names of other +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# Awk script converts an include file with definitions for signal names +# in to a predefined array that associates the signal numbers to the names. +# + BEGIN { nsig = 0; j = 0; @@ -13,41 +48,44 @@ BEGIN { /^#define[ \t][ \t]*SIG[A-Z]/ { j = sprintf("%d", $3); + if (siglist[j] != "") next; str = $2; if (nsig < j) nsig = j; - siglist[j] = sprintf("\"%s\",\t%2d,", \ + siglist[j] = sprintf("\"%s\",\t%2d", \ substr(str, 4), j); } /^#[ \t]*define[ \t][ \t]*SIG[A-Z]/ { j = sprintf("%d", $4); + if (siglist[j] != "") next; str = $3; if (nsig < j) nsig = j; - siglist[j] = sprintf("\"%s\",\t%2d,", \ + siglist[j] = sprintf("\"%s\",\t%2d", \ substr(str, 4), j); } /^#[ \t]*define[ \t][ \t]*_SIG[A-Z]/ { j = sprintf("%d", $4); + if (siglist[j] != "") next; str = $3; if (nsig < j) nsig = j; - siglist[j] = sprintf("\"%s\",\t%2d,", \ + siglist[j] = sprintf("\"%s\",\t%2d", \ substr(str, 5), j); } END { for (n = 1; n <= nsig; n++) if (siglist[n] != "") - printf(" %s\n", siglist[n]); + printf(" { %s },\n", siglist[n]); - printf(" NULL,\t 0\n};\n"); + printf(" { NULL,\t 0 }\n};\n"); } diff --git a/top.1.in b/top.1.in new file mode 100644 index 000000000000..440cd8628f57 --- /dev/null +++ b/top.1.in @@ -0,0 +1,464 @@ +.\" NOTE: changes to the manual page for "top" should be made in the +.\" file "top.1.in" and NOT in the file "top.1". +.nr N @DEFAULT_TOPN@ +.nr D @DEFAULT_DELAY@ +.nr L @HAVE_GETOPT_LONG@ +.nr K @ENABLE_KILL@ +.TH TOP 1 Local +.UC 4 +.SH NAME +top \- display and update information about the top cpu processes +.SH SYNOPSIS +.B top +[ +.B \-CISTabcinqtuv +] [ +.BI \-d count +] [ +.BI \-m mode +] [ +.BI \-o field +] [ +.BI \-s time +] [ +.BI \-U username +] [ +.I number +] +.SH DESCRIPTION +.\" This defines appropriate quote strings for nroff and troff +.ds lq \&" +.ds rq \&" +.if t .ds lq `` +.if t .ds rq '' +.\" Just in case these number registers aren't set yet... +.if \nN==0 .nr N 10 +.if \nD==0 .nr D 5 +.I Top +displays the top +.if !\nN==-1 \nN +processes on the system and periodically updates this information. +.if \nN==-1 \ +\{\ +If standard output is an intelligent terminal (see below) then +as many processes as will fit on the terminal screen are displayed +by default. Otherwise, a good number of them are shown (around 20). +.\} +Raw cpu percentage is used to rank the processes. If +.I number +is given, then the top +.I number +processes will be displayed instead of the default. +.PP +.I Top +makes a distinction between terminals that support advanced capabilities +and those that do not. This +distinction affects the choice of defaults for certain options. In the +remainder of this document, an \*(lqintelligent\*(rq terminal is one that +supports cursor addressing, clear screen, and clear to end of line. +Conversely, a \*(lqdumb\*(rq terminal is one that does not support such +features. If the output of +.I top +is redirected to a file, it acts as if it were being run on a dumb +terminal. +.SH OPTIONS +.if \nL==0 Long options are not available on this system. +.TP +.B "\-C, \-\-color" +Turn off the use of color in the display. +.TP +.B "\-I, \-\-idle-procs" +Do not display idle processes. +By default, top displays both active and idle processes. +.TP +.B "\-S, \-\-system-procs" +Show system processes in the display. Normally, system processes such as +the pager and the swapper are not shown. This option makes them visible. +.TP +.B "\-T, \-\-tag-names" +List all available color tags and the current set of tests used for +color highlighting, then exit. +.TP +.B "\-a, \-\-all" +Show all processes for as long as possible. This is shorthand for +\*(lq-d all all\*(rq. This option is especially handy in batch mode. +.TP +.B "\-b, \-n, \-\-batch" +Use \*(lqbatch\*(rq mode. In this mode, all input from the terminal is +ignored. Interrupt characters (such as ^C and ^\e) still have an effect. +This is the default on a dumb terminal, or when the output is not a terminal. +.TP +.B "\-c, \-\-full-commands" +Show the full command line for each process. Default is to show just the +command name. This option is not supported on all platforms. +.TP +.B "\-i, \-\-interactive" +Use \*(lqinteractive\*(rq mode. In this mode, any input is immediately +read for processing. See the section on \*(lqInteractive Mode\*(rq +for an explanation of +which keys perform what functions. After the command is processed, the +screen will immediately be updated, even if the command was not +understood. This mode is the default when standard output is an +intelligent terminal. +.TP +.B "\-q, \-\-quick" +Renice +.I top +to -20 so that it will run faster. This can be used when the system is +being very sluggish to improve the possibility of discovering the problem. +This option can only be used by root. +.TP +.B "\-t, \-\-threads" +Show individual threads on separate lines. By default, on systems +which support threading, each process is shown with a count of the number +of threads. This option shows each thread on a separate line. This option +is not supported on all platforms. +.TP +.B "\-u, \-\-uids" +Do not take the time to map uid numbers to usernames. Normally, +.I top +will read as much of the file \*(lq/etc/passwd\*(rq as is necessary to map +all the user id numbers it encounters into login names. This option +disables all that, while possibly decreasing execution time. The uid +numbers are displayed instead of the names. +.TP +.B "\-v, \-\-version" +Write version number information to stderr then exit immediately. +No other processing takes place when this option is used. To see current +revision information while top is running, use the help command \*(lq?\*(rq. +.TP +.B "\-d \fIcount\fP, \-\-displays \fIcount\fP" +Show only +.I count +displays, then exit. A display is considered to be one update of the +screen. This option allows the user to select the number of displays he +wants to see before +.I top +automatically exits. Any proper prefix of the words \*(lqinfinity\*(rq, +\*(lqmaximum\*(rq, +or +\*(lqall\*(rq can be used to indicate an infinite number of displays. +The default for intelligent terminals is infinity. +The default for dumb terminals is 1. +.TP +.B "\-m \fImode\fP, \-\-mode=\fImode\fP" +Start the display in an alternate mode. Some platforms support multiple +process displays to show additional process information. The value +\fImode\fP is a number indicating which mode to display. The default is +0. On platforms that do not have multiple display modes this option has +no effect. +.TP +.B "\-o \fIfield\fP, \-\-sort-order=\fIfield\fP" +Sort the process display area on the specified field. The field name is +the name of the column as seen in the output, but in lower case. Likely +values are \*(lqcpu\*(rq, \*(lqsize\*(rq, \*(lqres\*(rq, and \*(lqtime\*(rq, +but may vary on different operating systems. Note that +not all operating systems support this option. +.TP +.B "\-s \fItime\fP, \-\-delay=\fItime\fP" +Set the delay between screen updates to +.I time +seconds. The default delay between updates is \nD seconds. +.TP +.B "\-U \fIusername\fP, \-\-user=\fIusername\fP" +Show only those processes owned by +.IR username . +This option currently only accepts usernames and will not understand +uid numbers. +.PP +Both +.I count +and +.I number +fields can be specified as \*(lqinfinite\*(rq, indicating that they can +stretch as far as possible. This is accomplished by using any proper +prefix of the keywords +\*(lqinfinity\*(rq, +\*(lqmaximum\*(rq, +or +\*(lqall\*(rq. +The default for +.I count +on an intelligent terminal is, in fact, +\fBinfinity\fP. +.PP +The environment variable +.B TOP +is examined for options before the command line is scanned. This enables +a user to set his or her own defaults. The number of processes to display +can also be specified in the environment variable +.BR TOP . +The options +.BR \-C , +.BR \-I , +.BR \-S , +and +.B \-u +are actually toggles. A second specification of any of these options +will negate the first. Thus a user who has the environment variable +.B TOP +set to \*(lq\-I\*(rq may use the command \*(lqtop \-I\*(rq to see idle processes. +.SH "INTERACTIVE MODE" +When +.I top +is running in \*(lqinteractive mode\*(rq, it reads commands from the +terminal and acts upon them accordingly. In this mode, the terminal is +put in \*(lqCBREAK\*(rq, so that a character will be +processed as soon as it is typed. Almost always, a key will be +pressed when +.I top +is between displays; that is, while it is waiting for +.I time +seconds to elapse. If this is the case, the command will be +processed and the display will be updated immediately thereafter +(reflecting any changes that the command may have specified). This +happens even if the command was incorrect. If a key is pressed while +.I top +is in the middle of updating the display, it will finish the update and +then process the command. Some commands require additional information, +and the user will be prompted accordingly. While typing this information +in, the user's erase and kill keys (as set up by the command +.IR stty ) +are recognized, and a newline terminates the input. Note that a control-L +(^L) always redraws the current screen and a space forces an immediate +update to the screen using new data. +.PP +These commands are currently recognized: +.TP +.I "\fBh\fP\ or\ \fB?\fP" +Display a summary of the commands (help screen). Version information +is included in this display. +.TP +.B C +Toggle the use of color in the display. +.TP +.B c +Display only processes whose commands match the specified string. An empty +string will display all processes. This command is not supported on all +platforms. +.TP +.B d +Change the number of displays to show (prompt for new number). +Remember that the next display counts as one, so typing +.B d1 +will make +.I top +show one final display and then immediately exit. +.TP +.B f +Toggle the display of the full command line. +.TP +.B H +Toggle the display of threads on separate lines. By default, on systems +which support threading, each process is shown with a count of the number +of threads. This command shows each thread on a separate line. This command +is not supported on all platforms. +.TP +.B i +(or +.BR I ) +Toggle the display of idle processes. +.if \nK==1 \{\ +.TP +.B k +Send a signal (\*(lqkill\*(rq by default) to a list of processes. This +acts similarly to the command +.IR kill (1)). +.\} +.TP +.B M +Sort display by memory usage. Shorthand for \*(lqo size\*(rq. +.TP +.B m +Change to a different process display mode. Some systems provide multiple +display modes for the process display which shows different information. +This command toggles between the available modes. This command is not +supported on all platforms. +.TP +.B N +Sort by process id. Shorthand for \*(lqo pid\*(rq. +.TP +.B n or # +Change the number of processes to display (prompt for new number). +.TP +.B o +Change the order in which the display is sorted. This command is not +available on all systems. The sort key names vary fron system to system +but usually include: \*(lqcpu\*(rq, \*(lqres\*(rq, \*(lqsize\*(rq, +\*(lqtime\*(rq. The default is cpu. +.TP +.B P +Sort by CPU usage. Shorthand for \*(lqo cpu\*(rq. +.TP +.B q +Quit +.IR top. +.if \nK==1 \{\ +.TP +.B r +Change the priority (the \*(lqnice\*(rq) of a list of processes. +This acts similarly to the command +.IR renice (8)). +.\} +.TP +.B s +Change the number of seconds to delay between displays +(prompt for new number). +.TP +.B T +Sort by CPU time. Shorthand for \*(lqo time\*(rq. +.TP +.B U +Toggle between displaying usernames and uids. +.TP +.B u +Display only processes owned by a specific username (prompt for username). +If the username specified is simply \*(lq+\*(rq, then processes belonging +to all users will be displayed. +.SH "THE DISPLAY" +The actual display varies depending on the specific variant of Unix +that the machine is running. This description may not exactly match +what is seen by top running on this particular machine. Differences +are listed at the end of this manual entry. +.PP +The top lines of the display show general information +about the state of the system. The first line shows +(on some systems) the last process id assigned to a process, +the three load averages, +the system uptime, and the current time. +The second line displays the total number of processes followed +by a breakdown of processes per state. Examples of states common +to Unix systems are sleeping, running, starting, stopped, and zombie. +The next line displays a percentage of time spent in each of the +processor states (typically user, nice, system, idle, and iowait). +These percentages show the processor activity during the time since +the last update. For multi-processor systems, this information is +a summation of time across all processors. The next line shows +kernel-related activity (not available on all systems). The numbers +shown on this line are per-second rates sampled since the last update. +The exact +information displayed varies between systems, but some examples are: +context switches, interrupts, traps, forks, and page faults. The last +one or two lines show a summary of memory and swap activity. These lines +vary between systems. +.PP +The remainder of the screen displays information about individual +processes. This display is similar in spirit to +.IR ps (1) +but it is not exactly the same. The columns displayed by top will +differ slightly between operating systems. Generally, the following +fields are displayed: +.TP +.B PID +The process id. +.TP +.B USERNAME +Username of the process's owner (if +.B \-u +is specified, a UID column will be substituted for USERNAME). +.TP +.B THR +The number of threads in the processes (this column may also +be labeled NLWP). +.TP +.B PRI +Current priority of the process. +.TP +.B NICE +Nice amount in the range \-20 to 20, as established by the use of +the command +.IR nice . +.TP +.B SIZE +Total size of the process (text, data, and stack) given in kilobytes. +.TP +.B RES +Resident memory: current amount of process memory that resides in physical +memory, given in kilobytes. +.TP +.B STATE +Current state (typically one of \*(lqsleep\*(rq, +\*(lqrun\*(rq, \*(lqidl\*(rq, \*(lqzomb\*(rq, or \*(lqstop\*(rq). +.TP +.B TIME +Number of system and user cpu seconds that the process has used. +.TP +.B CPU +Percentage of available cpu time used by this process. +.TP +.B COMMAND +Name of the command that the process is currently running. +.SH COLOR +Top supports the use of ANSI color in its output. By default, color is +available but not used. The environment variable +.B TOPCOLORS +specifies colors to use and conditions for which they should be used. +At the present time, only numbers in the summay display area can be +colored. In a future version it will be possible to highlight numbers +in the process display area as well. The environment variable is the +only way to specify color: there is no equivalent command line option. +Note that the environment variable +.B TOPCOLOURS +is also understood. The British spelling takes precedence. The use of +color only works on terminals that understand and process ANSI color +escape sequences. +.PP +The environment variable is a sequence of color specifications, separated +by colons. Each specification takes the form tag=min,max#code where +.I tag +is the name of the value to check, +.I min +and +.I max +specify a range for the value, and +.I code +is an ANSI color code. Multiple color codes can be listed and separated +with semi-colons. A missing +.I min +implies the lowest possible value (usually 0) +and a missing +.I max +implies infinity. The comma must always be present. When specifying numbers +for load averages, they should be multiplied by 100. +For example, the specification +.B 1min=500,1000#31 +indicates that a 1 minute load average between +5 and 10 should be displayed in red. Color attributes can be combined. +For example, the specification +.B 5min=1000,#37;41 +indicates that a 5 minute load average higher than 10 should be displayed +with white characters on a red background. A special tag named +.I header +is used to control the color of the header for process display. It should +be specified with no lower and upper limits, specifically +.B header=,# +followed by the ANSI color code. +.PP +You can see a list of color codes recognized by this installation of top +with the +.B \-T +option. This will also show the current set of tests used for +color highligting, as specified in the environment. +.SH AUTHOR +William LeFebvre +.SH ENVIRONMENT +.DT +TOP user-configurable defaults for options. +TOPCOLORS color specification +.SH BUGS +As with +.IR ps (1), +things can change while +.I top +is collecting information for an update. The picture it gives is only a +close approximation to reality. +.SH "SEE ALSO" +kill(1), +ps(1), +stty(1), +mem(4), +renice(8) +@MAN_SUPPLEMENT@ +.SH COPYRIGHT +Copyright (C) 1984-2007 William LeFebvre. For additional licensing +information, see http://www.unixtop.org/license/ diff --git a/top.X b/top.X deleted file mode 100644 index b8ea13ac84f8..000000000000 --- a/top.X +++ /dev/null @@ -1,336 +0,0 @@ -.\" NOTE: changes to the manual page for "top" should be made in the -.\" file "top.X" and NOT in the file "top.1". -.nr N %topn% -.nr D %delay% -.TH TOP 1 Local -.UC 4 -.SH NAME -top \- display and update information about the top cpu processes -.SH SYNOPSIS -.B top -[ -.B \-SbiInquv -] [ -.BI \-d count -] [ -.BI \-s time -] [ -.BI \-o field -] [ -.BI \-U username -] [ -.I number -] -.SH DESCRIPTION -.\" This defines appropriate quote strings for nroff and troff -.ds lq \&" -.ds rq \&" -.if t .ds lq `` -.if t .ds rq '' -.\" Just in case these number registers aren't set yet... -.if \nN==0 .nr N 10 -.if \nD==0 .nr D 5 -.I Top -displays the top -.if !\nN==-1 \nN -processes on the system and periodically updates this information. -.if \nN==-1 \ -\{\ -If standard output is an intelligent terminal (see below) then -as many processes as will fit on the terminal screen are displayed -by default. Otherwise, a good number of them are shown (around 20). -.\} -Raw cpu percentage is used to rank the processes. If -.I number -is given, then the top -.I number -processes will be displayed instead of the default. -.PP -.I Top -makes a distinction between terminals that support advanced capabilities -and those that do not. This -distinction affects the choice of defaults for certain options. In the -remainder of this document, an \*(lqintelligent\*(rq terminal is one that -supports cursor addressing, clear screen, and clear to end of line. -Conversely, a \*(lqdumb\*(rq terminal is one that does not support such -features. If the output of -.I top -is redirected to a file, it acts as if it were being run on a dumb -terminal. -.SH OPTIONS -.TP -.B \-S -Show system processes in the display. Normally, system processes such as -the pager and the swapper are not shown. This option makes them visible. -.TP -.B \-b -Use \*(lqbatch\*(rq mode. In this mode, all input from the terminal is -ignored. Interrupt characters (such as ^C and ^\e) still have an effect. -This is the default on a dumb terminal, or when the output is not a terminal. -.TP -.B \-i -Use \*(lqinteractive\*(rq mode. In this mode, any input is immediately -read for processing. See the section on \*(lqInteractive Mode\*(rq -for an explanation of -which keys perform what functions. After the command is processed, the -screen will immediately be updated, even if the command was not -understood. This mode is the default when standard output is an -intelligent terminal. -.TP -.B \-I -Do not display idle processes. -By default, top displays both active and idle processes. -.TP -.B \-n -Use \*(lqnon-interactive\*(rq mode. This is indentical to \*(lqbatch\*(rq -mode. -.TP -.B \-q -Renice -.I top -to -20 so that it will run faster. This can be used when the system is -being very sluggish to improve the possibility of discovering the problem. -This option can only be used by root. -.TP -.B \-u -Do not take the time to map uid numbers to usernames. Normally, -.I top -will read as much of the file \*(lq/etc/passwd\*(rq as is necessary to map -all the user id numbers it encounters into login names. This option -disables all that, while possibly decreasing execution time. The uid -numbers are displayed instead of the names. -.TP -.B \-v -Write version number information to stderr then exit immediately. -No other processing takes place when this option is used. To see current -revision information while top is running, use the help command \*(lq?\*(rq. -.TP -.BI \-d count -Show only -.I count -displays, then exit. A display is considered to be one update of the -screen. This option allows the user to select the number of displays he -wants to see before -.I top -automatically exits. For intelligent terminals, no upper limit -is set. The default is 1 for dumb terminals. -.TP -.BI \-s time -Set the delay between screen updates to -.I time -seconds. The default delay between updates is \nD seconds. -.TP -.BI \-o field -Sort the process display area on the specified field. The field name is -the name of the column as seen in the output, but in lower case. Likely -values are \*(lqcpu\*(rq, \*(lqsize\*(rq, \*(lqres\*(rq, and \*(lqtime\*(rq, -but may vary on different operating systems. Note that -not all operating systems support this option. -.TP -.BI \-U username -Show only those processes owned by -.IR username . -This option currently only accepts usernames and will not understand -uid numbers. -.PP -Both -.I count -and -.I number -fields can be specified as \*(lqinfinite\*(rq, indicating that they can -stretch as far as possible. This is accomplished by using any proper -prefix of the keywords -\*(lqinfinity\*(rq, -\*(lqmaximum\*(rq, -or -\*(lqall\*(rq. -The default for -.I count -on an intelligent terminal is, in fact, -.BI infinity . -.PP -The environment variable -.B TOP -is examined for options before the command line is scanned. This enables -a user to set his or her own defaults. The number of processes to display -can also be specified in the environment variable -.BR TOP . -The options -.BR \-I , -.BR \-S , -and -.B \-u -are actually toggles. A second specification of any of these options -will negate the first. Thus a user who has the environment variable -.B TOP -set to \*(lq\-I\*(rq may use the command \*(lqtop \-I\*(rq to see idle processes. -.SH "INTERACTIVE MODE" -When -.I top -is running in \*(lqinteractive mode\*(rq, it reads commands from the -terminal and acts upon them accordingly. In this mode, the terminal is -put in \*(lqCBREAK\*(rq, so that a character will be -processed as soon as it is typed. Almost always, a key will be -pressed when -.I top -is between displays; that is, while it is waiting for -.I time -seconds to elapse. If this is the case, the command will be -processed and the display will be updated immediately thereafter -(reflecting any changes that the command may have specified). This -happens even if the command was incorrect. If a key is pressed while -.I top -is in the middle of updating the display, it will finish the update and -then process the command. Some commands require additional information, -and the user will be prompted accordingly. While typing this information -in, the user's erase and kill keys (as set up by the command -.IR stty ) -are recognized, and a newline terminates the input. -.PP -These commands are currently recognized (^L refers to control-L): -.TP -.B ^L -Redraw the screen. -.IP "\fBh\fP\ or\ \fB?\fP" -Display a summary of the commands (help screen). Version information -is included in this display. -.TP -.B q -Quit -.IR top. -.TP -.B d -Change the number of displays to show (prompt for new number). -Remember that the next display counts as one, so typing -.B d1 -will make -.I top -show one final display and then immediately exit. -.TP -.B n or # -Change the number of processes to display (prompt for new number). -.TP -.B s -Change the number of seconds to delay between displays -(prompt for new number). -.TP -.B k -Send a signal (\*(lqkill\*(rq by default) to a list of processes. This -acts similarly to the command -.IR kill (1)). -.TP -.B r -Change the priority (the \*(lqnice\*(rq) of a list of processes. -This acts similarly to the command -.IR renice (8)). -.TP -.B u -Display only processes owned by a specific username (prompt for username). -If the username specified is simply \*(lq+\*(rq, then processes belonging -to all users will be displayed. -.TP -.B o -Change the order in which the display is sorted. This command is not -available on all systems. The sort key names vary fron system to system -but usually include: \*(lqcpu\*(rq, \*(lqres\*(rq, \*(lqsize\*(rq, -\*(lqtime\*(rq. The default is cpu. -.TP -.B e -Display a list of system errors (if any) generated by the last -.BR k ill -or -.BR r enice -command. -.TP -.B i -(or -.BR I) -Toggle the display of idle processes. -.SH "THE DISPLAY" -The actual display varies depending on the specific variant of Unix -that the machine is running. This description may not exactly match -what is seen by top running on this particular machine. Differences -are listed at the end of this manual entry. -.PP -The top few lines of the display show general information -about the state of the system, including -the last process id assigned to a process (on most systems), -the three load averages, -the current time, -the number of existing processes, -the number of processes in each state -(sleeping, running, starting, zombies, and stopped), -and a percentage of time spent in each of the processor states -(user, nice, system, and idle). -It also includes information about physial and virtual memory allocation. -.PP -The remainder of the screen displays information about individual -processes. This display is similar in spirit to -.IR ps (1) -but it is not exactly the same. PID is the process id, USERNAME is the name -of the process's owner (if -.B \-u -is specified, a UID column will be substituted for USERNAME), -PRI is the current priority of the process, -NICE is the nice amount (in the range \-20 to 20), -SIZE is the total size of the process (text, data, and stack), -RES is the current amount of resident memory (both SIZE and RES are -given in kilobytes), -STATE is the current state (one of \*(lqsleep\*(rq, \*(lqWAIT\*(rq, -\*(lqrun\*(rq, \*(lqidl\*(rq, \*(lqzomb\*(rq, or \*(lqstop\*(rq), -TIME is the number of system and user cpu seconds that the process has used, -WCPU, when displayed, is the weighted cpu percentage (this is the same -value that -.IR ps (1) -displays as CPU), -CPU is the raw percentage and is the field that is sorted to determine -the order of the processes, and -COMMAND is the name of the command that the process is currently running -(if the process is swapped out, this column is marked \*(lq<swapped>\*(rq). -.SH NOTES -The \*(lqABANDONED\*(rq state (known in the kernel as \*(lqSWAIT\*(rq) was -abandoned, thus the name. A process should never end up in this state. -.SH AUTHOR -William LeFebvre, EECS Department, Northwestern University -.SH ENVIRONMENT -.DT -TOP user-configurable defaults for options. -.SH FILES -.DT -/dev/kmem kernel memory -.br -/dev/mem physical memory -.br -/etc/passwd used to map uid numbers to user names -.br -/vmunix system image -.SH BUGS -Don't shoot me, but the default for -.B \-I -has changed once again. So many people were confused by the fact that -.I top -wasn't showing them all the processes that I have decided to make the -default behavior show idle processes, just like it did in version 2. -But to appease folks who can't stand that behavior, I have added the -ability to set \*(lqdefault\*(rq options in the environment variable -.B TOP -(see the OPTIONS section). Those who want the behavior that version -3.0 had need only set the environment variable -.B TOP -to \*(lq\-I\*(rq. -.PP -The command name for swapped processes should be tracked down, but this -would make the program run slower. -.PP -As with -.IR ps (1), -things can change while -.I top -is collecting information for an update. The picture it gives is only a -close approximation to reality. -.SH "SEE ALSO" -kill(1), -ps(1), -stty(1), -mem(4), -renice(8) @@ -1,1022 +1,980 @@ -char *copyright = - "Copyright (c) 1984 through 1996, William LeFebvre"; - -/* - * Top users/processes display for Unix - * Version 3 - * - * This program may be freely redistributed, - * but this entire comment MUST remain intact. - * - * Copyright (c) 1984, 1989, William LeFebvre, Rice University - * Copyright (c) 1989 - 1994, William LeFebvre, Northwestern University - * Copyright (c) 1994, 1995, William LeFebvre, Argonne National Laboratory - * Copyright (c) 1996, William LeFebvre, Group sys Consulting - */ - /* - * See the file "Changes" for information on version-to-version changes. + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * This file contains "main" and other high-level routines. - */ +char *copyright = + "Copyright (c) 1984 through 2008, William LeFebvre"; /* - * The following preprocessor variables, when defined, are used to - * distinguish between different Unix implementations: - * - * SIGHOLD - use SVR4 sighold function when defined - * SIGRELSE - use SVR4 sigrelse function when defined - * FD_SET - macros FD_SET and FD_ZERO are used when defined + * Changes to other files that we can do at the same time: + * screen.c:init_termcap: get rid of the "interactive" argument and have it + * pass back something meaningful (such as success/failure/error). */ #include "os.h" #include <signal.h> #include <setjmp.h> #include <ctype.h> -#include <sys/time.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <unistd.h> + +#ifdef HAVE_SYS_UTSNAME_H +#include <sys/utsname.h> +#endif + +#ifdef HAVE_GETOPT_H +#include <getopt.h> +#endif + +/* definitions */ +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif + +/* determine which type of signal functions to use */ +/* cant have sigaction without sigprocmask */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGPROCMASK) +#undef HAVE_SIGACTION +#endif +/* always use sigaction when it is available */ +#ifdef HAVE_SIGACTION +#undef HAVE_SIGHOLD +#else +/* use sighold/sigrelse, otherwise use old fashioned BSD signals */ +#if !defined(HAVE_SIGHOLD) || !defined(HAVE_SIGRELSE) +#define BSD_SIGNALS +#endif +#endif + +/* if FD_SET and friends aren't present, then fake something up */ +#ifndef FD_SET +typedef int fd_set; +#define FD_ZERO(x) (*(x) = 0) +#define FD_SET(f, x) (*(x) = 1<<f) +#endif /* includes specific to top */ -#include "display.h" /* interface to display package */ -#include "screen.h" /* interface to screen package */ + #include "top.h" -#include "top.local.h" -#include "boolean.h" #include "machine.h" +#include "globalstate.h" +#include "commands.h" +#include "display.h" +#include "screen.h" +#include "boolean.h" +#include "username.h" #include "utils.h" +#include "version.h" +#ifdef ENABLE_COLOR +#include "color.h" +#endif -/* Size of the stdio buffer given to stdout */ -#define Buffersize 2048 - -/* The buffer that stdio will use */ -char stdoutbuf[Buffersize]; - -/* build Signal masks */ -#define Smask(s) (1 << ((s) - 1)) +/* definitions */ +#define BUFFERSIZE 4096 +#define JMP_RESUME 1 +#define JMP_RESIZE 2 -/* for getopt: */ +/* externs for getopt: */ extern int optind; extern char *optarg; -/* imported from screen.c */ -extern int overstrike; +/* statics */ +static char stdoutbuf[BUFFERSIZE]; +static jmp_buf jmp_int; -/* signal handling routines */ -sigret_t leave(); -sigret_t onalrm(); -sigret_t tstop(); -#ifdef SIGWINCH -sigret_t winch(); -#endif +/* globals */ +char *myname = "top"; -/* internal routines */ -void quit(); +void +quit(int status) -/* values which need to be accessed by signal handlers */ -static int max_topn; /* maximum displayable processes */ +{ + screen_end(); + chdir("/tmp"); + exit(status); + /* NOTREACHED */ +} -/* miscellaneous things */ -char *myname = "top"; -jmp_buf jmp_int; +/* + * signal handlers + */ -/* routines that don't return int */ +void +set_signal(int sig, RETSIGTYPE (*handler)(int)) -char *username(); -char *ctime(); -char *kill_procs(); -char *renice_procs(); +{ +#ifdef HAVE_SIGACTION + struct sigaction action; -#ifdef ORDER -extern int (*proc_compares[])(); + action.sa_handler = handler; + action.sa_flags = 0; + (void) sigaction(sig, &action, NULL); #else -extern int proc_compare(); -#endif -time_t time(); - -caddr_t get_process_info(); - -/* different routines for displaying the user's identification */ -/* (values assigned to get_userid) */ -char *username(); -char *itoa7(); - -/* display routines that need to be predeclared */ -int i_loadave(); -int u_loadave(); -int i_procstates(); -int u_procstates(); -int i_cpustates(); -int u_cpustates(); -int i_memory(); -int u_memory(); -int i_message(); -int u_message(); -int i_header(); -int u_header(); -int i_process(); -int u_process(); - -/* pointers to display routines */ -int (*d_loadave)() = i_loadave; -int (*d_procstates)() = i_procstates; -int (*d_cpustates)() = i_cpustates; -int (*d_memory)() = i_memory; -int (*d_message)() = i_message; -int (*d_header)() = i_header; -int (*d_process)() = i_process; - - -main(argc, argv) - -int argc; -char *argv[]; + (void) signal(sig, handler); +#endif +} + +void +release_signal(int sig) { - register int i; - register int active_procs; - register int change; +#ifdef HAVE_SIGACTION + sigset_t set; + sigemptyset(&set); + sigaddset(&set, sig); + sigprocmask(SIG_UNBLOCK, &set, NULL); +#endif - struct system_info system_info; - struct statics statics; - caddr_t processes; +#ifdef HAVE_SIGHOLD + sigrelse(sig); +#endif - static char tempbuf1[50]; - static char tempbuf2[50]; - int old_sigmask; /* only used for BSD-style signals */ - int topn = Default_TOPN; - int delay = Default_DELAY; - int displays = 0; /* indicates unspecified */ - time_t curr_time; - char *(*get_userid)() = username; - char *uname_field = "USERNAME"; - char *header_text; - char *env_top; - char **preset_argv; - int preset_argc = 0; - char **av; - int ac; - char dostates = No; - char do_unames = Yes; - char interactive = Maybe; - char warnings = 0; -#if Default_TOPN == Infinity - char topn_specified = No; -#endif - char ch; - char *iptr; - char no_command = 1; - struct timeval timeout; - struct process_select ps; -#ifdef ORDER - char *order_name = NULL; - int order_index = 0; +#ifdef BSD_SIGNALS + (void) sigsetmask(sigblock(0) & ~(sigmask(sig))); #endif -#ifndef FD_SET - /* FD_SET and friends are not present: fake it */ - typedef int fd_set; -#define FD_ZERO(x) (*(x) = 0) -#define FD_SET(f, x) (*(x) = 1<<f) +} + +RETSIGTYPE +sig_leave(int i) /* exit under normal conditions -- INT handler */ + +{ + screen_end(); + exit(EX_OK); +} + +RETSIGTYPE +sig_tstop(int i) /* SIGTSTP handler */ + +{ + /* move to the lower left */ + screen_end(); + fflush(stdout); + + /* default the signal handler action */ + set_signal(SIGTSTP, SIG_DFL); + + /* unblock the TSTP signal */ + release_signal(SIGTSTP); + + /* send ourselves a TSTP to stop the process */ + (void) kill(0, SIGTSTP); + + /* reset the signal handler */ + set_signal(SIGTSTP, sig_tstop); + + /* reinit screen */ + screen_reinit(); + + /* jump back to a known place in the main loop */ + longjmp(jmp_int, JMP_RESUME); + + /* NOTREACHED */ +} + +#ifdef SIGWINCH +RETSIGTYPE +sig_winch(int i) /* SIGWINCH handler */ + +{ + /* reascertain the screen dimensions */ + screen_getsize(); + + /* jump back to a known place in the main loop */ + longjmp(jmp_int, JMP_RESIZE); +} #endif - fd_set readfds; -#ifdef ORDER - static char command_chars[] = "\f qh?en#sdkriIuo"; -#else - static char command_chars[] = "\f qh?en#sdkriIu"; -#endif -/* these defines enumerate the "strchr"s of the commands in command_chars */ -#define CMD_redraw 0 -#define CMD_update 1 -#define CMD_quit 2 -#define CMD_help1 3 -#define CMD_help2 4 -#define CMD_OSLIMIT 4 /* terminals with OS can only handle commands */ -#define CMD_errors 5 /* less than or equal to CMD_OSLIMIT */ -#define CMD_number1 6 -#define CMD_number2 7 -#define CMD_delay 8 -#define CMD_displays 9 -#define CMD_kill 10 -#define CMD_renice 11 -#define CMD_idletog 12 -#define CMD_idletog2 13 -#define CMD_user 14 -#ifdef ORDER -#define CMD_order 15 -#endif - - /* set the buffer for stdout */ -#ifdef DEBUG - extern FILE *debug; - debug = fopen("debug.run", "w"); - setbuffer(stdout, NULL, 0); -#else - setbuffer(stdout, stdoutbuf, Buffersize); +#ifdef HAVE_SIGACTION +static sigset_t signalset; #endif - /* get our name */ - if (argc > 0) - { - if ((myname = strrchr(argv[0], '/')) == 0) - { - myname = argv[0]; - } - else - { - myname++; - } - } +void * +hold_signals() + +{ +#ifdef HAVE_SIGACTION + sigemptyset(&signalset); + sigaddset(&signalset, SIGINT); + sigaddset(&signalset, SIGQUIT); + sigaddset(&signalset, SIGTSTP); +#ifdef SIGWINCH + sigaddset(&signalset, SIGWINCH); +#endif + sigprocmask(SIG_BLOCK, &signalset, NULL); + return (void *)(&signalset); +#endif - /* initialize some selection options */ - ps.idle = Yes; - ps.system = No; - ps.uid = -1; - ps.command = NULL; +#ifdef HAVE_SIGHOLD + sighold(SIGINT); + sighold(SIGQUIT); + sighold(SIGTSTP); +#ifdef SIGWINCH + sighold(SIGWINCH); + return NULL; +#endif +#endif - /* get preset options from the environment */ - if ((env_top = getenv("TOP")) != NULL) - { - av = preset_argv = argparse(env_top, &preset_argc); - ac = preset_argc; +#ifdef BSD_SIGNALS + int mask; +#ifdef SIGWINCH + mask = sigblock(sigmask(SIGINT) | sigmask(SIGQUIT) | + sigmask(SIGTSTP) | sigmask(SIGWINCH)); +#else + mask = sigblock(sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGTSTP)); + return (void *)mask; +#endif +#endif - /* set the dummy argument to an explanatory message, in case - getopt encounters a bad argument */ - preset_argv[0] = "while processing environment"; - } +} - /* process options */ - do { - /* if we're done doing the presets, then process the real arguments */ - if (preset_argc == 0) - { - ac = argc; - av = argv; +void +set_signals() - /* this should keep getopt happy... */ - optind = 1; - } +{ + (void) set_signal(SIGINT, sig_leave); + (void) set_signal(SIGQUIT, sig_leave); + (void) set_signal(SIGTSTP, sig_tstop); +#ifdef SIGWINCH + (void) set_signal(SIGWINCH, sig_winch); +#endif +} - while ((i = getopt(ac, av, "SIbinquvs:d:U:o:")) != EOF) - { - switch(i) - { - case 'v': /* show version number */ - fprintf(stderr, "%s: version %s\n", - myname, version_string()); - exit(1); - break; +void +release_signals(void *parm) - case 'u': /* toggle uid/username display */ - do_unames = !do_unames; - break; +{ +#ifdef HAVE_SIGACTION + sigprocmask(SIG_UNBLOCK, (sigset_t *)parm, NULL); +#endif - case 'U': /* display only username's processes */ - if ((ps.uid = userid(optarg)) == -1) - { - fprintf(stderr, "%s: unknown user\n", optarg); - exit(1); - } - break; +#ifdef HAVE_SIGHOLD + sigrelse(SIGINT); + sigrelse(SIGQUIT); + sigrelse(SIGTSTP); +#ifdef SIGWINCH + sigrelse(SIGWINCH); +#endif +#endif - case 'S': /* show system processes */ - ps.system = !ps.system; - break; +#ifdef BSD_SIGNALS + (void) sigsetmask((int)parm); +#endif +} - case 'I': /* show idle processes */ - ps.idle = !ps.idle; - break; +/* + * void do_arguments(globalstate *gstate, int ac, char **av) + * + * Arguments processing. gstate points to the global state, + * ac and av are the arguments to process. This can be called + * multiple times with different sets of arguments. + */ - case 'i': /* go interactive regardless */ - interactive = Yes; - break; +#ifdef HAVE_GETOPT_LONG +static struct option longopts[] = { + { "color", no_argument, NULL, 'C' }, + { "debug", no_argument, NULL, 'D' }, + { "system-procs", no_argument, NULL, 'S' }, + { "idle-procs", no_argument, NULL, 'I' }, + { "tag-names", no_argument, NULL, 'T' }, + { "all", no_argument, NULL, 'a' }, + { "batch", no_argument, NULL, 'b' }, + { "full-commands", no_argument, NULL, 'c' }, + { "interactive", no_argument, NULL, 'i' }, + { "quick", no_argument, NULL, 'q' }, + { "threads", no_argument, NULL, 't' }, + { "uids", no_argument, NULL, 'u' }, + { "version", no_argument, NULL, 'v' }, + { "delay", required_argument, NULL, 's' }, + { "displays", required_argument, NULL, 'd' }, + { "user", required_argument, NULL, 'U' }, + { "sort-order", required_argument, NULL, 'o' }, + { "display-mode", required_argument, NULL, 'm' }, + { NULL, 0, NULL, 0 }, +}; +#endif - case 'n': /* batch, or non-interactive */ - case 'b': - interactive = No; - break; - case 'd': /* number of displays to show */ - if ((i = atoiwi(optarg)) == Invalid || i == 0) - { - fprintf(stderr, - "%s: warning: display count should be positive -- option ignored\n", - myname); - warnings++; - } - else - { - displays = i; - } - break; +void +do_arguments(globalstate *gstate, int ac, char **av) - case 's': - if ((delay = atoi(optarg)) < 0 || (delay == 0 && getuid() != 0)) - { - fprintf(stderr, - "%s: warning: seconds delay should be positive -- using default\n", - myname); - delay = Default_DELAY; - warnings++; - } - break; +{ + int i; - case 'q': /* be quick about it */ - /* only allow this if user is really root */ - if (getuid() == 0) - { - /* be very un-nice! */ - (void) nice(-20); - } - else - { - fprintf(stderr, - "%s: warning: `-q' option can only be used by root\n", - myname); - warnings++; - } - break; + /* this appears to keep getopt happy */ + optind = 1; - case 'o': /* select sort order */ -#ifdef ORDER - order_name = optarg; +#ifdef HAVE_GETOPT_LONG + while ((i = getopt_long(ac, av, "CDSITabcinqtuvs:d:U:o:m:", longopts, NULL)) != -1) #else - fprintf(stderr, - "%s: this platform does not support arbitrary ordering. Sorry.\n", - myname); - warnings++; + while ((i = getopt(ac, av, "CDSITabcinqtuvs:d:U:o:m:")) != EOF) +#endif + { + switch(i) + { +#ifdef ENABLE_COLOR + case 'C': + gstate->use_color = !gstate->use_color; + break; #endif - break; - default: - fprintf(stderr, "\ -Top version %s\n\ -Usage: %s [-ISbinqu] [-d x] [-s x] [-o field] [-U username] [number]\n", - version_string(), myname); - exit(1); + case 'D': + debug_set(1); + break; + + case 'v': + fprintf(stderr, "%s: version %s\n", myname, version_string()); + exit(EX_OK); + break; + + case 'b': + case 'n': + gstate->interactive = No; + break; + + case 'a': + gstate->displays = Infinity; + gstate->topn = Infinity; + break; + + case 'i': + gstate->interactive = Yes; + break; + + case 'o': + gstate->order_name = optarg; + break; + + case 'd': + i = atoiwi(optarg); + if (i == Invalid || i == 0) + { + message_error(" Bad display count"); } - } + else + { + gstate->displays = i; + } + break; - /* get count of top processes to display (if any) */ - if (optind < ac) - { - if ((topn = atoiwi(av[optind])) == Invalid) + case 's': + i = atoi(optarg); + if (i < 0 || (i == 0 && getuid() != 0)) { - fprintf(stderr, - "%s: warning: process display count should be non-negative -- using default\n", - myname); - warnings++; + message_error(" Bad seconds delay"); } -#if Default_TOPN == Infinity - else + else { - topn_specified = Yes; + gstate->delay = i; } -#endif - } + break; - /* tricky: remember old value of preset_argc & set preset_argc = 0 */ - i = preset_argc; - preset_argc = 0; + case 'u': + gstate->show_usernames = !gstate->show_usernames; + break; - /* repeat only if we really did the preset arguments */ - } while (i != 0); + case 'U': + i = userid(optarg); + if (i == -1) + { + message_error(" Unknown user '%s'", optarg); + } + else + { + gstate->pselect.uid = i; + } + break; - /* set constants for username/uid display correctly */ - if (!do_unames) - { - uname_field = " UID "; - get_userid = itoa7; - } + case 'm': + i = atoi(optarg); + gstate->pselect.mode = i; + break; - /* initialize the kernel memory interface */ - if (machine_init(&statics) == -1) - { - exit(1); - } + case 'S': + gstate->pselect.system = !gstate->pselect.system; + break; -#ifdef ORDER - /* determine sorting order index, if necessary */ - if (order_name != NULL) - { - if ((order_index = string_index(order_name, statics.order_names)) == -1) - { - char **pp; + case 'I': + gstate->pselect.idle = !gstate->pselect.idle; + break; - fprintf(stderr, "%s: '%s' is not a recognized sorting order.\n", - myname, order_name); - fprintf(stderr, "\tTry one of these:"); - pp = statics.order_names; - while (*pp != NULL) +#ifdef ENABLE_COLOR + case 'T': + gstate->show_tags = 1; + break; +#endif + + case 'c': + gstate->pselect.fullcmd = !gstate->pselect.fullcmd; + break; + + case 't': + gstate->pselect.threads = !gstate->pselect.threads; + break; + + case 'q': /* be quick about it */ + /* only allow this if user is really root */ + if (getuid() == 0) + { + /* be very un-nice! */ + (void) nice(-20); + } + else { - fprintf(stderr, " %s", *pp++); + message_error(" Option -q can only be used by root"); } - fputc('\n', stderr); - exit(1); + break; + + default: + fprintf(stderr, "\ +Top version %s\n\ +Usage: %s [-ISTabcinqu] [-d x] [-s x] [-o field] [-U username] [number]\n", + version_string(), myname); + exit(EX_USAGE); } } -#endif -#ifdef no_initialization_needed - /* initialize the hashing stuff */ - if (do_unames) + /* get count of top processes to display */ + if (optind < ac && *av[optind]) { - init_hash(); + if ((i = atoiwi(av[optind])) == Invalid) + { + message_error(" Process count not a number"); + } + else + { + gstate->topn = i; + } } -#endif +} - /* initialize termcap */ - init_termcap(interactive); +void +do_display(globalstate *gstate) - /* get the string to use for the process area header */ - header_text = format_header(uname_field); +{ + int active_procs; + int i; + time_t curr_time; + caddr_t processes; + struct system_info system_info; + char *hdr; - /* initialize display interface */ - if ((max_topn = display_init(&statics)) == -1) - { - fprintf(stderr, "%s: can't allocate sufficient memory\n", myname); - exit(4); - } - - /* print warning if user requested more processes than we can display */ - if (topn > max_topn) - { - fprintf(stderr, - "%s: warning: this terminal can only display %d processes.\n", - myname, max_topn); - warnings++; - } + /* get the time */ + time_mark(&(gstate->now)); + curr_time = (time_t)(gstate->now.tv_sec); - /* adjust for topn == Infinity */ - if (topn == Infinity) - { - /* - * For smart terminals, infinity really means everything that can - * be displayed, or Largest. - * On dumb terminals, infinity means every process in the system! - * We only really want to do that if it was explicitly specified. - * This is always the case when "Default_TOPN != Infinity". But if - * topn wasn't explicitly specified and we are on a dumb terminal - * and the default is Infinity, then (and only then) we use - * "Nominal_TOPN" instead. - */ -#if Default_TOPN == Infinity - topn = smart_terminal ? Largest : - (topn_specified ? Largest : Nominal_TOPN); -#else - topn = Largest; -#endif - } + /* get the current stats */ + get_system_info(&system_info); - /* set header display accordingly */ - display_header(topn > 0); + /* get the current processes */ + processes = get_process_info(&system_info, &(gstate->pselect), gstate->order_index); - /* determine interactive state */ - if (interactive == Maybe) + /* determine number of processes to actually display */ + if (gstate->topn > 0) { - interactive = smart_terminal; + /* this number will be the smallest of: active processes, + number user requested, number current screen accomodates */ + active_procs = system_info.P_ACTIVE; + if (active_procs > gstate->topn) + { + active_procs = gstate->topn; + } + if (active_procs > gstate->max_topn) + { + active_procs = gstate->max_topn; + } } - - /* if # of displays not specified, fill it in */ - if (displays == 0) + else { - displays = smart_terminal ? Infinity : 1; + /* dont show any */ + active_procs = 0; } - /* hold interrupt signals while setting up the screen and the handlers */ -#ifdef SIGHOLD - sighold(SIGINT); - sighold(SIGQUIT); - sighold(SIGTSTP); -#else - old_sigmask = sigblock(Smask(SIGINT) | Smask(SIGQUIT) | Smask(SIGTSTP)); -#endif - init_screen(); - (void) signal(SIGINT, leave); - (void) signal(SIGQUIT, leave); - (void) signal(SIGTSTP, tstop); -#ifdef SIGWINCH - (void) signal(SIGWINCH, winch); -#endif -#ifdef SIGRELSE - sigrelse(SIGINT); - sigrelse(SIGQUIT); - sigrelse(SIGTSTP); +#ifdef HAVE_FORMAT_PROCESS_HEADER + /* get the process header to use */ + hdr = format_process_header(&(gstate->pselect), processes, active_procs); #else - (void) sigsetmask(old_sigmask); + hdr = gstate->header_text; #endif - if (warnings) - { - fputs("....", stderr); - fflush(stderr); /* why must I do this? */ - sleep((unsigned)(3 * warnings)); - fputc('\n', stderr); - } - - /* setup the jump buffer for stops */ - if (setjmp(jmp_int) != 0) - { - /* control ends up here after an interrupt */ - reset_display(); - } - - /* - * main loop -- repeat while display count is positive or while it - * indicates infinity (by being -1) - */ - while ((displays == -1) || (displays-- > 0)) + /* full screen or update? */ + if (gstate->fulldraw) { - /* get the current stats */ - get_system_info(&system_info); - - /* get the current set of processes */ - processes = - get_process_info(&system_info, - &ps, -#ifdef ORDER - proc_compares[order_index]); -#else - proc_compare); -#endif - - /* display the load averages */ - (*d_loadave)(system_info.last_pid, - system_info.load_avg); - - /* display the current time */ - /* this method of getting the time SHOULD be fairly portable */ - time(&curr_time); + display_clear(); + i_loadave(system_info.last_pid, system_info.load_avg); + i_uptime(&(gstate->statics->boottime), &curr_time); i_timeofday(&curr_time); - - /* display process state breakdown */ - (*d_procstates)(system_info.p_total, - system_info.procstates); - - /* display the cpu state percentage breakdown */ - if (dostates) /* but not the first time */ + i_procstates(system_info.p_total, system_info.procstates, gstate->pselect.threads); + if (gstate->show_cpustates) { - (*d_cpustates)(system_info.cpustates); + i_cpustates(system_info.cpustates); } else { - /* we'll do it next time */ if (smart_terminal) { z_cpustates(); } - else - { - putchar('\n'); - } - dostates = Yes; + gstate->show_cpustates = Yes; + } + i_kernel(system_info.kernel); + i_memory(system_info.memory); + i_swap(system_info.swap); + i_message(&(gstate->now)); + i_header(hdr); + for (i = 0; i < active_procs; i++) + { + i_process(i, format_next_process(processes, gstate->get_userid)); } + i_endscreen(); + if (gstate->smart_terminal) + { + gstate->fulldraw = No; + } + } + else + { + u_loadave(system_info.last_pid, system_info.load_avg); + u_uptime(&(gstate->statics->boottime), &curr_time); + i_timeofday(&curr_time); + u_procstates(system_info.p_total, system_info.procstates, gstate->pselect.threads); + u_cpustates(system_info.cpustates); + u_kernel(system_info.kernel); + u_memory(system_info.memory); + u_swap(system_info.swap); + u_message(&(gstate->now)); + u_header(hdr); + for (i = 0; i < active_procs; i++) + { + u_process(i, format_next_process(processes, gstate->get_userid)); + } + u_endscreen(); + } +} - /* display memory stats */ - (*d_memory)(system_info.memory); +#ifdef DEBUG +void +timeval_xdprint(char *s, struct timeval tv) + +{ + xdprintf("%s %d.%06d\n", s, tv.tv_sec, tv.tv_usec); +} +#endif + +void +do_wait(globalstate *gstate) + +{ + struct timeval wait; + + wait.tv_sec = gstate->delay; + wait.tv_usec = 0; + select(0, NULL, NULL, NULL, &wait); +} + +void +do_command(globalstate *gstate) + +{ + int status; + struct timeval wait = {0, 0}; + struct timeval now; + fd_set readfds; + unsigned char ch; - /* handle message area */ - (*d_message)(); + /* calculate new refresh time */ + gstate->refresh = gstate->now; + gstate->refresh.tv_sec += gstate->delay; + time_get(&now); - /* update the header area */ - (*d_header)(header_text); - - if (topn > 0) + /* loop waiting for time to expire */ + do { + /* calculate time to wait */ + if (gstate->delay > 0) { - /* determine number of processes to actually display */ - /* this number will be the smallest of: active processes, - number user requested, number current screen accomodates */ - active_procs = system_info.P_ACTIVE; - if (active_procs > topn) + wait = gstate->refresh; + wait.tv_usec -= now.tv_usec; + if (wait.tv_usec < 0) { - active_procs = topn; + wait.tv_usec += 1000000; + wait.tv_sec--; } - if (active_procs > max_topn) + wait.tv_sec -= now.tv_sec; + } + + /* set up arguments for select on stdin (0) */ + FD_ZERO(&readfds); + FD_SET(STDIN_FILENO, &readfds); + + /* wait for something to read or time out */ + if (select(32, &readfds, NULL, NULL, &wait) > 0) + { + /* read it */ + if (read(STDIN_FILENO, &ch, 1) != 1) { - active_procs = max_topn; + /* read error */ + message_error(" Read error on stdin"); + quit(EX_DATAERR); + /*NOTREACHED*/ } - /* now show the top "n" processes. */ - for (i = 0; i < active_procs; i++) + /* mark pending messages as old */ + message_mark(); + + /* dispatch */ + status = command_process(gstate, (int)ch); + switch(status) { - (*d_process)(i, format_next_process(processes, get_userid)); + case CMD_ERROR: + quit(EX_SOFTWARE); + /*NOTREACHED*/ + + case CMD_REFRESH: + return; + + case CMD_UNKNOWN: + message_error(" Unknown command"); + break; + + case CMD_NA: + message_error(" Command not available"); } } - else - { - i = 0; - } - /* do end-screen processing */ - u_endscreen(i); + /* get new time */ + time_get(&now); + } while (timercmp(&now, &(gstate->refresh), < )); +} + +void +do_minidisplay(globalstate *gstate) - /* now, flush the output buffer */ - if (fflush(stdout) != 0) +{ + int real_delay; + struct system_info si; + + /* save the real delay and substitute 1 second */ + real_delay = gstate->delay; + gstate->delay = 1; + + /* wait 1 second for a command */ + time_mark(&(gstate->now)); + do_command(gstate); + + /* do a mini update that only updates the cpustates */ + get_system_info(&si); + u_cpustates(si.cpustates); + + /* restore the delay time */ + gstate->delay = real_delay; + + /* done */ + i_endscreen(); +} + +int +main(int argc, char *argv[]) + +{ + char *env_top; + char **preset_argv; + int preset_argc = 0; + void *mask; + int need_mini = 1; + + struct statics statics; + globalstate *gstate; + + /* get our name */ + if (argc > 0) + { + if ((myname = strrchr(argv[0], '/')) == 0) { - new_message(MT_standout, " Write error on stdout"); - putchar('\r'); - quit(1); - /*NOTREACHED*/ + myname = argv[0]; + } + else + { + myname++; } + } - /* only do the rest if we have more displays to show */ - if (displays) + /* binary compatibility check */ +#ifdef HAVE_UNAME + { + struct utsname uts; + + if (uname(&uts) == 0) { - /* switch out for new display on smart terminals */ - if (smart_terminal) - { - if (overstrike) - { - reset_display(); - } - else - { - d_loadave = u_loadave; - d_procstates = u_procstates; - d_cpustates = u_cpustates; - d_memory = u_memory; - d_message = u_message; - d_header = u_header; - d_process = u_process; - } - } - - no_command = Yes; - if (!interactive) - { - /* set up alarm */ - (void) signal(SIGALRM, onalrm); - (void) alarm((unsigned)delay); - - /* wait for the rest of it .... */ - pause(); - } - else while (no_command) + if (strcmp(uts.machine, UNAME_HARDWARE) != 0) { - /* assume valid command unless told otherwise */ - no_command = No; - - /* set up arguments for select with timeout */ - FD_ZERO(&readfds); - FD_SET(0, &readfds); /* for standard input */ - timeout.tv_sec = delay; - timeout.tv_usec = 0; - - /* wait for either input or the end of the delay period */ - if (select(32, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timeout) > 0) - { - int newval; - char *errmsg; - - /* something to read -- clear the message area first */ - clear_message(); - - /* now read it and convert to command strchr */ - /* (use "change" as a temporary to hold strchr) */ - if (read(0, &ch, 1) != 1) - { - /* read error: either 0 or -1 */ - new_message(MT_standout, " Read error on stdin"); - putchar('\r'); - quit(1); - /*NOTREACHED*/ - } - if ((iptr = strchr(command_chars, ch)) == NULL) - { - /* illegal command */ - new_message(MT_standout, " Command not understood"); - putchar('\r'); - no_command = Yes; - } - else - { - change = iptr - command_chars; - if (overstrike && change > CMD_OSLIMIT) - { - /* error */ - new_message(MT_standout, - " Command cannot be handled by this terminal"); - putchar('\r'); - no_command = Yes; - } - else switch(change) - { - case CMD_redraw: /* redraw screen */ - reset_display(); - break; - - case CMD_update: /* merely update display */ - /* is the load average high? */ - if (system_info.load_avg[0] > LoadMax) - { - /* yes, go home for visual feedback */ - go_home(); - fflush(stdout); - } - break; - - case CMD_quit: /* quit */ - quit(0); - /*NOTREACHED*/ - break; - - case CMD_help1: /* help */ - case CMD_help2: - reset_display(); - clear(); - show_help(); - standout("Hit any key to continue: "); - fflush(stdout); - (void) read(0, &ch, 1); - break; - - case CMD_errors: /* show errors */ - if (error_count() == 0) - { - new_message(MT_standout, - " Currently no errors to report."); - putchar('\r'); - no_command = Yes; - } - else - { - reset_display(); - clear(); - show_errors(); - standout("Hit any key to continue: "); - fflush(stdout); - (void) read(0, &ch, 1); - } - break; - - case CMD_number1: /* new number */ - case CMD_number2: - new_message(MT_standout, - "Number of processes to show: "); - newval = readline(tempbuf1, 8, Yes); - if (newval > -1) - { - if (newval > max_topn) - { - new_message(MT_standout | MT_delayed, - " This terminal can only display %d processes.", - max_topn); - putchar('\r'); - } - - if (newval == 0) - { - /* inhibit the header */ - display_header(No); - } - else if (newval > topn && topn == 0) - { - /* redraw the header */ - display_header(Yes); - d_header = i_header; - } - topn = newval; - } - break; - - case CMD_delay: /* new seconds delay */ - new_message(MT_standout, "Seconds to delay: "); - if ((i = readline(tempbuf1, 8, Yes)) > -1) - { - if ((delay = i) == 0 && getuid() != 0) - { - delay = 1; - } - } - clear_message(); - break; - - case CMD_displays: /* change display count */ - new_message(MT_standout, - "Displays to show (currently %s): ", - displays == -1 ? "infinite" : - itoa(displays)); - if ((i = readline(tempbuf1, 10, Yes)) > 0) - { - displays = i; - } - else if (i == 0) - { - quit(0); - } - clear_message(); - break; - - case CMD_kill: /* kill program */ - new_message(0, "kill "); - if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) - { - if ((errmsg = kill_procs(tempbuf2)) != NULL) - { - new_message(MT_standout, errmsg); - putchar('\r'); - no_command = Yes; - } - } - else - { - clear_message(); - } - break; - - case CMD_renice: /* renice program */ - new_message(0, "renice "); - if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) - { - if ((errmsg = renice_procs(tempbuf2)) != NULL) - { - new_message(MT_standout, errmsg); - putchar('\r'); - no_command = Yes; - } - } - else - { - clear_message(); - } - break; - - case CMD_idletog: - case CMD_idletog2: - ps.idle = !ps.idle; - new_message(MT_standout | MT_delayed, - " %sisplaying idle processes.", - ps.idle ? "D" : "Not d"); - putchar('\r'); - break; - - case CMD_user: - new_message(MT_standout, - "Username to show: "); - if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) - { - if (tempbuf2[0] == '+' && - tempbuf2[1] == '\0') - { - ps.uid = -1; - } - else if ((i = userid(tempbuf2)) == -1) - { - new_message(MT_standout, - " %s: unknown user", tempbuf2); - no_command = Yes; - } - else - { - ps.uid = i; - } - putchar('\r'); - } - else - { - clear_message(); - } - break; - -#ifdef ORDER - case CMD_order: - new_message(MT_standout, - "Order to sort: "); - if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) - { - if ((i = string_index(tempbuf2, statics.order_names)) == -1) - { - new_message(MT_standout, - " %s: unrecognized sorting order", tempbuf2); - no_command = Yes; - } - else - { - order_index = i; - } - putchar('\r'); - } - else - { - clear_message(); - } - break; -#endif - - default: - new_message(MT_standout, " BAD CASE IN SWITCH!"); - putchar('\r'); - } - } - - /* flush out stuff that may have been written */ - fflush(stdout); - } + fprintf(stderr, "%s: incompatible hardware platform\n", + myname); + exit(EX_UNAVAILABLE); } } } +#endif -#ifdef DEBUG - fclose(debug); + /* initialization */ + gstate = (globalstate *)calloc(1, sizeof(globalstate)); + gstate->statics = &statics; + time_mark(NULL); + + /* preset defaults for various options */ + gstate->show_usernames = Yes; + gstate->topn = DEFAULT_TOPN; + gstate->delay = DEFAULT_DELAY; + gstate->fulldraw = Yes; + gstate->use_color = Yes; + gstate->interactive = Maybe; + + /* preset defaults for process selection */ + gstate->pselect.idle = Yes; + gstate->pselect.system = No; + gstate->pselect.fullcmd = No; + gstate->pselect.command = NULL; + gstate->pselect.uid = -1; + gstate->pselect.mode = 0; + + /* use a large buffer for stdout */ +#ifdef HAVE_SETVBUF + setvbuf(stdout, stdoutbuf, _IOFBF, BUFFERSIZE); +#else +#ifdef HAVE_SETBUFFER + setbuffer(stdout, stdoutbuf, BUFFERSIZE); +#endif #endif - quit(0); - /*NOTREACHED*/ -} -/* - * reset_display() - reset all the display routine pointers so that entire - * screen will get redrawn. - */ + /* get preset options from the environment */ + if ((env_top = getenv("TOP")) != NULL) + { + preset_argv = argparse(env_top, &preset_argc); + preset_argv[0] = myname; + do_arguments(gstate, preset_argc, preset_argv); + } -reset_display() + /* process arguments */ + do_arguments(gstate, argc, argv); -{ - d_loadave = i_loadave; - d_procstates = i_procstates; - d_cpustates = i_cpustates; - d_memory = i_memory; - d_message = i_message; - d_header = i_header; - d_process = i_process; -} +#ifdef ENABLE_COLOR + /* If colour has been turned on read in the settings. */ + env_top = getenv("TOPCOLOURS"); + if (!env_top) + { + env_top = getenv("TOPCOLORS"); + } + /* must do something about error messages */ + color_env_parse(env_top); + color_activate(gstate->use_color); +#endif -/* - * signal handlers - */ + /* in order to support forward compatability, we have to ensure that + the entire statics structure is set to a known value before we call + machine_init. This way fields that a module does not know about + will retain their default values */ + memzero((void *)&statics, sizeof(statics)); + statics.boottime = -1; -sigret_t leave() /* exit under normal conditions -- INT handler */ + /* call the platform-specific init */ + if (machine_init(&statics) == -1) + { + exit(EX_SOFTWARE); + } -{ - end_screen(); - exit(0); -} + /* create a helper list of sort order names */ + gstate->order_namelist = string_list(statics.order_names); -sigret_t tstop(i) /* SIGTSTP handler */ + /* look up chosen sorting order */ + if (gstate->order_name != NULL) + { + int i; -int i; + if (statics.order_names == NULL) + { + message_error(" This platform does not support arbitrary ordering"); + } + else if ((i = string_index(gstate->order_name, + statics.order_names)) == -1) + { + message_error(" Sort order `%s' not recognized", gstate->order_name); + message_error(" Recognized sort orders: %s", gstate->order_namelist); + } + else + { + gstate->order_index = i; + } + } -{ - /* move to the lower left */ - end_screen(); - fflush(stdout); + /* initialize extensions */ + init_username(); - /* default the signal handler action */ - (void) signal(SIGTSTP, SIG_DFL); + /* initialize termcap */ + gstate->smart_terminal = screen_readtermcap(gstate->interactive); - /* unblock the signal and send ourselves one */ -#ifdef SIGRELSE - sigrelse(SIGTSTP); -#else - (void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1))); -#endif - (void) kill(0, SIGTSTP); + /* determine interactive state */ + if (gstate->interactive == Maybe) + { + gstate->interactive = smart_terminal; + } - /* reset the signal handler */ - (void) signal(SIGTSTP, tstop); + /* if displays were not specified, choose an appropriate default */ + if (gstate->displays == 0) + { + gstate->displays = gstate->smart_terminal ? Infinity: 1; + } - /* reinit screen */ - reinit_screen(); + /* we don't need a mini display when delay is less than 2 + seconds or when we are not on a smart terminal */ + if (gstate->delay <= 1 || !smart_terminal) + { + need_mini = 0; + } - /* jump to appropriate place */ - longjmp(jmp_int, 1); +#ifndef HAVE_FORMAT_PROCESS_HEADER + /* set constants for username/uid display */ + if (gstate->show_usernames) + { + gstate->header_text = format_header("USERNAME"); + gstate->get_userid = username; + } + else + { + gstate->header_text = format_header(" UID "); + gstate->get_userid = itoa7; + } +#endif + gstate->pselect.usernames = gstate->show_usernames; - /*NOTREACHED*/ -} + /* initialize display */ + if ((gstate->max_topn = display_init(&statics)) == -1) + { + fprintf(stderr, "%s: can't allocate sufficient memory\n", myname); + exit(EX_OSERR); + } -#ifdef SIGWINCH -sigret_t winch(i) /* SIGWINCH handler */ + /* check for infinity and for overflowed screen */ + if (gstate->topn == Infinity) + { + gstate->topn = INT_MAX; + } + else if (gstate->topn > gstate->max_topn) + { + message_error(" This terminal can only display %d processes", + gstate->max_topn); + } -int i; +#ifdef ENABLE_COLOR + /* producing a list of color tags is easy */ + if (gstate->show_tags) + { + color_dump(stdout); + exit(EX_OK); + } +#endif -{ - /* reascertain the screen dimensions */ - get_screensize(); + /* hold all signals while we initialize the screen */ + mask = hold_signals(); + screen_init(); - /* tell display to resize */ - max_topn = display_resize(); + /* set the signal handlers */ + set_signals(); - /* reset the signal handler */ - (void) signal(SIGWINCH, winch); + /* longjmp re-entry point */ + /* set the jump buffer for long jumps out of signal handlers */ + if (setjmp(jmp_int) != 0) + { + /* this is where we end up after processing sigwinch or sigtstp */ - /* jump to appropriate place */ - longjmp(jmp_int, 1); -} -#endif + /* tell display to resize its buffers, and get the new length */ + if ((gstate->max_topn = display_resize()) == -1) + { + /* thats bad */ + quit(EX_OSERR); + /*NOTREACHED*/ + } -void quit(status) /* exit under duress */ + /* set up for a full redraw, and get the current line count */ + gstate->fulldraw = Yes; -int status; + /* safe to release the signals now */ + release_signals(mask); + } + else + { + /* release the signals */ + release_signals(mask); -{ - end_screen(); - exit(status); - /*NOTREACHED*/ -} + /* some systems require a warmup */ + /* always do a warmup for batch mode */ + if (gstate->interactive == 0 || statics.flags.warmup) + { + struct system_info system_info; + struct timeval timeout; + + time_mark(&(gstate->now)); + get_system_info(&system_info); + (void)get_process_info(&system_info, &gstate->pselect, 0); + timeout.tv_sec = 1; + timeout.tv_usec = 0; + select(0, NULL, NULL, NULL, &timeout); + + /* if we've warmed up, then we can show good states too */ + gstate->show_cpustates = Yes; + need_mini = 0; + } + } -sigret_t onalrm() /* SIGALRM handler */ + /* main loop */ + while ((gstate->displays == -1) || (--gstate->displays > 0)) + { + do_display(gstate); + if (gstate->interactive) + { + if (need_mini) + { + do_minidisplay(gstate); + need_mini = 0; + } + do_command(gstate); + } + else + { + do_wait(gstate); + } + } -{ - /* this is only used in batch mode to break out of the pause() */ - /* return; */ -} + /* do one last display */ + do_display(gstate); + quit(EX_OK); + /* NOTREACHED */ + return 1; /* Keep compiler quiet. */ +} @@ -1,26 +1,52 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * Top - a top users display for Berkeley Unix * * General (global) definitions */ -/* Current major version number */ -#define VERSION 3 +#ifndef _TOP_H_ +#define _TOP_H_ -/* Number of lines of header information on the standard screen */ -#define Header_lines 6 +#include <sys/time.h> /* Maximum number of columns allowed for display */ -#define MAX_COLS 128 +#define MAX_COLS 255 /* Log base 2 of 1024 is 10 (2^10 == 1024) */ #define LOG1024 10 -char *itoa(); -char *itoa7(); - -char *version_string(); - /* Special atoi routine returns either a non-negative number or one of: */ #define Infinity -1 #define Invalid -2 @@ -34,3 +60,21 @@ char *version_string(); #define NUM_AVERAGES 3 +struct ext_decl { + int (*f_minibar)(char *, int); + int (*f_display)(char *, int); +}; + +/* + * "Table_size" defines the size of the hash tables used to map uid to + * username. Things will work best if the number is a prime number. + * We use a number that should be suitable for most installations. + */ +#ifndef Table_size +#define Table_size 8191 +#endif + +void gettime(struct timeval *); +void quit(int); + +#endif /* _TOP_H_ */ diff --git a/top.local.H b/top.local.H deleted file mode 100644 index 9eb7a64e532a..000000000000 --- a/top.local.H +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Top - a top users display for Berkeley Unix - * - * Definitions for things that might vary between installations. - */ - -/* - * The space command forces an immediate update. Sometimes, on loaded - * systems, this update will take a significant period of time (because all - * the output is buffered). So, if the short-term load average is above - * "LoadMax", then top will put the cursor home immediately after the space - * is pressed before the next update is attempted. This serves as a visual - * acknowledgement of the command. On Suns, "LoadMax" will get multiplied by - * "FSCALE" before being compared to avenrun[0]. Therefore, "LoadMax" - * should always be specified as a floating point number. - */ -#ifndef LoadMax -#define LoadMax %LoadMax% -#endif - -/* - * "Table_size" defines the size of the hash tables used to map uid to - * username. The number of users in /etc/passwd CANNOT be greater than - * this number. If the error message "table overflow: too many users" - * is printed by top, then "Table_size" needs to be increased. Things will - * work best if the number is a prime number that is about twice the number - * of lines in /etc/passwd. - */ -#ifndef Table_size -#define Table_size %TableSize% -#endif - -/* - * "Nominal_TOPN" is used as the default TOPN when Default_TOPN is Infinity - * and the output is a dumb terminal. If we didn't do this, then - * installations who use a default TOPN of Infinity will get every - * process in the system when running top on a dumb terminal (or redirected - * to a file). Note that Nominal_TOPN is a default: it can still be - * overridden on the command line, even with the value "infinity". - */ -#ifndef Nominal_TOPN -#define Nominal_TOPN %NominalTopn% -#endif - -#ifndef Default_TOPN -#define Default_TOPN %topn% -#endif - -#ifndef Default_DELAY -#define Default_DELAY %delay% -#endif - -/* - * If the local system's getpwnam interface uses random access to retrieve - * a record (i.e.: 4.3 systems, Sun "yellow pages"), then defining - * RANDOM_PW will take advantage of that fact. If RANDOM_PW is defined, - * then getpwnam is used and the result is cached. If not, then getpwent - * is used to read and cache the password entries sequentially until the - * desired one is found. - * - * We initially set RANDOM_PW to something which is controllable by the - * Configure script. Then if its value is 0, we undef it. - */ - -#define RANDOM_PW %random% -#if RANDOM_PW == 0 -#undef RANDOM_PW -#endif diff --git a/username.c b/username.c index 4a98a2bfc973..9866bffb320b 100644 --- a/username.c +++ b/username.c @@ -1,185 +1,150 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * Top users/processes display for Unix * Version 3 - * - * This program may be freely redistributed, - * but this entire comment MUST remain intact. - * - * Copyright (c) 1984, 1989, William LeFebvre, Rice University - * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University */ /* * Username translation code for top. * - * These routines handle uid to username mapping. - * They use a hashing table scheme to reduce reading overhead. - * For the time being, these are very straightforward hashing routines. - * Maybe someday I'll put in something better. But with the advent of - * "random access" password files, it might not be worth the effort. - * - * Changes to these have been provided by John Gilmore (gnu@toad.com). + * These routines handle uid to username mapping. They use a hash table to + * reduce reading overhead. Entries are refreshed every EXPIRETIME seconds. * - * The hash has been simplified in this release, to avoid the - * table overflow problems of previous releases. If the value - * at the initial hash location is not right, it is replaced - * by the right value. Collisions will cause us to call getpw* - * but hey, this is a cache, not the Library of Congress. - * This makes the table size independent of the passwd file size. + * The old ad-hoc hash functions have been replaced with something a little + * more formal and (hopefully) more robust (found in hash.c) */ -#include <stdio.h> +#include "os.h" + #include <pwd.h> -#include "top.local.h" +#include "top.h" #include "utils.h" +#include "hash.h" -struct hash_el { - int uid; - char name[9]; -}; +#define EXPIRETIME (60 * 5) -#define is_empty_hash(x) (hash_table[x].name[0] == 0) +/* we need some sort of idea how long usernames can be */ +#ifndef MAXLOGNAME +#ifdef _POSIX_LOGIN_NAME_MAX +#define MAXLOGNAME _POSIX_LOGIN_NAME_MAX +#else +#define MAXLOGNAME 9 +#endif +#endif -/* simple minded hashing function */ -/* Uid "nobody" is -2 results in hashit(-2) = -2 which is out of bounds for - the hash_table. Applied abs() function to fix. 2/16/96 tpugh -*/ -#define hashit(i) (abs(i) % Table_size) +struct hash_data { + int uid; + char name[MAXLOGNAME]; /* big enough? */ + time_t expire; +}; -/* K&R requires that statically declared tables be initialized to zero. */ -/* We depend on that for hash_table and YOUR compiler had BETTER do it! */ -struct hash_el hash_table[Table_size]; +hash_table *userhash; -init_hash() -{ - /* - * There used to be some steps we had to take to initialize things. - * We don't need to do that anymore, but we will leave this stub in - * just in case future changes require initialization steps. - */ -} - -char *username(uid) - -register int uid; +void +init_username() { - register int hashindex; - - hashindex = hashit(uid); - if (is_empty_hash(hashindex) || (hash_table[hashindex].uid != uid)) - { - /* not here or not right -- get it out of passwd */ - hashindex = get_user(uid); - } - return(hash_table[hashindex].name); + userhash = hash_create(211); } -int userid(username) - -char *username; +char * +username(int uid) { - struct passwd *pwd; - - /* Eventually we want this to enter everything in the hash table, - but for now we just do it simply and remember just the result. - */ - - if ((pwd = getpwnam(username)) == NULL) - { - return(-1); - } + struct hash_data *data; + struct passwd *pw; + time_t now; - /* enter the result in the hash table */ - enter_user(pwd->pw_uid, username, 1); + /* what time is it? */ + now = time(NULL); - /* return our result */ - return(pwd->pw_uid); -} - -int enter_user(uid, name, wecare) + /* get whatever is in the cache */ + data = hash_lookup_uint(userhash, (unsigned int)uid); -register int uid; -register char *name; -int wecare; /* 1 = enter it always, 0 = nice to have */ - -{ - register int hashindex; + /* if we had a cache miss, then create space for a new entry */ + if (data == NULL) + { + /* make space */ + data = (struct hash_data *)malloc(sizeof(struct hash_data)); -#ifdef DEBUG - fprintf(stderr, "enter_hash(%d, %s, %d)\n", uid, name, wecare); -#endif + /* fill in some data, including an already expired time */ + data->uid = uid; + data->expire = (time_t)0; - hashindex = hashit(uid); + /* add it to the hash: the rest gets filled in later */ + hash_add_uint(userhash, uid, data); + } - if (!is_empty_hash(hashindex)) + /* Now data points to the correct hash entry for "uid". If this is + a new entry, then expire is 0 and the next test will be true. */ + if (data->expire <= now) { - if (!wecare) - return 0; /* Don't clobber a slot for trash */ - if (hash_table[hashindex].uid == uid) - return(hashindex); /* Fortuitous find */ + if ((pw = getpwuid(uid)) != NULL) + { + strncpy(data->name, pw->pw_name, MAXLOGNAME-1); + data->expire = now + EXPIRETIME; + dprintf("username: updating %d with %s, expires %d\n", + data->uid, data->name, data->expire); + } + else + { + /* username doesnt exist ... so invent one */ + snprintf(data->name, sizeof(data->name), "%d", uid); + data->expire = now + EXPIRETIME; + dprintf("username: updating %d with %s, expires %d\n", + data->uid, data->name, data->expire); + } } - /* empty or wrong slot -- fill it with new value */ - hash_table[hashindex].uid = uid; - (void) strncpy(hash_table[hashindex].name, name, 8); - return(hashindex); + /* return what we have */ + return data->name; } -/* - * Get a userid->name mapping from the system. - * If the passwd database is hashed (#define RANDOM_PW), we - * just handle this uid. Otherwise we scan the passwd file - * and cache any entries we pass over while looking. - */ - -int get_user(uid) - -register int uid; +int +userid(char *username) { struct passwd *pwd; -#ifdef RANDOM_PW - /* no performance penalty for using getpwuid makes it easy */ - if ((pwd = getpwuid(uid)) != NULL) + if ((pwd = getpwnam(username)) == NULL) { - return(enter_user(pwd->pw_uid, pwd->pw_name, 1)); + return(-1); } -#else - int from_start = 0; - - /* - * If we just called getpwuid each time, things would be very slow - * since that just iterates through the passwd file each time. So, - * we walk through the file instead (using getpwent) and cache each - * entry as we go. Once the right record is found, we cache it and - * return immediately. The next time we come in, getpwent will get - * the next record. In theory, we never have to read the passwd file - * a second time (because we cache everything we read). But in - * practice, the cache may not be large enough, so if we don't find - * it the first time we have to scan the file a second time. This - * is not very efficient, but it will do for now. - */ - - while (from_start++ < 2) - { - while ((pwd = getpwent()) != NULL) - { - if (pwd->pw_uid == uid) - { - return(enter_user(pwd->pw_uid, pwd->pw_name, 1)); - } - (void) enter_user(pwd->pw_uid, pwd->pw_name, 0); - } - /* try again */ - setpwent(); - } -#endif - /* if we can't find the name at all, then use the uid as the name */ - return(enter_user(uid, itoa7(uid), 1)); + /* return our result */ + return(pwd->pw_uid); } + diff --git a/username.h b/username.h new file mode 100644 index 000000000000..3c56399557a4 --- /dev/null +++ b/username.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* interface for username.c */ + +#ifndef _USERNAME_H_ +#define _USERNAME_H_ + +void init_username(); +char *username(int uid); +int userid(char *username); + +#endif /* _USERNAME_H_ */ @@ -1,24 +1,72 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * Top users/processes display for Unix * Version 3 - * - * This program may be freely redistributed, - * but this entire comment MUST remain intact. - * - * Copyright (c) 1984, 1989, William LeFebvre, Rice University - * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University */ /* * This file contains various handy utilities used by top. */ -#include "top.h" #include "os.h" +#include <ctype.h> +#ifdef HAVE_STDARG_H +#include <stdarg.h> +#else +#undef DEBUG +#endif +#include "top.h" +#include "utils.h" + +static int +alldigits(char *s) -int atoiwi(str) +{ + int ch; + + while ((ch = *s++) != '\0') + { + if (!isdigit(ch)) + { + return 0; + } + } + return 1; +} -char *str; +int +atoiwi(char *str) { register int len; @@ -32,13 +80,13 @@ char *str; { return(Infinity); } - else if (str[0] == '-') + else if (alldigits(str)) { - return(Invalid); + return(atoi(str)); } else { - return(atoi(str)); + return(Invalid); } } return(0); @@ -57,9 +105,8 @@ char *str; * digits. */ -char *itoa(val) - -register int val; +char * +itoa(int val) { register char *ptr; @@ -88,18 +135,22 @@ register int val; * a front end to a more general routine for efficiency. */ -char *itoa7(val) - -register int val; +char * +itoa_w(int val, int w) { - register char *ptr; + char *ptr; + char *eptr; static char buffer[16]; /* result is built here */ /* 16 is sufficient since the largest number we will ever convert will be 2^32-1, which is 10 digits. */ - ptr = buffer + sizeof(buffer); + if (w > 15) + { + w = 15; + } + eptr = ptr = buffer + sizeof(buffer); *--ptr = '\0'; if (val == 0) { @@ -110,25 +161,36 @@ register int val; *--ptr = (val % 10) + '0'; val /= 10; } - while (ptr > buffer + sizeof(buffer) - 7) + while (ptr >= eptr - w) { *--ptr = ' '; } return(ptr); } +char * +itoa7(int val) + +{ + return itoa_w(val, 7); +} + /* * digits(val) - return number of decimal digits in val. Only works for - * positive numbers. If val <= 0 then digits(val) == 0. + * positive numbers. If val < 0 then digits(val) == 0, but + * digits(0) == 1. */ -int digits(val) - -int val; +int +digits(int val) { register int cnt = 0; + if (val == 0) + { + return 1; + } while (val > 0) { cnt++; @@ -138,14 +200,38 @@ int val; } /* - * strecpy(to, from) - copy string "from" into "to" and return a pointer - * to the END of the string "to". + * printable(char *str) - make the string pointed to by "str" into one that is + * printable (i.e.: all ascii), by converting all non-printable + * characters into '?'. Replacements are done in place and a pointer + * to the original buffer is returned. */ -char *strecpy(to, from) +char * +printable(char *str) -register char *to; -register char *from; +{ + register char *ptr; + register int ch; + + ptr = str; + while ((ch = *ptr) != '\0') + { + if (!isprint(ch)) + { + *ptr = '?'; + } + ptr++; + } + return(str); +} + +/* + * strcpyend(to, from) - copy string "from" into "to" and return a pointer + * to the END of the string "to". + */ + +char * +strcpyend(char *to, char *from) { while ((*to++ = *from++) != '\0'); @@ -153,13 +239,40 @@ register char *from; } /* - * string_index(string, array) - find string in array and return index + * char * + * homogenize(char *str) + * + * Remove unwanted characters from "str" and make everything lower case. + * Newly allocated string is returned: the original is not altered. */ -int string_index(string, array) +char *homogenize(char *str) + +{ + char *ans; + char *fr; + char *to; + int ch; + + to = fr = ans = strdup(str); + while ((ch = *fr++) != '\0') + { + if (isalnum(ch)) + { + *to++ = tolower(ch); + } + } -char *string; -char **array; + *to = '\0'; + return ans; +} + +/* + * string_index(string, array) - find string in array and return index + */ + +int +string_index(char *string, char **array) { register int i = 0; @@ -177,16 +290,54 @@ char **array; } /* + * char *string_list(char **strings) + * + * Create a comma-separated list of the strings in the NULL-terminated + * "strings". Returned string is malloc-ed and should be freed when the + * caller is done. Note that this is not an efficient function. + */ + +char *string_list(char **strings) + +{ + int cnt = 0; + char **pp; + char *p; + char *result = NULL; + char *resp = NULL; + + pp = strings; + while ((p = *pp++) != NULL) + { + cnt += strlen(p) + 2; + } + + if (cnt > 0) + { + resp = result = (char *)malloc(cnt); + pp = strings; + while ((p = *pp++) != NULL) + { + resp = strcpyend(resp, p); + if (*pp != NULL) + { + resp = strcpyend(resp, ", "); + } + } + } + + return result; +} + +/* * argparse(line, cntp) - parse arguments in string "line", separating them * out into an argv-like array, and setting *cntp to the number of * arguments encountered. This is a simple parser that doesn't understand * squat about quotes. */ -char **argparse(line, cntp) - -char *line; -int *cntp; +char ** +argparse(char *line, int *cntp) { register char *from; @@ -268,13 +419,8 @@ int *cntp; * useful on BSD mchines for calculating cpu state percentages. */ -long percentages(cnt, out, new, old, diffs) - -int cnt; -int *out; -register long *new; -register long *old; -long *diffs; +long +percentages(int cnt, int *out, long *new, long *old, long *diffs) { register int i; @@ -331,17 +477,15 @@ long *diffs; /* externs referenced by errmsg */ #ifndef HAVE_STRERROR -#ifndef SYS_ERRLIST_DECLARED -#define SYS_ERRLIST_DECLARED +#if !HAVE_DECL_SYS_ERRLIST extern char *sys_errlist[]; #endif extern int sys_nerr; #endif -char *errmsg(errnum) - -int errnum; +char * +errmsg(int errnum) { #ifdef HAVE_STRERROR @@ -353,12 +497,43 @@ int errnum; #else if (errnum > 0 && errnum < sys_nerr) { - return(sys_errlist[errnum]); + return((char *)(sys_errlist[errnum])); } #endif return("No error"); } +/* format_percent(v) - format a double as a percentage in a manner that + * does not exceed 5 characters (excluding any trailing + * percent sign). Since it is possible for the value + * to exceed 100%, we format such values with no fractional + * component to fit within the 5 characters. + */ + +char * +format_percent(double v) + +{ + static char result[10]; + + /* enumerate the possibilities */ + if (v < 0 || v >= 100000.) + { + /* we dont want to try extreme values */ + strcpy(result, " ???"); + } + else if (v > 99.99) + { + sprintf(result, "%5.0f", v); + } + else + { + sprintf(result, "%5.2f", v); + } + + return result; +} + /* format_time(seconds) - format number of seconds into a suitable * display that will fit within 6 characters. Note that this * routine builds its string in a static area. If it needs @@ -375,14 +550,10 @@ int errnum; exceed 9999.9, we use "???". */ -char *format_time(seconds) - -long seconds; +char * +format_time(long seconds) { - register int value; - register int digit; - register char *ptr; static char result[10]; /* sanity protection */ @@ -405,7 +576,7 @@ long seconds; { /* standard method produces MMM:SS */ /* we avoid printf as must as possible to make this quick */ - sprintf(result, "%3d:%02d", seconds / 60l, seconds % 60l); + sprintf(result, "%3ld:%02ld", seconds / 60l, seconds % 60l); } return(result); } @@ -435,18 +606,16 @@ long seconds; #define NUM_STRINGS 8 -char *format_k(amt) - -int amt; +char * +format_k(long amt) { static char retarray[NUM_STRINGS][16]; static int index = 0; - register char *p; register char *ret; register char tag = 'K'; - p = ret = retarray[index]; + ret = retarray[index]; index = (index + 1) % NUM_STRINGS; if (amt >= 10000) @@ -460,9 +629,117 @@ int amt; } } - p = strecpy(p, itoa(amt)); - *p++ = tag; - *p = '\0'; + snprintf(ret, sizeof(retarray[index])-1, "%ld%c", amt, tag); return(ret); } + +/* + * Time keeping functions. + */ + +static struct timeval lasttime = { 0, 0 }; +static unsigned int elapsed_msecs = 0; + +void +time_get(struct timeval *tv) + +{ + /* get the current time */ +#ifdef HAVE_GETTIMEOFDAY + gettimeofday(tv, NULL); +#else + tv->tv_sec = (long)time(NULL); + tv->tv_usec = 0; +#endif +} + +void +time_mark(struct timeval *tv) + +{ + struct timeval thistime; + struct timeval timediff; + + /* if the caller didnt provide one then use our own */ + if (tv == NULL) + { + tv = &thistime; + } + + /* get the current time */ +#ifdef HAVE_GETTIMEOFDAY + gettimeofday(tv, NULL); +#else + tv->tv_sec = (long)time(NULL); + tv->tv_usec = 0; +#endif + + /* calculate the difference */ + timediff.tv_sec = tv->tv_sec - lasttime.tv_sec; + timediff.tv_usec = tv->tv_usec - lasttime.tv_usec; + if (timediff.tv_usec < 0) { + timediff.tv_sec--; + timediff.tv_usec += 1000000; + } + + /* convert to milliseconds */ + elapsed_msecs = timediff.tv_sec * 1000 + timediff.tv_usec / 1000; + if (elapsed_msecs == 0) + { + elapsed_msecs = 1; + } + + /* save for next time */ + lasttime = *tv; +} + +unsigned int +time_elapsed() + +{ + return elapsed_msecs; +} + +unsigned int +diff_per_second(unsigned int x, unsigned int y) + +{ + return (y > x ? UINT_MAX - y + x + 1 : x - y) * 1000 / elapsed_msecs; +} + +static int debug_on = 0; + +#ifdef DEBUG +FILE *debugfile; +#endif + +void +debug_set(int i) + +{ + debug_on = i; +#ifdef DEBUG + debugfile = fopen("/tmp/top.debug", "w"); +#endif +} + +#ifdef DEBUG +void +xdprintf(char *fmt, ...) + +{ + va_list argp; + + va_start(argp, fmt); + + if (debug_on) + { + vfprintf(debugfile, fmt, argp); + fflush(debugfile); + } + + va_end(argp); +} +#endif + @@ -1,23 +1,78 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * Top users/processes display for Unix - * Version 3 - * - * This program may be freely redistributed, - * but this entire comment MUST remain intact. - * - * Copyright (c) 1984, 1989, William LeFebvre, Rice University - * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University */ /* prototypes for functions found in utils.c */ -int atoiwi(); -char *itoa(); -char *itoa7(); -int digits(); -char *strecpy(); -char **argparse(); -long percentages(); -char *errmsg(); -char *format_time(); -char *format_k(); +#ifndef _UTILS_H +#define _UTILS_H + +int atoiwi(char *); +char *itoa(int); +char *itoa_w(int, int); +char *itoa7(int); +int digits(int); +char *printable(char *); +char *strcpyend(char *, char *); +char *homogenize(char *); +int string_index(char *, char **); +char **argparse(char *, int *); +long percentages(int, int *, long *, long *, long *); +char *errmsg(int); +char *format_percent(double); +char *format_time(long); +char *format_k(long); +char *string_list(char **); +void time_get(struct timeval *); +void time_mark(struct timeval *); +unsigned int time_elapsed(); +unsigned int diff_per_second(unsigned int, unsigned int); +void debug_set(int); +#ifdef DEBUG +#define dprintf xdprintf +void xdprintf(char *fmt, ...); +#else +#ifdef HAVE_C99_VARIADIC_MACROS +#define dprintf(...) +#else +#ifdef HAVE_GNU_VARIADIC_MACROS +#define dprintf(x...) +#else +#define dprintf if (0) +#endif +#endif +#endif + +#endif diff --git a/version.c b/version.c index 5f360fd32fe4..63a6960b942d 100644 --- a/version.c +++ b/version.c @@ -1,25 +1,46 @@ /* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* * Top users/processes display for Unix * Version 3 - * - * This program may be freely redistributed, - * but this entire comment MUST remain intact. - * - * Copyright (c) 1984, 1989, William LeFebvre, Rice University - * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University */ +#include "config.h" #include "top.h" -#include "patchlevel.h" - -static char version[16]; -char *version_string() +char * +version_string() { - sprintf(version, "%d.%d", VERSION, PATCHLEVEL); -#ifdef BETA - strcat(version, BETA); -#endif - return(version); + return(PACKAGE_VERSION); } diff --git a/version.h b/version.h new file mode 100644 index 000000000000..f1b5ee68804d --- /dev/null +++ b/version.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 1984 through 2008, William LeFebvre + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of William LeFebvre nor the names of other + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Top users/processes display for Unix + */ + +char *version_string(); |