1 Commits
gdb ... v3.1.2a

Author SHA1 Message Date
nobody
f9e7fa1a87 This commit was manufactured by cvs2svn to create tag 'r3_1_2a_cds'. 2006-05-03 22:45:30 +00:00
15966 changed files with 447059 additions and 3202798 deletions

43
.gitignore vendored
View File

@@ -1,43 +0,0 @@
cscope.*
*.swap
.*.sw[po]
.sw[po]
*~
*.orig
*.diff
*.patch
*.rej
*.[1-9].gz
*.o
*.[psS]o
*.pico
lib*.so*
*.a
*.so.*
*.d
.depend
nbsdsrc/*
TAGS
tags
GPATH
GRTAGS
GSYMS
GTAGS
\#*#
CVS
!/.gitignore
.gitignore
.svn
minix-port.patch
*.worldstone.log
.worldstone*
usr.bin/mdocml/man/*.7
etc/passwd
etc/pwd.db
etc/spwd.db
releasetools/image
releasetools/kernel
releasetools/revision
share/zoneinfo/builddir
lib/libc/compat__*
.gdbinit

View File

@@ -1,17 +0,0 @@
# MINIX 3 code review setup.
#
# This gerrit code review configuration is meant for performing per commit
# internal code reviews. If you are an external contributor please read and
# apply http://wiki.minix3.org/en/HowToContribute
#
# Consider reading http://wiki.openstack.org/GerritWorkflow to learn how
# to install git review on a Linux setup. On Minix you can use pkgin to
# install git-review.
#
[gerrit]
# The git-minix host is to be configured in your .ssh/config
#
host=git-minix
port=2222
project=minix
defaultbranch=master

10
LICENSE Normal file → Executable file
View File

@@ -50,13 +50,3 @@ observe the conditions of the GPL with respect to this software. As
clearly stated in Article 2 of the GPL, when GPL and nonGPL software are
distributed together on the same medium, this aggregation does not cause
the license of either part to apply to the other part.
Acknowledgements
This product includes software developed by the University of
California, Berkeley and its contributors.
This product includes software developed by Softweyr LLC, the
University of California, Berkeley, and its contributors.

591
Makefile Normal file → Executable file
View File

@@ -1,548 +1,71 @@
# $NetBSD: Makefile,v 1.299 2012/08/17 16:22:27 joerg Exp $
# Master Makefile to compile everything in /usr/src except the system.
#
# This is the top-level makefile for building NetBSD. For an outline of
# how to build a snapshot or release, as well as other release engineering
# information, see http://www.NetBSD.org/developers/releng/index.html
#
# Not everything you can set or do is documented in this makefile. In
# particular, you should review the files in /usr/share/mk (especially
# bsd.README) for general information on building programs and writing
# Makefiles within this structure, and see the comments in src/etc/Makefile
# for further information on installation and release set options.
#
# Variables listed below can be set on the make command line (highest
# priority), in /etc/mk.conf (middle priority), or in the environment
# (lowest priority).
#
# Variables:
# DESTDIR is the target directory for installation of the compiled
# software. It defaults to /. Note that programs are built against
# libraries installed in DESTDIR.
# MKMAN, if `no', will prevent building of manual pages.
# MKOBJDIRS, if not `no', will build object directories at
# an appropriate point in a build.
# MKSHARE, if `no', will prevent building and installing
# anything in /usr/share.
# MKUPDATE, if not `no', will avoid a `make cleandir' at the start of
# `make build', as well as having the effects listed in
# /usr/share/mk/bsd.README.
# NOCLEANDIR, if defined, will avoid a `make cleandir' at the start
# of the `make build'.
# NOINCLUDES will avoid the `make includes' usually done by `make build'.
#
# See mk.conf(5) for more details.
#
#
# Targets:
# build:
# Builds a full release of NetBSD in DESTDIR, except for the
# /etc configuration files.
# If BUILD_DONE is set, this is an empty target.
# distribution:
# Builds a full release of NetBSD in DESTDIR, including the /etc
# configuration files.
# buildworld:
# As per `make distribution', except that it ensures that DESTDIR
# is not the root directory.
# installworld:
# Install the distribution from DESTDIR to INSTALLWORLDDIR (which
# defaults to the root directory). Ensures that INSTALLWORLDDIR
# is not the root directory if cross compiling.
# release:
# Does a `make distribution', and then tars up the DESTDIR files
# into ${RELEASEDIR}/${RELEASEMACHINEDIR}, in release(7) format.
# (See etc/Makefile for more information on this.)
# regression-tests:
# Runs the regression tests in "regress" on this host.
# sets:
# Populate ${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/sets
# from ${DESTDIR}
# sourcesets:
# Populate ${RELEASEDIR}/source/sets from ${NETBSDSRCDIR}
# syspkgs:
# Populate ${RELEASEDIR}/${RELEASEMACHINEDIR}/binary/syspkgs
# from ${DESTDIR}
# iso-image:
# Create CD-ROM image in RELEASEDIR/iso.
# RELEASEDIR must already have been populated by `make release'
# or equivalent.
# iso-image-source:
# Create CD-ROM image with source in RELEASEDIR/iso.
# RELEASEDIR must already have been populated by
# `make release sourcesets' or equivalent.
# live-image:
# Create bootable live image for emulators or USB stick etc.
# in RELEASEDIR/liveimage.
# RELEASEDIR must already have been populated by `make release'
# or equivalent.
# install-image:
# Create bootable installation image for USB stick etc.
# in RELEASEDIR/installimage.
# RELEASEDIR must already have been populated by `make release'
# or equivalent.
#
# Targets invoked by `make build,' in order:
# cleandir: cleans the tree.
# do-top-obj: creates the top level object directory.
# do-tools-obj: creates object directories for the host toolchain.
# do-tools: builds host toolchain.
# obj: creates object directories.
# do-distrib-dirs: creates the distribution directories.
# includes: installs include files.
# do-tools-compat: builds the "libnbcompat" library; needed for some
# random host tool programs in the source tree.
# do-lib: builds and installs prerequisites from lib
# if ${MKCOMPAT} != "no".
# do-compat-lib: builds and installs prerequisites from compat/lib
# if ${MKCOMPAT} != "no".
# do-build: builds and installs the entire system.
# do-x11: builds and installs X11 if ${MKX11} != "no"; either
# X11R7 from src/external/mit/xorg if ${X11FLAVOUR} == "Xorg"
# or X11R6 from src/x11
# do-extsrc: builds and installs extsrc if ${MKEXTSRC} != "no".
# do-obsolete: installs the obsolete sets (for the postinstall-* targets).
#
MAKE = exec make -$(MAKEFLAGS)
.if ${.MAKEFLAGS:M${.CURDIR}/share/mk} == ""
.MAKEFLAGS: -m ${.CURDIR}/share/mk
.endif
usage:
@echo ""
@echo "Master Makefile for MINIX commands and utilities."
@echo "Root privileges are required for some actions."
@echo ""
@echo "Usage:"
@echo " make world # Compile everything (libraries & commands)"
@echo " make includes # Install include files from src/"
@echo " make libraries # Compile and install libraries"
@echo " make cmds # Compile all, commands, but don't install"
@echo " make install # Compile and install commands"
@echo " make depend # Generate required .depend files"
@echo " make clean # Remove all compiler results"
@echo ""
@echo "Run 'make' in tools/ to create a new MINIX configuration."
@echo ""
#
# If _SRC_TOP_OBJ_ gets set here, we will end up with a directory that may
# not be the top level objdir, because "make obj" can happen in the *middle*
# of "make build" (long after <bsd.own.mk> is calculated it). So, pre-set
# _SRC_TOP_OBJ_ here so it will not be added to ${.MAKEOVERRIDES}.
#
_SRC_TOP_OBJ_=
# world has to be able to make a new system, even if there
# is no complete old system. it has to install commands, for which
# it has to install libraries, for which it has to install includes,
# for which it has to install /etc (for users and ownerships).
# etcfiles also creates a directory hierarchy in its
# 'make install' target.
#
# etcfiles has to be done first.
world: includes depend libraries cmds install postinstall
.include <bsd.own.mk>
includes:
cd include && $(MAKE) install gcc
#
# Sanity check: make sure that "make build" is not invoked simultaneously
# with a standard recursive target.
#
libraries:
cd lib && $(MAKE) all install
.if make(build) || make(release) || make(snapshot)
.for targ in ${TARGETS:Nobj:Ncleandir}
.if make(${targ}) && !target(.BEGIN)
.BEGIN:
@echo 'BUILD ABORTED: "make build" and "make ${targ}" are mutually exclusive.'
@false
.endif
.endfor
.endif
cmds:
if [ -f commands/Makefile ] ; then cd commands && $(MAKE) all; fi
#
# _SUBDIR is used to set SUBDIR, after removing directories that have
# BUILD_${dir}=no, or that have no ${dir}/Makefile.
#
_SUBDIR= tools lib .WAIT include gnu external crypto/external bin games
_SUBDIR+= libexec sbin usr.bin
_SUBDIR+= commands man
_SUBDIR+= common drivers kernel servers
_SUBDIR+= usr.sbin share rescue sys etc test compat .WAIT distrib regress
install::
if [ -f commands/Makefile ] ; then cd commands && $(MAKE) install; fi
.if defined(__MINIX)
_SUBDIR+= benchmarks
.endif
.for dir in ${_SUBDIR}
.if "${dir}" == ".WAIT" \
|| (${BUILD_${dir}:Uyes} != "no" && exists(${dir}/Makefile))
SUBDIR+= ${dir}
.endif
.endfor
.if exists(regress)
regression-tests: .PHONY .MAKE
@echo Running regression tests...
${MAKEDIRTARGET} regress regress
.endif
.if ${MKUNPRIVED} != "no"
NOPOSTINSTALL= # defined
.endif
afterinstall: .PHONY .MAKE
.if ${MKMAN} != "no"
.if !defined(__MINIX)
${MAKEDIRTARGET} share/man makedb
.else
${MAKEDIRTARGET} man makedb
.endif # !defined(__MINIX)
.endif
.if (${MKUNPRIVED} != "no" && ${MKINFO} != "no")
${MAKEDIRTARGET} gnu/usr.bin/texinfo/install-info infodir-meta
.endif
.if !defined(NOPOSTINSTALL)
${MAKEDIRTARGET} . postinstall-check
.endif
_POSTINSTALL= ${.CURDIR}/usr.sbin/postinstall/postinstall
_POSTINSTALL_ENV= \
AWK=${TOOL_AWK:Q} \
DB=${TOOL_DB:Q} \
HOST_SH=${HOST_SH:Q} \
MAKE=${MAKE:Q} \
PWD_MKDB=${TOOL_PWD_MKDB:Q} \
STAT=${TOOL_STAT:Q}
postinstall-check: .PHONY
@echo " === Post installation checks ==="
${_POSTINSTALL_ENV} ${HOST_SH} ${_POSTINSTALL} -s ${.CURDIR} -d ${DESTDIR}/ check; if [ $$? -gt 1 ]; then exit 1; fi
@echo " ================================"
postinstall-fix: .NOTMAIN .PHONY
@echo " === Post installation fixes ==="
${_POSTINSTALL_ENV} ${HOST_SH} ${_POSTINSTALL} -s ${.CURDIR} -d ${DESTDIR}/ fix
@echo " ==============================="
postinstall-fix-obsolete: .NOTMAIN .PHONY
@echo " === Removing obsolete files ==="
${_POSTINSTALL_ENV} ${HOST_SH} ${_POSTINSTALL} -s ${.CURDIR} -d ${DESTDIR}/ fix obsolete
@echo " ==============================="
depend::
mkdep kernel
mkdep servers
mkdep drivers
cd kernel && $(MAKE) $@
cd servers && $(MAKE) $@
cd drivers && $(MAKE) $@
#
# Targets (in order!) called by "make build".
#
.if defined(HAVE_GCC)
.if ${HAVE_GCC} == "4"
LIBGCC_EXT=4
BUILD_CC_LIB_BASEDIR= gnu/lib
BUILD_CC_LIB_BASETARGET= gnu-lib
.else
LIBGCC_EXT=
BUILD_CC_LIB_BASEDIR= external/gpl3/gcc/lib
BUILD_CC_LIB_BASETARGET= external-gpl3-gcc-lib
.endif
.endif
clean::
cd lib && $(MAKE) $@
test ! -f commands/Makefile || { cd commands && $(MAKE) $@; }
BUILDTARGETS+= check-tools
.if ${MKUPDATE} == "no" && !defined(NOCLEANDIR)
BUILDTARGETS+= cleandir
.endif
.if ${MKOBJDIRS} != "no"
BUILDTARGETS+= do-top-obj
.endif
.if ${USETOOLS} == "yes" # {
.if ${MKOBJDIRS} != "no"
BUILDTARGETS+= do-tools-obj
.endif
BUILDTARGETS+= do-tools
.endif # USETOOLS # }
.if ${MKOBJDIRS} != "no"
BUILDTARGETS+= obj
.endif
BUILDTARGETS+= clean_METALOG
.if !defined(NODISTRIBDIRS)
BUILDTARGETS+= do-distrib-dirs
.endif
.if !defined(NOINCLUDES)
BUILDTARGETS+= includes
.endif
BUILDTARGETS+= do-lib
.if !defined(__MINIX)
# LSC Not used in MINIX3
BUILDTARGETS+= do-compat-lib
.endif # !defined(__MINIX)
BUILDTARGETS+= do-build
.if ${MKX11} != "no"
BUILDTARGETS+= do-x11
.endif
.if ${MKEXTSRC} != "no"
BUILDTARGETS+= do-extsrc
.endif
BUILDTARGETS+= do-obsolete
etcfiles::
cd etc && $(MAKE) install
#
# Enforce proper ordering of some rules.
#
clean::
cd test && $(MAKE) $@
.ORDER: ${BUILDTARGETS}
includes-lib: .PHONY includes-include includes-sys
includes-gnu: .PHONY includes-lib
all install clean::
cd boot && $(MAKE) $@
cd man && $(MAKE) $@ # First manpages, then commands
test ! -f commands/Makefile || { cd commands && $(MAKE) $@; }
cd tools && $(MAKE) $@
cd servers && $(MAKE) $@
#
# Build the system and install into DESTDIR.
#
START_TIME!= date
.if defined(__MINIX)
world: build .PHONY .MAKE
${MAKEDIRTARGET} . etcfiles
@echo "WARNING: "
@echo "WARNING: The 'world' target is obsolete, please use 'build' instead."
@echo "WARNING: "
etcfiles: .PHONY .MAKE
${MAKEDIRTARGET} etc install-etc-files-safe DESTDIR=${DESTDIR:U/}
etcforce: .PHONY .MAKE
${MAKEDIRTARGET} etc install-etc-files DESTDIR=${DESTDIR:U/}
.endif # defined(__MINIX)
build: .PHONY .MAKE
.if defined(BUILD_DONE)
@echo "Build already installed into ${DESTDIR}"
.else
@echo "Build started at: ${START_TIME}"
.for tgt in ${BUILDTARGETS}
${MAKEDIRTARGET} . ${tgt}
.endfor
${MAKEDIRTARGET} etc install-etc-release
.if defined(__MINIX)
${MAKEDIRTARGET} etc install-etc-files-safe DESTDIR=${DESTDIR:U/}
${MAKEDIRTARGET} releasetools do-hdboot
.endif # defined(__MINIX)
@echo "Build started at: ${START_TIME}"
@printf "Build finished at: " && date
.endif
#
# Build a full distribution, but not a release (i.e. no sets into
# ${RELEASEDIR}). "buildworld" enforces a build to ${DESTDIR} != /
#
distribution buildworld: .PHONY .MAKE
.if make(buildworld) && \
(!defined(DESTDIR) || ${DESTDIR} == "" || ${DESTDIR} == "/")
@echo "Won't make ${.TARGET} with DESTDIR=/"
@false
.endif
${MAKEDIRTARGET} . build NOPOSTINSTALL=1
${MAKEDIRTARGET} etc distribution INSTALL_DONE=1
.if defined(DESTDIR) && ${DESTDIR} != "" && ${DESTDIR} != "/" && ${CHECKFLIST:Uyes} == "yes"
${MAKEDIRTARGET} . postinstall-fix-obsolete
${MAKEDIRTARGET} distrib/sets checkflist
.endif
@echo "make ${.TARGET} started at: ${START_TIME}"
@printf "make ${.TARGET} finished at: " && date
#
# Install the distribution from $DESTDIR to $INSTALLWORLDDIR (defaults to `/')
# If installing to /, ensures that the host's operating system is NetBSD and
# the host's `uname -m` == ${MACHINE}.
#
HOST_UNAME_S!= uname -s
.if ${HOST_OSTYPE:C/\-.*//} != "Minix"
HOST_UNAME_M!= uname -m
.else
HOST_UNAME_M:= ${MACHINE}
.endif
installworld: .PHONY .MAKE
.if (!defined(DESTDIR) || ${DESTDIR} == "" || ${DESTDIR} == "/")
@echo "Can't make ${.TARGET} to DESTDIR=/"
@false
.endif
.if !defined(INSTALLWORLDDIR) || \
${INSTALLWORLDDIR} == "" || ${INSTALLWORLDDIR} == "/"
.if (${HOST_UNAME_S} != "Minix")
@echo "Won't cross-make ${.TARGET} from ${HOST_UNAME_S} to Minix with INSTALLWORLDDIR=/"
@false
.endif
.if (${HOST_UNAME_M} != ${MACHINE})
@echo "Won't cross-make ${.TARGET} from ${HOST_UNAME_M} to ${MACHINE} with INSTALLWORLDDIR=/"
@false
.endif
.endif
${MAKEDIRTARGET} distrib/sets installsets \
INSTALLDIR=${INSTALLWORLDDIR:U/} INSTALLSETS=${INSTALLSETS:Q}
${MAKEDIRTARGET} . postinstall-check DESTDIR=${INSTALLWORLDDIR}
@echo "make ${.TARGET} started at: ${START_TIME}"
@printf "make ${.TARGET} finished at: " && date
#
# Install modules from $DESTDIR to $INSTALLMODULESDIR
#
installmodules: .PHONY .MAKE
.if (!defined(DESTDIR) || ${DESTDIR} == "" || ${DESTDIR} == "/")
@echo "Can't make ${.TARGET} to DESTDIR=/"
@false
.endif
.if !defined(INSTALLMODULESDIR) || \
${INSTALLMODULESDIR} == "" || ${INSTALLMODULESDIR} == "/"
.if (${HOST_UNAME_S} != "NetBSD")
@echo "Won't cross-make ${.TARGET} from ${HOST_UNAME_S} to NetBSD with INSTALLMODULESDIR=/"
@false
.endif
.if (${HOST_UNAME_M} != ${MACHINE})
@echo "Won't cross-make ${.TARGET} from ${HOST_UNAME_M} to ${MACHINE} with INSTALLMODULESDIR=/"
@false
.endif
.endif
${MAKEDIRTARGET} sys/modules install DESTDIR=${INSTALLMODULESDIR:U/}
@echo "make ${.TARGET} started at: ${START_TIME}"
@printf "make ${.TARGET} finished at: " && date
#
# Create sets from $DESTDIR or $NETBSDSRCDIR into $RELEASEDIR
#
.for tgt in sets sourcesets syspkgs
${tgt}: .PHONY .MAKE
${MAKEDIRTARGET} distrib/sets ${tgt}
.endfor
#
# Build a release or snapshot (implies "make distribution"). Note that
# in this case, the set lists will be checked before the tar files
# are made.
#
release snapshot: .PHONY .MAKE
${MAKEDIRTARGET} . distribution
${MAKEDIRTARGET} etc release DISTRIBUTION_DONE=1
@echo "make ${.TARGET} started at: ${START_TIME}"
@printf "make ${.TARGET} finished at: " && date
#
# Create a CD-ROM image.
#
iso-image: .PHONY
${MAKEDIRTARGET} distrib iso_image
${MAKEDIRTARGET} etc iso-image
@echo "make ${.TARGET} started at: ${START_TIME}"
@printf "make ${.TARGET} finished at: " && date
iso-image-source: .PHONY
${MAKEDIRTARGET} distrib iso_image CDSOURCE=true
${MAKEDIRTARGET} etc iso-image
@echo "make ${.TARGET} started at: ${START_TIME}"
@printf "make ${.TARGET} finished at: " && date
#
# Create bootable live images.
#
live-image: .PHONY
${MAKEDIRTARGET} etc live-image
@echo "make ${.TARGET} started at: ${START_TIME}"
@printf "make ${.TARGET} finished at: " && date
#
# Create bootable installation images.
#
install-image: .PHONY
${MAKEDIRTARGET} etc install-image
@echo "make ${.TARGET} started at: ${START_TIME}"
@printf "make ${.TARGET} finished at: " && date
#
# Special components of the "make build" process.
#
check-tools: .PHONY
.if ${TOOLCHAIN_MISSING} != "no" && !defined(EXTERNAL_TOOLCHAIN)
@echo '*** WARNING: Building on MACHINE=${MACHINE} with missing toolchain.'
@echo '*** May result in a failed build or corrupt binaries!'
.elif defined(EXTERNAL_TOOLCHAIN)
@echo '*** Using external toolchain rooted at ${EXTERNAL_TOOLCHAIN}.'
.endif
.if defined(NBUILDJOBS)
@echo '*** WARNING: NBUILDJOBS is obsolete; use -j directly instead!'
.endif
# Delete or sanitise a leftover METALOG from a previous build.
clean_METALOG: .PHONY .MAKE
.if ${MKUPDATE} != "no"
${MAKEDIRTARGET} distrib/sets clean_METALOG
.endif
do-distrib-dirs: .PHONY .MAKE
.if !defined(DESTDIR) || ${DESTDIR} == ""
${MAKEDIRTARGET} etc distrib-dirs DESTDIR=/
.else
${MAKEDIRTARGET} etc distrib-dirs DESTDIR=${DESTDIR}
.endif
.for targ in cleandir obj includes
do-${targ}: .PHONY ${targ}
@true
.endfor
.for dir in tools tools/compat
do-${dir:S/\//-/g}: .PHONY .MAKE
.for targ in dependall install
${MAKEDIRTARGET} ${dir} ${targ}
.endfor
.endfor
do-lib: .PHONY .MAKE
${MAKEDIRTARGET} lib build_install
do-compat-lib: .PHONY .MAKE
${MAKEDIRTARGET} compat build_install BOOTSTRAP_SUBDIRS="../../../lib"
do-top-obj: .PHONY .MAKE
${MAKEDIRTARGET} . obj NOSUBDIR=
do-tools-obj: .PHONY .MAKE
${MAKEDIRTARGET} tools obj
do-build: .PHONY .MAKE
.for targ in dependall install
${MAKEDIRTARGET} . ${targ} BUILD_tools=no BUILD_lib=no
.endfor
do-x11: .PHONY .MAKE
.if ${MKX11} != "no"
.if ${X11FLAVOUR} == "Xorg"
${MAKEDIRTARGET} external/mit/xorg build
.else
${MAKEDIRTARGET} x11 build
.endif
.else
@echo "MKX11 is not enabled"
@false
.endif
do-extsrc: .PHONY .MAKE
.if ${MKEXTSRC} != "no"
${MAKEDIRTARGET} extsrc build
.else
@echo "MKEXTSRC is not enabled"
@false
.endif
do-obsolete: .PHONY .MAKE
${MAKEDIRTARGET} etc install-obsolete-lists
#
# Speedup stubs for some subtrees that don't need to run these rules.
# (Tells <bsd.subdir.mk> not to recurse for them.)
#
.for dir in bin etc distrib games libexec regress sbin usr.bin usr.sbin tools
includes-${dir}: .PHONY
@true
.endfor
.for dir in etc distrib regress
install-${dir}: .PHONY
@true
.endfor
#
# XXX this needs to change when distrib Makefiles are recursion compliant
# XXX many distrib subdirs need "cd etc && make snap_pre snap_kern" first...
#
dependall-distrib depend-distrib all-distrib: .PHONY
@true
.include <bsd.sys.mk>
.include <bsd.obj.mk>
.include <bsd.kernobj.mk>
.include <bsd.subdir.mk>
#
# Display current make(1) parameters
#
params: .PHONY .MAKE
${MAKEDIRTARGET} etc params
postinstall:
cd etc && $(MAKE) $@

View File

@@ -1,5 +0,0 @@
# Makefile for the benchmarks.
SUBDIR=unixbench-5.1.2
.include <bsd.subdir.mk>

View File

@@ -1,51 +0,0 @@
#!/bin/sh
set -e
make
BENCHDIR=/usr/local/benchmarks
basebenchmarks=`echo *bench*`
if [ -d $BENCHDIR ]
then packagebenchmarks=`(cd $BENCHDIR && echo *bench*)`
fi
runbench() {
bench=$1
out="Results/$bench.`date +%Y%m%d.%H%M%S`"
if [ -d $bench ]
then dir=$bench
fi
if [ -d $BENCHDIR/$bench ]
then dir=$BENCHDIR/$bench
fi
clear
echo "Running $dir."
echo "Saving output to $out."
echo ""
( cd $dir && sh run.sh 2>&1 ) | tee $out
}
clear
n=1
for b in $basebenchmarks $packagebenchmarks
do echo "$n. $b"
eval "n$n=$b"
n=`expr $n + 1`
done
echo
echo -n "Run which benchmark or 'all'? "
read bench
eval var=\$n$bench
if [ "$bench" = all ]
then for b in $basebenchmarks $packagebenchmarks
do runbench $b
done
else if [ -d "$var" -o -d "$BENCHDIR/$var" ]
then runbench $var
else echo "Unknown benchmark $var."
exit 1
fi
fi

View File

@@ -1,5 +0,0 @@
SCRIPTS=Run
SUBDIR=pgms testdir run.sh
.include "Makefile.inc"
.include <bsd.prog.mk>
.include <bsd.subdir.mk>

View File

@@ -1 +0,0 @@
BINDIR=/usr/benchmarks/unixbench

View File

@@ -1,406 +0,0 @@
Version 5.1.2 -- 2007-12-26
================================================================
To use Unixbench:
1. UnixBench from version 5.1 on has both system and graphics tests.
If you want to use the graphic tests, edit the Makefile and make sure
that the line "GRAPHIC_TESTS = defined" is not commented out; then check
that the "GL_LIBS" definition is OK for your system. Also make sure
that the "x11perf" command is on your search path.
If you don't want the graphics tests, then comment out the
"GRAPHIC_TESTS = defined" line. Note: comment it out, don't
set it to anything.
2. Do "make".
3. Do "Run" to run the system test; "Run graphics" to run the graphics
tests; "Run gindex" to run both.
You will need perl, as Run is written in perl.
For more information on using the tests, read "USAGE".
For information on adding tests into the benchmark, see "WRITING_TESTS".
===================== RELEASE NOTES =====================================
======================== Dec 07 ==========================
v5.1.2
One big fix: if unixbench is installed in a directory whose pathname contains
a space, it should now run (previously it failed).
To avoid possible clashes, the environment variables unixbench uses are now
prefixed with "UB_". These are all optional, and for most people will be
completely unnecessary, but if you want you can set these:
UB_BINDIR Directory where the test programs live.
UB_TMPDIR Temp directory, for temp files.
UB_RESULTDIR Directory to put results in.
UB_TESTDIR Directory where the tests are executed.
And a couple of tiny fixes:
* In pgms/tst.sh, changed "sort -n +1" to "sort -n -k 1"
* In Makefile, made it clearer that GRAPHIC_TESTS should be commented
out (not set to 0) to disable graphics
Thanks to nordi for pointing these out.
Ian Smith, December 26, 2007
johantheghost at yahoo period com
======================== Oct 07 ==========================
v5.1.1
It turns out that the setting of LANG is crucial to the results. This
explains why people in different regions were seeing odd results, and also
why runlevel 1 produced odd results -- runlevel 1 doesn't set LANG, and
hence reverts to ASCII, whereas most people use a UTF-8 encoding, which is
much slower in some tests (eg. shell tests).
So now we manually set LANG to "en_US.utf8", which is configured with the
variable "$language". Don't change this if you want to share your results.
We also report the language settings in use.
See "The Language Setting" in USAGE for more info. Thanks to nordi for
pointing out the LANG issue.
I also added the "grep" and "sysexec" tests. These are non-index tests,
and "grep" uses the system's grep, so it's not much use for comparing
different systems. But some folks on the OpenSuSE list have been finding
these useful. They aren't in any of the main test groups; do "Run grep
sysexec" to run them.
Index Changes
-------------
The setting of LANG will affect consistency with systems where this is
not the default value. However, it should produce more consistent results
in future.
Ian Smith, October 15, 2007
johantheghost at yahoo period com
======================== Oct 07 ==========================
v5.1
The major new feature in this version is the addition of graphical
benchmarks. Since these may not compile on all systems, you can enable/
disable them with the GRAPHIC_TESTS variable in the Makefile.
As before, each test is run for 3 or 10 iterations. However, we now discard
the worst 1/3 of the scores before averaging the remainder. The logic is
that a glitch in the system (background process waking up, for example) may
make one or two runs go slow, so let's discard those. Hopefully this will
produce more consistent and repeatable results. Check the log file
for a test run to see the discarded scores.
Made the tests compile and run on x86-64/Linux (fixed an execl bug passing
int instead of pointer).
Also fixed some general bugs.
Thanks to Stefan Esser for help and testing / bug reporting.
Index Changes
-------------
The tests are now divided into categories, and each category generates
its own index. This keeps the graphics test results separate from
the system tests.
The "graphics" test and corresponding index are new.
The "discard the worst scores" strategy should produce slightly higher
test scores, but at least they should (hopefully!) be more consistent.
The scores should not be higher than the best scores you would have got
with 5.0, so this should not be a huge consistency issue.
Ian Smith, October 11, 2007
johantheghost at yahoo period com
======================== Sep 07 ==========================
v5.0
All the work I've done on this release is Linux-based, because that's
the only Unix I have access to. I've tried to make it more OS-agnostic
if anything; for example, it no longer has to figure out the format reported
by /usr/bin/time. However, it's possible that portability has been damaged.
If anyone wants to fix this, please feel free to mail me patches.
In particular, the analysis of the system's CPUs is done via /proc/cpuinfo.
For systems which don't have this, please make appropriate changes in
getCpuInfo() and getSystemInfo().
The big change has been to make the tests multi-CPU aware. See the
"Multiple CPUs" section in "USAGE" for details. Other changes:
* Completely rewrote Run in Perl; drastically simplified the way data is
processed. The confusing system of interlocking shell and awk scripts is
now just one script. Various intermediate files used to store and process
results are now replaced by Perl data structures internal to the script.
* Removed from the index runs file system read and write tests which were
ignored for the index and wasted about 10 minutes per run (see fstime.c).
The read and write tests can now be selected individually. Made fstime.c
take parameters, so we no longer need to build 3 versions of it.
* Made the output file names unique; they are built from
hostname-date-sequence.
* Worked on result reporting, error handling, and logging. See TESTS.
We now generate both text and HTML reports.
* Removed some obsolete files.
Index Changes
-------------
The index is still based on David Niemi's SPARCstation 20-61 (rated at 10.0),
and the intention in the changes I've made has been to keep the tests
unchanged, in order to maintain consistency with old result sets.
However, the following changes have been made to the index:
* The Pipe-based Context Switching test (context1) was being dropped
from the index report in v4.1.0 due to a bug; I've put it back in.
* I've added shell1 to the index, to get a measure of how the shell tests
scale with multiple CPUs (shell8 already exercises all the CPUs, even
in single-copy mode). I made up the baseline score for this by
extrapolation.
Both of these test can be dropped, if you wish, by editing the "TEST
SPECIFICATIONS" section of Run.
Ian Smith, September 20, 2007
johantheghost at yahoo period com
======================== Aug 97 ==========================
v4.1.0
Double precision Whetstone put in place instead of the old "double" benchmark.
Removal of some obsolete files.
"system" suite adds shell8.
perlbench and poll added as "exhibition" (non-index) benchmarks.
Incorporates several suggestions by Andre Derrick Balsa <andrewbalsa@usa.net>
Code cleanups to reduce compiler warnings by David C Niemi <niemi@tux.org>
and Andy Kahn <kahn@zk3.dec.com>; Digital Unix options by Andy Kahn.
======================== Jun 97 ==========================
v4.0.1
Minor change to fstime.c to fix overflow problems on fast machines. Counting
is now done in units of 256 (smallest BUFSIZE) and unsigned longs are used,
giving another 23 dB or so of headroom ;^) Results should be virtually
identical aside from very small rounding errors.
======================== Dec 95 ==========================
v4.0
Byte no longer seems to have anything to do with this benchmark, and I was
unable to reach any of the original authors; so I have taken it upon myself
to clean it up.
This is version 4. Major assumptions made in these benchmarks have changed
since they were written, but they are nonetheless popular (particularly for
measuring hardware for Linux). Some changes made:
- The biggest change is to put a lot more operating system-oriented
tests into the index. I experimented for a while with a decibel-like
logarithmic scale, but finally settled on using a geometric mean for
the final index (the individual scores are a normalized, and their
logs are averaged; the resulting value is exponentiated).
"George", certain SPARCstation 20-61 with 128 MB RAM, a SPARC Storage
Array, and Solaris 2.3 is my new baseline; it is rated at 10.0 in each
of the index scores for a final score of 10.0.
Overall I find the geometric averaging is a big improvement for
avoiding the skew that was once possible (e.g. a Pentium-75 which got
40 on the buggy version of fstime, such that fstime accounted for over
half of its total score and hence wildly skewed its average).
I also expect that the new numbers look different enough from the old
ones that no one is too likely to casually mistake them for each other.
I am finding new SPARCs running Solaris 2.4 getting about 15-20, and
my 486 DX2-66 Compaq running Linux 1.3.45 got a 9.1. It got
understandably poor scores on CPU and FPU benchmarks (a horrible
1.8 on "double" and 1.3 on "fsdisk"); but made up for it by averaging
over 20 on the OS-oriented benchmarks. The Pentium-75 running
Linux gets about 20 (and it *still* runs Windows 3.1 slowly. Oh well).
- It is difficult to get a modern compiler to even consider making
dhry2 without registers, short of turning off *all* optimizations.
This is also not a terribly meaningful test, even if it were possible,
as noone compiles without registers nowadays. Replaced this benchmark
with dhry2reg in the index, and dropped it out of usage in general as
it is so hard to make a legitimate one.
- fstime: this had some bugs when compiled on modern systems which return
the number of bytes read/written for read(2)/write(2) calls. The code
assumed that a negative return code was given for EOF, but most modern
systems return 0 (certainly on SunOS 4, Solaris2, and Linux, which is
what counts for me). The old code yielded wildly inflated read scores,
would eat up tens of MB of disk space on fast systems, and yielded
roughly 50% lower than normal copy scores than it should have.
Also, it counted partial blocks *fully*; made it count the proportional
part of the block which was actually finished.
Made bigger and smaller variants of fstime which are designed to beat
up the disk I/O and the buffer cache, respectively. Adjusted the
sleeps so that they are short for short benchmarks.
- Instead of 1,2,4, and 8-shell benchmarks, went to 1, 8, and 16 to
give a broader range of information (and to run 1 fewer test).
The only real problem with this is that not many iterations get
done with 16 at a time on slow systems, so there are some significant
rounding errors; 8 therefore still used for the benchmark. There is
also the problem that the last (uncompleted) loop is counted as a full
loop, so it is impossible to score below 1.0 lpm (which gave my laptop
a break). Probably redesigning Shell to do each loop a bit more
quickly (but with less intensity) would be a good idea.
This benchmark appears to be very heavily influenced by the speed
of the loader, by which shell is being used as /bin/sh, and by how
well-compiled some of the common shell utilities like grep, sed, and
sort are. With a consistent tool set it is also a good indicator of
the bandwidth between main memory and the CPU (e.g. Pentia score about
twice as high as 486es due to their 64-bit bus). Small, sometimes
broken shells like "ash-linux" do particularly well here, while big,
robust shells like bash do not.
- "dc" is a somewhat iffy benchmark, because there are two versions of
it floating around, one being small, very fast, and buggy, and one
being more correct but slow. It was never in the index anyway.
- Execl is a somewhat troubling benchmark in that it yields much higher
scores if compiled statically. I frown on this practice because it
distorts the scores away from reflecting how programs are really used
(i.e. dynamically linked).
- Arithoh is really more an indicator of the compiler quality than of
the computer itself. For example, GCC 2.7.x with -O2 and a few extra
options optimizes much of it away, resulting in about a 1200% boost
to the score. Clearly not a good one for the index.
I am still a bit unhappy with the variance in some of the benchmarks, most
notably the fstime suite; and with how long it takes to run. But I think
it gets significantly more reliable results than the older version in less
time.
If anyone has ideas on how to make these benchmarks faster, lower-variance,
or more meaningful; or has nice, new, portable benchmarks to add, don't
hesitate to e-mail me.
David C Niemi <niemi@tux.org> 7 Dec 1995
======================== May 91 ==========================
This is version 3. This set of programs should be able to determine if
your system is BSD or SysV. (It uses the output format of time (1)
to see. If you have any problems, contact me (by email,
preferably): ben@bytepb.byte.com
---
The document doc/bench.doc describes the basic flow of the
benchmark system. The document doc/bench3.doc describes the major
changes in design of this version. As a user of the benchmarks,
you should understand some of the methods that have been
implemented to generate loop counts:
Tests that are compiled C code:
The function wake_me(second, func) is included (from the file
timeit.c). This function uses signal and alarm to set a countdown
for the time request by the benchmark administration script
(Run). As soon as the clock is started, the test is run with a
counter keeping track of the number of loops that the test makes.
When alarm sends its signal, the loop counter value is sent to stderr
and the program terminates. Since the time resolution, signal
trapping and other factors don't insure that the test is for the
precise time that was requested, the test program is also run
from the time (1) command. The real time value returned from time
(1) is what is used in calculating the number of loops per second
(or minute, depending on the test). As is obvious, there is some
overhead time that is not taken into account, therefore the
number of loops per second is not absolute. The overhead of the
test starting and stopping and the signal and alarm calls is
common to the overhead of real applications. If a program loads
quickly, the number of loops per second increases; a phenomenon
that favors systems that can load programs quickly. (Setting the
sticky bit of the test programs is not considered fair play.)
Test that use existing UNIX programs or shell scripts:
The concept is the same as that of compiled tests, except the
alarm and signal are contained in separate compiled program,
looper (source is looper.c). Looper uses an execvp to invoke the
test with its arguments. Here, the overhead includes the
invocation and execution of looper.
--
The index numbers are generated from a baseline file that is in
pgms/index.base. You can put tests that you wish in this file.
All you need to do is take the results/log file from your
baseline machine, edit out the comment and blank lines, and sort
the result (vi/ex command: 1,$!sort). The sort in necessary
because the process of generating the index report uses join (1).
You can regenerate the reports by running "make report."
--
========================= Jan 90 =============================
Tom Yager has joined the effort here at BYTE; he is responsible
for many refinements in the UNIX benchmarks.
The memory access tests have been deleted from the benchmarks.
The file access tests have been reversed so that the test is run
for a fixed time. The amount of data transfered (written, read,
and copied) is the variable. !WARNING! This test can eat up a
large hunk of disk space.
The initial line of all shell scripts has been changed from the
SCO and XENIX form (:) to the more standard form "#! /bin/sh".
But different systems handle shell switching differently. Check
the documentation on your system and find out how you are
supposed to do it. Or, simpler yet, just run the benchmarks from
the Bourne shell. (You may need to set SHELL=/bin/sh as well.)
The options to Run have not been checked in a while. They may no
longer function. Next time, I'll get back on them. There needs to
be another option added (next time) that halts testing between
each test. !WARNING! Some systems have caches that are not getting flushed
before the next test or iteration is run. This can cause
erroneous values.
========================= Sept 89 =============================
The database (db) programs now have a tuneable message queue space.
queue space. The default set in the Run script is 1024 bytes.
Other major changes are in the format of the times. We now show
Arithmetic and Geometric mean and standard deviation for User
Time, System Time, and Real Time. Generally, in reporting, we
plan on using the Real Time values with the benchs run with one
active user (the bench user). Comments and arguments are requested.
contact: BIX bensmith or rick_g

File diff suppressed because it is too large Load Diff

View File

@@ -1,394 +0,0 @@
Running the Tests
=================
All the tests are executed using the "Run" script in the top-level directory.
The simplest way to generate results is with the commmand:
./Run
This will run a standard "index" test (see "The BYTE Index" below), and
save the report in the "results" directory, with a filename like
hostname-2007-09-23-01
An HTML version is also saved.
If you want to generate both the basic system index and the graphics index,
then do:
./Run gindex
If your system has more than one CPU, the tests will be run twice -- once
with a single copy of each test running at once, and once with N copies,
where N is the number of CPUs. Some categories of tests, however (currently
the graphics tests) will only run with a single copy.
Since the tests are based on constant time (variable work), a "system"
run usually takes about 29 minutes; the "graphics" part about 18 minutes.
A "gindex" run on a dual-core machine will do 2 "system" passes (single-
and dual-processing) and one "graphics" run, for a total around one and
a quarter hours.
============================================================================
Detailed Usage
==============
The Run script takes a number of options which you can use to customise a
test, and you can specify the names of the tests to run. The full usage
is:
Run [ -q | -v ] [-i <n> ] [-c <n> [-c <n> ...]] [test ...]
The option flags are:
-q Run in quiet mode.
-v Run in verbose mode.
-i <count> Run <count> iterations for each test -- slower tests
use <count> / 3, but at least 1. Defaults to 10 (3 for
slow tests).
-c <n> Run <n> copies of each test in parallel.
The -c option can be given multiple times; for example:
./Run -c 1 -c 4
will run a single-streamed pass, then a 4-streamed pass. Note that some
tests (currently the graphics tests) will only run in a single-streamed pass.
The remaining non-flag arguments are taken to be the names of tests to run.
The default is to run "index". See "Tests" below.
When running the tests, I do *not* recommend switching to single-user mode
("init 1"). This seems to change the results in ways I don't understand,
and it's not realistic (unless your system will actually be running in this
mode, of course). However, if using a windowing system, you may want to
switch to a minimal window setup (for example, log in to a "twm" session),
so that randomly-churning background processes don't randomise the results
too much. This is particularly true for the graphics tests.
============================================================================
Tests
=====
The available tests are organised into categories; when generating index
scores (see "The BYTE Index" below) the results for each category are
produced separately. The categories are:
system The original Unix system tests (not all are actually
in the index)
2d 2D graphics tests (not all are actually in the index)
3d 3D graphics tests
misc Various non-indexed tests
The following individual tests are available:
system:
dhry2reg Dhrystone 2 using register variables
whetstone-double Double-Precision Whetstone
syscall System Call Overhead
pipe Pipe Throughput
context1 Pipe-based Context Switching
spawn Process Creation
execl Execl Throughput
fstime-w File Write 1024 bufsize 2000 maxblocks
fstime-r File Read 1024 bufsize 2000 maxblocks
fstime File Copy 1024 bufsize 2000 maxblocks
fsbuffer-w File Write 256 bufsize 500 maxblocks
fsbuffer-r File Read 256 bufsize 500 maxblocks
fsbuffer File Copy 256 bufsize 500 maxblocks
fsdisk-w File Write 4096 bufsize 8000 maxblocks
fsdisk-r File Read 4096 bufsize 8000 maxblocks
fsdisk File Copy 4096 bufsize 8000 maxblocks
shell1 Shell Scripts (1 concurrent) (runs "looper 60 multi.sh 1")
shell8 Shell Scripts (8 concurrent) (runs "looper 60 multi.sh 8")
shell16 Shell Scripts (8 concurrent) (runs "looper 60 multi.sh 16")
2d:
2d-rects 2D graphics: rectangles
2d-lines 2D graphics: lines
2d-circle 2D graphics: circles
2d-ellipse 2D graphics: ellipses
2d-shapes 2D graphics: polygons
2d-aashapes 2D graphics: aa polygons
2d-polys 2D graphics: complex polygons
2d-text 2D graphics: text
2d-blit 2D graphics: images and blits
2d-window 2D graphics: windows
3d:
ubgears 3D graphics: gears
misc:
C C Compiler Throughput ("looper 60 $cCompiler cctest.c")
arithoh Arithoh (huh?)
short Arithmetic Test (short) (this is arith.c configured for
"short" variables; ditto for the ones below)
int Arithmetic Test (int)
long Arithmetic Test (long)
float Arithmetic Test (float)
double Arithmetic Test (double)
dc Dc: sqrt(2) to 99 decimal places (runs
"looper 30 dc < dc.dat", using your system's copy of "dc")
hanoi Recursion Test -- Tower of Hanoi
grep Grep for a string in a large file, using your system's
copy of "grep"
sysexec Exercise fork() and exec().
The following pseudo-test names are aliases for combinations of other
tests:
arithmetic Runs arithoh, short, int, long, float, double,
and whetstone-double
dhry Alias for dhry2reg
dhrystone Alias for dhry2reg
whets Alias for whetstone-double
whetstone Alias for whetstone-double
load Runs shell1, shell8, and shell16
misc Runs C, dc, and hanoi
speed Runs the arithmetic and system groups
oldsystem Runs execl, fstime, fsbuffer, fsdisk, pipe, context1,
spawn, and syscall
system Runs oldsystem plus shell1, shell8, and shell16
fs Runs fstime-w, fstime-r, fstime, fsbuffer-w,
fsbuffer-r, fsbuffer, fsdisk-w, fsdisk-r, and fsdisk
shell Runs shell1, shell8, and shell16
index Runs the tests which constitute the official index:
the oldsystem group, plus dhry2reg, whetstone-double,
shell1, and shell8
See "The BYTE Index" below for more information.
graphics Runs the tests which constitute the graphics index:
2d-rects, 2d-ellipse, 2d-aashapes, 2d-text, 2d-blit,
2d-window, and ubgears
gindex Runs the index and graphics groups, to generate both
sets of index results
all Runs all tests
============================================================================
The BYTE Index
==============
The purpose of this test is to provide a basic indicator of the performance
of a Unix-like system; hence, multiple tests are used to test various
aspects of the system's performance. These test results are then compared
to the scores from a baseline system to produce an index value, which is
generally easier to handle than the raw sores. The entire set of index
values is then combined to make an overall index for the system.
Since 1995, the baseline system has been "George", a SPARCstation 20-61
with 128 MB RAM, a SPARC Storage Array, and Solaris 2.3, whose ratings
were set at 10.0. (So a system which scores 520 is 52 times faster than
this machine.) Since the numbers are really only useful in a relative
sense, there's no particular reason to update the base system, so for the
sake of consistency it's probably best to leave it alone. George's scores
are in the file "pgms/index.base"; this file is used to calculate the
index scores for any particular run.
Over the years, various changes have been made to the set of tests in the
index. Although there is a desire for a consistent baseline, various tests
have been determined to be misleading, and have been removed; and a few
alternatives have been added. These changes are detailed in the README,
and should be born in mind when looking at old scores.
A number of tests are included in the benchmark suite which are not part of
the index, for various reasons; these tests can of course be run manually.
See "Tests" above.
============================================================================
Graphics Tests
==============
As of version 5.1, UnixBench now contains some graphics benchmarks. These
are intended to give a rough idea of the general graphics performance of
a system.
The graphics tests are in categories "2d" and "3d", so the index scores
for these tests are separate from the basic system index. This seems
like a sensible division, since the graphics performance of a system
depends largely on the graphics adaptor.
The tests currently consist of some 2D "x11perf" tests and "ubgears".
* The 2D tests are a selection of the x11perf tests, using the host
system's x11perf command (which must be installed and in the search
path). Only a few of the x11perf tests are used, in the interests
of completing a test run in a reasonable time; if you want to do
detailed diagnosis of an X server or graphics chip, then use x11perf
directly.
* The 3D test is "ubgears", a modified version of the familiar "glxgears".
This version runs for 5 seconds to "warm up", then performs a timed
run and displays the average frames-per-second.
On multi-CPU systems, the graphics tests will only run in single-processing
mode. This is because the meaning of running two copies of a test at once
is dubious; and the test windows tend to overlay each other, meaning that
the window behind isn't actually doing any work.
============================================================================
Multiple CPUs
=============
If your system has multiple CPUs, the default behaviour is to run the selected
tests twice -- once with one copy of each test program running at a time,
and once with N copies, where N is the number of CPUs. (You can override
this with the "-c" option; see "Detailed Usage" above.) This is designed to
allow you to assess:
- the performance of your system when running a single task
- the performance of your system when running multiple tasks
- the gain from your system's implementation of parallel processing
The results, however, need to be handled with care. Here are the results
of two runs on a dual-processor system, one in single-processing mode, one
dual-processing:
Test Single Dual Gain
-------------------- ------ ------ ----
Dhrystone 2 562.5 1110.3 97%
Double Whetstone 320.0 640.4 100%
Execl Throughput 450.4 880.3 95%
File Copy 1024 759.4 595.9 -22%
File Copy 256 535.8 438.8 -18%
File Copy 4096 1261.8 1043.4 -17%
Pipe Throughput 481.0 979.3 104%
Pipe-based Switching 326.8 1229.0 276%
Process Creation 917.2 1714.1 87%
Shell Scripts (1) 1064.9 1566.3 47%
Shell Scripts (8) 1567.7 1709.9 9%
System Call Overhead 944.2 1445.5 53%
-------------------- ------ ------ ----
Index Score: 678.2 1026.2 51%
As expected, the heavily CPU-dependent tasks -- dhrystone, whetstone,
execl, pipe throughput, process creation -- show close to 100% gain when
running 2 copies in parallel.
The Pipe-based Context Switching test measures context switching overhead
by sending messages back and forth between 2 processes. I don't know why
it shows such a huge gain with 2 copies (ie. 4 processes total) running,
but it seems to be consistent on my system. I think this may be an issue
with the SMP implementation.
The System Call Overhead shows a lesser gain, presumably because it uses a
lot of CPU time in single-threaded kernel code. The shell scripts test with
8 concurrent processes shows no gain -- because the test itself runs 8
scripts in parallel, it's already using both CPUs, even when the benchmark
is run in single-stream mode. The same test with one process per copy
shows a real gain.
The filesystem throughput tests show a loss, instead of a gain, when
multi-processing. That there's no gain is to be expected, since the tests
are presumably constrained by the throughput of the I/O subsystem and the
disk drive itself; the drop in performance is presumably down to the
increased contention for resources, and perhaps greater disk head movement.
So what tests should you use, how many copies should you run, and how should
you interpret the results? Well, that's up to you, since it depends on
what it is you're trying to measure.
Implementation
--------------
The multi-processing mode is implemented at the level of test iterations.
During each iteration of a test, N slave processes are started using fork().
Each of these slaves executes the test program using fork() and exec(),
reads and stores the entire output, times the run, and prints all the
results to a pipe. The Run script reads the pipes for each of the slaves
in turn to get the results and times. The scores are added, and the times
averaged.
The result is that each test program has N copies running at once. They
should all finish at around the same time, since they run for constant time.
If a test program itself starts off K multiple processes (as with the shell8
test), then the effect will be that there are N * K processes running at
once. This is probably not very useful for testing multi-CPU performance.
============================================================================
The Language Setting
====================
The $LANG environment variable determines how programs abnd library
routines interpret text. This can have a big impact on the test results.
If $LANG is set to POSIX, or is left unset, text is treated as ASCII; if
it is set to en_US.UTF-8, foir example, then text is treated as being
encoded in UTF-8, which is more complex and therefore slower. Setting
it to other languages can have varying results.
To ensure consistency between test runs, the Run script now (as of version
5.1.1) sets $LANG to "en_US.utf8".
This setting which is configured with the variable "$language". You
should not change this if you want to share your results to allow
comparisons between systems; however, you may want to change it to see
how different language settings affect performance.
Each test report now includes the language settings in use. The reported
language is what is set in $LANG, and is not necessarily supported by the
system; but we also report the character mapping and collation order which
are actually in use (as reported by "locale").
============================================================================
Interpreting the Results
========================
Interpreting the results of these tests is tricky, and totally depends on
what you're trying to measure.
For example, are you trying to measure how fast your CPU is? Or how good
your compiler is? Because these tests are all recompiled using your host
system's compiler, the performance of the compiler will inevitably impact
the performance of the tests. Is this a problem? If you're choosing a
system, you probably care about its overall speed, which may well depend
on how good its compiler is; so including that in the test results may be
the right answer. But you may want to ensure that the right compiler is
used to build the tests.
On the other hand, with the vast majority of Unix systems being x86 / PC
compatibles, running Linux and the GNU C compiler, the results will tend
to be more dependent on the hardware; but the versions of the compiler and
OS can make a big difference. (I measured a 50% gain between SUSE 10.1
and OpenSUSE 10.2 on the same machine.) So you may want to make sure that
all your test systems are running the same version of the OS; or at least
publish the OS and compuiler versions with your results. Then again, it may
be compiler performance that you're interested in.
The C test is very dubious -- it tests the speed of compilation. If you're
running the exact same compiler on each system, OK; but otherwise, the
results should probably be discarded. A slower compilation doesn't say
anything about the speed of your system, since the compiler may simply be
spending more time to super-optimise the code, which would actually make it
faster.
This will be particularly true on architectures like IA-64 (Itanium etc.)
where the compiler spends huge amounts of effort scheduling instructions
to run in parallel, with a resultant significant gain in execution speed.
Some tests are even more dubious in terms of host-dependency -- for example,
the "dc" test uses the host's version of dc (a calculator program). The
version of this which is available can make a huge difference to the score,
which is why it's not in the index group. Read through the release notes
for more on these kinds of issues.
Another age-old issue is that of the benchmarks being too trivial to be
meaningful. With compilers getting ever smarter, and performing more
wide-ranging flow path analyses, the danger of parts of the benchmarks
simply being optimised out of existance is always present.
All in all, the "index" and "gindex" tests (see above) are designed to
give a reasonable measure of overall system performance; but the results
of any test run should always be used with care.

View File

@@ -1,133 +0,0 @@
Writing a Test
==============
Writing a test program is pretty easy. Basically, a test is configured via
a monster array in the Run script, which specifics (among other things) the
program to execute and the parameters to pass it.
The test itself is simply a program which is given the optional parameters
on the command line, and produces logging data on stdout and its results on
stderr.
============================================================================
Test Configuration
==================
In Run, all tests are named in the "$testList" array. This names the
individual tests, and also sets up aliases for groups of tests, eg. "index".
The test specifications are in the "$testParams" array. This contains the
details of each individual test as a hash. The fields in the hash are:
* "logmsg": the full name to display for this test.
* "cat": the category this test belongs to; must be configured
in $testCats.
* "prog": the name of the program to execute; defaults to the name of
the benchmark.
* "repeat": number of passes to run; either 'short' (the default),
'long', or 'single'. For 'short' and 'long', the actual numbers of
passes are given by $shortIterCount and $longIterCount, which are
configured at the top of the script or by the "-i" flag. 'single'
means just run one pass; this should be used for test which do their
own multi-pass handling internally.
* "stdout": non-0 to add the test's stdout to the log file; defaults to 1.
Set to 0 for tests that are too wordy.
* "stdin": name of a file to send to the program's stdin; default null.
* "options": options to be put on the program's command line; default null.
============================================================================
Output Format
=============
The results on stderr take the form of a line header and fields, separated
by "|" characters. A result line can be one of:
COUNT|score|timebase|label
TIME|seconds
ERROR|message
Any other text on stderr is treated as if it were:
ERROR|text
Any output to stdout is placed in a log file, and can be used for debugging.
COUNT
-----
The COUNT line is the line used to report a test score.
* "score" is the result, typically the number of loops performed during
the run
* "timebase" is the time base used for the final report to the user. A
value of 1 reports the score as is; a value of 60, for example, divides
the time taken by 60 to get loops per minute. Atimebase of zero indicates
that the score is already a rate, ie. a count of things per second.
* "label" is the label to use for the score; like "lps" (loops per
second), etc.
TIME
----
The TIME line is optionally used to report the time taken. The Run script
normally measures this, but if your test has signifant overhead outside the
actual test loop, you should use TIME to report the time taken for the actual
test. The argument is the time in seconds in floating-point.
ERROR
-----
The argument is an error message; this will abort the benchmarking run and
display the message.
Any output to stderr which is not a formatted line will be treated as an
error message, so use of ERROR is optional.
============================================================================
Test Examples
=============
Iteration Count
---------------
The simplest thing is to count the number of loops executed in a given time;
see eg. arith.c. The utlilty functions in timeit.c can be used to implement
the fixed time interval, which is generally passed in on the command line.
The result is reported simply as the number of iterations completed:
fprintf(stderr,"COUNT|%lu|1|lps\n", iterations);
The bnenchmark framework will measure the time taken itself. If the test
code has significant overhead (eg. a "pump-priming" pass), then you should
explicitly report the time taken for the test by adding a line like this:
fprintf(stderr, "TIME|%.1f\n", seconds);
If you want results reported as loops per minute, then set timebase to 60:
fprintf(stderr,"COUNT|%lu|60|lpm\n", iterations);
Note that this only affects the final report; all times passed to or
from the test are still in seconds.
Rate
----
The other technique is to calculate the rate (things per second) in the test,
and report that directly. To do this, just set timebase to 0:
fprintf(stderr, "COUNT|%ld|0|KBps\n", kbytes_per_sec);
Again, you can use TIME to explicitly report the time taken:
fprintf(stderr, "TIME|%.1f\n", end - start);
but this isn't so important since you've already calculated the rate.

View File

@@ -1,6 +0,0 @@
SUBDIR=arithoh register short int long float double whetstone-double hanoi \
poll select fstime syscall context1 pipe spawn execl dhry2 \
dhry2reg looper multi.sh tst.sh unixbench.logo index.base # ubgears poll2BB
.include <bsd.subdir.mk>

View File

@@ -1,5 +0,0 @@
CPPFLAGS+=-DTIME -DMINIX=1 -I../../src/
HZ=60
BINDIR=/usr/benchmarks/unixbench/pgms
.PATH: ${.CURDIR}/../../src

View File

@@ -1,7 +0,0 @@
PROG=arithoh
SRCS=arith.c
CPPFLAGS+=-Darithoh
MAN=
.include <bsd.prog.mk>

View File

@@ -1,5 +0,0 @@
PROG=context1
MAN=
.include <bsd.prog.mk>

View File

@@ -1,7 +0,0 @@
PROG=dhry2
SRCS=dhry_1.c dhry_2.c
CPPFLAGS+=-DHZ=${HZ}
MAN=
.include <bsd.prog.mk>

View File

@@ -1,7 +0,0 @@
PROG=dhry2reg
SRCS=dhry_1.c dhry_2.c
CPPFLAGS+=-DHZ=${HZ} -DREG=register
MAN=
.include <bsd.prog.mk>

View File

@@ -1,7 +0,0 @@
PROG=double
SRCS=arith.c
CPPFLAGS=-Ddatum='double'
MAN=
.include <bsd.prog.mk>

View File

@@ -1,5 +0,0 @@
PROG=execl
MAN=
.include <bsd.prog.mk>

View File

@@ -1,7 +0,0 @@
PROG=float
SRCS=arith.c
CPPFLAGS=-Ddatum='float'
MAN=
.include <bsd.prog.mk>

View File

@@ -1,5 +0,0 @@
PROG=fstime
MAN=
.include <bsd.prog.mk>

View File

@@ -1,476 +0,0 @@
#!/usr/bin/perl -w
use strict;
############################################################################
# gfx-x11: a front-end for x11perf. Runs a selected x11perf test, and
# produces output in the format needed by UnixBench.
############################################################################
# Modification Log:
# 2007.09.26 Ian Smith Created
############################################################################
# This program runs sets of x11perf tests, indexes the results against
# a common base reference system (see $testData below), and reports the
# final score.
#
# Usage:
# gfx-x11 <group> <reps> <time>
# where:
# <group> is one of the test groups defined in $testGroups below
# <reps> is the number of repeats to do per test (the -repeat
# argument to x11perf)
# <time> is the number of seconds to run each repeat for (the
# -time argument to x11perf)
# Note that x11perf runs a calibration pass before the requested number
# of test passes. The score we compute for a test is the average of the
# test passes, divided by the base value in $testData, times 1000.0.
# The final score we report is the average of the test scores.
############################################################################
# TEST DATA
############################################################################
# This array lists all of the x11perf tests, together with their scores
# on an HP Compaq nc8430, with an ATI Mobility Radeon X1600 (256MB)
# graphics adapter. There isn't anything special about this reference
# system, but scaling all the scores back to a single reference system
# allows us to average them in a roughly meaningful way, which in turn
# allows us to produce sensible scores for the test groups defined below.
#
# The results we report are indexed to these values, at a base of 1000.0.
my $testData = {
'dot' => [ 31700000.0, "Dot" ],
'rect1' => [ 18400000.0, "1x1 rectangle" ],
'rect10' => [ 7180000.0, "10x10 rectangle" ],
'rect100' => [ 110000.0, "100x100 rectangle" ],
'rect500' => [ 4110.0, "500x500 rectangle" ],
'srect1' => [ 15800000.0, "1x1 stippled rectangle (8x8 stipple)" ],
'srect10' => [ 7400000.0, "10x10 stippled rectangle (8x8 stipple)" ],
'srect100' => [ 110000.0, "100x100 stippled rectangle (8x8 stipple)" ],
'srect500' => [ 4110.0, "500x500 stippled rectangle (8x8 stipple)" ],
'osrect1' => [ 15900000.0, "1x1 opaque stippled rectangle (8x8 stipple)" ],
'osrect10' => [ 7170000.0, "10x10 opaque stippled rectangle (8x8 stipple)" ],
'osrect100' => [ 110000.0, "100x100 opaque stippled rectangle (8x8 stipple)" ],
'osrect500' => [ 4110.0, "500x500 opaque stippled rectangle (8x8 stipple)" ],
'tilerect1' => [ 15800000.0, "1x1 tiled rectangle (4x4 tile)" ],
'tilerect10' => [ 7170000.0, "10x10 tiled rectangle (4x4 tile)" ],
'tilerect100' => [ 110000.0, "100x100 tiled rectangle (4x4 tile)" ],
'tilerect500' => [ 4110.0, "500x500 tiled rectangle (4x4 tile)" ],
'oddsrect1' => [ 2990000.0, "1x1 stippled rectangle (17x15 stipple)" ],
'oddsrect10' => [ 1490000.0, "10x10 stippled rectangle (17x15 stipple)" ],
'oddsrect100' => [ 55600.0, "100x100 stippled rectangle (17x15 stipple)" ],
'oddsrect500' => [ 2360.0, "500x500 stippled rectangle (17x15 stipple)" ],
'oddosrect1' => [ 2990000.0, "1x1 opaque stippled rectangle (17x15 stipple)" ],
'oddosrect10' => [ 1430000.0, "10x10 opaque stippled rectangle (17x15 stipple)" ],
'oddosrect100' => [ 54500.0, "100x100 opaque stippled rectangle (17x15 stipple)" ],
'oddosrect500' => [ 2320.0, "500x500 opaque stippled rectangle (17x15 stipple)" ],
'oddtilerect1' => [ 2990000.0, "1x1 tiled rectangle (17x15 tile)" ],
'oddtilerect10' => [ 1430000.0, "10x10 tiled rectangle (17x15 tile)" ],
'oddtilerect100' => [ 54500.0, "100x100 tiled rectangle (17x15 tile)" ],
'oddtilerect500' => [ 2320.0, "500x500 tiled rectangle (17x15 tile)" ],
'bigsrect1' => [ 4300000.0, "1x1 stippled rectangle (161x145 stipple)" ],
'bigsrect10' => [ 705000.0, "10x10 stippled rectangle (161x145 stipple)" ],
'bigsrect100' => [ 12300.0, "100x100 stippled rectangle (161x145 stipple)" ],
'bigsrect500' => [ 524.0, "500x500 stippled rectangle (161x145 stipple)" ],
'bigosrect1' => [ 3980000.0, "1x1 opaque stippled rectangle (161x145 stipple)" ],
'bigosrect10' => [ 644000.0, "10x10 opaque stippled rectangle (161x145 stipple)" ],
'bigosrect100' => [ 12800.0, "100x100 opaque stippled rectangle (161x145 stipple)" ],
'bigosrect500' => [ 584.0, "500x500 opaque stippled rectangle (161x145 stipple)" ],
'bigtilerect1' => [ 5970000.0, "1x1 tiled rectangle (161x145 tile)" ],
'bigtilerect10' => [ 684000.0, "10x10 tiled rectangle (161x145 tile)" ],
'bigtilerect100' => [ 16200.0, "100x100 tiled rectangle (161x145 tile)" ],
'bigtilerect500' => [ 872.0, "500x500 tiled rectangle (161x145 tile)" ],
'eschertilerect1' => [ 5940000.0, "1x1 tiled rectangle (216x208 tile)" ],
'eschertilerect10' => [ 639000.0, "10x10 tiled rectangle (216x208 tile)" ],
'eschertilerect100' => [ 18000.0, "100x100 tiled rectangle (216x208 tile)" ],
'eschertilerect500' => [ 922.0, "500x500 tiled rectangle (216x208 tile)" ],
'seg1' => [ 28800000.0, "1-pixel line segment" ],
'seg10' => [ 4460000.0, "10-pixel line segment" ],
'seg100' => [ 470000.0, "100-pixel line segment" ],
'seg500' => [ 94600.0, "500-pixel line segment" ],
'seg100c1' => [ 449000.0, "100-pixel line segment (1 kid)" ],
'seg100c2' => [ 432000.0, "100-pixel line segment (2 kids)" ],
'seg100c3' => [ 421000.0, "100-pixel line segment (3 kids)" ],
'dseg10' => [ 3720000.0, "10-pixel dashed segment" ],
'dseg100' => [ 687000.0, "100-pixel dashed segment" ],
'ddseg100' => [ 454000.0, "100-pixel double-dashed segment" ],
'hseg10' => [ 7020000.0, "10-pixel horizontal line segment" ],
'hseg100' => [ 2170000.0, "100-pixel horizontal line segment" ],
'hseg500' => [ 456000.0, "500-pixel horizontal line segment" ],
'vseg10' => [ 3990000.0, "10-pixel vertical line segment" ],
'vseg100' => [ 411000.0, "100-pixel vertical line segment" ],
'vseg500' => [ 82400.0, "500-pixel vertical line segment" ],
'whseg10' => [ 2880000.0, "10x1 wide horizontal line segment" ],
'whseg100' => [ 616000.0, "100x10 wide horizontal line segment" ],
'whseg500' => [ 33300.0, "500x50 wide horizontal line segment" ],
'wvseg10' => [ 2890000.0, "10x1 wide vertical line segment" ],
'wvseg100' => [ 584000.0, "100x10 wide vertical line segment" ],
'wvseg500' => [ 31700.0, "500x50 wide vertical line segment" ],
'line1' => [ 28300000.0, "1-pixel line" ],
'line10' => [ 4470000.0, "10-pixel line" ],
'line100' => [ 472000.0, "100-pixel line" ],
'line500' => [ 94200.0, "500-pixel line" ],
'dline10' => [ 3640000.0, "10-pixel dashed line" ],
'dline100' => [ 673000.0, "100-pixel dashed line" ],
'ddline100' => [ 453000.0, "100-pixel double-dashed line" ],
'wline10' => [ 908000.0, "10x1 wide line" ],
'wline100' => [ 146000.0, "100x10 wide line" ],
'wline500' => [ 30600.0, "500x50 wide line" ],
'wdline100' => [ 69900.0, "100x10 wide dashed line" ],
'wddline100' => [ 60600.0, "100x10 wide double-dashed line" ],
'orect10' => [ 5100000.0, "10x10 rectangle outline" ],
'orect100' => [ 709000.0, "100x100 rectangle outline" ],
'orect500' => [ 146000.0, "500x500 rectangle outline" ],
'worect10' => [ 4530000.0, "10x10 wide rectangle outline" ],
'worect100' => [ 204000.0, "100x100 wide rectangle outline" ],
'worect500' => [ 9790.0, "500x500 wide rectangle outline" ],
'circle1' => [ 5160000.0, "1-pixel circle" ],
'circle10' => [ 1160000.0, "10-pixel circle" ],
'circle100' => [ 141000.0, "100-pixel circle" ],
'circle500' => [ 28900.0, "500-pixel circle" ],
'dcircle100' => [ 98400.0, "100-pixel dashed circle" ],
'ddcircle100' => [ 75000.0, "100-pixel double-dashed circle" ],
'wcircle10' => [ 780000.0, "10-pixel wide circle" ],
'wcircle100' => [ 90900.0, "100-pixel wide circle" ],
'wcircle500' => [ 11300.0, "500-pixel wide circle" ],
'wdcircle100' => [ 8100.0, "100-pixel wide dashed circle" ],
'wddcircle100' => [ 8300.0, "100-pixel wide double-dashed circle" ],
'pcircle10' => [ 1270000.0, "10-pixel partial circle" ],
'pcircle100' => [ 212000.0, "100-pixel partial circle" ],
'wpcircle10' => [ 104000.0, "10-pixel wide partial circle" ],
'wpcircle100' => [ 39000.0, "100-pixel wide partial circle" ],
'fcircle1' => [ 61300000.0, "1-pixel solid circle" ],
'fcircle10' => [ 1720000.0, "10-pixel solid circle" ],
'fcircle100' => [ 120000.0, "100-pixel solid circle" ],
'fcircle500' => [ 5170.0, "500-pixel solid circle" ],
'fcpcircle10' => [ 981000.0, "10-pixel fill chord partial circle" ],
'fcpcircle100' => [ 205000.0, "100-pixel fill chord partial circle" ],
'fspcircle10' => [ 876000.0, "10-pixel fill slice partial circle" ],
'fspcircle100' => [ 187000.0, "100-pixel fill slice partial circle" ],
'ellipse10' => [ 1410000.0, "10-pixel ellipse" ],
'ellipse100' => [ 172000.0, "100-pixel ellipse" ],
'ellipse500' => [ 35100.0, "500-pixel ellipse" ],
'dellipse100' => [ 114000.0, "100-pixel dashed ellipse" ],
'ddellipse100' => [ 88900.0, "100-pixel double-dashed ellipse" ],
'wellipse10' => [ 889000.0, "10-pixel wide ellipse" ],
'wellipse100' => [ 124000.0, "100-pixel wide ellipse" ],
'wellipse500' => [ 15600.0, "500-pixel wide ellipse" ],
'wdellipse100' => [ 7730.0, "100-pixel wide dashed ellipse" ],
'wddellipse100' => [ 6680.0, "100-pixel wide double-dashed ellipse" ],
'pellipse10' => [ 1350000.0, "10-pixel partial ellipse" ],
'pellipse100' => [ 260000.0, "100-pixel partial ellipse" ],
'wpellipse10' => [ 97900.0, "10-pixel wide partial ellipse" ],
'wpellipse100' => [ 16800.0, "100-pixel wide partial ellipse" ],
'fellipse10' => [ 2110000.0, "10-pixel filled ellipse" ],
'fellipse100' => [ 212000.0, "100-pixel filled ellipse" ],
'fellipse500' => [ 11000.0, "500-pixel filled ellipse" ],
'fcpellipse10' => [ 1060000.0, "10-pixel fill chord partial ellipse" ],
'fcpellipse100' => [ 296000.0, "100-pixel fill chord partial ellipse" ],
'fspellipse10' => [ 945000.0, "10-pixel fill slice partial ellipse" ],
'fspellipse100' => [ 269000.0, "100-pixel fill slice partial ellipse" ],
'triangle1' => [ 2460000.0, "Fill 1x1 equivalent triangle" ],
'triangle10' => [ 969000.0, "Fill 10x10 equivalent triangle" ],
'triangle100' => [ 97000.0, "Fill 100x100 equivalent triangle" ],
'trap1' => [ 2630000.0, "Fill 1x1 trapezoid" ],
'trap10' => [ 1260000.0, "Fill 10x10 trapezoid" ],
'trap100' => [ 106000.0, "Fill 100x100 trapezoid" ],
'trap300' => [ 11600.0, "Fill 300x300 trapezoid" ],
'strap1' => [ 2010000.0, "Fill 1x1 stippled trapezoid (8x8 stipple)" ],
'strap10' => [ 910000.0, "Fill 10x10 stippled trapezoid (8x8 stipple)" ],
'strap100' => [ 104000.0, "Fill 100x100 stippled trapezoid (8x8 stipple)" ],
'strap300' => [ 11700.0, "Fill 300x300 stippled trapezoid (8x8 stipple)" ],
'ostrap1' => [ 2000000.0, "Fill 1x1 opaque stippled trapezoid (8x8 stipple)" ],
'ostrap10' => [ 907000.0, "Fill 10x10 opaque stippled trapezoid (8x8 stipple)" ],
'ostrap100' => [ 104000.0, "Fill 100x100 opaque stippled trapezoid (8x8 stipple)" ],
'ostrap300' => [ 11600.0, "Fill 300x300 opaque stippled trapezoid (8x8 stipple)" ],
'tiletrap1' => [ 1430000.0, "Fill 1x1 tiled trapezoid (4x4 tile)" ],
'tiletrap10' => [ 778000.0, "Fill 10x10 tiled trapezoid (4x4 tile)" ],
'tiletrap100' => [ 104000.0, "Fill 100x100 tiled trapezoid (4x4 tile)" ],
'tiletrap300' => [ 11600.0, "Fill 300x300 tiled trapezoid (4x4 tile)" ],
'oddstrap1' => [ 1700000.0, "Fill 1x1 stippled trapezoid (17x15 stipple)" ],
'oddstrap10' => [ 296000.0, "Fill 10x10 stippled trapezoid (17x15 stipple)" ],
'oddstrap100' => [ 18600.0, "Fill 100x100 stippled trapezoid (17x15 stipple)" ],
'oddstrap300' => [ 2090.0, "Fill 300x300 stippled trapezoid (17x15 stipple)" ],
'oddostrap1' => [ 1830000.0, "Fill 1x1 opaque stippled trapezoid (17x15 stipple)" ],
'oddostrap10' => [ 296000.0, "Fill 10x10 opaque stippled trapezoid (17x15 stipple)" ],
'oddostrap100' => [ 18400.0, "Fill 100x100 opaque stippled trapezoid (17x15 stipple)" ],
'oddostrap300' => [ 2080.0, "Fill 300x300 opaque stippled trapezoid (17x15 stipple)" ],
'oddtiletrap1' => [ 1710000.0, "Fill 1x1 tiled trapezoid (17x15 tile)" ],
'oddtiletrap10' => [ 296000.0, "Fill 10x10 tiled trapezoid (17x15 tile)" ],
'oddtiletrap100' => [ 18400.0, "Fill 100x100 tiled trapezoid (17x15 tile)" ],
'oddtiletrap300' => [ 2080.0, "Fill 300x300 tiled trapezoid (17x15 tile)" ],
'bigstrap1' => [ 1510000.0, "Fill 1x1 stippled trapezoid (161x145 stipple)" ],
'bigstrap10' => [ 235000.0, "Fill 10x10 stippled trapezoid (161x145 stipple)" ],
'bigstrap100' => [ 9110.0, "Fill 100x100 stippled trapezoid (161x145 stipple)" ],
'bigstrap300' => [ 1260.0, "Fill 300x300 stippled trapezoid (161x145 stipple)" ],
'bigostrap1' => [ 1480000.0, "Fill 1x1 opaque stippled trapezoid (161x145 stipple)" ],
'bigostrap10' => [ 213000.0, "Fill 10x10 opaque stippled trapezoid (161x145 stipple)" ],
'bigostrap100' => [ 8830.0, "Fill 100x100 opaque stippled trapezoid (161x145 stipple)" ],
'bigostrap300' => [ 1420.0, "Fill 300x300 opaque stippled trapezoid (161x145 stipple)" ],
'bigtiletrap1' => [ 1630000.0, "Fill 1x1 tiled trapezoid (161x145 tile)" ],
'bigtiletrap10' => [ 272000.0, "Fill 10x10 tiled trapezoid (161x145 tile)" ],
'bigtiletrap100' => [ 12900.0, "Fill 100x100 tiled trapezoid (161x145 tile)" ],
'bigtiletrap300' => [ 2350.0, "Fill 300x300 tiled trapezoid (161x145 tile)" ],
'eschertiletrap1' => [ 1650000.0, "Fill 1x1 tiled trapezoid (216x208 tile)" ],
'eschertiletrap10' => [ 273000.0, "Fill 10x10 tiled trapezoid (216x208 tile)" ],
'eschertiletrap100' => [ 13400.0, "Fill 100x100 tiled trapezoid (216x208 tile)" ],
'eschertiletrap300' => [ 2450.0, "Fill 300x300 tiled trapezoid (216x208 tile)" ],
'aatrap1' => [ 260000.0, "Fill 1x1 aa trap" ],
'aatrap10' => [ 23500.0, "Fill 10x10 aa trap" ],
'aatrap100' => [ 13300.0, "Fill 100x100 aa trap" ],
'aatrap300' => [ 4450.0, "Fill 300x300 aa trap" ],
'aa4trap1' => [ 2150.0, "Fill 1x1 aa trap with 4 bit alpha" ],
'aa4trap10' => [ 2130.0, "Fill 10x10 aa trap with 4 bit alpha" ],
'aa4trap100' => [ 1890.0, "Fill 100x100 aa trap with 4 bit alpha" ],
'aa4trap300' => [ 1460.0, "Fill 300x300 aa trap with 4 bit alpha" ],
'aa1trap1' => [ 2200000.0, "Fill 1x1 aa trap with 1 bit alpha" ],
'aa1trap10' => [ 357000.0, "Fill 10x10 aa trap with 1 bit alpha" ],
'aa1trap100' => [ 167000.0, "Fill 100x100 aa trap with 1 bit alpha" ],
'aa1trap300' => [ 67000.0, "Fill 300x300 aa trap with 1 bit alpha" ],
'aatrap2x1' => [ 368000.0, "Fill 2x1 aa trap" ],
'aatrap2x10' => [ 25700.0, "Fill 2x10 aa trap" ],
'aatrap2x100' => [ 12400.0, "Fill 2x100 aa trap" ],
'aatrap2x300' => [ 5710.0, "Fill 2x300 aa trap" ],
'aatrapezoid1' => [ 372000.0, "Fill 1x1 aa trapezoid" ],
'aatrapezoid10' => [ 137000.0, "Fill 10x10 aa trapezoid" ],
'aatrapezoid100' => [ 9590.0, "Fill 100x100 aa trapezoid" ],
'aatrapezoid300' => [ 1420.0, "Fill 300x300 aa trapezoid" ],
'addaatrapezoid1' => [ 433000.0, "Fill 1x1 aa pre-added trapezoid" ],
'addaatrapezoid10' => [ 24100.0, "Fill 10x10 aa pre-added trapezoid" ],
'addaatrapezoid100' => [ 13300.0, "Fill 100x100 aa pre-added trapezoid" ],
'addaatrapezoid300' => [ 4460.0, "Fill 300x300 aa pre-added trapezoid" ],
'complex10' => [ 655000.0, "Fill 10x10 equivalent complex polygon" ],
'complex100' => [ 87000.0, "Fill 100x100 equivalent complex polygons" ],
'64poly10convex' => [ 481000.0, "Fill 10x10 64-gon (Convex)" ],
'64poly100convex' => [ 105000.0, "Fill 100x100 64-gon (Convex)" ],
'64poly10complex' => [ 353000.0, "Fill 10x10 64-gon (Complex)" ],
'64poly100complex' => [ 105000.0, "Fill 100x100 64-gon (Complex)" ],
'ftext' => [ 2200000.0, "Char in 80-char line (6x13)" ],
'f8text' => [ 1970000.0, "Char in 70-char line (8x13)" ],
'f9text' => [ 1690000.0, "Char in 60-char line (9x15)" ],
'f14text16' => [ 679000.0, "Char16 in 40-char line (k14)" ],
'f24text16' => [ 272000.0, "Char16 in 23-char line (k24)" ],
'tr10text' => [ 2520000.0, "Char in 80-char line (TR 10)" ],
'tr24text' => [ 940000.0, "Char in 30-char line (TR 24)" ],
'polytext' => [ 2230000.0, "Char in 20/40/20 line (6x13, TR 10)" ],
'polytext16' => [ 369000.0, "Char16 in 7/14/7 line (k14, k24)" ],
'fitext' => [ 1350000.0, "Char in 80-char image line (6x13)" ],
'f8itext' => [ 1130000.0, "Char in 70-char image line (8x13)" ],
'f9itext' => [ 902000.0, "Char in 60-char image line (9x15)" ],
'f14itext16' => [ 449000.0, "Char16 in 40-char image line (k14)" ],
'f24itext16' => [ 169000.0, "Char16 in 23-char image line (k24)" ],
'tr10itext' => [ 1590000.0, "Char in 80-char image line (TR 10)" ],
'tr24itext' => [ 435000.0, "Char in 30-char image line (TR 24)" ],
'aa10text' => [ 53200.0, "Char in 80-char aa line (Charter 10)" ],
'aa24text' => [ 13300.0, "Char in 30-char aa line (Charter 24)" ],
'aaftext' => [ 45200.0, "Char in 80-char aa line (Courier 12)" ],
'a10text' => [ 53100.0, "Char in 80-char a line (Charter 10)" ],
'a24text' => [ 13300.0, "Char in 30-char a line (Charter 24)" ],
'aftext' => [ 45200.0, "Char in 80-char a line (Courier 12)" ],
'rgb10text' => [ 49400.0, "Char in 80-char rgb line (Charter 10)" ],
'rgb24text' => [ 10200.0, "Char in 30-char rgb line (Charter 24)" ],
'rgbftext' => [ 42200.0, "Char in 80-char rgb line (Courier 12)" ],
'caa10text' => [ 15300.0, "Char in 80-char aa core line (Charter 10)" ],
'caa24text' => [ 2540.0, "Char in 30-char aa core line (Charter 24)" ],
'caaftext' => [ 10900.0, "Char in 80-char aa core line (Courier 12)" ],
'ca10text' => [ 15300.0, "Char in 80-char a core line (Charter 10)" ],
'ca24text' => [ 2540.0, "Char in 30-char a core line (Charter 24)" ],
'caftext' => [ 10900.0, "Char in 80-char a core line (Courier 12)" ],
'rgb10text' => [ 15000.0, "Char in 80-char rgb core line (Charter 10)" ],
'rgb24text' => [ 2510.0, "Char in 30-char rgb core line (Charter 24)" ],
'rgbftext' => [ 10700.0, "Char in 80-char rgb core line (Courier 12)" ],
'scroll10' => [ 1310000.0, "Scroll 10x10 pixels" ],
'scroll100' => [ 52000.0, "Scroll 100x100 pixels" ],
'scroll500' => [ 2190.0, "Scroll 500x500 pixels" ],
'copywinwin10' => [ 1030000.0, "Copy 10x10 from window to window" ],
'copywinwin100' => [ 52200.0, "Copy 100x100 from window to window" ],
'copywinwin500' => [ 2080.0, "Copy 500x500 from window to window" ],
'copypixwin10' => [ 502000.0, "Copy 10x10 from pixmap to window" ],
'copypixwin100' => [ 20300.0, "Copy 100x100 from pixmap to window" ],
'copypixwin500' => [ 1020.0, "Copy 500x500 from pixmap to window" ],
'copywinpix10' => [ 7730.0, "Copy 10x10 from window to pixmap" ],
'copywinpix100' => [ 127.0, "Copy 100x100 from window to pixmap" ],
'copywinpix500' => [ 5.0, "Copy 500x500 from window to pixmap" ],
'copypixpix10' => [ 1260000.0, "Copy 10x10 from pixmap to pixmap" ],
'copypixpix100' => [ 56300.0, "Copy 100x100 from pixmap to pixmap" ],
'copypixpix500' => [ 2470.0, "Copy 500x500 from pixmap to pixmap" ],
'copyplane10' => [ 466000.0, "Copy 10x10 1-bit deep plane" ],
'copyplane100' => [ 13700.0, "Copy 100x100 1-bit deep plane" ],
'copyplane500' => [ 671.0, "Copy 500x500 1-bit deep plane" ],
'deepcopyplane10' => [ 151000.0, "Copy 10x10 n-bit deep plane" ],
'deepcopyplane100' => [ 6090.0, "Copy 100x100 n-bit deep plane" ],
'deepcopyplane500' => [ 278.0, "Copy 500x500 n-bit deep plane" ],
'putimage10' => [ 434000.0, "PutImage 10x10 square" ],
'putimage100' => [ 13600.0, "PutImage 100x100 square" ],
'putimage500' => [ 713.0, "PutImage 500x500 square" ],
'putimagexy10' => [ 321.0, "PutImage XY 10x10 square" ],
'putimagexy100' => [ 3.2, "PutImage XY 100x100 square" ],
'putimagexy500' => [ 0.1, "PutImage XY 500x500 square" ],
'shmput10' => [ 465000.0, "ShmPutImage 10x10 square" ],
'shmput100' => [ 20200.0, "ShmPutImage 100x100 square" ],
'shmput500' => [ 1020.0, "ShmPutImage 500x500 square" ],
'shmputxy10' => [ 31400.0, "ShmPutImage XY 10x10 square" ],
'shmputxy100' => [ 458.0, "ShmPutImage XY 100x100 square" ],
'shmputxy500' => [ 19.0, "ShmPutImage XY 500x500 square" ],
'getimage10' => [ 6650.0, "GetImage 10x10 square" ],
'getimage100' => [ 77.0, "GetImage 100x100 square" ],
'getimage500' => [ 3.1, "GetImage 500x500 square" ],
'getimagexy10' => [ 320.0, "GetImage XY 10x10 square" ],
'getimagexy100' => [ 3.2, "GetImage XY 100x100 square" ],
'getimagexy500' => [ 0.1, "GetImage XY 500x500 square" ],
'noop' => [ 8760000.0, "X protocol NoOperation" ],
'pointer' => [ 54800.0, "QueryPointer" ],
'prop' => [ 50900.0, "GetProperty" ],
'gc' => [ 1190000.0, "Change graphics context" ],
'create' => [ 597000.0, "Create and map subwindows (25 kids)" ],
'ucreate' => [ 1100000.0, "Create unmapped window (25 kids)" ],
'map' => [ 1350000.0, "Map window via parent (25 kids)" ],
'unmap' => [ 3360000.0, "Unmap window via parent (25 kids)" ],
'destroy' => [ 1190000.0, "Destroy window via parent (25 kids)" ],
'popup' => [ 660000.0, "Hide/expose window via popup (25 kids)" ],
'move' => [ 120000.0, "Move window (25 kids)" ],
'umove' => [ 1990000.0, "Moved unmapped window (25 kids)" ],
'movetree' => [ 877000.0, "Move window via parent (25 kids)" ],
'resize' => [ 136000.0, "Resize window (25 kids)" ],
'uresize' => [ 1870000.0, "Resize unmapped window (25 kids)" ],
'circulate' => [ 56300.0, "Circulate window (25 kids)" ],
'ucirculate' => [ 3630000.0, "Circulate Unmapped window (25 kids)" ],
};
# This array defines named groups of tests. This is designed to allow
# for simpler runs of related tests.
#
# Note that this array does *not* include all the x11perf tests. The idea
# here is to run a representative sampling of the available tests, to get
# a general idea of a system's performance, without taking forever to
# do it. If you want to do detailed analysis of an X server or graphics
# chip, then use x11perf directly.
my $testGroups = {
'rects' => [ "rect10", "rect100", "oddtilerect10", "eschertilerect100" ],
'lines' => [ "seg100c3", "wvseg100", "ddline100", "worect500" ],
'circle' => [ "circle500", "wddcircle100", "wpcircle100", "fspcircle100" ],
'ellipse' => [ "ddellipse100", "wddellipse100", "pellipse10", "fspellipse100" ],
'shapes' => [ "triangle10", "trap300", "oddostrap300", "eschertiletrap300" ],
'aashapes' => [ "aa4trap300", "aa1trap10", "aatrap2x300", "addaatrapezoid300" ],
'polys' => [ "complex10", "64poly100convex", "64poly10complex", "64poly100complex" ],
'text' => [ "polytext16", "rgb24text", "caa10text", "ca24text" ],
'blit' => [ "scroll100", "copypixwin10", "deepcopyplane10", "putimagexy500" ],
'window' => [ "popup", "move", "movetree", "resize" ],
};
############################################################################
# CODE
############################################################################
# Exec the given command, and catch its standard output.
# We return an array containing the PID and the filehandle on the
# process' standard output. It's up to the caller to wait for the command
# to terminate.
sub command {
my ( $cmd ) = @_;
my $pid = open(my $childFd, "-|");
if (!defined($pid)) {
die("Run: fork() failed (undef)\n");
} elsif ($pid == 0) {
exec($cmd);
die("Run: exec() failed (returned)\n");
}
return ( $pid, $childFd );
}
# Get data from running a system command. Used for things like getting
# the host OS from `uname -o` etc.
#
# Ignores initial blank lines from the command and returns the first
# non-blank line, with white space trimmed off.
sub runTest {
my ( $test, $reps, $time ) = @_;
my $tdata = $testData->{$test};
if (!defined($tdata)) {
printf STDERR "gfx-x11: No such test: %s\n", $test;
exit(9);
}
my $cmd = sprintf "x11perf -repeat %d -subs 25 -time %d -%s",
$reps, $time, $test;
my ( $pid, $fd ) = command($cmd);
my $average = 0;
while (<$fd>) {
chomp;
# Display the output for logging.
printf "%s\n", $_;
# Save the score.
my ( $reps, $per, $rate ) =
( m:([0-9]+)\s+trep\s+@\s+([0-9.]+)\s+msec\s+\(\s*([0-9.]+)/sec\): );
$average = $rate if (defined($rate));
}
# Close the command and wait for it to die. Bomb out if it failed.
# close($fd);
my $p = waitpid($pid, 0);
my $status = $?;
exit($status) if ($status != 0);
# Calculate and return the weighted result.
my $score = $average / $tdata->[0] * 1000.0;
printf "Test %s: %d --> %.1f\n", $test, $average, $score;
return $score;
}
sub runGroup {
my ( $group, $reps, $time ) = @_;
my $gdata = $testGroups->{$group};
if (!defined($gdata)) {
printf STDERR "gfx-x11: No such test group: %s\n", $group;
exit(9);
}
my $count = 0;
my $total = 0;
foreach my $test (@$gdata) {
$total += runTest($test, $reps, $time);
++$count;
}
$total /= $count;
$total;
}
############################################################################
# MAIN
############################################################################
sub main {
my @args = @_;
if (scalar(@args) < 3) {
printf STDERR "Usage: gfx-x11 group reps time\n";
exit(9);
}
my $reps = $args[1];
my $time = $args[2];
my $score = runGroup($args[0], $reps, $time);
printf STDERR "COUNT|%.1f|0|score\n", $score;
return 0;
}
exit(main(@ARGV));

View File

@@ -1,5 +0,0 @@
PROG=hanoi
MAN=
.include <bsd.prog.mk>

View File

@@ -1,3 +0,0 @@
SCRIPTS=index.base
SCRIPTSNAME=index.base
.include <bsd.prog.mk>

View File

@@ -1,46 +0,0 @@
# Baseline benchmark scores, used for calculating index results.
# Scores from "George", a SPARCstation 20-61.
dhry2reg|10|lps|116700|116700|2
whetstone-double|10|MWIPS|55.0|55.0|2
execl|20|lps|43.0|43.0|1
fstime|20|KBps|3960|3960|1
fsbuffer|20|KBps|1655|1655|1
fsdisk|20|KBps|5800|5800|1
pipe|10|lps|12440|12440|2
context1|10|lps|4000|4000|2
spawn|20|lps|126|126|1
shell8|60|lpm|6|6|1
syscall|10|lps|15000|15000|2
# The shell1 test was added to the index in 5.0, and this baseline score
# was extrapolated to roughly match George's performance.
shell1|60|lpm|42.4|42.4|1
# The 2D baseline scores were derived from a test run on an HP Compaq nc8430
# with an ATI Mobility Radeon X1600 Video (256MB) — this is a fairly
# common modern adaptor with 3D. The baseline scores here are then
# 1/66.6 of the values from that run, to bring them roughly in line with
# George. (The HP has an index score of 666.6 single-process.)
2d-rects|3|score|15|15|1
#2d-lines|3|score|15|15|1
#2d-circle|3|score|15|15|1
2d-ellipse|3|score|15|15|1
#2d-shapes|3|score|15|15|1
2d-aashapes|3|score|15|15|1
#2d-polys|3|score|15|15|1
2d-text|3|score|15|15|1
2d-blit|3|score|15|15|1
2d-window|3|score|15|15|1
# The gears test score is derived from a test run on an HP Compaq nc8430
# with an ATI Mobility Radeon X1600 Video (256MB) — this is a fairly
# common modern adaptor with 3D. The baseline scores here are then
# 1/66.6 of the values from that run, to bring them roughly in line with
# George.
ubgears|20|fps|33.4|33.4|3
# The grep and sysexec tests were added in 5.1.1; they are not index tests,
# but these baseline scores were added for convenience.
grep|30|lpm|1|1|3
sysexec|10|lps|25|25|10

View File

@@ -1,7 +0,0 @@
PROG=int
SRCS=arith.c
CPPFLAGS=-Ddatum='int'
MAN=
.include <bsd.prog.mk>

View File

@@ -1,7 +0,0 @@
PROG=long
SRCS=arith.c
CPPFLAGS=-Ddatum='long'
MAN=
.include <bsd.prog.mk>

View File

@@ -1,5 +0,0 @@
PROG=looper
MAN=
.include <bsd.prog.mk>

View File

@@ -1,3 +0,0 @@
SCRIPTS=multi.sh
SCRIPTSNAME=multi.sh
.include <bsd.prog.mk>

View File

@@ -1,23 +0,0 @@
#! /bin/sh
###############################################################################
# The BYTE UNIX Benchmarks - Release 3
# Module: multi.sh SID: 3.4 5/15/91 19:30:24
#
###############################################################################
# Bug reports, patches, comments, suggestions should be sent to:
#
# Ben Smith or Rick Grehan at BYTE Magazine
# ben@bytepb.UUCP rick_g@bytepb.UUCP
#
###############################################################################
# Modification Log:
#
###############################################################################
ID="@(#)multi.sh:3.4 -- 5/15/91 19:30:24";
instance=1
while [ $instance -le $1 ]; do
/bin/sh "$UB_BINDIR/tst.sh" &
instance=`expr $instance + 1`
done
wait

View File

@@ -1,5 +0,0 @@
PROG=pipe
MAN=
.include <bsd.prog.mk>

View File

@@ -1,7 +0,0 @@
PROG=poll
SRCS=time-polling.c
CPPFLAGS+=-DHAS_POLL -DUNIXBENCH
MAN=
.include <bsd.prog.mk>

View File

@@ -1,7 +0,0 @@
PROG=poll2
SRCS=time-polling.c
CPPFLAGS+=-DHAS_POLL2 -DUNIXBENCH
MAN=
.include <bsd.prog.mk>

View File

@@ -1,7 +0,0 @@
PROG=register
SRCS=arith.c
CPPFLAGS=-Ddatum='register int'
MAN=
.include <bsd.prog.mk>

View File

@@ -1,7 +0,0 @@
PROG=select
SRCS=time-polling.c
CPPFLAGS+=-DHAS_SELECT -DUNIXBENCH
MAN=
.include <bsd.prog.mk>

View File

@@ -1,7 +0,0 @@
PROG=short
SRCS=arith.c
CPPFLAGS=-Ddatum='short'
MAN=
.include <bsd.prog.mk>

View File

@@ -1,5 +0,0 @@
PROG=spawn
MAN=
.include <bsd.prog.mk>

View File

@@ -1,5 +0,0 @@
PROG=syscall
MAN=
.include <bsd.prog.mk>

View File

@@ -1,3 +0,0 @@
SCRIPTS=tst.sh
SCRIPTSNAME=tst.sh
.include <bsd.prog.mk>

View File

@@ -1,19 +0,0 @@
#! /bin/sh
###############################################################################
# The BYTE UNIX Benchmarks - Release 3
# Module: tst.sh SID: 3.4 5/15/91 19:30:24
#
###############################################################################
# Bug reports, patches, comments, suggestions should be sent to:
#
# Ben Smith or Rick Grehan at BYTE Magazine
# ben@bytepb.UUCP rick_g@bytepb.UUCP
#
###############################################################################
# Modification Log:
#
###############################################################################
ID="@(#)tst.sh:3.4 -- 5/15/91 19:30:24";
sort >sort.$$ <sort.src
grep the sort.$$ | tee grep.$$ | wc > wc.$$
rm sort.$$ grep.$$ wc.$$

View File

@@ -1,5 +0,0 @@
PROG=ubgears
MAN=
.include <bsd.prog.mk>

View File

@@ -1,3 +0,0 @@
SCRIPTS=unixbench.logo
SCRIPTSNAME=unixbench.logo
.include <bsd.prog.mk>

View File

@@ -1,14 +0,0 @@
# # # # # # # ##### ###### # # #### # #
# # ## # # # # # # # ## # # # # #
# # # # # # ## ##### ##### # # # # ######
# # # # # # ## # # # # # # # # #
# # # ## # # # # # # # ## # # # #
#### # # # # # ##### ###### # # #### # #
Version 5.1.2 Based on the Byte Magazine Unix Benchmark
Multi-CPU version Version 5 revisions by Ian Smith,
Sunnyvale, CA, USA
December 22, 2007 johantheghost at yahoo period com

View File

@@ -1,8 +0,0 @@
PROG=whetstone-double
SRCS=whets.c
CPPFLAGS+= -DDP -DUNIX -DUNIXBENCH
LDADD+=-lm
MAN=
.include <bsd.prog.mk>

View File

@@ -1,3 +0,0 @@
SCRIPTS=run.sh
SCRIPTSNAME=run.sh
.include <bsd.prog.mk>

View File

@@ -1,4 +0,0 @@
#!/bin/sh
export CC=cc
export MINIX=1
./Run

View File

@@ -1,108 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: arith.c SID: 3.3 5/15/91 19:30:19
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
* May 12, 1989 - modified empty loops to avoid nullifying by optimizing
* compilers
* August 28, 1990 - changed timing relationship--now returns total number
* of iterations (ty)
* November 9, 1990 - made changes suggested by Keith Cantrell
* (digi!kcantrel) to defeat optimization
* to non-existence
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
******************************************************************************/
char SCCSid[] = "@(#) @(#)arith.c:3.3 -- 5/15/91 19:30:19";
/*
* arithmetic test
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "timeit.c"
int dumb_stuff(int);
unsigned long iter;
/* this function is called when the alarm expires */
void report(int sig)
{
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
exit(0);
}
int main(int argc, char *argv[])
{
int duration;
int result = 0;
if (argc != 2) {
printf("Usage: %s duration\n", argv[0]);
exit(1);
}
duration = atoi(argv[1]);
/* set up alarm call */
iter = 0; /* init iteration count */
wake_me(duration, report);
/* this loop will be interrupted by the alarm call */
while (1)
{
/* in switching to time-based (instead of iteration-based),
the following statement was added. It should not skew
the timings too much--there was an increment and test
in the "while" expression above. The only difference is
that now we're incrementing a long instead of an int. (ty) */
++iter;
/* the loop calls a function to insure that something is done
the results of the function are fed back in (just so they
they won't be thrown away. A loop with
unused assignments may get optimized out of existence */
result = dumb_stuff(result);
}
}
/************************** dumb_stuff *******************/
int dumb_stuff(i)
int i;
{
#ifndef arithoh
datum x, y, z;
z = 0;
#endif
/*
* 101
* sum i*i/(i*i-1)
* i=2
*/
/* notice that the i value is always reset by the loop */
for (i=2; i<=101; i++)
{
#ifndef arithoh
x = i;
y = x*x;
z += y/(y-1);
}
return(x+y+z);
#else
}
return(0);
#endif
}

View File

@@ -1,595 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: big.c SID: 3.3 5/15/91 19:30:18
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
******************************************************************************/
/*
* dummy code for execl test [ old version of makework.c ]
*
* makework [ -r rate ] [ -c copyfile ] nusers
*
* job streams are specified on standard input with lines of the form
* full_path_name_for_command [ options ] [ <standard_input_file ]
*
* "standard input" is send to all nuser instances of the commands in the
* job streams at a rate not in excess of "rate" characters per second
* per command
*
*/
/* this code is included in other files and therefore has no SCCSid */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <sys/wait.h>
#define DEF_RATE 5.0
#define GRANULE 5
#define CHUNK 60
#define MAXCHILD 12
#define MAXWORK 10
/* Can't seem to get this declared in the headers... */
extern int kill(pid_t pid, int sig);
void wrapup(char *);
void onalarm(int);
void pipeerr(int sig);
void grunt(int sig);
void getwork(void);
#if debug
void dumpwork(void);
#endif
void fatal(char *s);
float thres;
float est_rate = DEF_RATE;
int nusers; /* number of concurrent users to be simulated by
* this process */
int firstuser; /* ordinal identification of first user for this
* process */
int nwork = 0; /* number of job streams */
int exit_status = 0; /* returned to parent */
int sigpipe; /* pipe write error flag */
struct st_work {
char *cmd; /* name of command to run */
char **av; /* arguments to command */
char *input; /* standard input buffer */
int inpsize; /* size of standard input buffer */
char *outf; /* standard output (filename) */
} work[MAXWORK];
struct {
int xmit; /* # characters sent */
char *bp; /* std input buffer pointer */
int blen; /* std input buffer length */
int fd; /* stdin to command */
int pid; /* child PID */
char *line; /* start of input line */
int firstjob; /* inital piece of work */
int thisjob; /* current piece of work */
} child[MAXCHILD], *cp;
int main(int argc, char *argv[])
{
int i;
int l;
int fcopy = 0; /* fd for copy output */
int master = 1; /* the REAL master, == 0 for clones */
int nchild; /* no. of children for a clone to run */
int done; /* count of children finished */
int output; /* aggregate output char count for all
children */
int c;
int thiswork = 0; /* next job stream to allocate */
int nch; /* # characters to write */
int written; /* # characters actully written */
char logname[15]; /* name of the log file(s) */
int pvec[2]; /* for pipes */
char *p;
char *prog; /* my name */
#if ! debug
freopen("masterlog.00", "a", stderr);
#endif
prog = argv[0];
while (argc > 1 && argv[1][0] == '-') {
p = &argv[1][1];
argc--;
argv++;
while (*p) {
switch (*p) {
case 'r':
est_rate = atoi(argv[1]);
sscanf(argv[1], "%f", &est_rate);
if (est_rate <= 0) {
fprintf(stderr, "%s: bad rate, reset to %.2f chars/sec\n", prog, DEF_RATE);
est_rate = DEF_RATE;
}
argc--;
argv++;
break;
case 'c':
fcopy = open(argv[1], 1);
if (fcopy < 0)
fcopy = creat(argv[1], 0600);
if (fcopy < 0) {
fprintf(stderr, "%s: cannot open copy file '%s'\n",
prog, argv[1]);
exit(2);
}
lseek(fcopy, 0L, 2); /* append at end of file */
argc--;
argv++;
break;
default:
fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
exit(4);
}
p++;
}
}
if (argc < 2) {
fprintf(stderr, "%s: missing nusers\n", prog);
exit(4);
}
nusers = atoi(argv[1]);
if (nusers < 1) {
fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
exit(4);
}
fprintf(stderr, "%d Users\n", nusers);
argc--;
argv++;
/* build job streams */
getwork();
#if debug
dumpwork();
#endif
/* clone copies of myself to run up to MAXCHILD jobs each */
firstuser = MAXCHILD;
fprintf(stderr, "master pid %d\n", getpid());
fflush(stderr);
while (nusers > MAXCHILD) {
fflush(stderr);
if (nusers >= 2*MAXCHILD)
/* the next clone must run MAXCHILD jobs */
nchild = MAXCHILD;
else
/* the next clone must run the leftover jobs */
nchild = nusers - MAXCHILD;
if ((l = fork()) == -1) {
/* fork failed */
fatal("** clone fork failed **\n");
goto bepatient;
} else if (l > 0) {
fprintf(stderr, "master clone pid %d\n", l);
/* I am the master with nchild fewer jobs to run */
nusers -= nchild;
firstuser += MAXCHILD;
continue;
} else {
/* I am a clone, run MAXCHILD jobs */
#if ! debug
sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
freopen(logname, "w", stderr);
#endif
master = 0;
nusers = nchild;
break;
}
}
if (master)
firstuser = 0;
close(0);
for (i = 0; i < nusers; i++ ) {
fprintf(stderr, "user %d job %d ", firstuser+i, thiswork);
if (pipe(pvec) == -1) {
/* this is fatal */
fatal("** pipe failed **\n");
goto bepatient;
}
fflush(stderr);
if ((child[i].pid = fork()) == 0) {
int fd;
/* the command */
if (pvec[0] != 0) {
close(0);
dup(pvec[0]);
}
#if ! debug
sprintf(logname, "userlog.%02d", firstuser+i);
freopen(logname, "w", stderr);
#endif
for (fd = 3; fd < 24; fd++)
close(fd);
if (work[thiswork].outf[0] != '\0') {
/* redirect std output */
char *q;
for (q = work[thiswork].outf; *q != '\n'; q++) ;
*q = '\0';
if (freopen(work[thiswork].outf, "w", stdout) == NULL) {
fprintf(stderr, "makework: cannot open %s for std output\n",
work[thiswork].outf);
fflush(stderr);
}
*q = '\n';
}
execv(work[thiswork].cmd, work[thiswork].av);
/* don't expect to get here! */
fatal("** exec failed **\n");
goto bepatient;
}
else if (child[i].pid == -1) {
fatal("** fork failed **\n");
goto bepatient;
}
else {
close(pvec[0]);
child[i].fd = pvec[1];
child[i].line = child[i].bp = work[thiswork].input;
child[i].blen = work[thiswork].inpsize;
child[i].thisjob = thiswork;
child[i].firstjob = thiswork;
fprintf(stderr, "pid %d pipe fd %d", child[i].pid, child[i].fd);
if (work[thiswork].outf[0] != '\0') {
char *q;
fprintf(stderr, " > ");
for (q=work[thiswork].outf; *q != '\n'; q++)
fputc(*q, stderr);
}
fputc('\n', stderr);
thiswork++;
if (thiswork >= nwork)
thiswork = 0;
}
}
fflush(stderr);
srand(time(0));
thres = 0;
done = output = 0;
for (i = 0; i < nusers; i++) {
if (child[i].blen == 0)
done++;
else
thres += est_rate * GRANULE;
}
est_rate = thres;
signal(SIGALRM, onalarm);
signal(SIGPIPE, pipeerr);
alarm(GRANULE);
while (done < nusers) {
for (i = 0; i < nusers; i++) {
cp = &child[i];
if (cp->xmit >= cp->blen) continue;
l = rand() % CHUNK + 1; /* 1-CHUNK chars */
if (l == 0) continue;
if (cp->xmit + l > cp->blen)
l = cp->blen - cp->xmit;
p = cp->bp;
cp->bp += l;
cp->xmit += l;
#if debug
fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
#endif
while (p < cp->bp) {
if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
/* write it out */
nch = p - cp->line + 1;
if ((written = write(cp->fd, cp->line, nch)) != nch) {
/* argh! */
cp->line[nch] = '\0';
fprintf(stderr, "user %d job %d cmd %s ",
firstuser+i, cp->thisjob, cp->line);
fprintf(stderr, "write(,,%d) returns %d\n", nch, written);
if (sigpipe)
fatal("** SIGPIPE error **\n");
else
fatal("** write error **\n");
goto bepatient;
}
if (fcopy)
write(fcopy, cp->line, p - cp->line + 1);
#if debug
fprintf(stderr, "child %d gets \"", i);
{
char *q = cp->line;
while (q <= p) {
if (*q >= ' ' && *q <= '~')
fputc(*q, stderr);
else
fprintf(stderr, "\\%03o", *q);
q++;
}
}
fputc('"', stderr);
#endif
cp->line = &p[1];
}
p++;
}
if (cp->xmit >= cp->blen) {
done++;
close(cp->fd);
#if debug
fprintf(stderr, "child %d, close std input\n", i);
#endif
}
output += l;
}
while (output > thres) {
pause();
#if debug
fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
#endif
}
}
bepatient:
alarm(0);
/****
* If everything is going OK, we should simply be able to keep
* looping unitil 'wait' fails, however some descendent process may
* be in a state from which it can never exit, and so a timeout
* is used.
* 5 minutes should be ample, since the time to run all jobs is of
* the order of 5-10 minutes, however some machines are painfully slow,
* so the timeout has been set at 20 minutes (1200 seconds).
****/
signal(SIGALRM, grunt);
alarm(1200);
while ((c = wait(&l)) != -1) {
for (i = 0; i < nusers; i++) {
if (c == child[i].pid) {
fprintf(stderr, "user %d job %d pid %d done", firstuser+i, child[i].thisjob, c);
if (l != 0) {
if (l & 0x7f)
fprintf(stderr, " status %d", l & 0x7f);
if (l & 0xff00)
fprintf(stderr, " exit code %d", (l>>8) & 0xff);
exit_status = 4;
}
fputc('\n', stderr);
c = child[i].pid = -1;
break;
}
}
if (c != -1) {
fprintf(stderr, "master clone done, pid %d ", c);
if (l != 0) {
if (l & 0x7f)
fprintf(stderr, " status %d", l & 0x7f);
if (l & 0xff00)
fprintf(stderr, " exit code %d", (l>>8) & 0xff);
exit_status = 4;
}
fputc('\n', stderr);
}
}
alarm(0);
wrapup("Finished waiting ...");
exit(0);
}
void onalarm(int foo)
{
thres += est_rate;
signal(SIGALRM, onalarm);
alarm(GRANULE);
}
void grunt(int sig)
{
/* timeout after label "bepatient" in main */
exit_status = 4;
wrapup("Timed out waiting for jobs to finish ...");
}
void pipeerr(int sig)
{
sigpipe++;
}
void wrapup(char *reason)
{
int i;
int killed = 0;
fflush(stderr);
for (i = 0; i < nusers; i++) {
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1) {
if (!killed) {
killed++;
fprintf(stderr, "%s\n", reason);
fflush(stderr);
}
fprintf(stderr, "user %d job %d pid %d killed off\n", firstuser+i, child[i].thisjob, child[i].pid);
fflush(stderr);
}
}
exit(exit_status);
}
#define MAXLINE 512
void getwork(void)
{
int i;
int f;
int ac=0;
char *lp = (void *)0;
char *q = (void *)0;
struct st_work *w = (void *)0;
char line[MAXLINE];
char c;
while (fgets(line, MAXLINE, stdin) != NULL) {
if (nwork >= MAXWORK) {
fprintf(stderr, "Too many jobs specified, .. increase MAXWORK\n");
exit(4);
}
w = &work[nwork];
lp = line;
i = 1;
while (*lp && *lp != ' ') {
i++;
lp++;
}
w->cmd = (char *)malloc(i);
strncpy(w->cmd, line, i-1);
w->cmd[i-1] = '\0';
w->inpsize = 0;
w->input = "";
/* start to build arg list */
ac = 2;
w->av = (char **)malloc(2*sizeof(char *));
q = w->cmd;
while (*q) q++;
q--;
while (q >= w->cmd) {
if (*q == '/') {
q++;
break;
}
q--;
}
w->av[0] = q;
while (*lp) {
if (*lp == ' ') {
/* space */
lp++;
continue;
}
else if (*lp == '<') {
/* standard input for this job */
q = ++lp;
while (*lp && *lp != ' ') lp++;
c = *lp;
*lp = '\0';
if ((f = open(q, 0)) == -1) {
fprintf(stderr, "cannot open input file (%s) for job %d\n",
q, nwork);
exit(4);
}
/* gobble input */
w->input = (char *)malloc(512);
while ((i = read(f, &w->input[w->inpsize], 512)) > 0) {
w->inpsize += i;
w->input = (char *)realloc(w->input, w->inpsize+512);
}
w->input = (char *)realloc(w->input, w->inpsize);
close(f);
/* extract stdout file name from line beginning "C=" */
w->outf = "";
for (q = w->input; q < &w->input[w->inpsize-10]; q++) {
if (*q == '\n' && strncmp(&q[1], "C=", 2) == 0) {
w->outf = &q[3];
break;
}
}
#if debug
if (*w->outf) {
fprintf(stderr, "stdout->");
for (q=w->outf; *q != '\n'; q++)
fputc(*q, stderr);
fputc('\n', stderr);
}
#endif
}
else {
/* a command option */
ac++;
w->av = (char **)realloc(w->av, ac*sizeof(char *));
q = lp;
i = 1;
while (*lp && *lp != ' ') {
lp++;
i++;
}
w->av[ac-2] = (char *)malloc(i);
strncpy(w->av[ac-2], q, i-1);
w->av[ac-2][i-1] = '\0';
}
}
w->av[ac-1] = (char *)0;
nwork++;
}
}
#if debug
void dumpwork(void)
{
int i;
int j;
for (i = 0; i < nwork; i++) {
fprintf(stderr, "job %d: cmd: %s\n", i, work[i].cmd);
j = 0;
while (work[i].av[j]) {
fprintf(stderr, "argv[%d]: %s\n", j, work[i].av[j]);
j++;
}
fprintf(stderr, "input: %d chars text: ", work[i].inpsize);
if (work[i].input == (char *)0)
fprintf(stderr, "<NULL>\n");
else {
register char *pend;
char *p;
char c;
p = work[i].input;
while (*p) {
pend = p;
while (*pend && *pend != '\n')
pend++;
c = *pend;
*pend = '\0';
fprintf(stderr, "%s\n", p);
*pend = c;
p = &pend[1];
}
}
}
}
#endif
void fatal(char *s)
{
int i;
fprintf(stderr, "%s", s);
fflush(stderr);
perror("Reason?");
fflush(stderr);
for (i = 0; i < nusers; i++) {
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1) {
fprintf(stderr, "pid %d killed off\n", child[i].pid);
fflush(stderr);
}
}
exit_status = 4;
}

View File

@@ -1,125 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: context1.c SID: 3.3 5/15/91 19:30:18
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
* $Header: context1.c,v 3.4 87/06/22 14:22:59 kjmcdonell Beta $
* August 28, 1990 - changed timing routines--now returns total number of
* iterations in specified time period
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
******************************************************************************/
char SCCSid[] = "@(#) @(#)context1.c:3.3 -- 5/15/91 19:30:18";
/*
* Context switching via synchronized unbuffered pipe i/o
*
*/
#ifdef MINIX
#include <signal.h>
#endif
#ifdef LINUX
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "timeit.c"
unsigned long iter;
#ifdef MINIX
pid_t child;
#endif
void report(int sig)
{
fprintf(stderr, "COUNT|%lu|1|lps\n", iter);
#ifdef MINIX
kill(child, SIGKILL);
#endif
exit(0);
}
int main(int argc, char *argv[])
{
int duration;
unsigned long check;
int p1[2], p2[2];
if (argc != 2) {
fprintf(stderr, "Usage: context duration\n");
exit(1);
}
duration = atoi(argv[1]);
/* set up alarm call */
iter = 0;
wake_me(duration, report);
if (pipe(p1) || pipe(p2)) {
perror("pipe create failed");
exit(1);
}
#ifndef MINIX
if (fork()) { /* parent process */
#else
if ((child = fork())) {
#endif
/* master, write p1 & read p2 */
close(p1[0]); close(p2[1]);
while (1) {
if (write(p1[1], (char *)&iter, sizeof(iter)) != sizeof(iter)) {
if ((errno != 0) && (errno != EINTR))
perror("master write failed");
exit(1);
}
if (read(p2[0], (char *)&check, sizeof(check)) != sizeof(check)) {
if ((errno != 0) && (errno != EINTR))
perror("master read failed");
exit(1);
}
if (check != iter) {
fprintf(stderr, "Master sync error: expect %lu, got %lu\n",
iter, check);
exit(2);
}
iter++;
}
}
else { /* child process */
unsigned long iter1;
iter1 = 0;
/* slave, read p1 & write p2 */
close(p1[1]); close(p2[0]);
while (1) {
if (read(p1[0], (char *)&check, sizeof(check)) != sizeof(check)) {
if ((errno != 0) && (errno != EINTR))
perror("slave read failed");
exit(1);
}
if (check != iter1) {
fprintf(stderr, "Slave sync error: expect %lu, got %lu\n",
iter, check);
exit(2);
}
if (write(p2[1], (char *)&iter1, sizeof(iter1)) != sizeof(check)) {
if ((errno != 0) && (errno != EINTR))
perror("slave write failed");
exit(1);
}
iter1++;
}
}
}

View File

@@ -1,435 +0,0 @@
/*****************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: dhry.h SID: 3.4 5/15/91 19:30:21
*
*****************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*****************************************************************************
* Modification Log:
* addapted from:
*
*
* "DHRYSTONE" Benchmark Program
* -----------------------------
*
* Version: C, Version 2.1
*
* File: dhry.h (part 1 of 3)
*
* Date: May 25, 1988
*
* Author: Reinhold P. Weicker
* Siemens AG, AUT E 51
* Postfach 3220
* 8520 Erlangen
* Germany (West)
* Phone: [+49]-9131-7-20330
* (8-17 Central European Time)
* Usenet: ..!mcvax!unido!estevax!weicker
*
* Original Version (in Ada) published in
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
* pp. 1013 - 1030, together with the statistics
* on which the distribution of statements etc. is based.
*
* In this C version, the following C library functions are used:
* - strcpy, strcmp (inside the measurement loop)
* - printf, scanf (outside the measurement loop)
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
* are used for execution time measurement. For measurements
* on other systems, these calls have to be changed.
*
* Collection of Results:
* Reinhold Weicker (address see above) and
*
* Rick Richardson
* PC Research. Inc.
* 94 Apple Orchard Drive
* Tinton Falls, NJ 07724
* Phone: (201) 834-1378 (9-17 EST)
* Usenet: ...!seismo!uunet!pcrat!rick
*
* Please send results to Rick Richardson and/or Reinhold Weicker.
* Complete information should be given on hardware and software used.
* Hardware information includes: Machine type, CPU, type and size
* of caches; for microprocessors: clock frequency, memory speed
* (number of wait states).
* Software information includes: Compiler (and runtime library)
* manufacturer and version, compilation switches, OS version.
* The Operating System version may give an indication about the
* compiler; Dhrystone itself performs no OS calls in the measurement loop.
*
* The complete output generated by the program should be mailed
* such that at least some checks for correctness can be made.
*
***************************************************************************
*
* History: This version C/2.1 has been made for two reasons:
*
* 1) There is an obvious need for a common C version of
* Dhrystone, since C is at present the most popular system
* programming language for the class of processors
* (microcomputers, minicomputers) where Dhrystone is used most.
* There should be, as far as possible, only one C version of
* Dhrystone such that results can be compared without
* restrictions. In the past, the C versions distributed
* by Rick Richardson (Version 1.1) and by Reinhold Weicker
* had small (though not significant) differences.
*
* 2) As far as it is possible without changes to the Dhrystone
* statistics, optimizing compilers should be prevented from
* removing significant statements.
*
* This C version has been developed in cooperation with
* Rick Richardson (Tinton Falls, NJ), it incorporates many
* ideas from the "Version 1.1" distributed previously by
* him over the UNIX network Usenet.
* I also thank Chaim Benedelac (National Semiconductor),
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
* for their help with comments on earlier versions of the
* benchmark.
*
* Changes: In the initialization part, this version follows mostly
* Rick Richardson's version distributed via Usenet, not the
* version distributed earlier via floppy disk by Reinhold Weicker.
* As a concession to older compilers, names have been made
* unique within the first 8 characters.
* Inside the measurement loop, this version follows the
* version previously distributed by Reinhold Weicker.
*
* At several places in the benchmark, code has been added,
* but within the measurement loop only in branches that
* are not executed. The intention is that optimizing compilers
* should be prevented from moving code out of the measurement
* loop, or from removing code altogether. Since the statements
* that are executed within the measurement loop have NOT been
* changed, the numbers defining the "Dhrystone distribution"
* (distribution of statements, operand types and locality)
* still hold. Except for sophisticated optimizing compilers,
* execution times for this version should be the same as
* for previous versions.
*
* Since it has proven difficult to subtract the time for the
* measurement loop overhead in a correct way, the loop check
* has been made a part of the benchmark. This does have
* an impact - though a very minor one - on the distribution
* statistics which have been updated for this version.
*
* All changes within the measurement loop are described
* and discussed in the companion paper "Rationale for
* Dhrystone version 2".
*
* Because of the self-imposed limitation that the order and
* distribution of the executed statements should not be
* changed, there are still cases where optimizing compilers
* may not generate code for some statements. To a certain
* degree, this is unavoidable for small synthetic benchmarks.
* Users of the benchmark are advised to check code listings
* whether code is generated for all statements of Dhrystone.
*
* Version 2.1 is identical to version 2.0 distributed via
* the UNIX network Usenet in March 1988 except that it corrects
* some minor deficiencies that were found by users of version 2.0.
* The only change within the measurement loop is that a
* non-executed "else" part was added to the "if" statement in
* Func_3, and a non-executed "else" part removed from Proc_3.
*
***************************************************************************
*
* Defines: The following "Defines" are possible:
* -DREG=register (default: Not defined)
* As an approximation to what an average C programmer
* might do, the "register" storage class is applied
* (if enabled by -DREG=register)
* - for local variables, if they are used (dynamically)
* five or more times
* - for parameters if they are used (dynamically)
* six or more times
* Note that an optimal "register" strategy is
* compiler-dependent, and that "register" declarations
* do not necessarily lead to faster execution.
* -DNOSTRUCTASSIGN (default: Not defined)
* Define if the C compiler does not support
* assignment of structures.
* -DNOENUMS (default: Not defined)
* Define if the C compiler does not support
* enumeration types.
* -DTIMES (default)
* -DTIME
* The "times" function of UNIX (returning process times)
* or the "time" function (returning wallclock time)
* is used for measurement.
* For single user machines, "time ()" is adequate. For
* multi-user machines where you cannot get single-user
* access, use the "times ()" function. If you have
* neither, use a stopwatch in the dead of night.
* "printf"s are provided marking the points "Start Timer"
* and "Stop Timer". DO NOT use the UNIX "time(1)"
* command, as this will measure the total time to
* run this program, which will (erroneously) include
* the time to allocate storage (malloc) and to perform
* the initialization.
* -DHZ=nnn
* In Berkeley UNIX, the function "times" returns process
* time in 1/HZ seconds, with HZ = 60 for most systems.
* CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
* A VALUE.
*
***************************************************************************
*
* Compilation model and measurement (IMPORTANT):
*
* This C version of Dhrystone consists of three files:
* - dhry.h (this file, containing global definitions and comments)
* - dhry_1.c (containing the code corresponding to Ada package Pack_1)
* - dhry_2.c (containing the code corresponding to Ada package Pack_2)
*
* The following "ground rules" apply for measurements:
* - Separate compilation
* - No procedure merging
* - Otherwise, compiler optimizations are allowed but should be indicated
* - Default results are those without register declarations
* See the companion paper "Rationale for Dhrystone Version 2" for a more
* detailed discussion of these ground rules.
*
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
* models ("small", "medium", "large" etc.) should be given if possible,
* together with a definition of these models for the compiler system used.
*
**************************************************************************
*
* Dhrystone (C version) statistics:
*
* [Comment from the first distribution, updated for version 2.
* Note that because of language differences, the numbers are slightly
* different from the Ada version.]
*
* The following program contains statements of a high level programming
* language (here: C) in a distribution considered representative:
*
* assignments 52 (51.0 %)
* control statements 33 (32.4 %)
* procedure, function calls 17 (16.7 %)
*
* 103 statements are dynamically executed. The program is balanced with
* respect to the three aspects:
*
* - statement type
* - operand type
* - operand locality
* operand global, local, parameter, or constant.
*
* The combination of these three aspects is balanced only approximately.
*
* 1. Statement Type:
* ----------------- number
*
* V1 = V2 9
* (incl. V1 = F(..)
* V = Constant 12
* Assignment, 7
* with array element
* Assignment, 6
* with record component
* --
* 34 34
*
* X = Y +|-|"&&"|"|" Z 5
* X = Y +|-|"==" Constant 6
* X = X +|- 1 3
* X = Y *|/ Z 2
* X = Expression, 1
* two operators
* X = Expression, 1
* three operators
* --
* 18 18
*
* if .... 14
* with "else" 7
* without "else" 7
* executed 3
* not executed 4
* for ... 7 | counted every time
* while ... 4 | the loop condition
* do ... while 1 | is evaluated
* switch ... 1
* break 1
* declaration with 1
* initialization
* --
* 34 34
*
* P (...) procedure call 11
* user procedure 10
* library procedure 1
* X = F (...)
* function call 6
* user function 5
* library function 1
* --
* 17 17
* ---
* 103
*
* The average number of parameters in procedure or function calls
* is 1.82 (not counting the function values as implicit parameters).
*
*
* 2. Operators
* ------------
* number approximate
* percentage
*
* Arithmetic 32 50.8
*
* + 21 33.3
* - 7 11.1
* * 3 4.8
* / (int div) 1 1.6
*
* Comparison 27 42.8
*
* == 9 14.3
* /= 4 6.3
* > 1 1.6
* < 3 4.8
* >= 1 1.6
* <= 9 14.3
*
* Logic 4 6.3
*
* && (AND-THEN) 1 1.6
* | (OR) 1 1.6
* ! (NOT) 2 3.2
*
* -- -----
* 63 100.1
*
*
* 3. Operand Type (counted once per operand reference):
* ---------------
* number approximate
* percentage
*
* Integer 175 72.3 %
* Character 45 18.6 %
* Pointer 12 5.0 %
* String30 6 2.5 %
* Array 2 0.8 %
* Record 2 0.8 %
* --- -------
* 242 100.0 %
*
* When there is an access path leading to the final operand (e.g. a record
* component), only the final data type on the access path is counted.
*
*
* 4. Operand Locality:
* -------------------
* number approximate
* percentage
*
* local variable 114 47.1 %
* global variable 22 9.1 %
* parameter 45 18.6 %
* value 23 9.5 %
* reference 22 9.1 %
* function result 6 2.5 %
* constant 55 22.7 %
* --- -------
* 242 100.0 %
*
*
* The program does not compute anything meaningful, but it is syntactically
* and semantically correct. All variables have a value assigned to them
* before they are used as a source operand.
*
* There has been no explicit effort to account for the effects of a
* cache, or to balance the use of long or short displacements for code or
* data.
*
***************************************************************************
*/
/* Compiler and system dependent definitions: */
#ifndef TIME
#define TIMES
#endif
/* Use times(2) time function unless */
/* explicitly defined otherwise */
#ifdef TIMES
#include <sys/types.h>
#include <sys/times.h>
/* for "times" */
#endif
#define Mic_secs_Per_Second 1000000.0
/* Berkeley UNIX C returns process times in seconds/HZ */
#ifdef NOSTRUCTASSIGN
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
#else
#define structassign(d, s) d = s
#endif
#ifdef NOENUM
#define Ident_1 0
#define Ident_2 1
#define Ident_3 2
#define Ident_4 3
#define Ident_5 4
typedef int Enumeration;
#else
typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
Enumeration;
#endif
/* for boolean and enumeration types in Ada, Pascal */
/* General definitions: */
#include <stdio.h>
/* for strcpy, strcmp */
#define Null 0
/* Value of a Null pointer */
#define true 1
#define false 0
typedef int One_Thirty;
typedef int One_Fifty;
typedef char Capital_Letter;
typedef int Boolean;
typedef char Str_30 [31];
typedef int Arr_1_Dim [50];
typedef int Arr_2_Dim [50] [50];
typedef struct record
{
struct record *Ptr_Comp;
Enumeration Discr;
union {
struct {
Enumeration Enum_Comp;
int Int_Comp;
char Str_Comp [31];
} var_1;
struct {
Enumeration E_Comp_2;
char Str_2_Comp [31];
} var_2;
struct {
char Ch_1_Comp;
char Ch_2_Comp;
} var_3;
} variant;
} Rec_Type, *Rec_Pointer;

View File

@@ -1,427 +0,0 @@
/*****************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: dhry_1.c SID: 3.4 5/15/91 19:30:21
*
*****************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*****************************************************************************
*
* *** WARNING **** With BYTE's modifications applied, results obtained with
* ******* this version of the Dhrystone program may not be applicable
* to other versions.
*
* Modification Log:
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
* Adapted from:
*
* "DHRYSTONE" Benchmark Program
* -----------------------------
*
* Version: C, Version 2.1
*
* File: dhry_1.c (part 2 of 3)
*
* Date: May 25, 1988
*
* Author: Reinhold P. Weicker
*
***************************************************************************/
char SCCSid[] = "@(#) @(#)dhry_1.c:3.4 -- 5/15/91 19:30:21";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dhry.h"
#include "timeit.c"
unsigned long Run_Index;
Enumeration Func_1(Capital_Letter, Capital_Letter);
void report(int sig)
{
fprintf(stderr,"COUNT|%ld|1|lps\n", Run_Index);
exit(0);
}
/* Global Variables: */
Rec_Pointer Ptr_Glob,
Next_Ptr_Glob;
int Int_Glob;
Boolean Bool_Glob;
char Ch_1_Glob,
Ch_2_Glob;
int Arr_1_Glob [50];
int Arr_2_Glob [50] [50];
#ifndef REG
Boolean Reg = false;
#define REG
/* REG becomes defined as empty */
/* i.e. no register variables */
#else
Boolean Reg = true;
#endif
/* variables for time measurement: */
#ifdef TIMES
struct tms time_info;
extern int times ();
/* see library function "times" */
#define Too_Small_Time 120
/* Measurements should last at least about 2 seconds */
#endif
#ifdef TIME
#define Too_Small_Time 2
/* Measurements should last at least 2 seconds */
#endif
long Begin_Time,
End_Time,
User_Time;
float Microseconds,
Dhrystones_Per_Second;
/* end of variables for time measurement */
void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
void Proc_2 (One_Fifty *Int_Par_Ref);
void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
void Proc_4 (void);
void Proc_5 (void);
extern Boolean Func_2(Str_30, Str_30);
extern void Proc_6(Enumeration, Enumeration *);
extern void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
extern void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
int main (int argc, char *argv[])
/* main program, corresponds to procedures */
/* Main and Proc_0 in the Ada version */
{
int duration;
One_Fifty Int_1_Loc;
REG One_Fifty Int_2_Loc;
One_Fifty Int_3_Loc;
REG char Ch_Index;
Enumeration Enum_Loc;
Str_30 Str_1_Loc;
Str_30 Str_2_Loc;
/* Initializations */
Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
Ptr_Glob->Discr = Ident_1;
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
Ptr_Glob->variant.var_1.Int_Comp = 40;
strcpy (Ptr_Glob->variant.var_1.Str_Comp,
"DHRYSTONE PROGRAM, SOME STRING");
strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
Arr_2_Glob [8][7] = 10;
/* Was missing in published program. Without this statement, */
/* Arr_2_Glob [8][7] would have an undefined value. */
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
/* overflow may occur for this array element. */
#ifdef PRATTLE
printf ("\n");
printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
printf ("\n");
if (Reg)
{
printf ("Program compiled with 'register' attribute\n");
printf ("\n");
}
else
{
printf ("Program compiled without 'register' attribute\n");
printf ("\n");
}
printf ("Please give the number of runs through the benchmark: ");
{
int n;
scanf ("%d", &n);
Number_Of_Runs = n;
}
printf ("\n");
printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
#endif /* PRATTLE */
if (argc != 2) {
fprintf(stderr, "Usage: %s duration\n", argv[0]);
exit(1);
}
duration = atoi(argv[1]);
Run_Index = 0;
wake_me(duration, report);
/***************/
/* Start timer */
/***************/
#ifdef SELF_TIMED
#ifdef TIMES
times (&time_info);
Begin_Time = (long) time_info.tms_utime;
#endif
#ifdef TIME
Begin_Time = time ( (long *) 0);
#endif
#endif /* SELF_TIMED */
for (Run_Index = 1; ; ++Run_Index)
{
Proc_5();
Proc_4();
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
Int_1_Loc = 2;
Int_2_Loc = 3;
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
Enum_Loc = Ident_2;
Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
/* Bool_Glob == 1 */
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
{
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
/* Int_3_Loc == 7 */
Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
/* Int_3_Loc == 7 */
Int_1_Loc += 1;
} /* while */
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
/* Int_Glob == 5 */
Proc_1 (Ptr_Glob);
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
/* loop body executed twice */
{
if (Enum_Loc == Func_1 (Ch_Index, 'C'))
/* then, not executed */
{
Proc_6 (Ident_1, &Enum_Loc);
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
Int_2_Loc = Run_Index;
Int_Glob = Run_Index;
}
}
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
Int_2_Loc = Int_2_Loc * Int_1_Loc;
Int_1_Loc = Int_2_Loc / Int_3_Loc;
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
Proc_2 (&Int_1_Loc);
/* Int_1_Loc == 5 */
} /* loop "for Run_Index" */
/**************/
/* Stop timer */
/**************/
#ifdef SELF_TIMED
#ifdef TIMES
times (&time_info);
End_Time = (long) time_info.tms_utime;
#endif
#ifdef TIME
End_Time = time ( (long *) 0);
#endif
#endif /* SELF_TIMED */
/* BYTE version never executes this stuff */
#ifdef SELF_TIMED
printf ("Execution ends\n");
printf ("\n");
printf ("Final values of the variables used in the benchmark:\n");
printf ("\n");
printf ("Int_Glob: %d\n", Int_Glob);
printf (" should be: %d\n", 5);
printf ("Bool_Glob: %d\n", Bool_Glob);
printf (" should be: %d\n", 1);
printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
printf (" should be: %c\n", 'A');
printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
printf (" should be: %c\n", 'B');
printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
printf (" should be: %d\n", 7);
printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
printf (" should be: Number_Of_Runs + 10\n");
printf ("Ptr_Glob->\n");
printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
printf (" should be: (implementation-dependent)\n");
printf (" Discr: %d\n", Ptr_Glob->Discr);
printf (" should be: %d\n", 0);
printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
printf (" should be: %d\n", 2);
printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
printf (" should be: %d\n", 17);
printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
printf ("Next_Ptr_Glob->\n");
printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
printf (" should be: (implementation-dependent), same as above\n");
printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
printf (" should be: %d\n", 0);
printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
printf (" should be: %d\n", 1);
printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
printf (" should be: %d\n", 18);
printf (" Str_Comp: %s\n",
Next_Ptr_Glob->variant.var_1.Str_Comp);
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
printf ("Int_1_Loc: %d\n", Int_1_Loc);
printf (" should be: %d\n", 5);
printf ("Int_2_Loc: %d\n", Int_2_Loc);
printf (" should be: %d\n", 13);
printf ("Int_3_Loc: %d\n", Int_3_Loc);
printf (" should be: %d\n", 7);
printf ("Enum_Loc: %d\n", Enum_Loc);
printf (" should be: %d\n", 1);
printf ("Str_1_Loc: %s\n", Str_1_Loc);
printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
printf ("Str_2_Loc: %s\n", Str_2_Loc);
printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
printf ("\n");
User_Time = End_Time - Begin_Time;
if (User_Time < Too_Small_Time)
{
printf ("Measured time too small to obtain meaningful results\n");
printf ("Please increase number of runs\n");
printf ("\n");
}
else
{
#ifdef TIME
Microseconds = (float) User_Time * Mic_secs_Per_Second
/ (float) Number_Of_Runs;
Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
#else
Microseconds = (float) User_Time * Mic_secs_Per_Second
/ ((float) HZ * ((float) Number_Of_Runs));
Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
/ (float) User_Time;
#endif
printf ("Microseconds for one run through Dhrystone: ");
printf ("%6.1f \n", Microseconds);
printf ("Dhrystones per Second: ");
printf ("%6.1f \n", Dhrystones_Per_Second);
printf ("\n");
}
#endif /* SELF_TIMED */
}
void Proc_1 (REG Rec_Pointer Ptr_Val_Par)
/* executed once */
{
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
/* == Ptr_Glob_Next */
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
/* corresponds to "rename" in Ada, "with" in Pascal */
structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
Next_Record->variant.var_1.Int_Comp
= Ptr_Val_Par->variant.var_1.Int_Comp;
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
Proc_3 (&Next_Record->Ptr_Comp);
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
== Ptr_Glob->Ptr_Comp */
if (Next_Record->Discr == Ident_1)
/* then, executed */
{
Next_Record->variant.var_1.Int_Comp = 6;
Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
&Next_Record->variant.var_1.Enum_Comp);
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
&Next_Record->variant.var_1.Int_Comp);
}
else /* not executed */
structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
} /* Proc_1 */
void Proc_2 (One_Fifty *Int_Par_Ref)
/* executed once */
/* *Int_Par_Ref == 1, becomes 4 */
{
One_Fifty Int_Loc;
Enumeration Enum_Loc;
Enum_Loc = 0;
Int_Loc = *Int_Par_Ref + 10;
do /* executed once */
if (Ch_1_Glob == 'A')
/* then, executed */
{
Int_Loc -= 1;
*Int_Par_Ref = Int_Loc - Int_Glob;
Enum_Loc = Ident_1;
} /* if */
while (Enum_Loc != Ident_1); /* true */
} /* Proc_2 */
void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
/* executed once */
/* Ptr_Ref_Par becomes Ptr_Glob */
{
if (Ptr_Glob != Null)
/* then, executed */
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
} /* Proc_3 */
void Proc_4 (void) /* without parameters */
/* executed once */
{
Boolean Bool_Loc;
Bool_Loc = Ch_1_Glob == 'A';
Bool_Glob = Bool_Loc | Bool_Glob;
Ch_2_Glob = 'B';
} /* Proc_4 */
void Proc_5 (void) /* without parameters */
/*******/
/* executed once */
{
Ch_1_Glob = 'A';
Bool_Glob = false;
} /* Proc_5 */
/* Procedure for the assignment of structures, */
/* if the C compiler doesn't support this feature */
#ifdef NOSTRUCTASSIGN
memcpy (d, s, l)
register char *d;
register char *s;
register int l;
{
while (l--) *d++ = *s++;
}
#endif

View File

@@ -1,209 +0,0 @@
/*****************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: dhry_2.c SID: 3.4 5/15/91 19:30:22
*
*****************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*****************************************************************************
* Modification Log:
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
* Adapted from:
*
* "DHRYSTONE" Benchmark Program
* -----------------------------
*
* **** WARNING **** See warning in n.dhry_1.c
*
* Version: C, Version 2.1
*
* File: dhry_2.c (part 3 of 3)
*
* Date: May 25, 1988
*
* Author: Reinhold P. Weicker
*
****************************************************************************/
/* SCCSid is defined in dhry_1.c */
#include <string.h>
#include "dhry.h"
#ifndef REG
#define REG
/* REG becomes defined as empty */
/* i.e. no register variables */
#endif
extern int Int_Glob;
extern char Ch_1_Glob;
void Proc_6(Enumeration, Enumeration *);
void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
Enumeration Func_1(Capital_Letter, Capital_Letter);
Boolean Func_2(Str_30, Str_30);
Boolean Func_3(Enumeration);
void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
/* executed once */
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
{
*Enum_Ref_Par = Enum_Val_Par;
if (! Func_3 (Enum_Val_Par))
/* then, not executed */
*Enum_Ref_Par = Ident_4;
switch (Enum_Val_Par)
{
case Ident_1:
*Enum_Ref_Par = Ident_1;
break;
case Ident_2:
if (Int_Glob > 100)
/* then */
*Enum_Ref_Par = Ident_1;
else *Enum_Ref_Par = Ident_4;
break;
case Ident_3: /* executed */
*Enum_Ref_Par = Ident_2;
break;
case Ident_4: break;
case Ident_5:
*Enum_Ref_Par = Ident_3;
break;
} /* switch */
} /* Proc_6 */
void Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
One_Fifty Int_1_Par_Val;
One_Fifty Int_2_Par_Val;
One_Fifty *Int_Par_Ref;
/**********************************************/
/* executed three times */
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
/* Int_Par_Ref becomes 7 */
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
/* Int_Par_Ref becomes 17 */
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
/* Int_Par_Ref becomes 18 */
{
One_Fifty Int_Loc;
Int_Loc = Int_1_Par_Val + 2;
*Int_Par_Ref = Int_2_Par_Val + Int_Loc;
} /* Proc_7 */
void Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
/*********************************************************************/
/* executed once */
/* Int_Par_Val_1 == 3 */
/* Int_Par_Val_2 == 7 */
Arr_1_Dim Arr_1_Par_Ref;
Arr_2_Dim Arr_2_Par_Ref;
int Int_1_Par_Val;
int Int_2_Par_Val;
{
REG One_Fifty Int_Index;
REG One_Fifty Int_Loc;
Int_Loc = Int_1_Par_Val + 5;
Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
Int_Glob = 5;
} /* Proc_8 */
Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)
/*************************************************/
/* executed three times */
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
{
Capital_Letter Ch_1_Loc;
Capital_Letter Ch_2_Loc;
Ch_1_Loc = Ch_1_Par_Val;
Ch_2_Loc = Ch_1_Loc;
if (Ch_2_Loc != Ch_2_Par_Val)
/* then, executed */
return (Ident_1);
else /* not executed */
{
Ch_1_Glob = Ch_1_Loc;
return (Ident_2);
}
} /* Func_1 */
Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
/*************************************************/
/* executed once */
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
Str_30 Str_1_Par_Ref;
Str_30 Str_2_Par_Ref;
{
REG One_Thirty Int_Loc;
Capital_Letter Ch_Loc;
Ch_Loc = 'A';
Int_Loc = 2;
while (Int_Loc <= 2) /* loop body executed once */
if (Func_1 (Str_1_Par_Ref[Int_Loc],
Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
/* then, executed */
{
Ch_Loc = 'A';
Int_Loc += 1;
} /* if, while */
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
/* then, not executed */
Int_Loc = 7;
if (Ch_Loc == 'R')
/* then, not executed */
return (true);
else /* executed */
{
if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
/* then, not executed */
{
Int_Loc += 7;
Int_Glob = Int_Loc;
return (true);
}
else /* executed */
return (false);
} /* if Ch_Loc */
} /* Func_2 */
Boolean Func_3 (Enum_Par_Val)
/***************************/
/* executed once */
/* Enum_Par_Val == Ident_3 */
Enumeration Enum_Par_Val;
{
Enumeration Enum_Loc;
Enum_Loc = Enum_Par_Val;
if (Enum_Loc == Ident_3)
/* then, executed */
return (true);
else /* not executed */
return (false);
} /* Func_3 */

View File

@@ -1,319 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: dummy.c SID: 3.3 5/15/91 19:30:19
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
******************************************************************************/
/*
* Hacked up C program for use in the standard shell.? scripts of
* the multiuser test. This is based upon makework.c, and is typically
* edited using edscript.2 before compilation.
*
* $Header: dummy.c,v 3.4 87/06/23 15:54:53 kjmcdonell Beta $
*/
char SCCSid[] = "@(#) @(#)dummy.c:3.3 -- 5/15/91 19:30:19";
#include <stdio.h>
#include <signal.h>
#define DEF_RATE 5.0
#define GRANULE 5
#define CHUNK 60
#define MAXCHILD 12
#define MAXWORK 10
float thres;
float est_rate = DEF_RATE;
int nusers; /* number of concurrent users to be simulated by
* this process */
int firstuser; /* ordinal identification of first user for this
* process */
int nwork = 0; /* number of job streams */
int exit_status = 0; /* returned to parent */
int sigpipe; /* pipe write error flag */
struct st_work {
char *cmd; /* name of command to run */
char **av; /* arguments to command */
char *input; /* standard input buffer */
int inpsize; /* size of standard input buffer */
} work[MAXWORK];
struct {
int xmit; /* # characters sent */
char *bp; /* std input buffer pointer */
int blen; /* std input buffer length */
int fd; /* stdin to command */
int pid; /* child PID */
char *line; /* start of input line */
int firstjob; /* inital piece of work */
int thisjob; /* current piece of work */
} child[MAXCHILD], *cp;
main(argc, argv)
int argc;
char *argv[];
{
int i;
int l;
int fcopy = 0; /* fd for copy output */
int master = 1; /* the REAL master, == 0 for clones */
int nchild; /* no. of children for a clone to run */
int done; /* count of children finished */
int output; /* aggregate output char count for all
children */
int c;
int thiswork = 0; /* next job stream to allocate */
int nch; /* # characters to write */
int written; /* # characters actully written */
char logname[15]; /* name of the log file(s) */
void onalarm(void);
void pipeerr(void);
void wrapup(void);
void grunt(void);
char *malloc();
int pvec[2]; /* for pipes */
char *p;
char *prog; /* my name */
#if ! debug
freopen("masterlog.00", "a", stderr);
#endif
fprintf(stderr, "*** New Run *** ");
prog = argv[0];
while (argc > 1 && argv[1][0] == '-') {
p = &argv[1][1];
argc--;
argv++;
while (*p) {
switch (*p) {
case 'r':
/* code DELETED here */
argc--;
argv++;
break;
case 'c':
/* code DELETED here */
lseek(fcopy, 0L, 2); /* append at end of file */
break;
default:
fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
exit(4);
}
p++;
}
}
if (argc < 2) {
fprintf(stderr, "%s: missing nusers\n", prog);
exit(4);
}
nusers = atoi(argv[1]);
if (nusers < 1) {
fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
exit(4);
}
fprintf(stderr, "%d Users\n", nusers);
argc--;
argv++;
/* build job streams */
getwork();
#if debug
dumpwork();
#endif
/* clone copies of myself to run up to MAXCHILD jobs each */
firstuser = MAXCHILD;
fprintf(stderr, "master pid %d\n", getpid());
fflush(stderr);
while (nusers > MAXCHILD) {
fflush(stderr);
if (nusers >= 2*MAXCHILD)
/* the next clone must run MAXCHILD jobs */
nchild = MAXCHILD;
else
/* the next clone must run the leftover jobs */
nchild = nusers - MAXCHILD;
if ((l = fork()) == -1) {
/* fork failed */
fatal("** clone fork failed **\n");
goto bepatient;
} else if (l > 0) {
fprintf(stderr, "master clone pid %d\n", l);
/* I am the master with nchild fewer jobs to run */
nusers -= nchild;
firstuser += MAXCHILD;
continue;
} else {
/* I am a clone, run MAXCHILD jobs */
#if ! debug
sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
freopen(logname, "w", stderr);
#endif
master = 0;
nusers = nchild;
break;
}
}
if (master)
firstuser = 0;
close(0);
/* code DELETED here */
fflush(stderr);
srand(time(0));
thres = 0;
done = output = 0;
for (i = 0; i < nusers; i++) {
if (child[i].blen == 0)
done++;
else
thres += est_rate * GRANULE;
}
est_rate = thres;
signal(SIGALRM, onalarm);
signal(SIGPIPE, pipeerr);
alarm(GRANULE);
while (done < nusers) {
for (i = 0; i < nusers; i++) {
cp = &child[i];
if (cp->xmit >= cp->blen) continue;
l = rand() % CHUNK + 1; /* 1-CHUNK chars */
if (l == 0) continue;
if (cp->xmit + l > cp->blen)
l = cp->blen - cp->xmit;
p = cp->bp;
cp->bp += l;
cp->xmit += l;
#if debug
fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
#endif
while (p < cp->bp) {
if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
/* write it out */
nch = p - cp->line + 1;
if ((written = write(cp->fd, cp->line, nch)) != nch) {
/* code DELETED here */
}
if (fcopy)
write(fcopy, cp->line, p - cp->line + 1);
#if debug
fprintf(stderr, "child %d gets \"", i);
{
char *q = cp->line;
while (q <= p) {
if (*q >= ' ' && *q <= '~')
fputc(*q, stderr);
else
fprintf(stderr, "\\%03o", *q);
q++;
}
}
fputc('"', stderr);
#endif
cp->line = &p[1];
}
p++;
}
if (cp->xmit >= cp->blen) {
done++;
close(cp->fd);
#if debug
fprintf(stderr, "child %d, close std input\n", i);
#endif
}
output += l;
}
while (output > thres) {
pause();
#if debug
fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
#endif
}
}
bepatient:
alarm(0);
/****
* If everything is going OK, we should simply be able to keep
* looping unitil 'wait' fails, however some descendent process may
* be in a state from which it can never exit, and so a timeout
* is used.
* 5 minutes should be ample, since the time to run all jobs is of
* the order of 5-10 minutes, however some machines are painfully slow,
* so the timeout has been set at 20 minutes (1200 seconds).
****/
/* code DELETED here */
}
onalarm()
{
thres += est_rate;
signal(SIGALRM, onalarm);
alarm(GRANULE);
}
grunt()
{
/* timeout after label "bepatient" in main */
exit_status = 4;
wrapup();
}
pipeerr()
{
sigpipe++;
}
wrapup()
{
/* DUMMY, real code dropped */
}
getwork()
{
/* DUMMY, real code dropped */
gets();
strncpy();
malloc(); realloc();
open(); close();
}
fatal(s)
char *s;
{
int i;
fprintf(stderr, s);
fflush(stderr);
perror("Reason?");
for (i = 0; i < nusers; i++) {
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1)
fprintf(stderr, "pid %d killed off\n", child[i].pid);
}
fflush(stderr);
exit_status = 4;
return;
}

View File

@@ -1,91 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: execl.c SID: 3.3 5/15/91 19:30:19
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
* $Header: execl.c,v 3.5 87/06/22 15:37:08 kjmcdonell Beta $
* August 28, 1990 - Modified timing routines
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
******************************************************************************/
/*
* Execing
*
*/
char SCCSid[] = "@(#) @(#)execl.c:3.3 -- 5/15/91 19:30:19";
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
char bss[8*1024]; /* something worthwhile */
#define main dummy
#include "big.c" /* some real code */
#undef main
int main(int argc, char *argv[]) /* the real program */
{
unsigned long iter = 0;
char *ptr;
char *fullpath;
int duration;
char count_str[12], start_str[24], path_str[256], *dur_str;
time_t start_time, this_time;
#ifdef DEBUG
int count;
for(count = 0; count < argc; ++ count)
printf("%s ",argv[count]);
printf("\n");
#endif
if (argc < 2)
{
fprintf(stderr, "Usage: %s duration\n", argv[0]);
exit(1);
}
duration = atoi(argv[1]);
if (duration > 0)
/* the first invocation */
{
dur_str = argv[1];
if((ptr = getenv("UB_BINDIR")) != NULL)
sprintf(path_str,"%s/execl",ptr);
fullpath=path_str;
time(&start_time);
}
else /* one of those execl'd invocations */
{
/* real duration follow the phoney null duration */
duration = atoi(argv[2]);
dur_str = argv[2];
iter = (unsigned long)atoi(argv[3]); /* where are we now ? */
sscanf(argv[4], "%lu", (unsigned long *) &start_time);
fullpath = argv[0];
}
sprintf(count_str, "%lu", ++iter); /* increment the execl counter */
sprintf(start_str, "%lu", (unsigned long) start_time);
time(&this_time);
if (this_time - start_time >= duration) { /* time has run out */
fprintf(stderr, "COUNT|%lu|1|lps\n", iter);
exit(0);
}
execl(fullpath, fullpath, "0", dur_str, count_str, start_str, (void *) 0);
fprintf(stderr, "Exec failed at iteration %lu\n", iter);
perror("Reason");
exit(1);
}

View File

@@ -1,469 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: fstime.c SID: 3.5 5/15/91 19:30:19
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
* $Header: fstime.c,v 3.4 87/06/22 14:23:05 kjmcdonell Beta $
* 10/19/89 - rewrote timing calcs and added clock check (Ben Smith)
* 10/26/90 - simplify timing, change defaults (Tom Yager)
* 11/16/90 - added better error handling and changed output format (Ben Smith)
* 11/17/90 - changed the whole thing around (Ben Smith)
* 2/22/91 - change a few style elements and improved error handling (Ben Smith)
* 4/17/91 - incorporated suggestions from Seckin Unlu (seckin@sumac.intel.com)
* 4/17/91 - limited size of file, will rewind when reaches end of file
* 7/95 - fixed mishandling of read() and write() return codes
* Carl Emilio Prelz <fluido@telepac.pt>
* 12/95 - Massive changes. Made sleep time proportional increase with run
* time; added fsbuffer and fsdisk variants; added partial counting
* of partial reads/writes (was *full* credit); added dual syncs.
* David C Niemi <niemi@tux.org>
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
* 9/24/07 - Separate out the read and write tests;
* output the actual time used in the results.
* Ian Smith <johantheghost at yahoo period com>
******************************************************************************/
char SCCSid[] = "@(#) @(#)fstime.c:3.5 -- 5/15/91 19:30:19";
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#define SECONDS 10
#define MAX_BUFSIZE 8192
/* This must be set to the smallest BUFSIZE or 1024, whichever is smaller */
#define COUNTSIZE 256
#define HALFCOUNT (COUNTSIZE/2) /* Half of COUNTSIZE */
#define FNAME0 "dummy0"
#define FNAME1 "dummy1"
#ifndef MINIX
extern void sync(void);
#endif
int w_test(int timeSecs);
int r_test(int timeSecs);
int c_test(int timeSecs);
long read_score = 1, write_score = 1, copy_score = 1;
/****************** GLOBALS ***************************/
/* The buffer size for the tests. */
int bufsize = 1024;
/*
* The max number of 1024-byte blocks in the file.
* Don't limit it much, so that memory buffering
* can be overcome.
*/
int max_blocks = 2000;
/* The max number of BUFSIZE blocks in the file. */
int max_buffs = 2000;
/* Countable units per 1024 bytes */
int count_per_k;
/* Countable units per bufsize */
int count_per_buf;
/* The actual buffer. */
/* char *buf = 0; */
/* Let's carry on using a static buffer for this, like older versions
* of the code did. It turns out that if you use a malloc buffer,
* it goes 50% slower on reads, when using a 4k buffer -- at least on
* my OpenSUSE 10.2 system.
* What up wit dat?
*/
char buf[MAX_BUFSIZE];
int f;
int g;
int i;
void stop_count(int);
void clean_up(int);
int sigalarm = 0;
/******************** MAIN ****************************/
int main(int argc, char *argv[])
{
/* The number of seconds to run for. */
int seconds = SECONDS;
/* The type of test to run. */
char test = 'c';
int status;
int i;
for (i = 1; i < argc; ++i) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'c':
case 'r':
case 'w':
test = argv[i][1];
break;
case 'b':
bufsize = atoi(argv[++i]);
break;
case 'm':
max_blocks = atoi(argv[++i]);
break;
case 't':
seconds = atoi(argv[++i]);
break;
case 'd':
if (chdir(argv[++i]) < 0) {
perror("fstime: chdir");
exit(1);
}
break;
default:
fprintf(stderr, "Usage: fstime [-c|-r|-w] [-b <bufsize>] [-m <max_blocks>] [-t <seconds>]\n");
exit(2);
}
} else {
fprintf(stderr, "Usage: fstime [-c|-r|-w] [-b <bufsize>] [-m <max_blocks>] [-t <seconds>]\n");
exit(2);
}
}
if (bufsize < COUNTSIZE || bufsize > MAX_BUFSIZE) {
fprintf(stderr, "fstime: buffer size must be in range %d-%d\n",
COUNTSIZE, 1024*1024);
exit(3);
}
if (max_blocks < 1 || max_blocks > 1024*1024) {
fprintf(stderr, "fstime: max blocks must be in range %d-%d\n",
1, 1024*1024);
exit(3);
}
if (seconds < 1 || seconds > 3600) {
fprintf(stderr, "fstime: time must be in range %d-%d seconds\n",
1, 3600);
exit(3);
}
max_buffs = max_blocks * 1024 / bufsize;
count_per_k = 1024 / COUNTSIZE;
count_per_buf = bufsize / COUNTSIZE;
/*
if ((buf = malloc(bufsize)) == 0) {
fprintf(stderr, "fstime: failed to malloc %d bytes\n", bufsize);
exit(4);
}
*/
if((f = creat(FNAME0, 0600)) == -1) {
perror("fstime: creat");
exit(1);
}
close(f);
if((g = creat(FNAME1, 0600)) == -1) {
perror("fstime: creat");
exit(1);
}
close(g);
if( (f = open(FNAME0, 2)) == -1) {
perror("fstime: open");
exit(1);
}
if( ( g = open(FNAME1, 2)) == -1 ) {
perror("fstime: open");
exit(1);
}
/* fill buffer */
for (i=0; i < bufsize; ++i)
buf[i] = i & 0xff;
signal(SIGKILL,clean_up);
/*
* Run the selected test.
* When I got here, this program ran full 30-second tests for
* write, read, and copy, outputting the results for each. BUT
* only the copy results are actually used in the benchmark index.
* With multiple iterations and three sets of FS tests, that amounted
* to about 10 minutes of wasted time per run.
*
* So, I've made the test selectable. Except that the read and write
* passes are used to create the test file and calibrate the rates used
* to tweak the results of the copy test. So, for copy tests, we do
* a few seconds of write and read to prime the pump.
*
* Note that this will also pull the file into the FS cache on any
* modern system prior to the copy test. Whether this is good or
* bad is a matter of perspective, but it's how it was when I got
* here.
*
* Ian Smith <johantheghost at yahoo period com> 21 Sep 2007
*/
switch (test) {
case 'w':
status = w_test(seconds);
break;
case 'r':
w_test(2);
status = r_test(seconds);
break;
case 'c':
w_test(2);
r_test(2);
status = c_test(seconds);
break;
default:
fprintf(stderr, "fstime: unknown test \'%c\'\n", test);
exit(6);
}
if (status) {
clean_up(0);
exit(1);
}
clean_up(0);
exit(0);
}
static double getFloatTime(void)
{
struct timeval t;
gettimeofday(&t, 0);
return (double) t.tv_sec + (double) t.tv_usec / 1000000.0;
}
/*
* Run the write test for the time given in seconds.
*/
int w_test(int timeSecs)
{
unsigned long counted = 0L;
unsigned long tmp;
long f_blocks;
double start, end;
extern int sigalarm;
/* Sync and let it settle */
sync();
sleep(2);
sync();
sleep(2);
/* Set an alarm. */
sigalarm = 0;
signal(SIGALRM, stop_count);
alarm(timeSecs);
start = getFloatTime();
while (!sigalarm) {
for(f_blocks=0; f_blocks < max_buffs; ++f_blocks) {
if ((tmp=write(f, buf, bufsize)) != bufsize) {
if (errno != EINTR) {
perror("fstime: write");
return(-1);
}
stop_count(0);
counted += ((tmp+HALFCOUNT)/COUNTSIZE);
} else
counted += count_per_buf;
}
lseek(f, 0L, 0); /* rewind */
}
/* stop clock */
end = getFloatTime();
write_score = (long) ((double) counted / ((end - start) * count_per_k));
printf("Write done: %ld in %.4f, score %ld\n",
counted, end - start, write_score);
/*
* Output the test results. Use the true time.
*/
fprintf(stderr, "COUNT|%ld|0|KBps\n", write_score);
fprintf(stderr, "TIME|%.1f\n", end - start);
return(0);
}
/*
* Run the read test for the time given in seconds.
*/
int r_test(int timeSecs)
{
unsigned long counted = 0L;
unsigned long tmp;
double start, end;
extern int sigalarm;
extern int errno;
/* Sync and let it settle */
sync();
sleep(2);
sync();
sleep(2);
/* rewind */
errno = 0;
lseek(f, 0L, 0);
/* Set an alarm. */
sigalarm = 0;
signal(SIGALRM, stop_count);
alarm(timeSecs);
start = getFloatTime();
while (!sigalarm) {
/* read while checking for an error */
if ((tmp=read(f, buf, bufsize)) != bufsize) {
switch(errno) {
case 0:
case EINVAL:
lseek(f, 0L, 0); /* rewind at end of file */
counted += (tmp+HALFCOUNT)/COUNTSIZE;
continue;
case EINTR:
stop_count(0);
counted += (tmp+HALFCOUNT)/COUNTSIZE;
break;
default:
perror("fstime: read");
return(-1);
break;
}
} else
counted += count_per_buf;
}
/* stop clock */
end = getFloatTime();
read_score = (long) ((double) counted / ((end - start) * count_per_k));
printf("Read done: %ld in %.4f, score %ld\n",
counted, end - start, read_score);
/*
* Output the test results. Use the true time.
*/
fprintf(stderr, "COUNT|%ld|0|KBps\n", read_score);
fprintf(stderr, "TIME|%.1f\n", end - start);
return(0);
}
/*
* Run the copy test for the time given in seconds.
*/
int c_test(int timeSecs)
{
unsigned long counted = 0L;
unsigned long tmp;
double start, end;
extern int sigalarm;
sync();
sleep(2);
sync();
sleep(1);
/* rewind */
errno = 0;
lseek(f, 0L, 0);
/* Set an alarm. */
sigalarm = 0;
signal(SIGALRM, stop_count);
alarm(timeSecs);
start = getFloatTime();
while (!sigalarm) {
if ((tmp=read(f, buf, bufsize)) != bufsize) {
switch(errno) {
case 0:
case EINVAL:
lseek(f, 0L, 0); /* rewind at end of file */
lseek(g, 0L, 0); /* rewind the output too */
continue;
case EINTR:
/* part credit for leftover bytes read */
counted += ( (tmp * write_score) /
(read_score + write_score)
+ HALFCOUNT) / COUNTSIZE;
stop_count(0);
break;
default:
perror("fstime: copy read");
return(-1);
break;
}
} else {
if ((tmp=write(g, buf, bufsize)) != bufsize) {
if (errno != EINTR) {
perror("fstime: copy write");
return(-1);
}
counted += (
/* Full credit for part of buffer written */
tmp +
/* Plus part credit having read full buffer */
( ((bufsize - tmp) * write_score) /
(read_score + write_score) )
+ HALFCOUNT) / COUNTSIZE;
stop_count(0);
} else
counted += count_per_buf;
}
}
/* stop clock */
end = getFloatTime();
copy_score = (long) ((double) counted / ((end - start) * count_per_k));
printf("Copy done: %ld in %.4f, score %ld\n",
counted, end - start, copy_score);
/*
* Output the test results. Use the true time.
*/
fprintf(stderr, "COUNT|%ld|0|KBps\n", copy_score);
fprintf(stderr, "TIME|%.1f\n", end - start);
return(0);
}
void stop_count(int sig)
{
extern int sigalarm;
sigalarm = 1;
}
void clean_up(int sig)
{
unlink(FNAME0);
unlink(FNAME1);
}

View File

@@ -1,75 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: hanoi.c SID: 3.3 5/15/91 19:30:20
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
* $Header: hanoi.c,v 3.5 87/08/06 08:11:14 kenj Exp $
* August 28, 1990 - Modified timing routines (ty)
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
******************************************************************************/
char SCCSid[] = "@(#) @(#)hanoi.c:3.3 -- 5/15/91 19:30:20";
#define other(i,j) (6-(i+j))
#include <stdio.h>
#include <stdlib.h>
#include "timeit.c"
void mov(int n, int f, int t);
unsigned long iter = 0;
int num[4];
long cnt;
void report(int sig)
{
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
exit(0);
}
int main(int argc, char *argv[])
{
int disk=10, /* default number of disks */
duration;
if (argc < 2) {
fprintf(stderr,"Usage: %s duration [disks]\n", argv[0]);
exit(1);
}
duration = atoi(argv[1]);
if(argc > 2) disk = atoi(argv[2]);
num[1] = disk;
wake_me(duration, report);
while(1) {
mov(disk,1,3);
iter++;
}
exit(0);
}
void mov(int n, int f, int t)
{
int o;
if(n == 1) {
num[f]--;
num[t]++;
return;
}
o = other(f,t);
mov(n-1,f,o);
mov(1,f,t);
mov(n-1,o,t);
}

View File

@@ -1,103 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 1
* Module: looper.c SID: 1.4 5/15/91 19:30:22
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith or Tom Yager at BYTE Magazine
* ben@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
*
* February 25, 1991 -- created (Ben S.)
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
******************************************************************************/
char SCCSid[] = "@(#) @(#)looper.c:1.4 -- 5/15/91 19:30:22";
/*
* Shell Process creation
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "timeit.c"
unsigned long iter;
char *cmd_argv[28];
int cmd_argc;
void report(int sig)
{
fprintf(stderr,"COUNT|%lu|60|lpm\n", iter);
exit(0);
}
int main(int argc, char *argv[])
{
int slave, count, duration;
int status;
if (argc < 2)
{
fprintf(stderr,"Usage: %s duration command [args..]\n", argv[0]);
fprintf(stderr," duration in seconds\n");
exit(1);
}
if((duration = atoi(argv[1])) < 1)
{
fprintf(stderr,"Usage: %s duration command [arg..]\n", argv[0]);
fprintf(stderr," duration in seconds\n");
exit(1);
}
/* get command */
cmd_argc=argc-2;
for( count=2;count < argc; ++count)
cmd_argv[count-2]=argv[count];
#ifdef DEBUG
printf("<<%s>>",cmd_argv[0]);
for(count=1;count < cmd_argc; ++count)
printf(" <%s>", cmd_argv[count]);
putchar('\n');
exit(0);
#endif
iter = 0;
wake_me(duration, report);
while (1)
{
if ((slave = fork()) == 0)
{ /* execute command */
execvp(cmd_argv[0],cmd_argv);
exit(99);
}
else if (slave < 0)
{
/* woops ... */
fprintf(stderr,"Fork failed at iteration %lu\n", iter);
perror("Reason");
exit(2);
}
else
/* master */
wait(&status);
if (status == 99 << 8)
{
fprintf(stderr, "Command \"%s\" didn't exec\n", cmd_argv[0]);
exit(2);
}
else if (status != 0)
{
fprintf(stderr,"Bad wait status: 0x%x\n", status);
exit(2);
}
iter++;
}
}

View File

@@ -1,66 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: pipe.c SID: 3.3 5/15/91 19:30:20
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
* $Header: pipe.c,v 3.5 87/06/22 14:32:36 kjmcdonell Beta $
* August 29, 1990 - modified timing routines (ty)
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
******************************************************************************/
char SCCSid[] = "@(#) @(#)pipe.c:3.3 -- 5/15/91 19:30:20";
/*
* pipe -- test single process pipe throughput (no context switching)
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "timeit.c"
unsigned long iter;
void report(int sig)
{
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
exit(0);
}
int main(int argc, char *argv[])
{
char buf[512];
int pvec[2], duration;
if (argc != 2) {
fprintf(stderr,"Usage: %s duration\n", argv[0]);
exit(1);
}
duration = atoi(argv[1]);
pipe(pvec);
wake_me(duration, report);
iter = 0;
while (1) {
if (write(pvec[1], buf, sizeof(buf)) != sizeof(buf)) {
if ((errno != EINTR) && (errno != 0))
fprintf(stderr,"write failed, error %d\n", errno);
}
if (read(pvec[0], buf, sizeof(buf)) != sizeof(buf)) {
if ((errno != EINTR) && (errno != 0))
fprintf(stderr,"read failed, error %d\n", errno);
}
iter++;
}
}

View File

@@ -1,78 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: spawn.c SID: 3.3 5/15/91 19:30:20
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yagerat BYTE Magazine
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
* $Header: spawn.c,v 3.4 87/06/22 14:32:48 kjmcdonell Beta $
* August 29, 1990 - Modified timing routines (ty)
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
******************************************************************************/
char SCCSid[] = "@(#) @(#)spawn.c:3.3 -- 5/15/91 19:30:20";
/*
* Process creation
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "timeit.c"
unsigned long iter;
void report(int sig)
{
fprintf(stderr,"COUNT|%lu|1|lps\n", iter);
exit(0);
}
int main(int argc, char *argv[])
{
int slave, duration;
int status;
if (argc != 2) {
fprintf(stderr,"Usage: %s duration \n", argv[0]);
exit(1);
}
duration = atoi(argv[1]);
iter = 0;
wake_me(duration, report);
while (1) {
if ((slave = fork()) == 0) {
/* slave .. boring */
#if debug
printf("fork OK\n");
#endif
/* kill it right away */
exit(0);
} else if (slave < 0) {
/* woops ... */
fprintf(stderr,"Fork failed at iteration %lu\n", iter);
perror("Reason");
exit(2);
} else
/* master */
wait(&status);
if (status != 0) {
fprintf(stderr,"Bad wait status: 0x%x\n", status);
exit(2);
}
iter++;
#if debug
printf("Child %d done.\n", slave);
#endif
}
}

View File

@@ -1,107 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 3
* Module: syscall.c SID: 3.3 5/15/91 19:30:21
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager at BYTE Magazine
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
* $Header: syscall.c,v 3.4 87/06/22 14:32:54 kjmcdonell Beta $
* August 29, 1990 - Modified timing routines
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
******************************************************************************/
/*
* syscall -- sit in a loop calling the system
*
*/
char SCCSid[] = "@(#) @(#)syscall.c:3.3 -- 5/15/91 19:30:21";
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "timeit.c"
unsigned long iter;
void report(int sig)
{
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
exit(0);
}
int main(int argc, char *argv[])
{
char *test;
int duration;
if (argc < 2) {
fprintf(stderr,"Usage: %s duration [ test ]\n", argv[0]);
fprintf(stderr,"test is one of:\n");
fprintf(stderr," \"mix\" (default), \"close\", \"getpid\", \"exec\"\n");
exit(1);
}
if (argc > 2)
test = argv[2];
else
test = "mix";
duration = atoi(argv[1]);
iter = 0;
wake_me(duration, report);
switch (test[0]) {
case 'm':
while (1) {
close(dup(0));
getpid();
getuid();
umask(022);
iter++;
}
/* NOTREACHED */
case 'c':
while (1) {
close(dup(0));
iter++;
}
/* NOTREACHED */
case 'g':
while (1) {
getpid();
iter++;
}
/* NOTREACHED */
case 'e':
while (1) {
pid_t pid = fork();
if (pid < 0) {
fprintf(stderr,"%s: fork failed\n", argv[0]);
exit(1);
} else if (pid == 0) {
execl("/bin/true", (char *) 0);
fprintf(stderr,"%s: exec /bin/true failed\n", argv[0]);
exit(1);
} else {
if (waitpid(pid, NULL, 0) < 0) {
fprintf(stderr,"%s: waitpid failed\n", argv[0]);
exit(1);
}
}
iter++;
}
/* NOTREACHED */
}
exit(9);
}

View File

@@ -1,578 +0,0 @@
/* Programme to test how long it takes to select(2), poll(2) and poll2(2) a
large number of file descriptors.
Copyright 1997 Richard Gooch rgooch@atnf.csiro.au
Distributed under the GNU General Public License.
To compile this programme, use gcc -O2 -o time-polling time-polling.c
Extra compile flags:
Add -DHAS_SELECT if your operating system has the select(2) system call
Add -DHAS_POLL if your operating system has the poll(2) system call
Add -DHAS_POLL2 if your operating system has the poll2(2) system call
Usage: time-polling [num_iter] [num_to_test] [num_active] [-v]
NOTE: on many systems the default limit on file descriptors is less than
1024. You should try to increase this limit to 1024 before doing the test.
Something like "limit descriptors 1024" or "limit openfiles 1024" should do
the trick. On some systems (like IRIX), doing the test on a smaller number
gives a *much* smaller time per descriptor, which shows that time taken
does not scale linearly with number of descriptors, which is non-optimal.
In the tests I've done, I try to use 1024 descriptors.
The benchmark results are available at:
http://www.atnf.csiro.au/~rgooch/benchmarks.html
If you want to contribute results, please email them to me. Please specify
if you want to be acknowledged.
This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
Richard Gooch may be reached by email at rgooch@atnf.csiro.au
The postal address is:
Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
*/
#ifdef UNIXBENCH
#define OUT stdout
#else
#define OUT stderr
#endif
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>
#ifdef HAS_POLL
# include <sys/poll.h>
#endif
#ifdef HAS_POLL2
# include <linux/poll2.h>
#endif
#ifdef HAS_SELECT
# include <sys/select.h>
#endif
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#ifdef UNIXBENCH
#define MAX_ITERATIONS 1000
#else
#define MAX_ITERATIONS 30
#endif
#define MAX_FDS 40960
#define CONST const
#define ERRSTRING strerror (errno)
typedef int flag;
#ifndef HAS_POLL
/*
static inline int find_first_set_bit (CONST void *array, int size)
*/
static int find_first_set_bit (CONST void *array, int size)
/* [SUMMARY] Find the first bit set in a bitfield.
<array> A pointer to the bitfield. This must be aligned on a long boundary.
<size> The number of bits in the bitfield.
[RETURNS] The index of the first set bit. If no bits are set, <<size>> + 1
is returned.
*/
{
int index;
unsigned long word;
unsigned int ul_size = 8 * sizeof (unsigned long);
CONST unsigned long *ul_array = array;
/* Find first word with any bit set */
for (index = 0; (*ul_array == 0) && (index < size);
index += ul_size, ++ul_array);
/* Find first bit set in word */
for (word = *ul_array; !(word & 1) && (index < size);
++index, word = word >> 1);
return (index);
} /* End Function find_first_set_bit */
/*
static inline int find_next_set_bit (CONST void *array, int size, int offset)
*/
static int find_next_set_bit (CONST void *array, int size, int offset)
/* [SUMMARY] Find the next bit set in a bitfield.
<array> A pointer to the bitfield. This must be aligned on a long boundary.
<size> The number of bits in the bitfield.
<offset> The offset of the current bit in the bitfield. The current bit is
ignored.
[RETURNS] The index of the next set bit. If no more bits are set,
<<size>> + 1 is returned.
*/
{
int index, tmp;
unsigned long word;
unsigned int ul_size = 8 * sizeof (unsigned long);
CONST unsigned long *ul_array = array;
if (++offset >= size) return (offset);
index = offset;
/* Jump to the long word containing the next bit */
tmp = offset / ul_size;
ul_array += tmp;
offset -= tmp * ul_size;
if ( (offset == 0) || (*ul_array == 0) )
return (find_first_set_bit (ul_array, size - index) + index);
/* There is a bit set somewhere in this word */
if ( ( (word = *ul_array) != 0 ) && ( (word = word >> offset) != 0 ) )
{
/* There is a bit set somewhere in this word at or after the offset
position */
for (; (word & 1) == 0; word = word >> 1, ++index);
return (index);
}
/* Have to go to subsequent word(s) */
index += ul_size - offset;
return (find_first_set_bit (++ul_array, size - index) + index);
} /* End Function find_next_set_bit */
#endif
struct callback_struct
{
void (*input_func) (void *info);
void (*output_func) (void *info);
void (*exception_func) (void *info);
void *info;
};
static int total_bits = 0;
struct callback_struct callbacks[MAX_FDS];
static void test_func (void *info)
{
++total_bits;
}
#ifdef HAS_SELECT
static void time_select (fd_set *input_fds, fd_set *output_fds,
fd_set *exception_fds, int max_fd, int num_iter,
long *times)
/* [SUMMARY] Time how long it takes to select(2) file descriptors.
<input_fds> The input masks.
<output_fds> The output masks.
<exception_fds> The exception masks.
<max_fd> The highest file descriptor in the fd_sets.
<num_iter> The number of iterations.
<times> The time taken (in microseconds) for each iteration.
[RETURNS] Nothing.
*/
{
int fd, count, nready;
fd_set i_fds, o_fds, e_fds;
struct timeval time1, time2, tv;
/* Warm the cache a bit */
memcpy (&i_fds, input_fds, sizeof i_fds);
memcpy (&o_fds, output_fds, sizeof i_fds);
memcpy (&e_fds, exception_fds, sizeof i_fds);
tv.tv_sec = 0;
tv.tv_usec = 0;
select (max_fd + 1, &i_fds, &o_fds, &e_fds, &tv);
for (count = 0; count < num_iter; ++count)
{
total_bits = 0;
gettimeofday (&time1, NULL);
memcpy (&i_fds, input_fds, sizeof i_fds);
memcpy (&o_fds, output_fds, sizeof i_fds);
memcpy (&e_fds, exception_fds, sizeof i_fds);
tv.tv_sec = 0;
tv.tv_usec = 0;
nready = select (max_fd + 1, &i_fds, &o_fds, &e_fds, &tv);
if (nready == -1)
{
fprintf (stderr, "Error selecting\t%s\n", ERRSTRING);
exit (2);
}
if (nready < 1)
{
fprintf (stderr, "Error: nready: %d\n", nready);
exit (1);
}
/* Scan the output */
for (fd = find_first_set_bit (&e_fds, sizeof e_fds * 8); fd <= max_fd;
fd = find_next_set_bit (&e_fds, sizeof e_fds * 8, fd) )
{
(*callbacks[fd].exception_func) (callbacks[fd].info);
}
for (fd = find_first_set_bit (&i_fds, sizeof i_fds * 8); fd <= max_fd;
fd = find_next_set_bit (&i_fds, sizeof i_fds * 8, fd) )
{
(*callbacks[fd].input_func) (callbacks[fd].info);
}
for (fd = find_first_set_bit (&o_fds, sizeof o_fds * 8); fd <= max_fd;
fd = find_next_set_bit (&o_fds, sizeof o_fds * 8, fd) )
{
(*callbacks[fd].output_func) (callbacks[fd].info);
}
gettimeofday (&time2, NULL);
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
times[count] += time2.tv_usec - time1.tv_usec;
}
} /* End Function time_select */
#endif /* HAS_SELECT */
#ifdef HAS_POLL
static void time_poll (struct pollfd *pollfd_array, int start_index,
int num_to_test, int num_iter, long *times)
/* [SUMMARY] Time how long it takes to poll(2) file descriptors.
<pollfd_array> The array of pollfd structures.
<start_index> The start index in the array of pollfd structures.
<num_to_test> The number of file descriptors to test.
<num_iter> The number of iterations.
<times> The time taken (in microseconds) for each iteration.
[RETURNS] Nothing.
*/
{
short revents;
int fd, count, nready;
struct timeval time1, time2;
struct pollfd *pollfd_ptr, *stop_pollfd;
/* Warm the cache a bit */
poll (pollfd_array + start_index, num_to_test, 0);
for (count = 0; count < num_iter; ++count)
{
total_bits = 0;
gettimeofday (&time1, NULL);
nready = poll (pollfd_array + start_index, num_to_test, 0);
if (nready == -1)
{
fprintf (stderr, "Error polling\t%s\n", ERRSTRING);
exit (2);
}
if (nready < 1)
{
fprintf (stderr, "Error: nready: %d\n", nready);
exit (1);
}
stop_pollfd = pollfd_array + start_index + num_to_test;
for (pollfd_ptr = pollfd_array + start_index; TRUE; ++pollfd_ptr)
{
if (pollfd_ptr->revents == 0) continue;
/* Have an active descriptor */
revents = pollfd_ptr->revents;
fd = pollfd_ptr->fd;
if (revents & POLLPRI)
(*callbacks[fd].exception_func) (callbacks[fd].info);
if (revents & POLLIN)
(*callbacks[fd].input_func) (callbacks[fd].info);
if (revents & POLLOUT)
(*callbacks[fd].output_func) (callbacks[fd].info);
if (--nready == 0) break;
}
gettimeofday (&time2, NULL);
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
times[count] += time2.tv_usec - time1.tv_usec;
}
} /* End Function time_poll */
#endif /* HAS_POLL */
#ifdef HAS_POLL2
static void time_poll2 (struct poll2ifd *poll2ifd_array, int start_index,
int num_to_test, int num_iter, long *times)
/* [SUMMARY] Time how long it takes to poll2(2) file descriptors.
<poll2ifd_array> The array of poll2ifd structures.
<start_index> The start index in the array of pollfd structures.
<num_to_test> The number of file descriptors to test.
<num_iter> The number of iterations.
<times> The time taken (in microseconds) for each iteration.
[RETURNS] Nothing.
*/
{
short revents;
int fd, count, nready, i;
struct timeval time1, time2;
struct poll2ofd poll2ofd_array[MAX_FDS];
/* Warm the cache a bit */
poll2 (poll2ifd_array + start_index, poll2ofd_array, num_to_test, 0);
for (count = 0; count < num_iter; ++count)
{
total_bits = 0;
gettimeofday (&time1, NULL);
nready = poll2 (poll2ifd_array + start_index, poll2ofd_array,
num_to_test, 0);
if (nready == -1)
{
times[count] = -1;
if (errno == ENOSYS) return; /* Must do this first */
fprintf (stderr, "Error calling poll2(2)\t%s\n", ERRSTRING);
exit (2);
}
if (nready < 1)
{
fprintf (stderr, "Error: nready: %d\n", nready);
exit (1);
}
for (i = 0; i < nready; ++i)
{
revents = poll2ofd_array[i].revents;
fd = poll2ofd_array[i].fd;
if (revents & POLLPRI)
(*callbacks[fd].exception_func) (callbacks[fd].info);
if (revents & POLLIN)
(*callbacks[fd].input_func) (callbacks[fd].info);
if (revents & POLLOUT)
(*callbacks[fd].output_func) (callbacks[fd].info);
}
gettimeofday (&time2, NULL);
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
times[count] += time2.tv_usec - time1.tv_usec;
}
} /* End Function time_poll2 */
#endif /* HAS_POLL2 */
int main (argc, argv)
int argc;
char *argv[];
{
flag failed = FALSE;
flag verbose = FALSE;
int first_fd = -1;
int fd, max_fd, count, total_fds;
int num_to_test, num_active;
#ifdef UNIXBENCH
int max_iter = 1000;
#else
int max_iter = 10;
#endif
#ifdef HAS_SELECT
long select_total = 0;
fd_set input_fds, output_fds, exception_fds;
long select_times[MAX_ITERATIONS];
#endif
#ifdef HAS_POLL
int start_index;
long poll_total = 0;
struct pollfd pollfd_array[MAX_FDS];
long poll_times[MAX_ITERATIONS];
#endif
#ifdef HAS_POLL2
long poll2_total = 0;
struct poll2ifd poll2ifd_array[MAX_FDS];
struct poll2ofd poll2ofd_array[MAX_FDS];
long poll2_times[MAX_ITERATIONS];
#endif
#if 0
extern char *sys_errlist[];
#endif
#ifdef HAS_SELECT
FD_ZERO (&input_fds);
FD_ZERO (&output_fds);
FD_ZERO (&exception_fds);
#endif
#ifdef HAS_POLL
memset (pollfd_array, 0, sizeof pollfd_array);
#endif
/* Allocate file descriptors */
total_fds = 0;
max_fd = 0;
while (!failed)
{
if ( ( fd = dup (1) ) == -1 )
{
if (errno != EMFILE)
{
fprintf (stderr, "Error dup()ing\t%s\n", ERRSTRING);
exit (1);
}
failed = TRUE;
continue;
}
if (fd >= MAX_FDS)
{
fprintf (stderr, "File descriptor: %d larger than max: %d\n",
fd, MAX_FDS - 1);
exit (1);
}
callbacks[fd].input_func = test_func;
callbacks[fd].output_func = test_func;
callbacks[fd].exception_func = test_func;
callbacks[fd].info = NULL;
if (fd > max_fd) max_fd = fd;
if (first_fd < 0) first_fd = fd;
#ifdef HAS_POLL
pollfd_array[fd].fd = fd;
pollfd_array[fd].events = 0;
#endif
#ifdef HAS_POLL2
poll2ifd_array[fd].fd = fd;
poll2ifd_array[fd].events = 0;
#endif
}
total_fds = max_fd + 1;
/* Process the command-line arguments */
if (argc > 5)
{
fputs ("Usage:\ttime-polling [num_iter] [num_to_test] [num_active] [-v]\n",
stderr);
exit (1);
}
if (argc > 1) max_iter = atoi (argv[1]);
if (max_iter > MAX_ITERATIONS)
{
fprintf (stderr, "num_iter too large\n");
exit (1);
}
if (argc > 2) num_to_test = atoi (argv[2]);
else num_to_test = total_fds - first_fd;
if (argc > 3) num_active = atoi (argv[3]);
else num_active = 1;
if (argc > 4)
{
if (strcmp (argv[4], "-v") != 0)
{
fputs ("Usage:\ttime-polling [num_iter] [num_to_test] [num_active] [-v]\n",
stderr);
exit (1);
}
verbose = TRUE;
}
/* Sanity tests */
if (num_to_test > total_fds - first_fd) num_to_test = total_fds - first_fd;
if (num_active > total_fds - first_fd) num_active = total_fds - first_fd;
/* Set activity monitoring flags */
for (fd = total_fds - num_to_test; fd < total_fds; ++fd)
{
#ifdef HAS_SELECT
FD_SET (fd, &exception_fds);
FD_SET (fd, &input_fds);
#endif
#ifdef HAS_POLL
pollfd_array[fd].events = POLLPRI | POLLIN;
#endif
#ifdef HAS_POLL2
poll2ifd_array[fd].events = POLLPRI | POLLIN;
#endif
}
for (fd = total_fds - num_active; fd < total_fds; ++fd)
{
#ifdef HAS_SELECT
FD_SET (fd, &output_fds);
#endif
#ifdef HAS_POLL
pollfd_array[fd].events |= POLLOUT;
#endif
#ifdef HAS_POLL2
poll2ifd_array[fd].events |= POLLOUT;
#endif
}
fprintf (OUT, "Num fds: %d, polling descriptors %d-%d\n",
total_fds, total_fds - num_to_test, max_fd);
/* First do all the tests, then print the results */
#ifdef HAS_SELECT
time_select (&input_fds, &output_fds, &exception_fds, max_fd, max_iter,
select_times);
#endif
#ifdef HAS_POLL
start_index = total_fds - num_to_test;
time_poll (pollfd_array, start_index, num_to_test, max_iter, poll_times);
#endif
#ifdef HAS_POLL2
start_index = total_fds - num_to_test;
time_poll2 (poll2ifd_array, start_index, num_to_test, max_iter,
poll2_times);
#endif
/* Now print out all the times */
fputs ("All times in microseconds\n", OUT);
fputs ("ITERATION\t", OUT);
#ifdef HAS_SELECT
fprintf (OUT, "%-12s", "select(2)");
#endif
#ifdef HAS_POLL
fprintf (OUT, "%-12s", "poll(2)");
#endif
#ifdef HAS_POLL2
if (poll2_times[0] >= 0) fprintf (OUT, "%-12s", "poll2(2)");
#endif
for (count = 0; count < max_iter; ++count)
{
if (verbose) fprintf (OUT, "\n%d\t\t", count);
#ifdef HAS_SELECT
if (verbose) fprintf (OUT, "%-12ld", select_times[count]);
select_total += select_times[count];
#endif
#ifdef HAS_POLL
if (verbose) fprintf (OUT, "%-12ld", poll_times[count]);
poll_total += poll_times[count];
#endif
#ifdef HAS_POLL2
if ( verbose && (poll2_times[0] >= 0) )
fprintf (OUT, "%-12ld", poll2_times[count]);
poll2_total += poll2_times[count];
#endif
}
fputs ("\n\naverage\t\t", OUT);
#ifdef HAS_SELECT
fprintf (OUT, "%-12ld", select_total / max_iter);
#endif
#ifdef HAS_POLL
fprintf (OUT, "%-12ld", poll_total / max_iter);
#endif
#ifdef HAS_POLL2
if (poll2_times[0] >= 0)
fprintf (OUT, "%-12ld", poll2_total / max_iter);
#endif
putc ('\n', OUT);
fputs ("Per fd\t\t", OUT);
#ifdef HAS_SELECT
fprintf (OUT, "%-12.2f",
(float) select_total / (float) max_iter / (float) num_to_test);
#ifdef UNIXBENCH
fprintf (stderr, "lps\t%.2f\t%.1f\n",
1000000 * (float) max_iter * (float) num_to_test
/ (float) select_total, (float)select_total / 1000000);
#endif
#endif
#ifdef HAS_POLL
fprintf (OUT, "%-12.2f",
(float) poll_total / (float) max_iter / (float) num_to_test);
#ifdef UNIXBENCH
fprintf (stderr, "lps\t%.2f\t%.1f\n",
1000000 * (float) max_iter * (float) num_to_test
/ (float) poll_total, (float)poll_total / 1000000);
#endif
#endif
#ifdef HAS_POLL2
if (poll2_times[0] >= 0) {
fprintf (OUT, "%-12.2f",
(float) poll2_total / (float) max_iter / (float) num_to_test);
#ifdef UNIXBENCH
fprintf (stderr, "lps\t%.2f\t%.1f\n",
1000000 * (float) max_iter * (float) num_to_test
/ (float) poll2_total, (float)poll2_total / 1000000);
#endif
}
#endif
fputs ("<- the most important value\n", OUT);
exit(0);
} /* End Function main */

View File

@@ -1,39 +0,0 @@
/*******************************************************************************
*
* The BYTE UNIX Benchmarks - Release 3
* Module: timeit.c SID: 3.3 5/15/91 19:30:21
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith, Rick Grehan or Tom Yager
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
*
*******************************************************************************
* Modification Log:
* May 12, 1989 - modified empty loops to avoid nullifying by optimizing
* compilers
* August 28, 1990 - changed timing relationship--now returns total number
* of iterations (ty)
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
* Andy Kahn <kahn@zk3.dec.com>
*
******************************************************************************/
/* this module is #included in other modules--no separate SCCS ID */
/*
* Timing routine
*
*/
#include <signal.h>
#include <unistd.h>
void wake_me(int seconds, void (*func)(int))
{
/* set up the signal handler */
signal(SIGALRM, func);
/* get the clock running */
alarm(seconds);
}

View File

@@ -1,650 +0,0 @@
/*
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* $XFree86: xc/programs/glxgears/glxgears.c,v 1.3tsi Exp $ */
/*
* This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
* Port by Brian Paul 23 March 2001
*
* Exact timing added by Behdad Esfahbod to achieve a fixed speed regardless
* of frame rate. November 2003
*
* Printer support added by Roland Mainz <roland.mainz@nrubsig.org>. April 2004
*
* This version modified by Ian Smith, 30 Sept 2007, to make ubgears.
* ubgears is cusoimised for use in the UnixBench benchmarking suite.
* Some redundant stuff is gone, and the -time option is added.
* Mainly it's forked so we don't use the host's version, which could change
* from platform to platform.
*
* Command line options:
* -display Set X11 display for output.
* -info Print additional GLX information.
* -time <t> Run for <t> seconds and produce a performance report.
* -h Print this help page.
* -v Verbose output.
*
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <sys/time.h>
#include <sched.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifndef M_PI
#define M_PI 3.14159265
#endif /* !M_PI */
/* Turn a NULL pointer string into an empty string */
#define NULLSTR(x) (((x)!=NULL)?(x):(""))
#define Log(x) { if(verbose) printf x; }
#define Msg(x) { printf x; }
/* Globla vars */
/* program name (from argv[0]) */
static const char *ProgramName;
/* verbose output what the program is doing */
static Bool verbose = False;
/* time in microseconds to run for; -1 means forever. */
static int runTime = -1;
/* Time at which start_time(void) was called. */
static struct timeval clockStart;
/* XXX this probably isn't very portable */
/* return current time (in seconds) */
static void
start_time(void)
{
(void) gettimeofday(&clockStart, 0);
}
/*
* return time (in microseconds) since start_time(void) was called.
*
* The older version of this function randomly returned negative results.
* This version won't, up to 2000 seconds and some.
*/
static long
current_time(void)
{
struct timeval tv;
long secs, micros;
(void) gettimeofday(&tv, 0);
secs = tv.tv_sec - clockStart.tv_sec;
micros = tv.tv_usec - clockStart.tv_usec;
if (micros < 0) {
--secs;
micros += 1000000;
}
return secs * 1000000 + micros;
}
static
void usage(void)
{
fprintf (stderr, "usage: %s [options]\n", ProgramName);
fprintf (stderr, "-display\tSet X11 display for output.\n");
fprintf (stderr, "-info\t\tPrint additional GLX information.\n");
fprintf (stderr, "-time t\t\tRun for t seconds and report performance.\n");
fprintf (stderr, "-h\t\tPrint this help page.\n");
fprintf (stderr, "-v\t\tVerbose output.\n");
fprintf (stderr, "\n");
exit(EXIT_FAILURE);
}
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
static GLint gear1, gear2, gear3;
static GLfloat angle = 0.0;
static GLint speed = 60;
static GLboolean printInfo = GL_FALSE;
/*
*
* Draw a gear wheel. You'll probably want to call this function when
* building a display list since we do a lot of trig here.
*
* Input: inner_radius - radius of hole at center
* outer_radius - radius at center of teeth
* width - width of gear
* teeth - number of teeth
* tooth_depth - depth of tooth
*/
static void
gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
GLint teeth, GLfloat tooth_depth)
{
GLint i;
GLfloat r0, r1, r2, maxr2, minr2;
GLfloat angle, da;
GLfloat u, v, len;
r0 = inner_radius;
r1 = outer_radius - tooth_depth / 2.0;
maxr2 = r2 = outer_radius + tooth_depth / 2.0;
minr2 = r2;
da = 2.0 * M_PI / teeth / 4.0;
glShadeModel(GL_FLAT);
glNormal3f(0.0, 0.0, 1.0);
/* draw front face */
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
if (i < teeth) {
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
width * 0.5);
}
}
glEnd();
/* draw front sides of teeth */
glBegin(GL_QUADS);
for (i = 0; i < teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
width * 0.5);
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
width * 0.5);
r2 = minr2;
}
r2 = maxr2;
glEnd();
glNormal3f(0.0, 0.0, -1.0);
/* draw back face */
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
if (i < teeth) {
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
-width * 0.5);
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
}
}
glEnd();
/* draw back sides of teeth */
glBegin(GL_QUADS);
da = 2.0 * M_PI / teeth / 4.0;
for (i = 0; i < teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
-width * 0.5);
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
-width * 0.5);
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
r2 = minr2;
}
r2 = maxr2;
glEnd();
/* draw outward faces of teeth */
glBegin(GL_QUAD_STRIP);
for (i = 0; i < teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
u = r2 * cos(angle + da) - r1 * cos(angle);
v = r2 * sin(angle + da) - r1 * sin(angle);
len = sqrt(u * u + v * v);
u /= len;
v /= len;
glNormal3f(v, -u, 0.0);
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
glNormal3f(cos(angle + 1.5 * da), sin(angle + 1.5 * da), 0.0);
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
width * 0.5);
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
-width * 0.5);
u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
glNormal3f(v, -u, 0.0);
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
width * 0.5);
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
-width * 0.5);
glNormal3f(cos(angle + 3.5 * da), sin(angle + 3.5 * da), 0.0);
r2 = minr2;
}
r2 = maxr2;
glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
glEnd();
glShadeModel(GL_SMOOTH);
/* draw inside radius cylinder */
glBegin(GL_QUAD_STRIP);
for (i = 0; i <= teeth; i++) {
angle = i * 2.0 * M_PI / teeth;
glNormal3f(-cos(angle), -sin(angle), 0.0);
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
}
glEnd();
}
static void
draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(view_rotx, 1.0, 0.0, 0.0);
glRotatef(view_roty, 0.0, 1.0, 0.0);
glRotatef(view_rotz, 0.0, 0.0, 1.0);
glPushMatrix();
glTranslatef(-3.0, -2.0, 0.0);
glRotatef(angle, 0.0, 0.0, 1.0);
glCallList(gear1);
glPopMatrix();
glPushMatrix();
glTranslatef(3.1, -2.0, 0.0);
glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
glCallList(gear2);
glPopMatrix();
glPushMatrix();
glTranslatef(-3.1, 4.2, 0.0);
glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
glCallList(gear3);
glPopMatrix();
glPopMatrix();
}
/* new window size or exposure */
static void
reshape(int width, int height)
{
GLfloat h = (GLfloat) height / (GLfloat) width;
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* fit width and height */
if (h >= 1.0)
glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
else
glFrustum(-1.0/h, 1.0/h, -1.0, 1.0, 5.0, 60.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -40.0);
}
static void
init(void)
{
static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
/* make the gears */
gear1 = glGenLists(1);
glNewList(gear1, GL_COMPILE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
gear(1.0, 4.0, 1.0, 20, 0.7);
glEndList();
gear2 = glGenLists(1);
glNewList(gear2, GL_COMPILE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
gear(0.5, 2.0, 2.0, 10, 0.7);
glEndList();
gear3 = glGenLists(1);
glNewList(gear3, GL_COMPILE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
gear(1.3, 2.0, 0.5, 10, 0.7);
glEndList();
glEnable(GL_NORMALIZE);
}
/*
* Create an RGB, double-buffered window.
* Return the window and context handles.
*/
static void
make_window( Display *dpy, Screen *scr,
const char *name,
int x, int y, int width, int height,
Window *winRet, GLXContext *ctxRet)
{
int attrib[] = { GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER,
GLX_DEPTH_SIZE, 1,
None };
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
Window win;
GLXContext ctx;
XVisualInfo *visinfo;
GLint max[2] = { 0, 0 };
scrnum = XScreenNumberOfScreen(scr);
root = XRootWindow(dpy, scrnum);
visinfo = glXChooseVisual( dpy, scrnum, attrib );
if (!visinfo) {
fprintf(stderr, "%s: Error: couldn't get an RGB, Double-buffered visual.\n", ProgramName);
exit(EXIT_FAILURE);
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow( dpy, root, x, y, width, height,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr );
/* set hints and properties */
{
XSizeHints sizehints;
sizehints.x = x;
sizehints.y = y;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(dpy, win, &sizehints);
XSetStandardProperties(dpy, win, name, name,
None, (char **)NULL, 0, &sizehints);
}
ctx = glXCreateContext( dpy, visinfo, NULL, True );
if (!ctx) {
fprintf(stderr, "%s: Error: glXCreateContext failed.\n", ProgramName);
exit(EXIT_FAILURE);
}
XFree(visinfo);
XMapWindow(dpy, win);
glXMakeCurrent(dpy, win, ctx);
/* Check for maximum size supported by the GL rasterizer */
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max);
if (printInfo)
printf("GL_MAX_VIEWPORT_DIMS=%d/%d\n", (int)max[0], (int)max[1]);
if (width > max[0] || height > max[1]) {
fprintf(stderr, "%s: Error: Requested window size (%d/%d) larger than "
"maximum supported by GL engine (%d/%d).\n",
ProgramName, width, height, (int)max[0], (int)max[1]);
exit(EXIT_FAILURE);
}
*winRet = win;
*ctxRet = ctx;
}
static void
event_loop(Display *dpy, Window win)
{
while (1) {
/* Process interactive events */
while (XPending(dpy) > 0) {
XEvent event;
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
Log(("Event: Expose\n"));
/* we'll redraw below */
break;
case ConfigureNotify:
Log(("Event: ConfigureNotify\n"));
reshape(event.xconfigure.width, event.xconfigure.height);
break;
}
}
{
/* Time at which we started measuring. */
static long startTime = 0;
/* Time of the previous frame. */
static long lastFrame = 0;
/* Time of the previous FPS report. */
static long lastFps = 0;
/* Number of frames we've done. */
static int frames = 0;
/* Number of frames we've done in the measured run. */
static long runFrames = 0;
long t = current_time();
long useconds;
if (!lastFrame)
lastFrame = t;
if (!lastFps)
lastFps = t;
/* How many microseconds since the previous frame? */
useconds = t - lastFrame;
if (!useconds) /* assume 100FPS if we don't have timer */
useconds = 10000;
/* Calculate how far the gears need to move and redraw. */
angle = angle + ((double)speed * useconds) / 1000000.0;
if (angle > 360.0)
angle = angle - 360.0; /* don't lose precision! */
draw();
glXSwapBuffers(dpy, win);
/* Done this frame. */
lastFrame = t;
frames++;
/* Every 5 seconds, print the FPS. */
if (t - lastFps >= 5000000L) {
GLfloat seconds = (t - lastFps) / 1000000.0;
GLfloat fps = frames / seconds;
printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
fps);
lastFps = t;
frames = 0;
/*
* Set the start time now -- ie. after one report. This
* gives us pump-priming time before we start for real.
*/
if (runTime > 0 && startTime == 0) {
printf("Start timing!\n");
startTime = t;
}
}
if (startTime > 0)
++runFrames;
/* If our run time is done, finish. */
if (runTime > 0 && startTime > 0 && t - startTime > runTime) {
double time = (double) (t - startTime) / 1000000.0;
fprintf(stderr, "COUNT|%ld|1|fps\n", runFrames);
fprintf(stderr, "TIME|%.1f\n", time);
exit(0);
}
/* Need to give cpu away in order to get precise timing next cycle,
* otherwise, gettimeofday would return almost the same value. */
sched_yield();
}
}
}
int
main(int argc, char *argv[])
{
Bool use_threadsafe_api = False;
Display *dpy;
Window win;
Screen *screen;
GLXContext ctx;
char *dpyName = NULL;
int i;
XRectangle winrect;
ProgramName = argv[0];
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
int len = strlen(arg);
if (strcmp(argv[i], "-display") == 0) {
if (++i >= argc)
usage();
dpyName = argv[i];
}
else if (strcmp(argv[i], "-info") == 0) {
printInfo = GL_TRUE;
}
else if (strcmp(argv[i], "-time") == 0) {
if (++i >= argc)
usage();
runTime = atoi(argv[i]) * 1000000;
}
else if (!strncmp("-v", arg, len)) {
verbose = True;
printInfo = GL_TRUE;
}
else if( !strncmp("-debug_use_threadsafe_api", arg, len) )
{
use_threadsafe_api = True;
}
else if (!strcmp(argv[i], "-h")) {
usage();
}
else
{
fprintf(stderr, "%s: Unsupported option '%s'.\n", ProgramName, argv[i]);
usage();
}
}
/* Init X threading API on demand (for debugging) */
if( use_threadsafe_api )
{
if( !XInitThreads() )
{
fprintf(stderr, "%s: XInitThreads() failure.\n", ProgramName);
exit(EXIT_FAILURE);
}
}
dpy = XOpenDisplay(dpyName);
if (!dpy) {
fprintf(stderr, "%s: Error: couldn't open display '%s'\n", ProgramName, dpyName);
return EXIT_FAILURE;
}
screen = XDefaultScreenOfDisplay(dpy);
winrect.x = 0;
winrect.y = 0;
winrect.width = 300;
winrect.height = 300;
Log(("Window x=%d, y=%d, width=%d, height=%d\n",
(int)winrect.x, (int)winrect.y, (int)winrect.width, (int)winrect.height));
make_window(dpy, screen, "ubgears", winrect.x, winrect.y, winrect.width, winrect.height, &win, &ctx);
reshape(winrect.width, winrect.height);
if (printInfo) {
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
}
init();
start_time();
event_loop(dpy, win);
glXDestroyContext(dpy, ctx);
XDestroyWindow(dpy, win);
XCloseDisplay(dpy);
return EXIT_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
SUBDIR=cctest.c dc.dat large.txt sort.src
.include <bsd.subdir.mk>

View File

@@ -1 +0,0 @@
BINDIR=/usr/benchmarks/unixbench/testdir

View File

@@ -1,3 +0,0 @@
SCRIPTS=cctest.c
SCRIPTSNAME=cctest.c
.include <bsd.prog.mk>

View File

@@ -1,156 +0,0 @@
/*******************************************************************************
* The BYTE UNIX Benchmarks - Release 1
* Module: cctest.c SID: 1.2 7/10/89 18:55:45
*
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Ben Smith or Rick Grehan at BYTE Magazine
* bensmith@bixpb.UUCP rick_g@bixpb.UUCP
*
*******************************************************************************
* Modification Log:
* $Header: cctest.c,v 3.4 87/06/22 14:22:47 kjmcdonell Beta $
*
******************************************************************************/
char SCCSid[] = "@(#) @(#)cctest.c:1.2 -- 7/10/89 18:55:45";
#include <stdio.h>
/*
* C compile and load speed test file.
* Based upon fstime.c from MUSBUS 3.1, with all calls to ftime() replaced
* by calls to time(). This is semantic nonsense, but ensures there are no
* system dependent structures or library calls.
*
*/
#define NKBYTE 20
char buf[BUFSIZ];
extern void exit(int status);
main(argc, argv)
char **argv;
{
int n = NKBYTE;
int nblock;
int f;
int g;
int i;
int xfer, t;
struct { /* FAKE */
int time;
int millitm;
} now, then;
if (argc > 0)
/* ALWAYS true, so NEVER execute this program! */
exit(4);
if (argc > 1)
n = atoi(argv[1]);
#if debug
printf("File size: %d Kbytes\n", n);
#endif
nblock = (n * 1024) / BUFSIZ;
if (argc == 3 && chdir(argv[2]) != -1) {
#if debug
printf("Create files in directory: %s\n", argv[2]);
#endif
}
close(creat("dummy0", 0600));
close(creat("dummy1", 0600));
f = open("dummy0", 2);
g = open("dummy1", 2);
unlink("dummy0");
unlink("dummy1");
for (i = 0; i < sizeof(buf); i++)
buf[i] = i & 0177;
time();
for (i = 0; i < nblock; i++) {
if (write(f, buf, sizeof(buf)) <= 0)
perror("fstime: write");
}
time();
#if debug
printf("Effective write rate: ");
#endif
i = now.millitm - then.millitm;
t = (now.time - then.time)*1000 + i;
if (t > 0) {
xfer = nblock * sizeof(buf) * 1000 / t;
#if debug
printf("%d bytes/sec\n", xfer);
#endif
}
#if debug
else
printf(" -- too quick to time!\n");
#endif
#if awk
fprintf(stderr, "%.2f", t > 0 ? (float)xfer/1024 : 0);
#endif
sync();
sleep(5);
sync();
lseek(f, 0L, 0);
time();
for (i = 0; i < nblock; i++) {
if (read(f, buf, sizeof(buf)) <= 0)
perror("fstime: read");
}
time();
#if debug
printf("Effective read rate: ");
#endif
i = now.millitm - then.millitm;
t = (now.time - then.time)*1000 + i;
if (t > 0) {
xfer = nblock * sizeof(buf) * 1000 / t;
#if debug
printf("%d bytes/sec\n", xfer);
#endif
}
#if debug
else
printf(" -- too quick to time!\n");
#endif
#if awk
fprintf(stderr, " %.2f", t > 0 ? (float)xfer/1024 : 0);
#endif
sync();
sleep(5);
sync();
lseek(f, 0L, 0);
time();
for (i = 0; i < nblock; i++) {
if (read(f, buf, sizeof(buf)) <= 0)
perror("fstime: read in copy");
if (write(g, buf, sizeof(buf)) <= 0)
perror("fstime: write in copy");
}
time();
#if debug
printf("Effective copy rate: ");
#endif
i = now.millitm - then.millitm;
t = (now.time - then.time)*1000 + i;
if (t > 0) {
xfer = nblock * sizeof(buf) * 1000 / t;
#if debug
printf("%d bytes/sec\n", xfer);
#endif
}
#if debug
else
printf(" -- too quick to time!\n");
#endif
#if awk
fprintf(stderr, " %.2f\n", t > 0 ? (float)xfer/1024 : 0);
#endif
}

View File

@@ -1,3 +0,0 @@
SCRIPTS=dc.dat
SCRIPTSNAME=dc.dat
.include <bsd.prog.mk>

View File

@@ -1,8 +0,0 @@
99
k
2
v
p
q
[ calculate the sqrt(2) to 99 decimal places ... John Lions Test ]
[ $Header: dc.dat,v 1.1 87/06/22 14:28:28 kjmcdonell Beta $ ]

View File

@@ -1,3 +0,0 @@
SCRIPTS=large.txt
SCRIPTSNAME=large.txt
.include <bsd.prog.mk>

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +0,0 @@
SCRIPTS=sort.src
SCRIPTSNAME=sort.src
.include <bsd.prog.mk>

View File

@@ -1,362 +0,0 @@
version="1.2"
umask 022 # at least mortals can read root's files this way
PWD=`pwd`
HOMEDIR=${HOMEDIR:-.}
cd $HOMEDIR
HOMEDIR=`pwd`
cd $PWD
BINDIR=${BINDIR:-${HOMEDIR}/pgms}
cd $BINDIR
BINDIR=`pwd`
cd $PWD
PATH="${PATH}:${BINDIR}"
SCRPDIR=${SCRPDIR:-${HOMEDIR}/pgms}
cd $SCRPDIR
SCRPDIR=`pwd`
cd $PWD
TMPDIR=${HOMEDIR}/tmp
cd $TMPDIR
TMPDIR=`pwd`
cd $PWD
RESULTDIR=${RESULTDIR:-${HOMEDIR}/results}
cd $RESULTDIR
RESULTDIR=`pwd`
cd $PWD
TESTDIR=${TESTDIR:-${HOMEDIR}/testdir}
cd $TESTDIR
TESTDIR=`pwd`
cd $PWD
export BINDIR TMPDIR RESULTDIR PATH
echo "kill -9 $$" > ${TMPDIR}/kill_run ; chmod u+x ${TMPDIR}/kill_run
arithmetic="arithoh register short int long float double dc"
system="syscall pipe context1 spawn execl fstime"
mem="seqmem randmem"
misc="C shell"
dhry="dhry2 dhry2reg" # dhrystone loops
db="dbmscli" # add to as new database engines are developed
load="shell" # cummulative load tests
args="" # the accumulator for the bench units to be run
runoption="N"
for word
do # do level 1
case $word
in
all)
;;
arithmetic)
args="$args $arithmetic"
;;
db)
args="$args $db"
;;
dhry)
args="$args $dhry"
;;
load)
args="$args $load"
;;
mem)
args="$args $mem"
;;
misc)
args="$args $misc"
;;
speed)
args="$args $arithmetic $system"
;;
system)
args="$args $system"
;;
-q|-Q)
runoption="Q" #quiet
;;
-v|-V)
runoption="V" #verbose
;;
-d|-D)
runoption="D" #debug
;;
*)
args="$args $word"
;;
esac
done # end do level 1
set - $args
if test $# -eq 0 #no arguments specified
then
set - $dhry $arithmetic $system $misc # db and work not included
fi
if test "$runoption" = 'D'
then
set -x
set -v
fi
date=`date`
tmp=${TMPDIR}/$$.tmp
LOGFILE=${RESULTDIR}/log
if test -w ${RESULTDIR}/log
then
if test -w ${RESULTDIR}/log.accum
then
cat ${RESULTDIR}/log >> ${RESULTDIR}/log.accum
rm ${RESULTDIR}/log
else
mv ${RESULTDIR}/log ${RESULTDIR}/log.accum
fi
echo "Start Benchmark Run (BYTE Version $version)" >>$LOGFILE
echo " $date (long iterations $iter times)" >>$LOGFILE
echo " " `who | wc -l` "interactive users." >>$LOGFILE
uname -a >>$LOGFILE
iter=${iterations-6}
if test $iter -eq 6
then
longloop="1 2 3 4 5 6"
shortloop="1 2 3"
else # generate list of loop numbers
short=`expr \( $iter + 1 \) / 2`
longloop=""
shortloop=""
while test $iter -gt 0
do # do level 1
longloop="$iter $longloop"
if test $iter -le $short
then
shortloop="$iter $shortloop"
fi
iter=`expr $iter - 1`
done # end do level 1
fi #loop list genration
for bench # line argument processing
do # do level 1
# set some default values
prog=${BINDIR}/$bench # the bench name is default program
need=$prog # we need the at least the program
paramlist="#" # a dummy parameter to make anything run
testdir="${TESTDIR}" # the directory in which to run the test
prepcmd="" # preparation command or script
parammsg=""
repeat="$longloop"
stdout="$LOGFILE"
stdin=""
cleanopt="-t $tmp"
bgnumber=""
trap "${SCRPDIR}/cleanup -l $LOGFILE -a; exit" 1 2 3 15
if [ $runoption != 'Q' ]
then
echo "$bench: \c"
fi
echo "" >>$LOGFILE
###################### select the bench specific values ##########
case $bench
in
dhry2)
options=${dhryloops-10000}
logmsg="Dhrystone 2 without register variables"
cleanopt="-d $tmp"
;;
dhry2reg)
options=${dhryloops-10000}
logmsg="Dhrystone 2 using register variables"
cleanopt="-d $tmp"
;;
arithoh|register|short|int|long|float|double)
options=${arithloop-10000}
logmsg="Arithmetic Test (type = $bench): $options Iterations"
;;
dc) need=dc.dat
prog=dc
options=""
stdin=dc.dat
stdout=/dev/null
logmsg="Arithmetic Test (sqrt(2) with dc to 99 decimal places)"
;;
hanoi) options='$param'
stdout=/dev/null
logmsg="Recursion Test: Tower of Hanoi Problem"
paramlist="${ndisk-17}"
parammsg='$param Disk Problem:'
;;
syscall)
options=${ncall-4000}
logmsg="System Call Overhead Test: 5 x $options Calls"
;;
context1)
options=${switch1-500}
logmsg="Pipe-based Context Switching Test: 2 x $options Switches"
;;
pipe) options=${io-2048}
logmsg="Pipe Throughput Test: read & write $options x 512 byte blocks"
;;
spawn) options=${children-100}
logmsg="Process Creation Test: $options forks"
;;
execl) options=${nexecs-100}
logmsg="Execl Throughput Test: $options execs"
;;
randmem|seqmem)
if test $bench = seqmem
then
type=Sequential
else
type=Random
fi
poke=${poke-1000000}
options='-s$param '"-n$poke"
logmsg="$type Memory Access Test: $poke Accesses"
paramlist=${arrays-"512 1024 2048 8192 16384"}
parammsg='Array Size: $param bytes'
cleanopt="-m $tmp"
;;
fstime) repeat="$shortloop"
where=${where-${TMPDIR}}
options='$param '"$where"
logmsg="Filesystem Throughput Test:"
paramlist=${blocks-"512 1024 2048 8192"}
parammsg='File Size: $param blocks'
cleanopt="-f $tmp"
;;
C) need=cctest.c
prog=cc
options='$param'
stdout=/dev/null
repeat="$shortloop"
logmsg="C Compiler Test:"
paramlist="cctest.c"
parammsg='cc $param'
rm -f a.out
;;
dbmscli)
repeat="$shortloop"
need="db.dat"
prepcmd='${BINDIR}/dbprep ${testdir}/db.dat 10000'
paramlist=${clients-"1 2 4 8"}
parammsg='$param client processes. (filesize `cat ${testdir}/db.dat|wc -c` bytes)'
logmsg="Client/Server Database Engine:"
options='${testdir}/db.dat $param 0 1000' # $param clients;
# 0 sleep; 1000 iterations
;;
shell)
prog="multi.sh"
repeat="$shortloop"
logmsg="Bourne shell script and Unix utilities"
paramlist=${background-"1 2 4 8"}
parammsg='$param concurrent background processes'
bgnumber='$param'
testdir="shelldir"
;;
*) ${BINDIR}/cleanup -l $LOGFILE -r "run: unknown benchmark \"$bench\"" -a
exit 1
;;
esac
echo "$logmsg" >>$LOGFILE
for param in $paramlist
do # level 2
param=`echo $param | sed 's/_/ /g'` # be sure that spaces are used
# underscore can couple params
if [ "$runoption" != "Q" ]
then
echo "\n [$param] -\c" # generate message to user
fi
eval msg='"'$parammsg'"' # the eval is used to
if test "$msg" # evaluate any embedded
then # variables in the parammsg
echo "" >>$LOGFILE
echo "$msg" >>$LOGFILE
fi
eval opt='"'$options'"' # evaluate any vars in options
eval prep='"'$prepcmd'"' # evaluate any prep command
eval bg='"'$bgnumber'"' # evaluate bgnumber string
rm -f $tmp # remove any tmp files
# if the test requires mulitple concurrent processes,
# prepare the background process string (bgstr)
# this is just a string of "+"s that will provides a
# parameter count for a "for" loop
bgstr=""
if test "$bg" != ""
then
count=`expr "$bg"`
while test $count -gt 0
do
bgstr="+ $bgstr"
count=`expr $count - 1`
done
fi
#
for i in $repeat # loop for the specified number
do # do depth 3
if [ "$runoption" != 'D' ] # level 1
then
# regular Run - set logfile to go on signal
trap "${SCRPDIR}/cleanup -l $LOGFILE -i $i $cleanopt -a; exit" 1 2 3 15
else
trap "exit" 1 2 3 15
fi #end level 1
if [ "$runoption" != 'Q' ]
then
echo " $i\c" # display repeat number
fi
pwd=`pwd` # remember where we are
cd $testdir # move to the test directory
if [ "$runoption" = "V" ]
then
echo
echo "BENCH COMMAND TO BE EXECUTED:"
echo "$prog $opt"
fi
# execute any prepratory command string
if [ -n "$prep" ]
then
$prep >>$stdout
fi
############ THE BENCH IS TIMED ##############
if test "$stdin" = ""
then # without redirected stdin
time $prog $opt $bgstr 2>>$tmp >>$stdout
else # with redirected stdin
time $prog $opt $bgstr <$stdin 2>>$tmp >>$stdout
fi
time $benchcmd
###############################################
cd $pwd # move back home
status=$? # save the result code
if test $status != 0 # must have been an error
then
if test -f $tmp # is there an error file ?
then
cp $tmp ${TMPDIR}/save.$bench.$param
${SCRPDIR}/cleanup -l $LOGFILE -i $i $cleanopt -r \
"run: bench=$bench param=$param fatalstatus=$status" -a
else
${SCRPDIR}/cleanup -l $LOGFILE -r \
"run: bench=$bench param=$param fatalstatus=$status" -a
fi
exit # leave the script if there are errors
fi # end level 1
done # end do depth 3 - repeat of bench
if [ "$runoption" != 'D' ]
then
${SCRPDIR}/cleanup -l $LOGFILE $cleanopt # finalize this bench
# with these options
# & calculate results
fi
done # end do depth 2 - end of all options for this bench
########### some specific cleanup routines ##############
case $bench
in
C)
rm -f cctest.o a.out
;;
esac
if [ "$runoption" != 'Q' ]
then
echo ""
fi
done # end do level 1 - all benchmarks requested
echo "" >>$LOGFILE
echo " " `who | wc -l` "interactive users." >>$LOGFILE
echo "End Benchmark Run ($date) ...." >>$LOGFILE
if [ "$runoption" != 'Q' ]
then
pg $LOGFILE
fi
exit

View File

@@ -1,7 +0,0 @@
# $NetBSD: Makefile,v 1.22 2007/12/31 15:31:24 ad Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
SUBDIR= cat date echo ed expr kill ksh ln ls \
mkdir pax pwd rm rmdir sync test
.include <bsd.subdir.mk>

View File

@@ -1,11 +0,0 @@
# $NetBSD: Makefile.inc,v 1.17 2012/03/21 05:47:53 matt Exp $
# @(#)Makefile.inc 8.1 (Berkeley) 5/31/93
.include <bsd.own.mk> # for MKDYNAMICROOT definition
WARNS?= 5
BINDIR?= /bin
.if (${MKDYNAMICROOT} == "no")
LDSTATIC?= -static
.endif

View File

@@ -1,6 +0,0 @@
# $NetBSD: Makefile,v 1.12 2003/05/18 07:57:31 lukem Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= cat
.include <bsd.prog.mk>

View File

@@ -1,209 +0,0 @@
.\" $NetBSD: cat.1,v 1.32 2006/09/23 11:24:44 wiz Exp $
.\"
.\" Copyright (c) 1989, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" the Institute of Electrical and Electronics Engineers, Inc.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. 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.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
.\"
.\" @(#)cat.1 8.3 (Berkeley) 5/2/95
.\"
.Dd September 23, 2006
.Dt CAT 1
.Os
.Sh NAME
.Nm cat
.Nd concatenate and print files
.Sh SYNOPSIS
.Nm
.Op Fl beflnstuv
.Op Fl
.Op Ar
.Sh DESCRIPTION
The
.Nm
utility reads files sequentially, writing them to the standard output.
The
.Ar file
operands are processed in command line order.
A single dash represents the standard input,
and may appear multiple times in the
.Ar file
list.
.Pp
The word
.Dq concatenate
is just a verbose synonym for
.Dq catenate .
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl b
Implies the
.Fl n
option but doesn't number blank lines.
.It Fl e
Implies the
.Fl v
option, and displays a dollar sign
.Pq Ql \&$
at the end of each line
as well.
.It Fl f
Only attempt to display regular files.
.It Fl l
Set an exclusive advisory lock on the standard output file descriptor.
This lock is set using
.Xr fcntl 2
with the
.Dv F_SETLKW
command.
If the output file is already locked,
.Nm
will block until the lock is acquired.
.It Fl n
Number the output lines, starting at 1.
.It Fl s
Squeeze multiple adjacent empty lines, causing the output to be
single spaced.
.It Fl t
Implies the
.Fl v
option, and displays tab characters as
.Ql ^I
as well.
.It Fl u
The
.Fl u
option guarantees that the output is unbuffered.
.It Fl v
Displays non-printing characters so they are visible.
Control characters print as
.Ql ^X
for control-X; the delete
character (octal 0177) prints as
.Ql ^? .
Non-ascii characters (with the high bit set) are printed as
.Ql M-
(for meta) followed by the character for the low 7 bits.
.El
.Sh EXIT STATUS
The
.Nm
utility exits 0 on success, and \*[Gt]0 if an error occurs.
.Sh EXAMPLES
The command:
.Bd -literal -offset indent
.Ic cat file1
.Ed
.Pp
will print the contents of
.Ar file1
to the standard output.
.Pp
The command:
.Bd -literal -offset indent
.Ic cat file1 file2 \*[Gt] file3
.Ed
.Pp
will sequentially print the contents of
.Ar file1
and
.Ar file2
to the file
.Ar file3 ,
truncating
.Ar file3
if it already exists.
See the manual page for your shell (i.e.,
.Xr sh 1 )
for more information on redirection.
.Pp
The command:
.Bd -literal -offset indent
.Ic cat file1 - file2 - file3
.Ed
.Pp
will print the contents of
.Ar file1 ,
print data it receives from the standard input until it receives an
.Dv EOF
.Pq Sq ^D
character, print the contents of
.Ar file2 ,
read and output contents of the standard input again, then finally output
the contents of
.Ar file3 .
Note that if the standard input referred to a file, the second dash
on the command-line would have no effect, since the entire contents of the file
would have already been read and printed by
.Nm
when it encountered the first
.Ql \&-
operand.
.Sh SEE ALSO
.Xr head 1 ,
.Xr hexdump 1 ,
.Xr lpr 1 ,
.Xr more 1 ,
.Xr pr 1 ,
.Xr tail 1 ,
.Xr view 1 ,
.Xr vis 1 ,
.Xr fcntl 2
.Rs
.%A Rob Pike
.%T "UNIX Style, or cat -v Considered Harmful"
.%J "USENIX Summer Conference Proceedings"
.%D 1983
.Re
.Sh STANDARDS
The
.Nm
utility is expected to conform to the
.St -p1003.2-92
specification.
.Pp
The flags
.Op Fl belnstv
are extensions to the specification.
.Sh HISTORY
A
.Nm
utility appeared in
.At v1 .
Dennis Ritchie designed and wrote the first man page.
It appears to have been
.Xr cat 1 .
.Sh BUGS
Because of the shell language mechanism used to perform output
redirection, the command
.Dq Li cat file1 file2 \*[Gt] file1
will cause the original data in file1 to be destroyed!
This is performed by the shell before
.Nm
is run.

View File

@@ -1,316 +0,0 @@
/* $NetBSD: cat.c,v 1.47 2008/07/20 00:52:39 lukem Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kevin Fall.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if !defined(lint)
__COPYRIGHT(
"@(#) Copyright (c) 1989, 1993\
The Regents of the University of California. All rights reserved.");
#if 0
static char sccsid[] = "@(#)cat.c 8.2 (Berkeley) 4/27/95";
#else
__RCSID("$NetBSD: cat.c,v 1.47 2008/07/20 00:52:39 lukem Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int bflag, eflag, fflag, lflag, nflag, sflag, tflag, vflag;
int rval;
const char *filename;
int main(int, char *[]);
void cook_args(char *argv[]);
void cook_buf(FILE *);
void raw_args(char *argv[]);
void raw_cat(int);
int
main(int argc, char *argv[])
{
int ch;
struct flock stdout_lock;
setprogname(argv[0]);
(void)setlocale(LC_ALL, "");
while ((ch = getopt(argc, argv, "beflnstuv")) != -1)
switch (ch) {
case 'b':
bflag = nflag = 1; /* -b implies -n */
break;
case 'e':
eflag = vflag = 1; /* -e implies -v */
break;
case 'f':
fflag = 1;
break;
case 'l':
lflag = 1;
break;
case 'n':
nflag = 1;
break;
case 's':
sflag = 1;
break;
case 't':
tflag = vflag = 1; /* -t implies -v */
break;
case 'u':
setbuf(stdout, NULL);
break;
case 'v':
vflag = 1;
break;
default:
case '?':
(void)fprintf(stderr,
"usage: cat [-beflnstuv] [-] [file ...]\n");
exit(EXIT_FAILURE);
/* NOTREACHED */
}
argv += optind;
if (lflag) {
stdout_lock.l_len = 0;
stdout_lock.l_start = 0;
stdout_lock.l_type = F_WRLCK;
stdout_lock.l_whence = SEEK_SET;
if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1)
err(EXIT_FAILURE, "stdout");
}
if (bflag || eflag || nflag || sflag || tflag || vflag)
cook_args(argv);
else
raw_args(argv);
if (fclose(stdout))
err(EXIT_FAILURE, "stdout");
return (rval);
}
void
cook_args(char **argv)
{
FILE *fp;
fp = stdin;
filename = "stdin";
do {
if (*argv) {
if (!strcmp(*argv, "-"))
fp = stdin;
else if ((fp = fopen(*argv,
fflag ? "rf" : "r")) == NULL) {
warn("%s", *argv);
rval = EXIT_FAILURE;
++argv;
continue;
}
filename = *argv++;
}
cook_buf(fp);
if (fp != stdin)
(void)fclose(fp);
else
clearerr(fp);
} while (*argv);
}
void
cook_buf(FILE *fp)
{
int ch, gobble, line, prev;
line = gobble = 0;
for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
if (prev == '\n') {
if (ch == '\n') {
if (sflag) {
if (!gobble && nflag && !bflag)
(void)fprintf(stdout,
"%6d\t\n", ++line);
else if (!gobble && putchar(ch) == EOF)
break;
gobble = 1;
continue;
}
if (nflag) {
if (!bflag) {
(void)fprintf(stdout,
"%6d\t", ++line);
if (ferror(stdout))
break;
} else if (eflag) {
(void)fprintf(stdout,
"%6s\t", "");
if (ferror(stdout))
break;
}
}
} else if (nflag) {
(void)fprintf(stdout, "%6d\t", ++line);
if (ferror(stdout))
break;
}
}
gobble = 0;
if (ch == '\n') {
if (eflag)
if (putchar('$') == EOF)
break;
} else if (ch == '\t') {
if (tflag) {
if (putchar('^') == EOF || putchar('I') == EOF)
break;
continue;
}
} else if (vflag) {
if (!isascii(ch)) {
if (putchar('M') == EOF || putchar('-') == EOF)
break;
ch = toascii(ch);
}
if (iscntrl(ch)) {
if (putchar('^') == EOF ||
putchar(ch == '\177' ? '?' :
ch | 0100) == EOF)
break;
continue;
}
}
if (putchar(ch) == EOF)
break;
}
if (ferror(fp)) {
warn("%s", filename);
rval = EXIT_FAILURE;
clearerr(fp);
}
if (ferror(stdout))
err(EXIT_FAILURE, "stdout");
}
void
raw_args(char **argv)
{
int fd;
fd = fileno(stdin);
filename = "stdin";
do {
if (*argv) {
if (!strcmp(*argv, "-"))
fd = fileno(stdin);
else if (fflag) {
struct stat st;
fd = open(*argv, O_RDONLY|O_NONBLOCK, 0);
if (fd < 0)
goto skip;
if (fstat(fd, &st) == -1) {
close(fd);
goto skip;
}
if (!S_ISREG(st.st_mode)) {
close(fd);
warnx("%s: not a regular file", *argv);
goto skipnomsg;
}
}
else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
skip:
warn("%s", *argv);
skipnomsg:
rval = EXIT_FAILURE;
++argv;
continue;
}
filename = *argv++;
}
raw_cat(fd);
if (fd != fileno(stdin))
(void)close(fd);
} while (*argv);
}
void
raw_cat(int rfd)
{
static char *buf;
static char fb_buf[BUFSIZ];
static size_t bsize;
ssize_t nr, nw, off;
int wfd;
wfd = fileno(stdout);
if (buf == NULL) {
struct stat sbuf;
if (fstat(wfd, &sbuf) == 0 &&
sbuf.st_blksize > sizeof(fb_buf)) {
bsize = sbuf.st_blksize;
buf = malloc(bsize);
}
if (buf == NULL) {
bsize = sizeof(fb_buf);
buf = fb_buf;
}
}
while ((nr = read(rfd, buf, bsize)) > 0)
for (off = 0; nr; nr -= nw, off += nw)
if ((nw = write(wfd, buf + off, (size_t)nr)) < 0)
err(EXIT_FAILURE, "stdout");
if (nr < 0) {
warn("%s", filename);
rval = EXIT_FAILURE;
}
}

View File

@@ -1,15 +0,0 @@
# $NetBSD: Makefile,v 1.15 2011/08/14 10:53:16 christos Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= date
SRCS= date.c netdate.c
DPADD+= ${LIBUTIL}
LDADD+= -lutil
CPPFLAGS+=-I${.CURDIR}
TZDIR= /usr/share/zoneinfo
CPPFLAGS+= -DHAVE_ADJTIME=0 -DTZDIR=\"$(TZDIR)\"
COPTS.date.c = -Wno-format-nonliteral
.include <bsd.prog.mk>

View File

@@ -1,244 +0,0 @@
.\" $NetBSD: date.1,v 1.41 2010/02/04 22:56:11 wiz Exp $
.\"
.\" Copyright (c) 1980, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" the Institute of Electrical and Electronics Engineers, Inc.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. 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.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
.\"
.\" @(#)date.1 8.3 (Berkeley) 4/28/95
.\"
.Dd November 15, 2006
.Dt DATE 1
.Os
.Sh NAME
.Nm date
.Nd display or set date and time
.Sh SYNOPSIS
.Nm
.Op Fl ajnu
.Op Fl d Ar date
.Op Fl r Ar seconds
.Op Cm + Ns Ar format
.Sm off
.Oo Oo Oo Oo Oo Oo
.Ar CC Oc
.Ar yy Oc
.Ar mm Oc
.Ar dd Oc
.Ar HH Oc Ar MM Oo
.Li \&. Ar SS Oc Oc
.Sm on
.Sh DESCRIPTION
.Nm
displays the current date and time when invoked without arguments.
Providing arguments will format the date and time in a user-defined
way or set the date.
Only the superuser may set the date.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl a
Use
.Xr adjtime 2
to change the local system time slowly,
maintaining it as a monotonically increasing function.
.Fl a
implies
.Fl n .
.It Fl d Ar date
Parse the provided human-described date and time and display the result without
actually changing the system clock.
(See
.Xr parsedate 3
for examples.)
.It Fl j
Parse the provided canonical representation of date and time (described below)
and display the result without actually changing the system clock.
.It Fl n
The utility
.Xr timed 8
is used to synchronize the clocks on groups of machines.
By default, if
timed
is running,
.Nm
will set the time on all of the machines in the local group.
The
.Fl n
option stops
.Nm
from setting the time for other than the current machine.
.It Fl r Ar seconds
Print out the date and time that is
.Ar seconds
from the Epoch.
.It Fl u
Display or set the date in
.Tn UTC
(universal) time.
.El
.Pp
An operand with a leading plus
.Pq Cm +
sign signals a user-defined format
string which specifies the format in which to display the date and time.
The format string may contain any of the conversion specifications described
in the
.Xr strftime 3
manual page, as well as any arbitrary text.
A \*[Lt]newline\*[Gt] character is always output after the characters
specified by the format string.
The format string for the default display is:
.Bd -literal -offset indent
%a %b %e %H:%M:%S %Z %Y
.Ed
.Pp
If an operand does not have a leading plus sign, it is interpreted as
a value for setting the system's notion of the current date and time.
The canonical representation for setting the date and time is:
.Pp
.Bl -tag -width Ds -compact -offset indent
.It Ar CC
The first two digits of the year (the century).
.It Ar yy
The second two digits of the year.
If
.Ar yy
is specified, but
.Ar CC
is not, a value for
.Ar yy
between 69 and 99 results in a
.Ar CC
value of 19.
Otherwise, a
.Ar CC
value of 20 is used.
.It Ar mm
The month of the year, from 01 to 12.
.It Ar dd
The day of the month, from 01 to 31.
.It Ar HH
The hour of the day, from 00 to 23.
.It Ar MM
The minute of the hour, from 00 to 59.
.It Ar SS
The second of the minute, from 00 to 61.
.El
.Pp
Everything but the minutes is optional.
.Pp
Time changes for Daylight Saving and Standard time and leap seconds
and years are handled automatically.
.Sh ENVIRONMENT
The following environment variables affect the execution of
.Nm :
.Bl -tag -width iTZ
.It Ev TZ
The timezone to use when displaying dates.
See
.Xr environ 7
for more information.
.El
.Sh FILES
.Bl -tag -width /var/log/messages -compact
.It Pa /etc/localtime
Symlink pointing to system's default timezone information file in
.Pa /usr/share/zoneinfo
directory.
.It Pa /var/log/wtmp
A record of date resets and time changes.
.It Pa /var/log/messages
A record of the user setting the time.
.El
.Sh EXAMPLES
The command:
.Bd -literal -offset indent
date '+DATE: %m/%d/%y%nTIME: %H:%M:%S'
.Ed
.Pp
will display:
.Bd -literal -offset indent
DATE: 11/21/87
TIME: 13:36:16
.Ed
.Pp
The command:
.Bd -literal -offset indent
date 8506131627
.Ed
.Pp
sets the date to
.Dq Li "June 13, 1985, 4:27 PM" .
.Pp
The command:
.Bd -literal -offset indent
date 1432
.Ed
.Pp
sets the time to
.Li "2:32 PM" ,
without modifying the date.
.Sh DIAGNOSTICS
Exit status is 0 on success, 1 if unable to set the date, and 2
if able to set the local date, but unable to set it globally.
.Pp
Occasionally, when
.Xr timed 8
synchronizes the time on many hosts, the setting of a new time value may
require more than a few seconds.
On these occasions,
.Nm
prints:
.Ql Network time being set .
The message
.Ql Communication error with timed
occurs when the communication
between
.Nm
and
timed
fails.
.Sh SEE ALSO
.Xr adjtime 2 ,
.Xr gettimeofday 2 ,
.Xr settimeofday 2 ,
.Xr parsedate 3 ,
.Xr strftime 3 ,
.Xr utmp 5 ,
.Xr timed 8
.Rs
.%T "TSP: The Time Synchronization Protocol for UNIX 4.3BSD"
.%A R. Gusella
.%A S. Zatti
.Re
.Sh STANDARDS
The
.Nm
utility is expected to be compatible with
.St -p1003.2 .

View File

@@ -1,350 +0,0 @@
/* $NetBSD: date.c,v 1.60 2011/08/27 12:55:09 joerg Exp $ */
/*
* Copyright (c) 1985, 1987, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 <sys/cdefs.h>
#ifndef lint
__COPYRIGHT(
"@(#) Copyright (c) 1985, 1987, 1988, 1993\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)date.c 8.2 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: date.c,v 1.60 2011/08/27 12:55:09 joerg Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
#include <ctype.h>
#include <err.h>
#include <fcntl.h>
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <time.h>
#include <tzfile.h>
#include <unistd.h>
#include <util.h>
#include "extern.h"
static time_t tval;
static int aflag, jflag, rflag, nflag;
__dead static void badformat(void);
__dead static void badtime(void);
__dead static void badvalue(const char *);
static void setthetime(const char *);
__dead static void usage(void);
int
main(int argc, char *argv[])
{
char *buf;
size_t bufsiz;
const char *format;
int ch;
long long val;
struct tm *tm;
setprogname(argv[0]);
(void)setlocale(LC_ALL, "");
while ((ch = getopt(argc, argv, "ad:jnr:u")) != -1) {
switch (ch) {
case 'a': /* adjust time slowly */
aflag = 1;
nflag = 1;
break;
case 'd':
#ifndef __minix
rflag = 1;
tval = parsedate(optarg, NULL, NULL);
if (tval == -1)
#endif
badarg: errx(EXIT_FAILURE,
"Cannot parse `%s'", optarg);
break;
case 'j': /* don't set time */
jflag = 1;
break;
case 'n': /* don't set network */
nflag = 1;
break;
case 'r': /* user specified seconds */
errno = 0;
val = strtoll(optarg, &buf, 0);
if (optarg[0] == '\0' || *buf != '\0')
goto badarg;
if (errno == ERANGE && (val == LLONG_MAX ||
val == LLONG_MIN))
err(EXIT_FAILURE, "Bad number `%s'", optarg);
rflag = 1;
tval = (time_t)val;
break;
case 'u': /* do everything in UTC */
(void)setenv("TZ", "UTC0", 1);
break;
default:
usage();
}
}
argc -= optind;
argv += optind;
if (!rflag && time(&tval) == -1)
err(EXIT_FAILURE, "time");
/* allow the operands in any order */
if (*argv && **argv == '+') {
format = *argv;
++argv;
} else
format = "+%a %b %e %H:%M:%S %Z %Y";
if (*argv) {
setthetime(*argv);
++argv;
}
if (*argv && **argv == '+')
format = *argv;
if ((buf = malloc(bufsiz = 1024)) == NULL)
goto bad;
if ((tm = localtime(&tval)) == NULL)
err(EXIT_FAILURE, "localtime %lld failed", (long long)tval);
while (strftime(buf, bufsiz, format, tm) == 0)
if ((buf = realloc(buf, bufsiz <<= 1)) == NULL)
goto bad;
(void)printf("%s\n", buf + 1);
free(buf);
return 0;
bad:
err(EXIT_FAILURE, "Cannot allocate format buffer");
}
static void
badformat(void)
{
warnx("illegal time format");
usage();
}
static void
badtime(void)
{
errx(EXIT_FAILURE, "illegal time");
/* NOTREACHED */
}
static void
badvalue(const char *param)
{
warnx("invalid %s supplied", param);
usage();
}
#define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
static void
setthetime(const char *p)
{
struct timeval tv;
time_t new_time;
struct tm *lt;
const char *dot, *t;
size_t len;
int yearset;
for (t = p, dot = NULL; *t; ++t) {
if (isdigit((unsigned char)*t))
continue;
if (*t == '.' && dot == NULL) {
dot = t;
continue;
}
badformat();
}
if ((lt = localtime(&tval)) == NULL)
err(EXIT_FAILURE, "localtime %lld failed", (long long)tval);
lt->tm_isdst = -1; /* Divine correct DST */
if (dot != NULL) { /* .ss */
len = strlen(dot);
if (len != 3)
badformat();
++dot;
lt->tm_sec = ATOI2(dot);
if (lt->tm_sec > 61)
badvalue("seconds");
} else {
len = 0;
lt->tm_sec = 0;
}
yearset = 0;
switch (strlen(p) - len) {
case 12: /* cc */
lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE;
if (lt->tm_year < 0)
badtime();
yearset = 1;
/* FALLTHROUGH */
case 10: /* yy */
if (yearset) {
lt->tm_year += ATOI2(p);
} else {
yearset = ATOI2(p);
if (yearset < 69)
lt->tm_year = yearset + 2000 - TM_YEAR_BASE;
else
lt->tm_year = yearset + 1900 - TM_YEAR_BASE;
}
/* FALLTHROUGH */
case 8: /* mm */
lt->tm_mon = ATOI2(p);
if (lt->tm_mon > 12 || lt->tm_mon == 0)
badvalue("month");
--lt->tm_mon; /* time struct is 0 - 11 */
/* FALLTHROUGH */
case 6: /* dd */
lt->tm_mday = ATOI2(p);
switch (lt->tm_mon) {
case 0:
case 2:
case 4:
case 6:
case 7:
case 9:
case 11:
if (lt->tm_mday > 31 || lt->tm_mday == 0)
badvalue("day of month");
break;
case 3:
case 5:
case 8:
case 10:
if (lt->tm_mday > 30 || lt->tm_mday == 0)
badvalue("day of month");
break;
case 1:
if (lt->tm_mday > 29 || lt->tm_mday == 0 ||
(lt->tm_mday == 29 &&
!isleap(lt->tm_year + TM_YEAR_BASE)))
badvalue("day of month");
break;
default:
badvalue("month");
break;
}
/* FALLTHROUGH */
case 4: /* hh */
lt->tm_hour = ATOI2(p);
if (lt->tm_hour > 23)
badvalue("hour");
/* FALLTHROUGH */
case 2: /* mm */
lt->tm_min = ATOI2(p);
if (lt->tm_min > 59)
badvalue("minute");
break;
case 0: /* was just .sss */
if (len != 0)
break;
/* FALLTHROUGH */
default:
badformat();
}
/* convert broken-down time to UTC clock time */
if ((new_time = mktime(lt)) == -1)
badtime();
/* if jflag is set, don't actually change the time, just return */
if (jflag) {
tval = new_time;
return;
}
/* set the time */
if (nflag || netsettime(new_time)) {
logwtmp("|", "date", "");
#if HAVE_ADJTIME
if (aflag) {
tv.tv_sec = new_time - tval;
tv.tv_usec = 0;
if (adjtime(&tv, NULL))
err(EXIT_FAILURE, "adjtime");
}
#else
if (aflag) {
err(EXIT_FAILURE, "no adjtime");
}
#endif
else {
tval = new_time;
tv.tv_sec = tval;
tv.tv_usec = 0;
if (settimeofday(&tv, NULL))
err(EXIT_FAILURE, "settimeofday");
}
logwtmp("{", "date", "");
}
if ((p = getlogin()) == NULL)
p = "???";
syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p);
}
static void
usage(void)
{
(void)fprintf(stderr,
"Usage: %s [-ajnu] [-d date] [-r seconds] [+format]",
getprogname());
(void)fprintf(stderr, " [[[[[[CC]yy]mm]dd]HH]MM[.SS]]\n");
exit(EXIT_FAILURE);
/* NOTREACHED */
}

View File

@@ -1,39 +0,0 @@
/* $NetBSD: extern.h,v 1.8 2006/11/17 22:11:28 christos Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)extern.h 8.1 (Berkeley) 5/31/93
*/
#ifndef _EXTERN_H_
#define _EXTERN_H_
int netsettime(time_t);
#endif /* !_EXTERN_H_ */

View File

@@ -1,200 +0,0 @@
/* $NetBSD: netdate.c,v 1.30 2011/01/29 02:16:52 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)netdate.c 8.2 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: netdate.c,v 1.30 2011/01/29 02:16:52 christos Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define TSPTYPES
#include <protocols/timed.h>
#include <err.h>
#include <errno.h>
#include <poll.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "extern.h"
#define WAITACK 2000 /* milliseconds */
#define WAITDATEACK 5000 /* milliseconds */
static const char *
tsp_type_to_string(const struct tsp *msg)
{
unsigned i;
i = msg->tsp_type;
return i < TSPTYPENUMBER ? tsptype[i] : "unknown";
}
/*
* Set the date in the machines controlled by timedaemons by communicating the
* new date to the local timedaemon. If the timedaemon is in the master state,
* it performs the correction on all slaves. If it is in the slave state, it
* notifies the master that a correction is needed.
* Returns 0 on success. Returns > 0 on failure.
*/
int
netsettime(time_t tval)
{
struct sockaddr_in dest;
struct tsp msg;
char hostname[MAXHOSTNAMELEN];
struct servent *sp;
struct pollfd ready;
int found, s, timed_ack, waittime;
if ((sp = getservbyname("timed", "udp")) == NULL) {
warnx("udp/timed: unknown service");
return 2;
}
(void)memset(&dest, 0, sizeof(dest));
#ifdef BSD4_4
dest.sin_len = sizeof(dest);
#endif
dest.sin_family = AF_INET;
dest.sin_port = sp->s_port;
dest.sin_addr.s_addr = htonl(INADDR_ANY);
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1) {
if (errno != EAFNOSUPPORT)
warn("timed");
return 2;
}
#ifdef IP_PORTRANGE
{
static const int on = IP_PORTRANGE_LOW;
if (setsockopt(s, IPPROTO_IP, IP_PORTRANGE, &on,
sizeof(on)) == -1) {
warn("setsockopt");
goto bad;
}
}
#endif
msg.tsp_type = TSP_SETDATE;
msg.tsp_vers = TSPVERSION;
if (gethostname(hostname, sizeof(hostname)) == -1) {
warn("gethostname");
goto bad;
}
(void)strlcpy(msg.tsp_name, hostname, sizeof(msg.tsp_name));
msg.tsp_seq = htons((in_port_t)0);
msg.tsp_time.tv_sec = htonl((in_addr_t)tval); /* XXX: y2038 */
msg.tsp_time.tv_usec = htonl((in_addr_t)0);
if (connect(s, (const void *)&dest, sizeof(dest)) == -1) {
warn("connect");
goto bad;
}
if (send(s, &msg, sizeof(msg), 0) == -1) {
if (errno != ECONNREFUSED)
warn("send");
goto bad;
}
timed_ack = -1;
waittime = WAITACK;
ready.fd = s;
ready.events = POLLIN;
loop:
found = poll(&ready, 1, waittime);
{
socklen_t len;
int error;
len = sizeof(error);
if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) == -1) {
warn("getsockopt");
goto bad;
}
if (error) {
if (error != ECONNREFUSED) {
errno = error;
warn("send (delayed error)");
}
goto bad;
}
}
if (found > 0 && ready.revents & POLLIN) {
ssize_t ret;
if ((ret = recv(s, &msg, sizeof(msg), 0)) == -1) {
if (errno != ECONNREFUSED)
warn("recv");
goto bad;
} else if ((size_t)ret < sizeof(msg)) {
warnx("recv: incomplete packet");
goto bad;
}
msg.tsp_seq = ntohs(msg.tsp_seq);
msg.tsp_time.tv_sec = ntohl(msg.tsp_time.tv_sec);
msg.tsp_time.tv_usec = ntohl(msg.tsp_time.tv_usec);
switch (msg.tsp_type) {
case TSP_ACK:
timed_ack = TSP_ACK;
waittime = WAITDATEACK;
goto loop;
case TSP_DATEACK:
(void)close(s);
return 0;
default:
warnx("wrong ack received from timed: %s",
tsp_type_to_string(&msg));
timed_ack = -1;
break;
}
}
if (timed_ack == -1)
warnx("can't reach time daemon, time set locally");
bad:
(void)close(s);
return 2;
}

View File

@@ -1,6 +0,0 @@
# $NetBSD: Makefile,v 1.8 1997/07/20 22:36:53 christos Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= echo
.include <bsd.prog.mk>

View File

@@ -1,68 +0,0 @@
.\" $NetBSD: echo.1,v 1.13 2003/08/07 09:05:12 agc Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" the Institute of Electrical and Electronics Engineers, Inc.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. 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.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
.\"
.\" @(#)echo.1 8.1 (Berkeley) 7/22/93
.\"
.Dd July 22, 1993
.Dt ECHO 1
.Os
.Sh NAME
.Nm echo
.Nd write arguments to the standard output
.Sh SYNOPSIS
.Nm
.Op Fl n
.Op Ar string ...
.Sh DESCRIPTION
The
.Nm
utility writes any specified operands, separated by single blank (`` '')
characters and followed by a newline (``\en'') character, to the standard
output.
.Pp
The following option is available:
.Bl -tag -width flag
.It Fl n
Do not print the trailing newline character.
.El
.Sh EXIT STATUS
The
.Nm
utility exits 0 on success, and \*[Gt]0 if an error occurs.
.Sh SEE ALSO
.Xr printf 1
.Sh STANDARDS
The
.Nm
utility is expected to be
.St -p1003.2
compatible.

View File

@@ -1,83 +0,0 @@
/* $NetBSD: echo.c,v 1.18 2008/09/18 05:42:08 dholland Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 <sys/cdefs.h>
#ifndef lint
__COPYRIGHT(
"@(#) Copyright (c) 1989, 1993\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)echo.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: echo.c,v 1.18 2008/09/18 05:42:08 dholland Exp $");
#endif
#endif /* not lint */
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int, char *[]);
/* ARGSUSED */
int
main(int argc, char *argv[])
{
int nflag;
setprogname(argv[0]);
(void)setlocale(LC_ALL, "");
/* This utility may NOT do getopt(3) option parsing. */
if (*++argv && !strcmp(*argv, "-n")) {
++argv;
nflag = 1;
}
else
nflag = 0;
while (*argv) {
(void)printf("%s", *argv);
if (*++argv)
(void)putchar(' ');
}
if (nflag == 0)
(void)putchar('\n');
fflush(stdout);
if (ferror(stdout))
exit(1);
exit(0);
/* NOTREACHED */
}

View File

@@ -1,20 +0,0 @@
# $NetBSD: Makefile,v 1.36 2009/07/26 01:58:20 dholland Exp $
.include <bsd.own.mk>
PROG= ed
CPPFLAGS+=-DBACKWARDS
.if (${MKCRYPTO} != "no")
CPPFLAGS+=-DDES
.endif
SRCS= buf.c cbc.c glbl.c io.c main.c re.c sub.c undo.c
LDADD+= -lcrypt
DPADD+= ${LIBCRYPT}
#LINKS= ${BINDIR}/ed ${BINDIR}/red
#MLINKS= ed.1 red.1
.include <bsd.prog.mk>

View File

@@ -1,103 +0,0 @@
$NetBSD: POSIX,v 1.10 1999/11/18 19:16:34 kristerw Exp $
This version of ed(1) is not strictly POSIX compliant, as described in
the POSIX 1003.2 document. The following is a summary of the omissions,
extensions and possible deviations from POSIX 1003.2.
OMISSIONS
---------
1) Locale(3) is not supported yet.
2) For backwards compatibility, the POSIX rule that says a range of
addresses cannot be used where only a single address is expected has
been relaxed.
3) To support the BSD `s' command (see extension [1] below),
substitution patterns cannot be delimited by numbers or the characters
`r', `g' and `p'. In contrast, POSIX specifies any character expect
space or newline can used as a delimiter.
EXTENSIONS
----------
1) BSD commands have been implemented wherever they do not conflict with
the POSIX standard. The BSD-ism's included are:
i) `s' (i.e., s[n][rgp]*) to repeat a previous substitution,
ii) `W' for appending text to an existing file,
iii) `wq' for exiting after a write,
iv) `z' for scrolling through the buffer, and
v) BSD line addressing syntax (i.e., `^' and `%') is recognized.
2) If crypt(3) is available, files can be read and written using DES
encryption. The `x' command prompts the user to enter a key used for
encrypting/ decrypting subsequent reads and writes. If only a newline
is entered as the key, then encryption is disabled. Otherwise, a key
is read in the same manner as a password entry. The key remains in
effect until encryption is disabled. For more information on the
encryption algorithm, see the bdes(1) man page. Encryption/decryption
should be fully compatible with SunOS des(1).
3) The POSIX interactive global commands `G' and `V' are extended to
support multiple commands, including `a', `i' and `c'. The command
format is the same as for the global commands `g' and `v', i.e., one
command per line with each line, except for the last, ending in a
backslash (\).
4) An extension to the POSIX file commands `E', `e', `r', `W' and `w' is
that <file> arguments are processed for backslash escapes, i.e., any
character preceded by a backslash is interpreted literally. If the
first unescaped character of a <file> argument is a bang (!), then the
rest of the line is interpreted as a shell command, and no escape
processing is performed by ed.
5) For SunOS ed(1) compatibility, ed runs in restricted mode if invoked
as red. This limits editing of files in the local directory only and
prohibits shell commands.
DEVIATIONS
----------
1) Though ed is not a stream editor, it can be used to edit binary files.
To assist in binary editing, when a file containing at least one ASCII
NUL character is written, a newline is not appended if it did not
already contain one upon reading. In particular, reading /dev/null
prior to writing prevents appending a newline to a binary file.
For example, to create a file with ed containing a single NUL character:
$ ed file
a
^@
.
r /dev/null
wq
Similarly, to remove a newline from the end of binary `file':
$ ed file
r /dev/null
wq
2) Since the behavior of `u' (undo) within a `g' (global) command list is
not specified by POSIX, it follows the behavior of the SunOS ed:
undo forces a global command list to be executed only once, rather than
for each line matching a global pattern. In addtion, each instance of
`u' within a global command undoes all previous commands (including
undo's) in the command list. This seems the best way, since the
alternatives are either too complicated to implement or too confusing
to use.
The global/undo combination is useful for masking errors that
would otherwise cause a script to fail. For instance, an ed script
to remove any occurrences of either `censor1' or `censor2' might be
written as:
ed - file <<EOF
1g/.*/u\
,s/censor1//g\
,s/censor2//g
...
3) The `m' (move) command within a `g' command list also follows the SunOS
ed implementation: any moved lines are removed from the global command's
`active' list.
4) If ed is invoked with a name argument prefixed by a bang (!), then the
remainder of the argument is interpreted as a shell command. To invoke
ed on a file whose name starts with bang, prefix the name with a
backslash.

View File

@@ -1,24 +0,0 @@
$NetBSD: README,v 1.9 1995/03/21 09:04:33 cgd Exp $
ed is an 8-bit-clean, POSIX-compliant line editor. It should work with
any regular expression package that conforms to the POSIX interface
standard, such as GNU regex(3).
If reliable signals are supported (e.g., POSIX sigaction(2)), it should
compile with little trouble. Otherwise, the macros SPL1() and SPL0()
should be redefined to disable interrupts.
The following compiler directives are recognized:
DES - to add encryption support (requires crypt(3))
NO_REALLOC_NULL - if realloc(3) does not accept a NULL pointer
BACKWARDS - for backwards compatibility
NEED_INSQUE - if insque(3) is missing
The file `POSIX' describes extensions to and deviations from the POSIX
standard.
The ./test directory contains regression tests for ed. The README
file in that directory explains how to run these.
For a description of the ed algorithm, see Kernighan and Plauger's book
"Software Tools in Pascal," Addison-Wesley, 1981.

View File

@@ -1,319 +0,0 @@
/* $NetBSD: buf.c,v 1.26 2006/03/17 14:37:14 rumble Exp $ */
/* buf.c: This file contains the scratch-file buffer routines for the
ed line editor. */
/*-
* Copyright (c) 1993 Andrew Moore, Talke Studio.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
#ifndef lint
#if 0
static char *rcsid = "@(#)buf.c,v 1.4 1994/02/01 00:34:35 alm Exp";
#else
__RCSID("$NetBSD: buf.c,v 1.26 2006/03/17 14:37:14 rumble Exp $");
#endif
#endif /* not lint */
#include <sys/file.h>
#include <sys/stat.h>
#include <paths.h>
#include <stdio.h>
#include <err.h>
#include "ed.h"
FILE *sfp; /* scratch file pointer */
off_t sfseek; /* scratch file position */
int seek_write; /* seek before writing */
line_t buffer_head; /* incore buffer */
/* get_sbuf_line: get a line of text from the scratch file; return pointer
to the text */
char *
get_sbuf_line(line_t *lp)
{
static char *sfbuf = NULL; /* buffer */
static int sfbufsz = 0; /* buffer size */
int len, ct;
if (lp == &buffer_head)
return NULL;
seek_write = 1; /* force seek on write */
/* out of position */
if (sfseek != lp->seek) {
sfseek = lp->seek;
if (fseek(sfp, sfseek, SEEK_SET) < 0) {
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "cannot seek temp file");
return NULL;
}
}
len = lp->len;
REALLOC(sfbuf, sfbufsz, len + 1, NULL);
if ((ct = fread(sfbuf, sizeof(char), len, sfp)) < 0 || ct != len) {
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "cannot read temp file");
return NULL;
}
sfseek += len; /* update file position */
sfbuf[len] = '\0';
return sfbuf;
}
/* put_sbuf_line: write a line of text to the scratch file and add a line node
to the editor buffer; return a pointer to the end of the text */
char *
put_sbuf_line(char *cs)
{
line_t *lp;
int len, ct;
char *s;
if ((lp = (line_t *) malloc(sizeof(line_t))) == NULL) {
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "out of memory");
return NULL;
}
/* assert: cs is '\n' terminated */
for (s = cs; *s != '\n'; s++)
;
if (s - cs >= LINECHARS) {
sprintf(errmsg, "line too long");
free(lp);
return NULL;
}
len = s - cs;
/* out of position */
if (seek_write) {
if (fseek(sfp, 0L, SEEK_END) < 0) {
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "cannot seek temp file");
free(lp);
return NULL;
}
sfseek = ftell(sfp);
seek_write = 0;
}
/* assert: SPL1() */
if ((ct = fwrite(cs, sizeof(char), len, sfp)) < 0 || ct != len) {
sfseek = -1;
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "cannot write temp file");
free(lp);
return NULL;
}
lp->len = len;
lp->seek = sfseek;
add_line_node(lp);
sfseek += len; /* update file position */
return ++s;
}
/* add_line_node: add a line node in the editor buffer after the current line */
void
add_line_node(line_t *lp)
{
line_t *cp;
cp = get_addressed_line_node(current_addr); /* this get_addressed_line_node last! */
INSQUE(lp, cp);
addr_last++;
current_addr++;
}
/* get_line_node_addr: return line number of pointer */
long
get_line_node_addr(line_t *lp)
{
line_t *cp = &buffer_head;
long n = 0;
while (cp != lp && (cp = cp->q_forw) != &buffer_head)
n++;
if (n && cp == &buffer_head) {
sprintf(errmsg, "invalid address");
return ERR;
}
return n;
}
/* get_addressed_line_node: return pointer to a line node in the editor buffer */
line_t *
get_addressed_line_node(long n)
{
static line_t *lp = &buffer_head;
static long on = 0;
SPL1();
if (n > on) {
if (n <= (on + addr_last) >> 1) {
for (; on < n; on++)
lp = lp->q_forw;
} else {
lp = buffer_head.q_back;
for (on = addr_last; on > n; on--)
lp = lp->q_back;
}
} else {
if (n >= on >> 1) {
for (; on > n; on--)
lp = lp->q_back;
} else {
lp = &buffer_head;
for (on = 0; on < n; on++)
lp = lp->q_forw;
}
}
SPL0();
return lp;
}
char *sfn = NULL; /* scratch file name */
/* open_sbuf: open scratch file */
int
open_sbuf(void)
{
int u, fd;
const char *tmp;
size_t s;
isbinary = newline_added = 0;
fd = -1;
u = umask(077);
if ((tmp = getenv("TMPDIR")) == NULL)
tmp = _PATH_TMP;
if ((s = strlen(tmp)) == 0 || tmp[s - 1] == '/')
(void)asprintf(&sfn, "%sed.XXXXXX", tmp);
else
(void)asprintf(&sfn, "%s/ed.XXXXXX", tmp);
if (sfn == NULL) {
warn(NULL);
sprintf(errmsg, "could not allocate memory");
umask(u);
return ERR;
}
if ((fd = mkstemp(sfn)) == -1 || (sfp = fdopen(fd, "w+")) == NULL) {
if (fd != -1)
close(fd);
warn("%s", sfn);
sprintf(errmsg, "cannot open temp file");
umask(u);
return ERR;
}
umask(u);
return 0;
}
/* close_sbuf: close scratch file */
int
close_sbuf(void)
{
if (sfp) {
if (fclose(sfp) < 0) {
fprintf(stderr, "%s: %s\n", sfn, strerror(errno));
sprintf(errmsg, "cannot close temp file");
return ERR;
}
sfp = NULL;
if (sfn) {
unlink(sfn);
free(sfn);
sfn = NULL;
}
}
sfseek = seek_write = 0;
return 0;
}
/* quit: remove_lines scratch file and exit */
void
quit(int n)
{
if (sfp) {
fclose(sfp);
if (sfn) {
unlink(sfn);
free(sfn);
sfn = NULL;
}
}
exit(n);
/* NOTREACHED */
}
unsigned char ctab[256]; /* character translation table */
/* init_buffers: open scratch buffer; initialize line queue */
void
init_buffers(void)
{
int i = 0;
/* Read stdin one character at a time to avoid i/o contention
with shell escapes invoked by nonterminal input, e.g.,
ed - <<EOF
!cat
hello, world
EOF */
setbuffer(stdin, stdinbuf, 1);
if (open_sbuf() < 0)
quit(2);
REQUE(&buffer_head, &buffer_head);
for (i = 0; i < 256; i++)
ctab[i] = i;
}
/* translit_text: translate characters in a string */
char *
translit_text(char *s, int len, int from, int to)
{
static int i = 0;
unsigned char *us;
ctab[i] = i; /* restore table to initial state */
ctab[i = from] = to;
for (us = (unsigned char *) s; len-- > 0; us++)
*us = ctab[*us];
return s;
}

View File

@@ -1,460 +0,0 @@
/* $NetBSD: cbc.c,v 1.22 2010/06/09 19:20:18 riz Exp $ */
/* cbc.c: This file contains the encryption routines for the ed line editor */
/*-
* Copyright (c) 1993 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* from: @(#)bdes.c 5.5 (Berkeley) 6/27/91
*/
/*-
* Copyright (c) 1993 Andrew Moore, Talke Studio.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* from: @(#)bdes.c 5.5 (Berkeley) 6/27/91
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char *rcsid = "@(#)cbc.c,v 1.2 1994/02/01 00:34:36 alm Exp";
#else
__RCSID("$NetBSD: cbc.c,v 1.22 2010/06/09 19:20:18 riz Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <pwd.h>
#ifdef DES
#include <time.h>
#endif
#include "ed.h"
/*
* Define a divisor for rand() that yields a uniform distribution in the
* range 0-255.
*/
#define RAND_DIV (((unsigned) RAND_MAX + 1) >> 8)
/*
* BSD and System V systems offer special library calls that do
* block move_liness and fills, so if possible we take advantage of them
*/
#define MEMCPY(dest,src,len) memcpy((dest),(src),(len))
#define MEMZERO(dest,len) memset((dest), 0, (len))
/* Hide the calls to the primitive encryption routines. */
#define DES_KEY(buf) \
if (des_setkey(buf)) \
des_error("des_setkey");
#define DES_XFORM(buf) \
if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \
des_error("des_cipher");
/*
* read/write - no error checking
*/
#define READ(buf, n, fp) fread(buf, sizeof(char), n, fp)
#define WRITE(buf, n, fp) fwrite(buf, sizeof(char), n, fp)
/*
* some things to make references easier
*/
typedef char Desbuf[8];
#define CHAR(x,i) (x[i])
#define UCHAR(x,i) (x[i])
#define BUFFER(x) (x)
#define UBUFFER(x) (x)
#ifdef DES
/*
* global variables and related macros
*/
static Desbuf ivec; /* initialization vector */
static Desbuf pvec; /* padding vector */
static char bits[] = { /* used to extract bits from a char */
'\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
};
static int pflag; /* 1 to preserve parity bits */
static char des_buf[8]; /* shared buffer for get_des_char/put_des_char */
static int des_ct = 0; /* count for get_des_char/put_des_char */
static int des_n = 0; /* index for put_des_char/get_des_char */
#endif
#ifdef DES
static void des_error(const char *);
static int hex_to_binary(int, int);
static void expand_des_key(char *, char *);
static void set_des_key(char *);
static int cbc_decode(char *, FILE *);
static int cbc_encode(char *, int, FILE *);
#endif
/* init_des_cipher: initialize DES */
void
init_des_cipher(void)
{
#ifdef DES
int i;
des_ct = des_n = 0;
/* initialize the initialization vector */
MEMZERO(ivec, 8);
/* intialize the padding vector */
srand((unsigned) time((time_t *) 0));
for (i = 0; i < 8; i++)
CHAR(pvec, i) = (char) (rand()/RAND_DIV);
#endif
}
/* get_des_char: return next char in an encrypted file */
int
get_des_char(FILE *fp)
{
#ifdef DES
if (des_n >= des_ct) {
des_n = 0;
des_ct = cbc_decode(des_buf, fp);
}
return (des_ct > 0) ? (unsigned char) des_buf[des_n++] : EOF;
#else
return EOF;
#endif
}
/* put_des_char: write a char to an encrypted file; return char written */
int
put_des_char(int c, FILE *fp)
{
#ifdef DES
if (des_n == sizeof des_buf) {
des_ct = cbc_encode(des_buf, des_n, fp);
des_n = 0;
}
return (des_ct >= 0) ? (unsigned char) (des_buf[des_n++] = c) : EOF;
#else
return EOF;
#endif
}
/* flush_des_file: flush an encrypted file's output; return status */
int
flush_des_file(FILE *fp)
{
#ifdef DES
if (des_n == sizeof des_buf) {
des_ct = cbc_encode(des_buf, des_n, fp);
des_n = 0;
}
return (des_ct >= 0 && cbc_encode(des_buf, des_n, fp) >= 0) ? 0 : EOF;
#else
return EOF;
#endif
}
#ifdef DES
/*
* get keyword from tty or stdin
*/
int
get_keyword(void)
{
char *p; /* used to obtain the key */
Desbuf msgbuf; /* I/O buffer */
/*
* get the key
*/
if (*(p = getpass("Enter key: "))) {
/*
* copy it, nul-padded, into the key area
*/
expand_des_key(BUFFER(msgbuf), p);
MEMZERO(p, _PASSWORD_LEN);
set_des_key(msgbuf);
MEMZERO(msgbuf, sizeof msgbuf);
return 1;
}
return 0;
}
/*
* print a warning message and, possibly, terminate
*/
static void
des_error(const char *s /* the message */)
{
(void)sprintf(errmsg, "%s", s ? s : strerror(errno));
}
/*
* map a hex character to an integer
*/
static int
hex_to_binary(int c /* char to be converted */,
int radix /* base (2 to 16) */)
{
switch(c) {
case '0': return(0x0);
case '1': return(0x1);
case '2': return(radix > 2 ? 0x2 : -1);
case '3': return(radix > 3 ? 0x3 : -1);
case '4': return(radix > 4 ? 0x4 : -1);
case '5': return(radix > 5 ? 0x5 : -1);
case '6': return(radix > 6 ? 0x6 : -1);
case '7': return(radix > 7 ? 0x7 : -1);
case '8': return(radix > 8 ? 0x8 : -1);
case '9': return(radix > 9 ? 0x9 : -1);
case 'A': case 'a': return(radix > 10 ? 0xa : -1);
case 'B': case 'b': return(radix > 11 ? 0xb : -1);
case 'C': case 'c': return(radix > 12 ? 0xc : -1);
case 'D': case 'd': return(radix > 13 ? 0xd : -1);
case 'E': case 'e': return(radix > 14 ? 0xe : -1);
case 'F': case 'f': return(radix > 15 ? 0xf : -1);
}
/*
* invalid character
*/
return(-1);
}
/*
* convert the key to a bit pattern
*/
static void
expand_des_key(char *obuf /* bit pattern */, char *inbuf /* the key itself */)
{
int i, j; /* counter in a for loop */
int nbuf[64]; /* used for hex/key translation */
/*
* leading '0x' or '0X' == hex key
*/
if (inbuf[0] == '0' && (inbuf[1] == 'x' || inbuf[1] == 'X')) {
inbuf = &inbuf[2];
/*
* now translate it, bombing on any illegal hex digit
*/
for (i = 0; inbuf[i] && i < 16; i++)
if ((nbuf[i] = hex_to_binary((int) inbuf[i], 16)) == -1)
des_error("bad hex digit in key");
while (i < 16)
nbuf[i++] = 0;
for (i = 0; i < 8; i++)
obuf[i] =
((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
/* preserve parity bits */
pflag = 1;
return;
}
/*
* leading '0b' or '0B' == binary key
*/
if (inbuf[0] == '0' && (inbuf[1] == 'b' || inbuf[1] == 'B')) {
inbuf = &inbuf[2];
/*
* now translate it, bombing on any illegal binary digit
*/
for (i = 0; inbuf[i] && i < 16; i++)
if ((nbuf[i] = hex_to_binary((int) inbuf[i], 2)) == -1)
des_error("bad binary digit in key");
while (i < 64)
nbuf[i++] = 0;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];
/* preserve parity bits */
pflag = 1;
return;
}
/*
* no special leader -- ASCII
*/
(void)strncpy(obuf, inbuf, 8);
}
/*****************
* DES FUNCTIONS *
*****************/
/*
* This sets the DES key and (if you're using the deszip version)
* the direction of the transformation. This uses the Sun
* to map the 64-bit key onto the 56 bits that the key schedule
* generation routines use: the old way, which just uses the user-
* supplied 64 bits as is, and the new way, which resets the parity
* bit to be the same as the low-order bit in each character. The
* new way generates a greater variety of key schedules, since many
* systems set the parity (high) bit of each character to 0, and the
* DES ignores the low order bit of each character.
*/
static void
set_des_key(Desbuf buf /* key block */)
{
int i, j; /* counter in a for loop */
int par; /* parity counter */
/*
* if the parity is not preserved, flip it
*/
if (!pflag) {
for (i = 0; i < 8; i++) {
par = 0;
for (j = 1; j < 8; j++)
if ((bits[j]&UCHAR(buf, i)) != 0)
par++;
if ((par&01) == 01)
UCHAR(buf, i) = UCHAR(buf, i)&0177;
else
UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200;
}
}
DES_KEY(UBUFFER(buf));
}
/*
* This encrypts using the Cipher Block Chaining mode of DES
*/
static int
cbc_encode(char *msgbuf, int n, FILE *fp)
{
int inverse = 0; /* 0 to encrypt, 1 to decrypt */
/*
* do the transformation
*/
if (n == 8) {
for (n = 0; n < 8; n++)
CHAR(msgbuf, n) ^= CHAR(ivec, n);
DES_XFORM(UBUFFER(msgbuf));
MEMCPY(BUFFER(ivec), BUFFER(msgbuf), 8);
return WRITE(BUFFER(msgbuf), 8, fp);
}
/*
* at EOF or last block -- in either case, the last byte contains
* the character representation of the number of bytes in it
*/
/*
MEMZERO(msgbuf + n, 8 - n);
*/
/*
* Pad the last block randomly
*/
(void)MEMCPY(BUFFER(msgbuf + n), BUFFER(pvec), 8 - n);
CHAR(msgbuf, 7) = n;
for (n = 0; n < 8; n++)
CHAR(msgbuf, n) ^= CHAR(ivec, n);
DES_XFORM(UBUFFER(msgbuf));
return WRITE(BUFFER(msgbuf), 8, fp);
}
/*
* This decrypts using the Cipher Block Chaining mode of DES
*/
static int
cbc_decode(char *msgbuf /* I/O buffer */,
FILE *fp /* input file descriptor */)
{
Desbuf inbuf; /* temp buffer for initialization vector */
int n; /* number of bytes actually read */
int c; /* used to test for EOF */
int inverse = 1; /* 0 to encrypt, 1 to decrypt */
if ((n = READ(BUFFER(msgbuf), 8, fp)) == 8) {
/*
* do the transformation
*/
MEMCPY(BUFFER(inbuf), BUFFER(msgbuf), 8);
DES_XFORM(UBUFFER(msgbuf));
for (c = 0; c < 8; c++)
UCHAR(msgbuf, c) ^= UCHAR(ivec, c);
MEMCPY(BUFFER(ivec), BUFFER(inbuf), 8);
/*
* if the last one, handle it specially
*/
if ((c = fgetc(fp)) == EOF) {
n = CHAR(msgbuf, 7);
if (n < 0 || n > 7) {
des_error("decryption failed (block corrupted)");
return EOF;
}
} else
(void)ungetc(c, fp);
return n;
}
if (n > 0)
des_error("decryption failed (incomplete block)");
else if (n < 0)
des_error("cannot read file");
return EOF;
}
#endif /* DES */

View File

@@ -1,972 +0,0 @@
.\" $NetBSD: ed.1,v 1.30 2010/05/14 02:09:58 joerg Exp $
.\" $OpenBSD: ed.1,v 1.42 2003/07/27 13:25:43 jmc Exp $
.\"
.\" Copyright (c) 1993 Andrew Moore, Talke Studio.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. 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.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
.\"
.Dd January 23, 2002
.Dt ED 1
.Os
.Sh NAME
.Nm ed
.Nd text editor
.Sh SYNOPSIS
.Nm
.Op Fl
.Op Fl Esx
.Op Fl p Ar string
.Op Ar file
.Sh DESCRIPTION
.Nm
is a line-oriented text editor.
It is used to create, display, modify, and otherwise manipulate text files.
If invoked with a
.Ar file
argument, then a copy of
.Ar file
is read into the editor's buffer.
Changes are made to this copy and not directly to
.Ar file
itself.
Upon quitting
.Nm ,
any changes not explicitly saved with a
.Ic w
command are lost.
.Pp
Editing is done in two distinct modes:
.Em command
and
.Em input .
When first invoked,
.Nm
is in command mode.
In this mode, commands are read from the standard input and
executed to manipulate the contents of the editor buffer.
.Pp
A typical command might look like:
.Bd -literal -offset indent
,s/old/new/g
.Ed
.Pp
which replaces all occurrences of the string
.Pa old
with
.Pa new .
.Pp
When an input command, such as
.Ic a
(append),
.Ic i
(insert),
or
.Ic c
(change) is given,
.Nm
enters input mode.
This is the primary means of adding text to a file.
In this mode, no commands are available;
instead, the standard input is written directly to the editor buffer.
Lines consist of text up to and including a newline character.
Input mode is terminated by entering a single period
.Pq Ql \&.
on a line.
.Pp
All
.Nm
commands operate on whole lines or ranges of lines; e.g.,
the
.Ic d
command deletes lines; the
.Ic m
command moves lines, and so on.
It is possible to modify only a portion of a line by means of replacement,
as in the example above.
However, even here, the
.Ic s
command is applied to whole lines at a time.
.Pp
In general,
.Nm
commands consist of zero or more line addresses, followed by a single
character command and possibly additional parameters; i.e.,
commands have the structure:
.Bd -literal -offset indent
[address [,address]]command[parameters]
.Ed
.Pp
The address(es) indicate the line or range of lines to be affected by the
command.
If fewer addresses are given than the command accepts, then
default addresses are supplied.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl
Same as the
.Fl s
option (deprecated).
.It Fl E
Enables the use of extended regular expressions instead of the basic
regular expressions that are normally used.
.It Fl p Ar string
Specifies a command prompt.
This may be toggled on and off with the
.Ic P
command.
.It Fl s
Suppress diagnostics.
This should be used if
.Nm
standard input is from a script.
.It Fl x
Prompt for an encryption key to be used in subsequent reads and writes
(see the
.Ic x
command).
.It Ar file
Specifies the name of a file to read.
If
.Ar file
is prefixed with a
bang
.Pq Ql \&! ,
then it is interpreted as a shell command.
In this case, what is read is the standard output of
.Ar file
executed via
.Xr sh 1 .
To read a file whose name begins with a bang, prefix the
name with a backslash
.Pq Ql \e .
The default filename is set to
.Ar file
only if it is not prefixed with a bang.
.El
.Ss LINE ADDRESSING
An address represents the number of a line in the buffer.
.Nm
maintains a
.Em current address
which is typically supplied to commands as the default address
when none is specified.
When a file is first read, the current address is set to the last line
of the file.
In general, the current address is set to the last line affected by a command.
.Pp
A line address is
constructed from one of the bases in the list below, optionally followed
by a numeric offset.
The offset may include any combination of digits, operators (i.e.,
.Sq + ,
.Sq - ,
and
.Sq ^ ) ,
and whitespace.
Addresses are read from left to right, and their values are computed
relative to the current address.
.Pp
One exception to the rule that addresses represent line numbers is the
address
.Em 0
(zero).
This means
.Dq before the first line ,
and is legal wherever it makes sense.
.Pp
An address range is two addresses separated either by a comma or semi-colon.
The value of the first address in a range cannot exceed the
value of the second.
If only one address is given in a range,
then the second address is set to the given address.
If an
.Em n Ns No -tuple
of addresses is given where
.Em n \*[Gt] 2 ,
then the corresponding range is determined by the last two addresses in the
.Em n Ns No -tuple.
If only one address is expected, then the last address is used.
.Pp
Each address in a comma-delimited range is interpreted relative to the
current address.
In a semi-colon-delimited range, the first address is
used to set the current address, and the second address is interpreted
relative to the first.
.Pp
The following address symbols are recognized:
.Bl -tag -width Ds
.It Em \&.
The current line (address) in the buffer.
.It Em $
The last line in the buffer.
.It Em n
The
.Em n Ns No th
line in the buffer where
.Em n
is a number in the range
.Em [0,$] .
.It Em - No or Em ^
The previous line.
This is equivalent to
.Em -1
and may be repeated with cumulative effect.
.It Em -n No or Em ^n
The
.Em n Ns No th
previous line, where
.Em n
is a non-negative number.
.It Em +
The next line.
This is equivalent to
.Em +1
and may be repeated with cumulative effect.
.It Em +n
The
.Em n Ns No th
next line, where
.Em n
is a non-negative number.
.It Em whitespace Em n
.Em whitespace
followed by a number
.Em n
is interpreted as
.Sq Em +n .
.It Em \&, No or Em %
The first through last lines in the buffer.
This is equivalent to the address range
.Em 1,$ .
.It Em \&;
The current through last lines in the buffer.
This is equivalent to the address range
.Em .,$ .
.It Em / Ns Ar re Ns Em /
The next line containing the regular expression
.Ar re .
The search wraps to the beginning of the buffer and continues down to the
current line, if necessary.
.Em //
repeats the last search.
.It Em \&? Ns Ar re Ns Em \&?
The previous line containing the regular expression
.Ar re .
The search wraps to the end of the buffer and continues up to the
current line, if necessary.
.Em ??
repeats the last search.
.It Em \&\' Ns Ar lc
The line previously marked by a
.Ic k
(mark) command, where
.Ar lc
is a lower case letter.
.El
.Ss REGULAR EXPRESSIONS
Regular expressions are patterns used in selecting text.
For example, the
.Nm
command
.Bd -literal -offset indent
g/string/
.Ed
.Pp
prints all lines containing
.Em string .
Regular expressions are also used by the
.Ic s
command for selecting old text to be replaced with new.
.Pp
In addition to specifying string literals, regular expressions can
represent classes of strings.
Strings thus represented are said to be matched by the
corresponding regular expression.
If it is possible for a regular expression to match several strings in
a line, then the leftmost longest match is the one selected.
.Pp
The following symbols are used in constructing regular expressions:
.Bl -tag -width Dsasdfsd
.It Em c
Any character
.Em c
not listed below, including
.Sq { ,
.Sq } ,
.Sq \&( ,
.Sq \&) ,
.Sq \*[Lt] ,
and
.Sq \*[Gt]
matches itself.
.It Em \ec
Any backslash-escaped character
.Em c ,
except for
.Sq { ,
.Sq } ,
.Sq \&( ,
.Sq \&) ,
.Sq \*[Lt] ,
and
.Sq \*[Gt]
matches itself.
.It Em \&.
Matches any single character.
.It Em [char-class]
Matches any single character in the character class
.Em char-class .
See
.Sx CHARACTER CLASSES
below for further information.
.It Em [^char-class]
Matches any single character, other than newline, not in the
character class
.Em char-class .
.It Em ^
If
.Em ^
is the first character of a regular expression, then it
anchors the regular expression to the beginning of a line.
Otherwise, it matches itself.
.It Em $
If
.Em $
is the last character of a regular expression,
it anchors the regular expression to the end of a line.
Otherwise, it matches itself.
.It Em \e\*[Lt]
Anchors the single character regular expression or subexpression
immediately following it to the beginning of a word.
(This may not be available.)
.It Em \e\*[Gt]
Anchors the single character regular expression or subexpression
immediately following it to the end of a word.
(This may not be available.)
.It Em \e( Ns Ar re Ns Em \e)
Defines a subexpression
.Ar re .
Subexpressions may be nested.
A subsequent backreference of the form
.Em \en ,
where
.Em n
is a number in the range [1,9], expands to the text matched by the
.Em n Ns No th
subexpression.
For example, the regular expression
.Em \e(.*\e)\e1
matches any string consisting of identical adjacent substrings.
Subexpressions are ordered relative to their left delimiter.
.It Em *
Matches the single character regular expression or subexpression
immediately preceding it zero or more times.
If
.Em *
is the first character of a regular expression or subexpression,
then it matches itself.
The
.Em *
operator sometimes yields unexpected results.
For example, the regular expression
.Em b*
matches the beginning of the string
.Em abbb
(as opposed to the substring
.Em bbb ) ,
since a null match is the only leftmost match.
.Sm off
.It Em \e{ No n,m Em \e}\ \e{ No n, Em \e}\ \& Em \e{ No n Em \e}
.Sm on
Matches the single character regular expression or subexpression
immediately preceding it at least
.Em n
and at most
.Em m
times.
If
.Em m
is omitted, then it matches at least
.Em n
times.
If the comma is also omitted, then it matches exactly
.Em n
times.
.El
.Pp
Additional regular expression operators may be defined depending on the
particular
.Xr regex 3
implementation.
.Ss CHARACTER CLASSES
A character class specifies a set of characters. It is written within
square brackets
.Pq []
and in its most basic form contains just the characters in the set.
.Pp
To include a
.Sq \&]
in a character class, it must be the first character.
A range of characters may be specified by separating the end characters
of the range with a
.Sq \&- ,
e.g.,
.Sq a-z
specifies the lower case characters.
.Pp
The following literals can also be used within character classes as
shorthand for particular sets of characters:
.Bl -tag -offset indent -compact -width [:blahblah:]
.It [:alnum:]
Alphanumeric characters.
.It [:cntrl:]
Control characters.
.It [:lower:]
Lowercase alphabetic characters.
.It [:space:]
Whitespace (space, tab, newline, form feed, etc.)
.It [:alpha:]
Alphabetic characters.
.It [:digit:]
Numeric characters (digits).
.It [:print:]
Printable characters.
.It [:upper:]
Uppercase alphabetic characters.
.It [:blank:]
Blank characters (space and tab).
.It [:graph:]
Graphical characters (printing nonblank characters).
.It [:punct:]
Punctuation characters.
.It [:xdigit:]
Hexadecimal digits.
.El
If
.Sq \&-
appears as the first or last character of a character class, then
it matches itself.
All other characters in a character class match themselves.
.Pp
Patterns in
a character class
of the form
.Em [.col-elm.]
or
.Em [=col-elm=]
where
.Em col-elm
is a
.Em collating element
are interpreted according to
.Xr locale 5
(not currently supported).
See
.Xr regex 3
for an explanation of these constructs.
.Ss COMMANDS
All
.Nm
commands are single characters, though some require additional parameters.
If a command's parameters extend over several lines, then
each line except for the last must be terminated with a backslash
.Pq Ql \e .
.Pp
In general, at most one command is allowed per line.
However, most commands accept a print suffix, which is any of
.Ic p
(print),
.Ic l
(list),
or
.Ic n
(enumerate), to print the last line affected by the command.
.Pp
An interrupt (typically ^C) has the effect of aborting the current command
and returning the editor to command mode.
.Pp
.Nm
recognizes the following commands.
The commands are shown together with
the default address or address range supplied if none is
specified (in parentheses), and other possible arguments on the right.
.Bl -tag -width Dxxs
.It (.) Ns Ic a
Appends text to the buffer after the addressed line.
Text is entered in input mode.
The current address is set to last line entered.
.It (.,.) Ns Ic c
Changes lines in the buffer.
The addressed lines are deleted from the buffer,
and text is appended in their place.
Text is entered in input mode.
The current address is set to last line entered.
.It (.,.) Ns Ic d
Deletes the addressed lines from the buffer.
If there is a line after the deleted range, then the current address is set
to this line.
Otherwise the current address is set to the line before the deleted range.
.It Ic e Ar file
Edits
.Ar file ,
and sets the default filename.
If
.Ar file
is not specified, then the default filename is used.
Any lines in the buffer are deleted before the new file is read.
The current address is set to the last line read.
.It Ic e Ar !command
Edits the standard output of
.Ar command ,
(see
.Ic \&! Ar command
below).
The default filename is unchanged.
Any lines in the buffer are deleted before the output of
.Em command
is read.
The current address is set to the last line read.
.It Ic E Ar file
Edits
.Ar file
unconditionally.
This is similar to the
.Ic e
command, except that unwritten changes are discarded without warning.
The current address is set to the last line read.
.It Ic f Ar file
Sets the default filename to
.Ar file .
If
.Ar file
is not specified, then the default unescaped filename is printed.
.It (1,$) Ns Ic g Ns Ar /re/command-list
Applies
.Ar command-list
to each of the addressed lines matching a regular expression
.Ar re .
The current address is set to the line currently matched before
.Ar command-list
is executed.
At the end of the
.Ic g
command, the current address is set to the last line affected by
.Ar command-list .
.Pp
Each command in
.Ar command-list
must be on a separate line,
and every line except for the last must be terminated by a backslash
.Pq Sq \e .
Any commands are allowed, except for
.Ic g ,
.Ic G ,
.Ic v ,
and
.Ic V .
A newline alone in
.Ar command-list
is equivalent to a
.Ic p
command.
.It (1,$) Ns Ic G Ns Ar /re/
Interactively edits the addressed lines matching a regular expression
.Ar re .
For each matching line, the line is printed, the current address is set,
and the user is prompted to enter a
.Ar command-list .
At the end of the
.Ic G
command, the current address is set to the last line affected by (the last)
.Ar command-list .
.Pp
The format of
.Ar command-list
is the same as that of the
.Ic g
command.
A newline alone acts as a null command list.
A single
.Sq \*[Am]
repeats the last non-null command list.
.It Ic H
Toggles the printing of error explanations.
By default, explanations are not printed.
It is recommended that
.Nm
scripts begin with this command to aid in debugging.
.It Ic h
Prints an explanation of the last error.
.It (.) Ns Ic i
Inserts text in the buffer before the current line.
Text is entered in input mode.
The current address is set to the last line entered.
.It (.,.+1) Ns Ic j
Joins the addressed lines.
The addressed lines are deleted from the buffer and replaced by a single
line containing their joined text.
The current address is set to the resultant line.
.It (.) Ns Ic k Ns Ar lc
Marks a line with a lower case letter
.Ar lc .
The line can then be addressed as
.Ar \&'lc
(i.e., a single quote followed by
.Ar lc )
in subsequent commands.
The mark is not cleared until the line is deleted or otherwise modified.
.It (.,.) Ns Ic l
Prints the addressed lines unambiguously.
If a single line fills more than one screen (as might be the case
when viewing a binary file, for instance), a
.Dq --More--
prompt is printed on the last line.
.Nm
waits until the RETURN key is pressed before displaying the next screen.
The current address is set to the last line printed.
.It (.,.) Ns Ic m Ns No (.)
Moves lines in the buffer.
The addressed lines are moved to after the
right-hand destination address, which may be the address
.Em 0
(zero).
The current address is set to the last line moved.
.It (.,.) Ns Ic n
Prints the addressed lines along with their line numbers.
The current address is set to the last line printed.
.It (.,.) Ns Ic p
Prints the addressed lines.
The current address is set to the last line printed.
.It Ic P
Toggles the command prompt on and off.
Unless a prompt was specified with the command-line option
.Fl p Ar string ,
the command prompt is by default turned off.
.It Ic q
Quits
.Nm .
.It Ic Q
Quits
.Nm
unconditionally.
This is similar to the
.Ic q
command, except that unwritten changes are discarded without warning.
.It ($) Ns Ic r Ar file
Reads
.Ar file
to after the addressed line.
If
.Ar file
is not specified, then the default filename is used.
If there was no default filename prior to the command,
then the default filename is set to
.Ar file .
Otherwise, the default filename is unchanged.
The current address is set to the last line read.
.It ($) Ns Ic r Ar !command
Reads to after the addressed line the standard output of
.Ar command ,
(see the
.Ic \&!
command below).
The default filename is unchanged.
The current address is set to the last line read.
.Sm off
.It (.,.) Ic s Ar /re/replacement/ , \ (.,.) \
Ic s Ar /re/replacement/ Em g , Ar \ (.,.) \
Ic s Ar /re/replacement/ Em n
.Sm on
Replaces text in the addressed lines matching a regular expression
.Ar re
with
.Ar replacement .
By default, only the first match in each line is replaced.
If the
.Em g
(global) suffix is given, then every match to be replaced.
The
.Em n
suffix, where
.Em n
is a positive number, causes only the
.Em n Ns No th
match to be replaced.
It is an error if no substitutions are performed on any of the addressed
lines.
The current address is set the last line affected.
.Pp
.Ar re
and
.Ar replacement
may be delimited by any character other than space and newline
(see the
.Ic s
command below).
If one or two of the last delimiters is omitted, then the last line
affected is printed as though the print suffix
.Em p
were specified.
.Pp
An unescaped
.Ql \*[Am]
in
.Ar replacement
is replaced by the currently matched text.
The character sequence
.Em \em ,
where
.Em m
is a number in the range [1,9], is replaced by the
.Em m Ns No th
backreference expression of the matched text.
If
.Ar replacement
consists of a single
.Ql % ,
then
.Ar replacement
from the last substitution is used.
Newlines may be embedded in
.Ar replacement
if they are escaped with a backslash
.Pq Ql \e .
.It (.,.) Ns Ic s
Repeats the last substitution.
This form of the
.Ic s
command accepts a count suffix
.Em n ,
or any combination of the characters
.Em r ,
.Em g ,
and
.Em p .
If a count suffix
.Em n
is given, then only the
.Em n Ns No th
match is replaced.
The
.Em r
suffix causes
the regular expression of the last search to be used instead of
that of the last substitution.
The
.Em g
suffix toggles the global suffix of the last substitution.
The
.Em p
suffix toggles the print suffix of the last substitution.
The current address is set to the last line affected.
.It (.,.) Ns Ic t Ns No (.)
Copies (i.e., transfers) the addressed lines to after the right-hand
destination address, which may be the address
.Em 0
(zero).
The current address is set to the last line copied.
.It Ic u
Undoes the last command and restores the current address
to what it was before the command.
The global commands
.Ic g ,
.Ic G ,
.Ic v ,
and
.Ic V
are treated as a single command by undo.
.Ic u
is its own inverse.
.It (1,$) Ns Ic v Ns Ar /re/command-list
Applies
.Ar command-list
to each of the addressed lines not matching a regular expression
.Ar re .
This is similar to the
.Ic g
command.
.It (1,$) Ns Ic V Ns Ar /re/
Interactively edits the addressed lines not matching a regular expression
.Ar re .
This is similar to the
.Ic G
command.
.It (1,$) Ns Ic w Ar file
Writes the addressed lines to
.Ar file .
Any previous contents of
.Ar file
are lost without warning.
If there is no default filename, then the default filename is set to
.Ar file ,
otherwise it is unchanged.
If no filename is specified, then the default filename is used.
The current address is unchanged.
.It (1,$) Ns Ic wq Ar file
Writes the addressed lines to
.Ar file ,
and then executes a
.Ic q
command.
.It (1,$) Ns Ic w Ar !command
Writes the addressed lines to the standard input of
.Ar command ,
(see the
.Ic \&!
command below).
The default filename and current address are unchanged.
.It (1,$) Ns Ic W Ar file
Appends the addressed lines to the end of
.Ar file .
This is similar to the
.Ic w
command, except that the previous contents of file are not clobbered.
The current address is unchanged.
.It Ic x
Prompts for an encryption key which is used in subsequent reads and writes.
If a newline alone is entered as the key, then encryption is turned off.
Otherwise, echoing is disabled while a key is read.
Encryption/decryption is done using the
.Xr bdes 1
algorithm.
.It (.+1) Ns Ic z Ns Ar n
Scrolls
.Ar n
lines at a time starting at addressed line.
If
.Ar n
is not specified, then the current window size is used.
The current address is set to the last line printed.
.It ($) Ns Ic =
Prints the line number of the addressed line.
.It (.+1) Ns Ic newline
Prints the addressed line, and sets the current address to that line.
.It Ic \&! Ns Ar command
Executes
.Ar command
via
.Xr sh 1 .
If the first character of
.Ar command
is
.Ic \&! ,
then it is replaced by text of the previous
.Ic !command .
.Nm
does not process
.Ar command
for
.Sq \e
(backslash) escapes.
However, an unescaped
.Sq %
is replaced by the default filename.
When the shell returns from execution, a
.Sq \&!
is printed to the standard output.
The current line is unchanged.
.El
.Sh LIMITATIONS
.Nm
processes
.Em file
arguments for backslash escapes, i.e., in a filename,
any characters preceded by a backslash
.Pq Ql \e
are interpreted literally.
.Pp
If a text (non-binary) file is not terminated by a newline character,
then
.Nm
appends one on reading/writing it.
In the case of a binary file,
.Nm
does not append a newline on reading/writing.
.Sh ENVIRONMENT
.Bl -tag -width iTMPDIR
.It Ev TMPDIR
The location used to store temporary files.
.El
.Sh FILES
.Bl -tag -width /tmp/ed.* -compact
.It Pa /tmp/ed.*
buffer file
.It Pa ed.hup
where
.Nm
attempts to write the buffer if the terminal hangs up
.El
.Sh DIAGNOSTICS
When an error occurs,
.Nm
prints a
.Dq \&?
and either returns to command mode or exits if its input is from a script.
An explanation of the last error can be printed with the
.Ic h
(help) command.
.Pp
Since the
.Ic g
(global) command masks any errors from failed searches and substitutions,
it can be used to perform conditional operations in scripts; e.g.,
.Bd -literal -offset indent
g/old/s//new/
.Ed
.Pp
replaces any occurrences of
.Em old
with
.Em new .
.Pp
If the
.Ic u
(undo) command occurs in a global command list, then
the command list is executed only once.
.Pp
If diagnostics are not disabled, attempting to quit
.Nm
or edit another file before writing a modified buffer results in an error.
If the command is entered a second time, it succeeds,
but any changes to the buffer are lost.
.Sh SEE ALSO
.Xr bdes 1 ,
.Xr sed 1 ,
.Xr sh 1 ,
.Xr vi 1 ,
.Xr regex 3
.Pp
USD:09-10
.Rs
.%A B. W. Kernighan
.%A P. J. Plauger
.%B Software Tools in Pascal
.%I Addison-Wesley
.%D 1981
.Re
.Sh HISTORY
An
.Nm
command appeared in
.At v1 .

View File

@@ -1,293 +0,0 @@
/* $NetBSD: ed.h,v 1.35 2011/08/29 14:51:18 joerg Exp $ */
/* ed.h: type and constant definitions for the ed editor. */
/*
* Copyright (c) 1993 Andrew Moore
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)ed.h,v 1.5 1994/02/01 00:34:39 alm Exp
*/
#include <sys/types.h>
#if defined(BSD) && BSD >= 199103 || defined(__386BSD__)
# include <sys/param.h> /* for MAXPATHLEN */
#endif
#include <errno.h>
#if defined(sun) || defined(__NetBSD__) || defined(__APPLE__) || \
defined(__minix)
# include <limits.h>
#endif
#include <regex.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define ERR (-2)
#define EMOD (-3)
#define FATAL (-4)
#ifndef MAXPATHLEN
# define MAXPATHLEN 255 /* _POSIX_PATH_MAX */
#endif
#define MINBUFSZ 512 /* minimum buffer size - must be > 0 */
#define SE_MAX 30 /* max subexpressions in a regular expression */
#ifdef INT_MAX
# define LINECHARS INT_MAX /* max chars per line */
#else
# define LINECHARS MAXINT /* max chars per line */
#endif
/* gflags */
#define GLB 001 /* global command */
#define GPR 002 /* print after command */
#define GLS 004 /* list after command */
#define GNP 010 /* enumerate after command */
#define GSG 020 /* global substitute */
typedef regex_t pattern_t;
/* Line node */
typedef struct line {
struct line *q_forw;
struct line *q_back;
off_t seek; /* address of line in scratch buffer */
int len; /* length of line */
} line_t;
typedef struct undo {
/* type of undo nodes */
#define UADD 0
#define UDEL 1
#define UMOV 2
#define VMOV 3
int type; /* command type */
line_t *h; /* head of list */
line_t *t; /* tail of list */
} undo_t;
#ifndef max
# define max(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif
#define INC_MOD(l, k) ((l) + 1 > (k) ? 0 : (l) + 1)
#define DEC_MOD(l, k) ((l) - 1 < 0 ? (k) : (l) - 1)
/* SPL1: disable some interrupts (requires reliable signals) */
#define SPL1() mutex++
/* SPL0: enable all interrupts; check sigflags (requires reliable signals) */
#define SPL0() \
if (--mutex == 0) { \
if (sigflags & (1 << (SIGHUP - 1))) handle_hup(SIGHUP); \
if (sigflags & (1 << (SIGINT - 1))) handle_int(SIGINT); \
}
/* STRTOL: convert a string to long */
#define STRTOL(i, p) { \
errno = 0 ; \
if (((i = strtol(p, &p, 10)) == LONG_MIN || i == LONG_MAX) && \
errno == ERANGE) { \
sprintf(errmsg, "number out of range"); \
i = 0; \
return ERR; \
} \
}
#if defined(sun) || defined(NO_REALLOC_NULL)
/* REALLOC: assure at least a minimum size for buffer b */
#define REALLOC(b,n,i,err) \
if ((i) > (n)) { \
int ti = (n); \
char *ts; \
SPL1(); \
if ((b) != NULL) { \
if ((ts = (char *) realloc((b), ti += max((i), MINBUFSZ))) == NULL) { \
fprintf(stderr, "%s\n", strerror(errno)); \
sprintf(errmsg, "out of memory"); \
SPL0(); \
return err; \
} \
} else { \
if ((ts = (char *) malloc(ti += max((i), MINBUFSZ))) == NULL) { \
fprintf(stderr, "%s\n", strerror(errno)); \
sprintf(errmsg, "out of memory"); \
SPL0(); \
return err; \
} \
} \
(n) = ti; \
(b) = ts; \
SPL0(); \
}
#else /* NO_REALLOC_NULL */
/* REALLOC: assure at least a minimum size for buffer b */
#define REALLOC(b,n,i,err) \
if ((i) > (n)) { \
int ti = (n); \
char *ts; \
SPL1(); \
if ((ts = (char *) realloc((b), ti += max((i), MINBUFSZ))) == NULL) { \
fprintf(stderr, "%s\n", strerror(errno)); \
sprintf(errmsg, "out of memory"); \
SPL0(); \
return err; \
} \
(n) = ti; \
(b) = ts; \
SPL0(); \
}
#endif /* NO_REALLOC_NULL */
/* REQUE: link pred before succ */
#define REQUE(pred, succ) (pred)->q_forw = (succ), (succ)->q_back = (pred)
/* INSQUE: insert elem in circular queue after pred */
#define INSQUE(elem, pred) \
{ \
REQUE((elem), (pred)->q_forw); \
REQUE((pred), elem); \
}
/* remque: remove_lines elem from circular queue */
#define REMQUE(elem) REQUE((elem)->q_back, (elem)->q_forw);
/* NUL_TO_NEWLINE: overwrite ASCII NULs with newlines */
#define NUL_TO_NEWLINE(s, l) translit_text(s, l, '\0', '\n')
/* NEWLINE_TO_NUL: overwrite newlines with ASCII NULs */
#define NEWLINE_TO_NUL(s, l) translit_text(s, l, '\n', '\0')
#if defined(sun) && !defined(__SVR4)
# define strerror(n) sys_errlist[n]
#endif
/* Local Function Declarations */
void add_line_node(line_t *);
int append_lines(long);
int apply_subst_template(char *, regmatch_t *, int, int);
int build_active_list(int);
int check_addr_range(long, long);
void clear_active_list(void);
void clear_undo_stack(void);
int close_sbuf(void);
int copy_lines(long);
int delete_lines(long, long);
int display_lines(long, long, int);
line_t *dup_line_node(line_t *);
int exec_command(void);
long exec_global(int, int);
int extract_addr_range(void);
char *extract_pattern(int);
int extract_subst_tail(int *, long *);
char *extract_subst_template(void);
int filter_lines(long, long, char *);
int flush_des_file(FILE *);
line_t *get_addressed_line_node(long);
pattern_t *get_compiled_pattern(void);
int get_des_char(FILE *);
char *get_extended_line(int *, int);
char *get_filename(void);
int get_keyword(void);
long get_line_node_addr(line_t *);
long get_matching_node_addr(pattern_t *, int);
long get_marked_node_addr(int);
char *get_sbuf_line(line_t *);
int get_shell_command(void);
int get_stream_line(FILE *);
int get_tty_line(void);
__dead void handle_hup(int);
__dead void handle_int(int);
void handle_winch(int);
int has_trailing_escape(char *, char *);
void init_buffers(void);
void init_des_cipher(void);
int is_legal_filename(char *);
int join_lines(long, long);
int mark_line_node(line_t *, int);
int move_lines(long);
line_t *next_active_node(void);
long next_addr(void);
int open_sbuf(void);
char *parse_char_class(char *);
int pop_undo_stack(void);
undo_t *push_undo_stack(int, long, long);
int put_des_char(int, FILE *);
char *put_sbuf_line(char *);
int put_stream_line(FILE *, char *, int);
int put_tty_line(char *, int, long, int);
__dead void quit(int);
long read_file(char *, long);
long read_stream(FILE *, long);
int search_and_replace(pattern_t *, int, int);
int set_active_node(line_t *);
void signal_hup(int);
void signal_int(int);
char *strip_escapes(const char *);
int substitute_matching_text(pattern_t *, line_t *, int, int);
char *translit_text(char *, int, int, int);
void unmark_line_node(line_t *);
void unset_active_nodes(line_t *, line_t *);
long write_file(const char *, const char *, long, long);
long write_stream(FILE *, long, long);
/* global buffers */
extern char stdinbuf[];
extern char *ibuf;
extern char *ibufp;
extern int ibufsz;
/* global flags */
extern int isbinary;
extern int isglobal;
extern int modified;
extern int mutex;
extern int sigflags;
/* global vars */
extern long addr_last;
extern long current_addr;
extern long first_addr;
extern int lineno;
extern long second_addr;
extern long rows;
extern int cols;
extern int scripted;
extern int ere;
extern int des;
extern int newline_added; /* io.c */
extern int patlock;
extern char errmsg[]; /* re.c */
extern long u_current_addr; /* undo.c */
extern long u_addr_last; /* undo.c */
#if defined(sun) && !defined(__SVR4)
extern char *sys_errlist[];
#endif

View File

@@ -1,227 +0,0 @@
/* $NetBSD: glbl.c,v 1.6 2005/06/26 19:10:49 christos Exp $ */
/* glob.c: This file contains the global command routines for the ed line
editor */
/*-
* Copyright (c) 1993 Andrew Moore, Talke Studio.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
#ifndef lint
#if 0
static char *rcsid = "@(#)glob.c,v 1.1 1994/02/01 00:34:40 alm Exp";
#else
__RCSID("$NetBSD: glbl.c,v 1.6 2005/06/26 19:10:49 christos Exp $");
#endif
#endif /* not lint */
#include <sys/ioctl.h>
#include <sys/wait.h>
#include "ed.h"
/* build_active_list: add line matching a pattern to the global-active list */
int
build_active_list(int isgcmd)
{
pattern_t *pat;
line_t *lp;
long n;
char *s;
char delimiter;
if ((delimiter = *ibufp) == ' ' || delimiter == '\n') {
sprintf(errmsg, "invalid pattern delimiter");
return ERR;
} else if ((pat = get_compiled_pattern()) == NULL)
return ERR;
else if (*ibufp == delimiter)
ibufp++;
clear_active_list();
lp = get_addressed_line_node(first_addr);
for (n = first_addr; n <= second_addr; n++, lp = lp->q_forw) {
if ((s = get_sbuf_line(lp)) == NULL)
return ERR;
if (isbinary)
NUL_TO_NEWLINE(s, lp->len);
if (!regexec(pat, s, 0, NULL, 0) == isgcmd &&
set_active_node(lp) < 0)
return ERR;
}
return 0;
}
/* exec_global: apply command list in the command buffer to the active
lines in a range; return command status */
long
exec_global(int interact, int gflag)
{
static char *ocmd = NULL;
static int ocmdsz = 0;
line_t *lp = NULL;
int status;
int n;
char *cmd = NULL;
#ifdef BACKWARDS
char cmdp[] = "p\n";
if (!interact) {
if (!strcmp(ibufp, "\n"))
cmd = cmdp; /* null cmd-list == `p' */
else if ((cmd = get_extended_line(&n, 0)) == NULL)
return ERR;
}
#else
if (!interact && (cmd = get_extended_line(&n, 0)) == NULL)
return ERR;
#endif
clear_undo_stack();
while ((lp = next_active_node()) != NULL) {
if ((current_addr = get_line_node_addr(lp)) < 0)
return ERR;
if (interact) {
/* print current_addr; get a command in global syntax */
if (display_lines(current_addr, current_addr, gflag) < 0)
return ERR;
while ((n = get_tty_line()) > 0 &&
ibuf[n - 1] != '\n')
clearerr(stdin);
if (n < 0)
return ERR;
else if (n == 0) {
sprintf(errmsg, "unexpected end-of-file");
return ERR;
} else if (n == 1 && !strcmp(ibuf, "\n"))
continue;
else if (n == 2 && !strcmp(ibuf, "&\n")) {
if (cmd == NULL) {
sprintf(errmsg, "no previous command");
return ERR;
} else cmd = ocmd;
} else if ((cmd = get_extended_line(&n, 0)) == NULL)
return ERR;
else {
REALLOC(ocmd, ocmdsz, n + 1, ERR);
memcpy(ocmd, cmd, n + 1);
cmd = ocmd;
}
}
ibufp = cmd;
for (; *ibufp;)
if ((status = extract_addr_range()) < 0 ||
(status = exec_command()) < 0 ||
(status > 0 && (status = display_lines(
current_addr, current_addr, status))) < 0)
return status;
}
return 0;
}
line_t **active_list; /* list of lines active in a global command */
long active_last; /* index of last active line in active_list */
long active_size; /* size of active_list */
long active_ptr; /* active_list index (non-decreasing) */
long active_ndx; /* active_list index (modulo active_last) */
/* set_active_node: add a line node to the global-active list */
int
set_active_node(line_t *lp)
{
if (active_last + 1 > active_size) {
int ti = active_size;
line_t **ts;
SPL1();
#if defined(sun) || defined(NO_REALLOC_NULL)
if (active_list != NULL) {
#endif
if ((ts = (line_t **) realloc(active_list,
(ti += MINBUFSZ) * sizeof(line_t **))) == NULL) {
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "out of memory");
SPL0();
return ERR;
}
#if defined(sun) || defined(NO_REALLOC_NULL)
} else {
if ((ts = (line_t **) malloc((ti += MINBUFSZ) *
sizeof(line_t **))) == NULL) {
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "out of memory");
SPL0();
return ERR;
}
}
#endif
active_size = ti;
active_list = ts;
SPL0();
}
active_list[active_last++] = lp;
return 0;
}
/* unset_active_nodes: remove a range of lines from the global-active list */
void
unset_active_nodes(line_t *np, line_t *mp)
{
line_t *lp;
long i;
for (lp = np; lp != mp; lp = lp->q_forw)
for (i = 0; i < active_last; i++)
if (active_list[active_ndx] == lp) {
active_list[active_ndx] = NULL;
active_ndx = INC_MOD(active_ndx, active_last - 1);
break;
} else active_ndx = INC_MOD(active_ndx, active_last - 1);
}
/* next_active_node: return the next global-active line node */
line_t *
next_active_node(void)
{
while (active_ptr < active_last && active_list[active_ptr] == NULL)
active_ptr++;
return (active_ptr < active_last) ? active_list[active_ptr++] : NULL;
}
/* clear_active_list: clear the global-active list */
void
clear_active_list(void)
{
SPL1();
active_size = active_last = active_ptr = active_ndx = 0;
free(active_list);
active_list = NULL;
SPL0();
}

View File

@@ -1,358 +0,0 @@
/* $NetBSD: io.c,v 1.9 2011/05/23 23:13:10 joerg Exp $ */
/* io.c: This file contains the i/o routines for the ed line editor */
/*-
* Copyright (c) 1993 Andrew Moore, Talke Studio.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
#ifndef lint
#if 0
static char *rcsid = "@(#)io.c,v 1.1 1994/02/01 00:34:41 alm Exp";
#else
__RCSID("$NetBSD: io.c,v 1.9 2011/05/23 23:13:10 joerg Exp $");
#endif
#endif /* not lint */
#include "ed.h"
/* read_file: read a named file/pipe into the buffer; return line count */
long
read_file(char *fn, long n)
{
FILE *fp;
long size;
fp = (*fn == '!') ? popen(fn + 1, "r") : fopen(strip_escapes(fn), "r");
if (fp == NULL) {
fprintf(stderr, "%s: %s\n", fn, strerror(errno));
sprintf(errmsg, "cannot open input file");
return ERR;
} else if ((size = read_stream(fp, n)) < 0)
return ERR;
else if (((*fn == '!') ? pclose(fp) : fclose(fp)) < 0) {
fprintf(stderr, "%s: %s\n", fn, strerror(errno));
sprintf(errmsg, "cannot close input file");
return ERR;
}
if (!scripted)
fprintf(stderr, "%lu\n", size);
return current_addr - n;
}
char *sbuf; /* file i/o buffer */
int sbufsz; /* file i/o buffer size */
int newline_added; /* if set, newline appended to input file */
/* read_stream: read a stream into the editor buffer; return status */
long
read_stream(FILE *fp, long n)
{
line_t *lp = get_addressed_line_node(n);
undo_t *up = NULL;
unsigned long size = 0;
int o_newline_added = newline_added;
int o_isbinary = isbinary;
int appended = (n == addr_last);
int len;
isbinary = newline_added = 0;
if (des)
init_des_cipher();
for (current_addr = n; (len = get_stream_line(fp)) > 0; size += len) {
SPL1();
if (put_sbuf_line(sbuf) == NULL) {
SPL0();
return ERR;
}
lp = lp->q_forw;
if (up)
up->t = lp;
else if ((up = push_undo_stack(UADD, current_addr,
current_addr)) == NULL) {
SPL0();
return ERR;
}
SPL0();
}
if (len < 0)
return ERR;
if (appended && size && o_isbinary && o_newline_added)
fputs("newline inserted\n", stderr);
else if (newline_added && (!appended || (!isbinary && !o_isbinary)))
fputs("newline appended\n", stderr);
if (isbinary && newline_added && !appended)
size += 1;
if (!size)
newline_added = 1;
newline_added = appended ? newline_added : o_newline_added;
isbinary = isbinary | o_isbinary;
if (des)
size += 8 - size % 8; /* adjust DES size */
return size;
}
/* get_stream_line: read a line of text from a stream; return line length */
int
get_stream_line(FILE *fp)
{
int c;
int i = 0;
while (((c = des ? get_des_char(fp) : getc(fp)) != EOF || (!feof(fp) &&
!ferror(fp))) && c != '\n') {
REALLOC(sbuf, sbufsz, i + 1, ERR);
if (!(sbuf[i++] = c))
isbinary = 1;
}
REALLOC(sbuf, sbufsz, i + 2, ERR);
if (c == '\n')
sbuf[i++] = c;
else if (ferror(fp)) {
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "cannot read input file");
return ERR;
} else if (i) {
sbuf[i++] = '\n';
newline_added = 1;
}
sbuf[i] = '\0';
return (isbinary && newline_added && i) ? --i : i;
}
/* write_file: write a range of lines to a named file/pipe; return line count */
long
write_file(const char *fn, const char *mode, long n, long m)
{
FILE *fp;
long size;
fp = (*fn == '!') ? popen(fn+1, "w") : fopen(strip_escapes(fn), mode);
if (fp == NULL) {
fprintf(stderr, "%s: %s\n", fn, strerror(errno));
sprintf(errmsg, "cannot open output file");
return ERR;
} else if ((size = write_stream(fp, n, m)) < 0)
return ERR;
else if (((*fn == '!') ? pclose(fp) : fclose(fp)) < 0) {
fprintf(stderr, "%s: %s\n", fn, strerror(errno));
sprintf(errmsg, "cannot close output file");
return ERR;
}
if (!scripted)
fprintf(stderr, "%lu\n", size);
return n ? m - n + 1 : 0;
}
/* write_stream: write a range of lines to a stream; return status */
long
write_stream(FILE *fp, long n, long m)
{
line_t *lp = get_addressed_line_node(n);
unsigned long size = 0;
char *s;
int len;
if (des)
init_des_cipher();
for (; n && n <= m; n++, lp = lp->q_forw) {
if ((s = get_sbuf_line(lp)) == NULL)
return ERR;
len = lp->len;
if (n != addr_last || !isbinary || !newline_added)
s[len++] = '\n';
if (put_stream_line(fp, s, len) < 0)
return ERR;
size += len;
}
if (des) {
flush_des_file(fp); /* flush buffer */
size += 8 - size % 8; /* adjust DES size */
}
return size;
}
/* put_stream_line: write a line of text to a stream; return status */
int
put_stream_line(FILE *fp, char *s, int len)
{
while (len--)
if ((des ? put_des_char(*s++, fp) : fputc(*s++, fp)) < 0) {
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "cannot write file");
return ERR;
}
return 0;
}
/* get_extended_line: get a an extended line from stdin */
char *
get_extended_line(int *sizep, int nonl)
{
static char *cvbuf = NULL; /* buffer */
static int cvbufsz = 0; /* buffer size */
int l, n;
char *t = ibufp;
while (*t++ != '\n')
;
if ((l = t - ibufp) < 2 || !has_trailing_escape(ibufp, ibufp + l - 1)) {
*sizep = l;
return ibufp;
}
*sizep = -1;
REALLOC(cvbuf, cvbufsz, l, NULL);
memcpy(cvbuf, ibufp, l);
*(cvbuf + --l - 1) = '\n'; /* strip trailing esc */
if (nonl) l--; /* strip newline */
for (;;) {
if ((n = get_tty_line()) < 0)
return NULL;
else if (n == 0 || ibuf[n - 1] != '\n') {
sprintf(errmsg, "unexpected end-of-file");
return NULL;
}
REALLOC(cvbuf, cvbufsz, l + n, NULL);
memcpy(cvbuf + l, ibuf, n);
l += n;
if (n < 2 || !has_trailing_escape(cvbuf, cvbuf + l - 1))
break;
*(cvbuf + --l - 1) = '\n'; /* strip trailing esc */
if (nonl) l--; /* strip newline */
}
REALLOC(cvbuf, cvbufsz, l + 1, NULL);
cvbuf[l] = '\0';
*sizep = l;
return cvbuf;
}
/* get_tty_line: read a line of text from stdin; return line length */
int
get_tty_line(void)
{
int oi = 0;
int i = 0;
int c;
for (;;)
switch (c = getchar()) {
default:
oi = 0;
REALLOC(ibuf, ibufsz, i + 2, ERR);
if (!(ibuf[i++] = c)) isbinary = 1;
if (c != '\n')
continue;
lineno++;
ibuf[i] = '\0';
ibufp = ibuf;
return i;
case EOF:
if (ferror(stdin)) {
fprintf(stderr, "stdin: %s\n", strerror(errno));
sprintf(errmsg, "cannot read stdin");
clearerr(stdin);
ibufp = NULL;
return ERR;
} else {
clearerr(stdin);
if (i != oi) {
oi = i;
continue;
} else if (i)
ibuf[i] = '\0';
ibufp = ibuf;
return i;
}
}
}
#define ESCAPES "\a\b\f\n\r\t\v\\"
#define ESCCHARS "abfnrtv\\"
/* put_tty_line: print text to stdout */
int
put_tty_line(char *s, int l, long n, int gflag)
{
int col = 0;
char *cp;
#ifndef BACKWARDS
int lc = 0;
#endif
if (gflag & GNP) {
printf("%ld\t", n);
col = 8;
}
for (; l--; s++) {
if ((gflag & GLS) && ++col > cols) {
fputs("\\\n", stdout);
col = 1;
#ifndef BACKWARDS
if (!scripted && !isglobal && ++lc > rows) {
lc = 0;
fputs("Press <RETURN> to continue... ", stdout);
fflush(stdout);
if (get_tty_line() < 0)
return ERR;
}
#endif
}
if (gflag & GLS) {
if (31 < *s && *s < 127 && *s != '\\')
putchar(*s);
else {
putchar('\\');
col++;
if (*s && (cp = strchr(ESCAPES, *s)) != NULL)
putchar(ESCCHARS[cp - ESCAPES]);
else {
putchar((((unsigned char) *s & 0300) >> 6) + '0');
putchar((((unsigned char) *s & 070) >> 3) + '0');
putchar(((unsigned char) *s & 07) + '0');
col += 2;
}
}
} else
putchar(*s);
}
#ifndef BACKWARDS
if (gflag & GLS)
putchar('$');
#endif
putchar('\n');
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,135 +0,0 @@
/* $NetBSD: re.c,v 1.19 2005/02/17 16:29:26 xtraeme Exp $ */
/* re.c: This file contains the regular expression interface routines for
the ed line editor. */
/*-
* Copyright (c) 1993 Andrew Moore, Talke Studio.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
#ifndef lint
#if 0
static char *rcsid = "@(#)re.c,v 1.6 1994/02/01 00:34:43 alm Exp";
#else
__RCSID("$NetBSD: re.c,v 1.19 2005/02/17 16:29:26 xtraeme Exp $");
#endif
#endif /* not lint */
#include "ed.h"
char errmsg[MAXPATHLEN + 40] = "";
/* get_compiled_pattern: return pointer to compiled pattern from command
buffer */
pattern_t *
get_compiled_pattern(void)
{
static pattern_t *expr = NULL;
char *exps;
char delimiter;
int n;
if ((delimiter = *ibufp) == ' ') {
sprintf(errmsg, "invalid pattern delimiter");
return NULL;
} else if (delimiter == '\n' || *++ibufp == '\n' || *ibufp == delimiter) {
if (!expr) sprintf(errmsg, "no previous pattern");
return expr;
} else if ((exps = extract_pattern(delimiter)) == NULL)
return NULL;
/* buffer alloc'd && not reserved */
if (expr && !patlock)
regfree(expr);
else if ((expr = (pattern_t *) malloc(sizeof(pattern_t))) == NULL) {
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "out of memory");
return NULL;
}
patlock = 0;
if ((n = regcomp(expr, exps, ere)) != 0) {
regerror(n, expr, errmsg, sizeof errmsg);
free(expr);
return expr = NULL;
}
return expr;
}
/* extract_pattern: copy a pattern string from the command buffer; return
pointer to the copy */
char *
extract_pattern(int delimiter)
{
static char *lhbuf = NULL; /* buffer */
static int lhbufsz = 0; /* buffer size */
char *nd;
int len;
for (nd = ibufp; *nd != delimiter && *nd != '\n'; nd++)
switch (*nd) {
default:
break;
case '[':
if ((nd = parse_char_class(++nd)) == NULL) {
sprintf(errmsg, "unbalanced brackets ([])");
return NULL;
}
break;
case '\\':
if (*++nd == '\n') {
sprintf(errmsg, "trailing backslash (\\)");
return NULL;
}
break;
}
len = nd - ibufp;
REALLOC(lhbuf, lhbufsz, len + 1, NULL);
memcpy(lhbuf, ibufp, len);
lhbuf[len] = '\0';
ibufp = nd;
return (isbinary) ? NUL_TO_NEWLINE(lhbuf, len) : lhbuf;
}
/* parse_char_class: expand a POSIX character class */
char *
parse_char_class(char *s)
{
int c, d;
if (*s == '^')
s++;
if (*s == ']')
s++;
for (; *s != ']' && *s != '\n'; s++)
if (*s == '[' && ((d = *(s+1)) == '.' || d == ':' || d == '='))
for (s++, c = *++s; *s != ']' || c != d; s++)
if ((c = *s) == '\n')
return NULL;
return (*s == ']') ? s : NULL;
}

View File

@@ -1,260 +0,0 @@
/* $NetBSD: sub.c,v 1.6 2005/02/17 16:29:26 xtraeme Exp $ */
/* sub.c: This file contains the substitution routines for the ed
line editor */
/*-
* Copyright (c) 1993 Andrew Moore, Talke Studio.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
#ifndef lint
#if 0
static char *rcsid = "@(#)sub.c,v 1.1 1994/02/01 00:34:44 alm Exp";
#else
__RCSID("$NetBSD: sub.c,v 1.6 2005/02/17 16:29:26 xtraeme Exp $");
#endif
#endif /* not lint */
#include "ed.h"
char *rhbuf; /* rhs substitution buffer */
int rhbufsz; /* rhs substitution buffer size */
int rhbufi; /* rhs substitution buffer index */
/* extract_subst_tail: extract substitution tail from the command buffer */
int
extract_subst_tail(int *flagp, long *np)
{
char delimiter;
*flagp = *np = 0;
if ((delimiter = *ibufp) == '\n') {
rhbufi = 0;
*flagp = GPR;
return 0;
} else if (extract_subst_template() == NULL)
return ERR;
else if (*ibufp == '\n') {
*flagp = GPR;
return 0;
} else if (*ibufp == delimiter)
ibufp++;
if ('1' <= *ibufp && *ibufp <= '9') {
STRTOL(*np, ibufp);
return 0;
} else if (*ibufp == 'g') {
ibufp++;
*flagp = GSG;
return 0;
}
return 0;
}
/* extract_subst_template: return pointer to copy of substitution template
in the command buffer */
char *
extract_subst_template(void)
{
int n = 0;
int i = 0;
char c;
char delimiter = *ibufp++;
if (*ibufp == '%' && *(ibufp + 1) == delimiter) {
ibufp++;
if (!rhbuf) sprintf(errmsg, "no previous substitution");
return rhbuf;
}
while (*ibufp != delimiter) {
REALLOC(rhbuf, rhbufsz, i + 2, NULL);
if ((c = rhbuf[i++] = *ibufp++) == '\n' && *ibufp == '\0') {
i--, ibufp--;
break;
} else if (c != '\\')
;
else if ((rhbuf[i++] = *ibufp++) != '\n')
;
else if (!isglobal) {
while ((n = get_tty_line()) == 0 ||
(n > 0 && ibuf[n - 1] != '\n'))
clearerr(stdin);
if (n < 0)
return NULL;
}
}
REALLOC(rhbuf, rhbufsz, i + 1, NULL);
rhbuf[rhbufi = i] = '\0';
return rhbuf;
}
char *rbuf; /* substitute_matching_text buffer */
int rbufsz; /* substitute_matching_text buffer size */
/* search_and_replace: for each line in a range, change text matching a pattern
according to a substitution template; return status */
int
search_and_replace(pattern_t *pat, int gflag, int kth)
{
undo_t *up;
char *txt;
char *eot;
long lc;
long xa = current_addr;
int nsubs = 0;
line_t *lp;
int len;
current_addr = first_addr - 1;
for (lc = 0; lc <= second_addr - first_addr; lc++) {
lp = get_addressed_line_node(++current_addr);
if ((len = substitute_matching_text(pat, lp, gflag, kth)) < 0)
return ERR;
else if (len) {
up = NULL;
if (delete_lines(current_addr, current_addr) < 0)
return ERR;
txt = rbuf;
eot = rbuf + len;
SPL1();
do {
if ((txt = put_sbuf_line(txt)) == NULL) {
SPL0();
return ERR;
} else if (up)
up->t = get_addressed_line_node(current_addr);
else if ((up = push_undo_stack(UADD,
current_addr, current_addr)) == NULL) {
SPL0();
return ERR;
}
} while (txt != eot);
SPL0();
nsubs++;
xa = current_addr;
}
}
current_addr = xa;
if (nsubs == 0 && !(gflag & GLB)) {
sprintf(errmsg, "no match");
return ERR;
} else if ((gflag & (GPR | GLS | GNP)) &&
display_lines(current_addr, current_addr, gflag) < 0)
return ERR;
return 0;
}
/* substitute_matching_text: replace text matched by a pattern according to
a substitution template; return pointer to the modified text */
int
substitute_matching_text(pattern_t *pat, line_t *lp, int gflag, int kth)
{
int off = 0;
int changed = 0;
int matchno = 0;
int i = 0;
regmatch_t rm[SE_MAX];
char *txt;
char *eot;
if ((txt = get_sbuf_line(lp)) == NULL)
return ERR;
if (isbinary)
NUL_TO_NEWLINE(txt, lp->len);
eot = txt + lp->len;
if (!regexec(pat, txt, SE_MAX, rm, 0)) {
do {
if (!kth || kth == ++matchno) {
changed++;
i = rm[0].rm_so;
REALLOC(rbuf, rbufsz, off + i, ERR);
if (isbinary)
NEWLINE_TO_NUL(txt, rm[0].rm_eo);
memcpy(rbuf + off, txt, i);
off += i;
if ((off = apply_subst_template(txt, rm, off,
pat->re_nsub)) < 0)
return ERR;
} else {
i = rm[0].rm_eo;
REALLOC(rbuf, rbufsz, off + i, ERR);
if (isbinary)
NEWLINE_TO_NUL(txt, i);
memcpy(rbuf + off, txt, i);
off += i;
}
txt += rm[0].rm_eo;
} while (*txt && (!changed || ((gflag & GSG) && rm[0].rm_eo))
&& !regexec(pat, txt, SE_MAX, rm, REG_NOTBOL));
i = eot - txt;
REALLOC(rbuf, rbufsz, off + i + 2, ERR);
if (i > 0 && !rm[0].rm_eo && (gflag & GSG)) {
sprintf(errmsg, "infinite substitution loop");
return ERR;
}
if (isbinary)
NEWLINE_TO_NUL(txt, i);
memcpy(rbuf + off, txt, i);
memcpy(rbuf + off + i, "\n", 2);
}
return changed ? off + i + 1 : 0;
}
/* apply_subst_template: modify text according to a substitution template;
return offset to end of modified text */
int
apply_subst_template(char *boln, regmatch_t *rm, int off, int re_nsub)
{
int j = 0;
int k = 0;
int n;
char *sub = rhbuf;
for (; sub - rhbuf < rhbufi; sub++)
if (*sub == '&') {
j = rm[0].rm_so;
k = rm[0].rm_eo;
REALLOC(rbuf, rbufsz, off + k - j, ERR);
while (j < k)
rbuf[off++] = boln[j++];
} else if (*sub == '\\' && '1' <= *++sub && *sub <= '9' &&
(n = *sub - '0') <= re_nsub) {
j = rm[n].rm_so;
k = rm[n].rm_eo;
REALLOC(rbuf, rbufsz, off + k - j, ERR);
while (j < k)
rbuf[off++] = boln[j++];
} else {
REALLOC(rbuf, rbufsz, off + 1, ERR);
rbuf[off++] = *sub;
}
REALLOC(rbuf, rbufsz, off + 1, ERR);
rbuf[off] = '\0';
return off;
}

Some files were not shown because too many files have changed in this diff Show More