summaryrefslogtreecommitdiff
path: root/pkgtools
diff options
context:
space:
mode:
authorapb <apb@pkgsrc.org>2012-10-31 14:41:55 +0000
committerapb <apb@pkgsrc.org>2012-10-31 14:41:55 +0000
commit880c31542f9cfe4d0d9742ae4d9120a51f109ee0 (patch)
treec9a973db269a5b79b9a93d08a46ea890e118eeb0 /pkgtools
parentb1ceb4997fa77eb11c2b489d71330bba1e6fd871 (diff)
downloadpkgsrc-880c31542f9cfe4d0d9742ae4d9120a51f109ee0.tar.gz
Add the ability for libkver to override all four of ostype, osrelease,
machine, and machine_arch. Add a helper script to simplify use of libkver. Set VERSION=0.7. An earlier version of this change was reviewed by seb@NetBSD.org.
Diffstat (limited to 'pkgtools')
-rw-r--r--pkgtools/libkver/Makefile13
-rw-r--r--pkgtools/libkver/PLIST5
-rw-r--r--pkgtools/libkver/files/Makefile4
-rw-r--r--pkgtools/libkver/files/kver/Makefile4
-rw-r--r--pkgtools/libkver/files/kver/kver.8145
-rw-r--r--pkgtools/libkver/files/kver/kver.sh247
-rw-r--r--pkgtools/libkver/files/lib/kver.3142
-rw-r--r--pkgtools/libkver/files/lib/kver.c188
8 files changed, 696 insertions, 52 deletions
diff --git a/pkgtools/libkver/Makefile b/pkgtools/libkver/Makefile
index ed7095be0c7..931a6de61e0 100644
--- a/pkgtools/libkver/Makefile
+++ b/pkgtools/libkver/Makefile
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.31 2012/09/11 23:19:35 asau Exp $
+# $NetBSD: Makefile,v 1.32 2012/10/31 14:41:55 apb Exp $
DISTNAME= libkver-${VERSION}
CATEGORIES= pkgtools
@@ -18,7 +18,7 @@ CHECK_PERMS= no
NO_PKGTOOLS_REQD_CHECK= yes
USE_BSD_MAKEFILE= yes
-VERSION= 0.6
+VERSION= 0.7
ONLY_FOR_PLATFORM= NetBSD-*-*
@@ -34,7 +34,14 @@ FILES_SUBST+= HAS_SYSCTL=true
FILES_SUBST+= HAS_SYSCTL=false
.endif
-INSTALLATION_DIRS+= lib man/man3 man/cat3
+SUBST_CLASSES+= paths
+SUBST_FILES.paths= kver/kver.sh kver/kver.8 lib/kver.3
+SUBST_SED.paths+= -e 's,@PREFIX@,${PREFIX},g'
+SUBST_SED.paths+= -e 's,@SH@,${SH},g'
+SUBST_STAGE.paths= post-patch
+
+INSTALLATION_DIRS+= sbin ${PKGMANDIR}/man8 ${PKGMANDIR}/cat8
+INSTALLATION_DIRS+= lib ${PKGMANDIR}/man3 ${PKGMANDIR}/cat3
.if empty(LDD_SYSCTL:M*libc*)
INSTALLATION_DIRS+= sbin
.endif
diff --git a/pkgtools/libkver/PLIST b/pkgtools/libkver/PLIST
index 56ed050cf42..b49780a17a5 100644
--- a/pkgtools/libkver/PLIST
+++ b/pkgtools/libkver/PLIST
@@ -1,8 +1,11 @@
-@comment $NetBSD: PLIST,v 1.3 2008/04/12 22:43:09 jlam Exp $
+@comment $NetBSD: PLIST,v 1.4 2012/10/31 14:41:55 apb Exp $
lib/libkver.a
lib/libkver.so
lib/libkver.so.1
lib/libkver.so.1.0
man/cat3/kver.0
+man/cat8/kver.0
man/man3/kver.3
+man/man8/kver.8
+sbin/kver
${PLIST.sysctl}sbin/sysctl
diff --git a/pkgtools/libkver/files/Makefile b/pkgtools/libkver/files/Makefile
index 6fd0ea8fed4..f77513e5383 100644
--- a/pkgtools/libkver/files/Makefile
+++ b/pkgtools/libkver/files/Makefile
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.3 2003/12/13 17:45:59 seb Exp $
+# $NetBSD: Makefile,v 1.4 2012/10/31 14:41:55 apb Exp $
-SUBDIR= lib
+SUBDIR= kver lib
.ifndef(LDD_SYSCTL)
LDD_SYSCTL!= ldd /sbin/sysctl 2>&1
diff --git a/pkgtools/libkver/files/kver/Makefile b/pkgtools/libkver/files/kver/Makefile
new file mode 100644
index 00000000000..d3721e45591
--- /dev/null
+++ b/pkgtools/libkver/files/kver/Makefile
@@ -0,0 +1,4 @@
+MAN= kver.8
+SCRIPTS= kver.sh
+
+.include <bsd.prog.mk>
diff --git a/pkgtools/libkver/files/kver/kver.8 b/pkgtools/libkver/files/kver/kver.8
new file mode 100644
index 00000000000..0fcfbe62f1e
--- /dev/null
+++ b/pkgtools/libkver/files/kver/kver.8
@@ -0,0 +1,145 @@
+.\" $NetBSD: kver.8,v 1.1 2012/10/31 14:41:55 apb Exp $
+.\"
+.Dd October 31, 2012
+.Os
+.Dt KVER 8
+.Sh NAME
+.Nm kver
+.Nd run a command with overriden system version
+.Sh SYNOPSIS
+.Nm
+.Op Fl s Ar ostype
+.Op Fl r Ar osrelease
+.Op Fl m Ar machine
+.Op Fl p Ar machine_arch
+.Ar command
+.Op Ar argument ...
+.Sh DESCRIPTION
+The
+.Nm
+utility
+provides a simple wrapper around the
+.Xr kver 3
+library.
+It converts its options to environment variables understood by
+.Xr kver 3 ,
+sets the
+.Ev LD_PRELOAD
+environment variable to ensure that the
+.Xr kver 3
+library
+.Pq Pa @PREFIX@/lib/libkver.so
+is loaded,
+and executes the specified
+.Ar command
+with the specified
+.Ar argument Ns s .
+.Pp
+The following options are accepted:
+.Bl -tag -offset indent
+.It Fl s Ar ostype
+The operating system type, e.g.
+.Qq Nx .
+Sets the
+.Ev LIBKVER_OSTYPE
+environment variable.
+.It Fl r Ar osrelease
+The operating system release, e.g.
+.Qq "6.0_STABLE" .
+Sets the
+.Ev LIBKVER_OSRELEASE
+environment variable.
+.It Fl m Ar machine
+The operating hardware platform, e.g.
+.Dq "amd64" .
+Sets the
+.Ev LIBKVER_MACHINE
+environment variable.
+.It Fl p Ar machine_arch
+The machine processor architecture, e.g.
+.Dq "x86_64" .
+Sets the
+.Ev LIBKVER_MACHINE_ARCH
+environment variable.
+.El
+.Pp
+If the
+.Fl m Ar machine
+option is specified and the
+.Fl p Ar machine_arch
+option is not specified, then
+.Nm
+checks that
+.Ar machine
+is valid, and attempts to set an appropriate value for
+.Va machine_arch ;
+for example,
+.Dq "-m macppc"
+implies
+.Dq "-p powerpc" .
+Some aliases for
+.Ar machine Ns / Ns Ar machine_arch
+pairs are also supported; for example,
+.Dq "-m macppc64"
+is shorthand for
+.Dq "-m macppc -p powerpc64" .
+The way
+.Nm
+handles a
+.Ar machine
+name without a
+.Ar machine_arch
+name is intended to be identical to the way the
+.Pa build.sh
+script in the
+.Nx
+source tree handles the same situation.
+To pass arbitrary values of
+.Fl m Ar machine
+without any validation, you must also specify
+.Fl p Ar machine_arch .
+.Sh EXAMPLES
+.Bl -tag
+.It Li "kver -r 1.5 uname -r"
+Run the
+.Ql "uname -r"
+command with
+.Va osrelease
+set to
+.Ql 1.5 .
+.It Li "kver -m i386 chroot ."
+Run the
+.Ql "chroot ."
+command with
+.Va machine
+set to
+.Ql i386
+and with
+.Va machine_arch
+set to
+.Ql i386
+(which is the default
+.Va machine_arch
+for that
+.Va machine ) .
+.It Li "kver -m evbmips sysctl hw.machine_arch"
+Error, because there is no default
+.Va machine_arch
+corresponding to
+.Dq "-m evbmips" .
+.It Li "kver -m evbmips -p mipseb sysctl hw.machine_arch"
+Run the
+.Ql "sysctl hw.machine_arch"
+command with
+.Va machine
+set to
+.Ql evbmips
+and
+.Va machine_arch
+set to
+.Ql mipseb .
+.El
+.Sh SEE ALSO
+.Xr kver 3
+.Sh AUTHORS
+.An Alan Barrett Aq apb@NetBSD.org
diff --git a/pkgtools/libkver/files/kver/kver.sh b/pkgtools/libkver/files/kver/kver.sh
new file mode 100644
index 00000000000..75c1b1ad5fc
--- /dev/null
+++ b/pkgtools/libkver/files/kver/kver.sh
@@ -0,0 +1,247 @@
+#!@SH@
+
+LIBKVER='@PREFIX@/lib/libkver.so'
+EX_USAGE=64
+nl='
+'
+tab=' '
+
+usage()
+{
+ cat <<ENDUSAGE;
+usage: $0 [-s ostype] [-r osrelease] [-m machine] [-p arch] command [args]
+ENDUSAGE
+}
+
+bomb()
+{
+ echo >&2 "$0: $*"
+ exit $EX_USAGE
+}
+
+# begin code copied from build.sh {{{
+
+# valid_MACHINE_ARCH -- A multi-line string, listing all valid
+# MACHINE/MACHINE_ARCH pairs.
+#
+# Each line contains a MACHINE and MACHINE_ARCH value, an optional ALIAS
+# which may be used to refer to the MACHINE/MACHINE_ARCH pair, and an
+# optional DEFAULT or NO_DEFAULT keyword.
+#
+# When a MACHINE corresponds to multiple possible values of
+# MACHINE_ARCH, then this table should list all allowed combinations.
+# If the MACHINE is associated with a default MACHINE_ARCH (to be
+# used when the user specifies the MACHINE but fails to specify the
+# MACHINE_ARCH), then one of the lines should have the "DEFAULT"
+# keyword. If there is no default MACHINE_ARCH for a particular
+# MACHINE, then there should be a line with the "NO_DEFAULT" keyword,
+# and with a blank MACHINE_ARCH.
+#
+valid_MACHINE_ARCH='
+MACHINE=acorn26 MACHINE_ARCH=arm
+MACHINE=acorn32 MACHINE_ARCH=arm
+MACHINE=algor MACHINE_ARCH=mips64el ALIAS=algor64
+MACHINE=algor MACHINE_ARCH=mipsel DEFAULT
+MACHINE=alpha MACHINE_ARCH=alpha
+MACHINE=amd64 MACHINE_ARCH=x86_64
+MACHINE=amiga MACHINE_ARCH=m68k
+MACHINE=amigappc MACHINE_ARCH=powerpc
+MACHINE=arc MACHINE_ARCH=mips64el ALIAS=arc64
+MACHINE=arc MACHINE_ARCH=mipsel DEFAULT
+MACHINE=atari MACHINE_ARCH=m68k
+MACHINE=bebox MACHINE_ARCH=powerpc
+MACHINE=cats MACHINE_ARCH=arm DEFAULT
+MACHINE=cats MACHINE_ARCH=earm
+MACHINE=cesfic MACHINE_ARCH=m68k
+MACHINE=cobalt MACHINE_ARCH=mips64el ALIAS=cobalt64
+MACHINE=cobalt MACHINE_ARCH=mipsel DEFAULT
+MACHINE=dreamcast MACHINE_ARCH=sh3el
+MACHINE=emips MACHINE_ARCH=mipseb
+MACHINE=evbarm MACHINE_ARCH=arm ALIAS=evbarm-el DEFAULT
+MACHINE=evbarm MACHINE_ARCH=armeb ALIAS=evbarm-eb
+MACHINE=evbarm MACHINE_ARCH=earm ALIAS=evbearm-el
+MACHINE=evbarm MACHINE_ARCH=earmeb ALIAS=evbearm-eb
+MACHINE=evbmips MACHINE_ARCH= NO_DEFAULT
+MACHINE=evbmips MACHINE_ARCH=mips64eb ALIAS=evbmips64-eb
+MACHINE=evbmips MACHINE_ARCH=mips64el ALIAS=evbmips64-el
+MACHINE=evbmips MACHINE_ARCH=mipseb ALIAS=evbmips-eb
+MACHINE=evbmips MACHINE_ARCH=mipsel ALIAS=evbmips-el
+MACHINE=evbppc MACHINE_ARCH=powerpc DEFAULT
+MACHINE=evbppc MACHINE_ARCH=powerpc64 ALIAS=evbppc64
+MACHINE=evbsh3 MACHINE_ARCH= NO_DEFAULT
+MACHINE=evbsh3 MACHINE_ARCH=sh3eb ALIAS=evbsh3-eb
+MACHINE=evbsh3 MACHINE_ARCH=sh3el ALIAS=evbsh3-el
+MACHINE=ews4800mips MACHINE_ARCH=mipseb
+MACHINE=hp300 MACHINE_ARCH=m68k
+MACHINE=hp700 MACHINE_ARCH=hppa
+MACHINE=hpcarm MACHINE_ARCH=arm
+MACHINE=hpcmips MACHINE_ARCH=mipsel
+MACHINE=hpcsh MACHINE_ARCH=sh3el
+MACHINE=i386 MACHINE_ARCH=i386
+MACHINE=ia64 MACHINE_ARCH=ia64
+MACHINE=ibmnws MACHINE_ARCH=powerpc
+MACHINE=iyonix MACHINE_ARCH=arm DEFAULT
+MACHINE=iyonix MACHINE_ARCH=earm
+MACHINE=landisk MACHINE_ARCH=sh3el
+MACHINE=luna68k MACHINE_ARCH=m68k
+MACHINE=mac68k MACHINE_ARCH=m68k
+MACHINE=macppc MACHINE_ARCH=powerpc DEFAULT
+MACHINE=macppc MACHINE_ARCH=powerpc64 ALIAS=macppc64
+MACHINE=mipsco MACHINE_ARCH=mipseb
+MACHINE=mmeye MACHINE_ARCH=sh3eb
+MACHINE=mvme68k MACHINE_ARCH=m68k
+MACHINE=mvmeppc MACHINE_ARCH=powerpc
+MACHINE=netwinder MACHINE_ARCH=arm DEFAULT
+MACHINE=netwinder MACHINE_ARCH=earm
+MACHINE=news68k MACHINE_ARCH=m68k
+MACHINE=newsmips MACHINE_ARCH=mipseb
+MACHINE=next68k MACHINE_ARCH=m68k
+MACHINE=ofppc MACHINE_ARCH=powerpc DEFAULT
+MACHINE=ofppc MACHINE_ARCH=powerpc64 ALIAS=ofppc64
+MACHINE=pmax MACHINE_ARCH=mips64el ALIAS=pmax64
+MACHINE=pmax MACHINE_ARCH=mipsel DEFAULT
+MACHINE=prep MACHINE_ARCH=powerpc
+MACHINE=rs6000 MACHINE_ARCH=powerpc
+MACHINE=sandpoint MACHINE_ARCH=powerpc
+MACHINE=sbmips MACHINE_ARCH= NO_DEFAULT
+MACHINE=sbmips MACHINE_ARCH=mips64eb ALIAS=sbmips64-eb
+MACHINE=sbmips MACHINE_ARCH=mips64el ALIAS=sbmips64-el
+MACHINE=sbmips MACHINE_ARCH=mipseb ALIAS=sbmips-eb
+MACHINE=sbmips MACHINE_ARCH=mipsel ALIAS=sbmips-el
+MACHINE=sgimips MACHINE_ARCH=mips64eb ALIAS=sgimips64
+MACHINE=sgimips MACHINE_ARCH=mipseb DEFAULT
+MACHINE=shark MACHINE_ARCH=arm DEFAULT
+MACHINE=shark MACHINE_ARCH=earm
+MACHINE=sparc MACHINE_ARCH=sparc
+MACHINE=sparc64 MACHINE_ARCH=sparc64
+MACHINE=sun2 MACHINE_ARCH=m68000
+MACHINE=sun3 MACHINE_ARCH=m68k
+MACHINE=vax MACHINE_ARCH=vax
+MACHINE=x68k MACHINE_ARCH=m68k
+MACHINE=zaurus MACHINE_ARCH=arm DEFAULT
+MACHINE=zaurus MACHINE_ARCH=earm
+'
+
+# getarch -- find the default MACHINE_ARCH for a MACHINE,
+# or convert an alias to a MACHINE/MACHINE_ARCH pair.
+#
+# Saves MACHINE in makewrappermachine before possibly modifying MACHINE.
+#
+# Sets MACHINE and MACHINE_ARCH if the input MACHINE value is
+# recognised as an alias, or recognised as a machine that has a default
+# MACHINE_ARCH (or that has only one possible MACHINE_ARCH).
+#
+# Leaves MACHINE and MACHINE_ARCH unchanged if MACHINE is recognised
+# as being associated with multiple MACHINE_ARCH values with no default.
+#
+# Bombs if MACHINE is not recognised.
+#
+getarch()
+{
+ local IFS
+ local found=""
+ local line
+
+ IFS="${nl}"
+ makewrappermachine="${MACHINE}"
+ for line in ${valid_MACHINE_ARCH}; do
+ line="${line%%#*}" # ignore comments
+ line="$( IFS=" ${tab}" ; echo $line )" # normalise white space
+ case "${line} " in
+ "")
+ # skip blank lines or comment lines
+ continue
+ ;;
+ *" ALIAS=${MACHINE} "*)
+ # Found a line with a matching ALIAS=<alias>.
+ found="$line"
+ break
+ ;;
+ "MACHINE=${MACHINE} "*" NO_DEFAULT"*)
+ # Found an explicit "NO_DEFAULT" for this MACHINE.
+ found="$line"
+ break
+ ;;
+ "MACHINE=${MACHINE} "*" DEFAULT"*)
+ # Found an explicit "DEFAULT" for this MACHINE.
+ found="$line"
+ break
+ ;;
+ "MACHINE=${MACHINE} "*)
+ # Found a line for this MACHINE. If it's the
+ # first such line, then tentatively accept it.
+ # If it's not the first matching line, then
+ # remember that there was more than one match.
+ case "$found" in
+ '') found="$line" ;;
+ *) found="MULTIPLE_MATCHES" ; break ;;
+ esac
+ ;;
+ esac
+ done
+
+ case "$found" in
+ *NO_DEFAULT*|*MULTIPLE_MATCHES*)
+ # MACHINE is OK, but MACHINE_ARCH is still unknown
+ return
+ ;;
+ "MACHINE="*" MACHINE_ARCH="*)
+ # Obey the MACHINE= and MACHINE_ARCH= parts of the line.
+ IFS=" "
+ for frag in ${found}; do
+ case "$frag" in
+ MACHINE=*|MACHINE_ARCH=*)
+ eval "$frag"
+ ;;
+ esac
+ done
+ ;;
+ *)
+ bomb "Unknown target MACHINE: ${MACHINE}"
+ ;;
+ esac
+}
+
+# end code copied from build.sh }}}
+
+
+# MAIN PROGRAM
+
+opt_s=""
+opt_r=""
+opt_m=""
+opt_p=""
+
+while getopts "s:r:m:p:" opt
+do
+ case "$opt" in
+ s) opt_s="$OPTARG"; export LIBKVER_OSTYPE="$OPTARG" ;;
+ r) opt_r="$OPTARG"; export LIBKVER_OSRELEASE="$OPTARG" ;;
+ m) opt_m="$OPTARG"; export LIBKVER_MACHINE="$OPTARG" ;;
+ p) opt_p="$OPTARG"; export LIBKVER_MACHINE_ARCH="$OPTARG" ;;
+ *) usage ; exit $EX_USAGE ;;
+ esac
+done
+shift $(($OPTIND - 1))
+if [ $# -eq 0 ]; then
+ usage
+ exit $EX_USAGE
+fi
+
+# If MACHINE was specified and MACHINE_ARCH was not specified,
+# then try to guess MACHINE_ARCH.
+if [ -n "$opt_m" ] && [ -z "$opt_p" ]; then
+ MACHINE="$opt_m"
+ getarch
+ if [ -n "$MACHINE_ARCH" ]; then
+ # in addition to setting MACHINE_ARCH,
+ # getarch might have modified MACHINE.
+ export LIBKVER_MACHINE="$MACHINE"
+ export LIBKVER_MACHINE_ARCH="$MACHINE_ARCH"
+ else
+ bomb "'-m ${MACHINE}' needs '-p <machine_arch>'"
+ fi
+fi
+
+export LD_PRELOAD="${LIBKVER}${LD_PRELOAD:+:}${LD_PRELOAD}"
+exec "$@"
diff --git a/pkgtools/libkver/files/lib/kver.3 b/pkgtools/libkver/files/lib/kver.3
index 56425ce07a1..c1bece385fe 100644
--- a/pkgtools/libkver/files/lib/kver.3
+++ b/pkgtools/libkver/files/lib/kver.3
@@ -1,13 +1,13 @@
-.\" $NetBSD: kver.3,v 1.2 2004/04/24 10:53:03 grant Exp $
+.\" $NetBSD: kver.3,v 1.3 2012/10/31 14:41:55 apb Exp $
.\"
-.Dd December 13, 2003
+.Dd October 31, 2012
.Os
.Dt KVER 3
.Sh NAME
.Nm kver
.Nd override system version library
.Sh SYNOPSIS
-LD_PRELOAD=.../libkver.so uname -a
+LD_PRELOAD=@PREFIX@/lib/libkver.so uname -a
.Sh DESCRIPTION
The
.Nm
@@ -16,24 +16,114 @@ library provides implementations of
.Xr uname 3 that
shadow the real implementation and could be configured to override the
information identifying the current system.
-The library is usually loaded by the run-time link-editor via the
-LD_PRELOAD hook.
-.Pp
This is useful for, among other things, building packages in a
sandbox/chrooted environment for a different
.Nx
release then the system hosting the sandbox.
.Pp
-The library must be configured for reporting a specific
-.Nx
-release or else it emits a warning message on the standard error output.
-The value of the environment variable
-.Ev LIBKVER_OSRELEASE
-or the ``name'' of the file referenced by the symbolic link named
-.Pa /libkver_osrelease
-are checked in that order for the
-.Nx
-release number the library should reports information for.
+The library is usually loaded by the run-time link-editor via the
+LD_PRELOAD hook.
+The
+.Xr kver 8
+utility provides a simple wrapper for convenience.
+.Pp
+For each variable that may be overridden,
+.Nm
+first attempts to obtain an override value from an environment variable;
+if the environment variable is not set then it uses
+.Xr readlink 3
+to get the target of a symbolic link, and treats that as the override value;
+if that also fails, then the variable is not overridden.
+If none of the variables are overridden, or if an error occurs, then
+the
+.Nm
+library emits a warning message on the standard error output,
+and allows the program to run without any overrides.
+.Pp
+The following table lists all the variables that may be overridden,
+giving the environment variable name, the symbolic link name,
+and a description of the way the value is used.
+.Pp
+.Bl -column "LIBKVER_MACHINE_ARCH" "/libkver_machine_arch"
+.It Sy Environment Ta Sy Symlink Ta Sy Description
+.
+.It Ev LIBKVER_OSTYPE Ta Pa /libkver_ostype Ta
+The operating system type, e.g.
+.Qq Nx .
+Overrides the
+.Xr sysctl 7
+variable
+.Va kern.ostype .
+Overrides the result from
+.Xr uname 1
+with the
+.Fl s
+flag.
+Overrides the
+.Va sysname
+element of the
+.Vt "struct utsname"
+result from
+.Xr uname 3 .
+.
+.It Ev LIBKVER_OSRELEASE Ta Pa /libkver_osrelease Ta
+The operating system release, e.g.
+.Qq "6.0_STABLE" .
+Overrides the
+.Xr sysctl 7
+variable
+.Va kern.osrelease .
+Overrides the result from
+.Xr uname 1
+with the
+.Fl r
+flag.
+Overrides the
+.Va release
+element of the
+.Vt "struct utsname"
+result from
+.Xr uname 3 .
+.Pp
+This value is also converted to an integer, which is used to
+override the value of the
+.Xr sysctl 7
+variable
+.Va kern.osrevision .
+.
+.It Ev LIBKVER_MACHINE Ta Pa /libkver_machine Ta
+The operating hardware platform, e.g.
+.Dq "amd64" .
+Overrides the
+.Xr sysctl 7
+variable
+.Va hw.machine .
+Overrides the result from
+.Xr uname 1
+with the
+.Fl m
+flag.
+Overrides the
+.Va machine
+element of the
+.Vt "struct utsname"
+result from
+.Xr uname 3 .
+.
+.It Ev LIBKVER_MACHINE_ARCH Ta Pa /libkver_machine_arch Ta
+The machine processor architecture, e.g.
+.Dq "x86_64" .
+Overrides the
+.Xr sysctl 7
+variable
+.Va hw.machine_arch .
+Overrides the result from
+.Xr uname 1
+with the
+.Fl p
+flag.
+.El
+.Pp
.Sh EXAMPLES
.Dl env LD_PRELOAD=/lib/libkver.so LIBKVER_OSRELEASE=1.5 uname -r
.Pp
@@ -41,7 +131,27 @@ release number the library should reports information for.
.Dl env LD_PRELOAD=/lib/libkver.so uname -r
.Sh SEE ALSO
.Xr ld.so 1 ,
+.Xr uname 1 ,
.Xr sysctl 3 ,
+.Xr uname 3 ,
+.Xr kver 8
+.Sh DIAGNOSTICS
+.Bl -diag
+.It "libkver: uname"
.Xr uname 3
+failed.
+.It "libkver: not configured"
+None of the configurable variables has been overridden.
+.It "libkver: sysctl hw.machine_arch"
+.Xr sysctl 3
+failed to retrieve the value of the
+.Va hw.machine_arch
+variable.
+.It "libkver: cannot convert osrelease to osrevision: %s"
+The osrelease string could not be converted to an integer for use by the
+.Va kern.osrevision
+.Xr sysctl 7
+variable.
.Sh AUTHORS
.An Stoned Elipot Aq seb@NetBSD.org
+.An Alan Barrett Aq apb@NetBSD.org
diff --git a/pkgtools/libkver/files/lib/kver.c b/pkgtools/libkver/files/lib/kver.c
index 7626b44bfbd..28210cfdebe 100644
--- a/pkgtools/libkver/files/lib/kver.c
+++ b/pkgtools/libkver/files/lib/kver.c
@@ -1,4 +1,4 @@
-/* $NetBSD: kver.c,v 1.10 2011/11/22 18:13:09 joerg Exp $ */
+/* $NetBSD: kver.c,v 1.11 2012/10/31 14:41:55 apb Exp $ */
#define sysctl _sysctl
#define uname _uname
@@ -19,11 +19,30 @@
#undef sysctl
#undef uname
-#define KVER_VERSION_FMT "NetBSD %s (LIBKVER) #0: Tue Jan 19 00:00:00 UTC 2038 root@localhost:/sys/arch/%s/compile/LIBKVER"
+
+#define KVER_VERSION_FMT "%s %s (LIBKVER) #0: Tue Jan 19 00:00:00 UTC 2038 root@localhost:/sys/arch/%s/compile/LIBKVER"
#define KVER_NOT_INITIALIZED_OSRELEASE -2
#define KVER_INVALID_OSRELEASE -1
+/*
+ * How to override the operating system name; e.g. "NetBSD".
+ * Used by sysctl kern.ostype, uname -s, struct utsname.sysname
+ */
+#ifndef PATH_LIBKVER_OSTYPE
+#define PATH_LIBKVER_OSTYPE "/libkver_ostype"
+#endif
+#ifndef VAR_LIBKVER_OSTYPE
+#define VAR_LIBKVER_OSTYPE "LIBKVER_OSTYPE"
+#endif
+
+/*
+ * How to override the operating system release level; e.g. "6.0_STABLE".
+ * Used by sysctl kern.osrelease, uname -r, struct utsname.release
+ *
+ * This is also coverted to an integer, e.g. 601000000,
+ * for use by sysctl.kern.osrevision.
+ */
#ifndef PATH_LIBKVER_OSRELEASE
#define PATH_LIBKVER_OSRELEASE "/libkver_osrelease"
#endif
@@ -31,12 +50,37 @@
#define VAR_LIBKVER_OSRELEASE "LIBKVER_OSRELEASE"
#endif
+/*
+ * How to override the machine hardware platform, e.g. "i386".
+ * Used by sysctl hw.machine, uname -m, struct utsname.machine.
+ */
+#ifndef PATH_LIBKVER_MACHINE
+#define PATH_LIBKVER_MACHINE "/libkver_machine"
+#endif
+#ifndef VAR_LIBKVER_MACHINE
+#define VAR_LIBKVER_MACHINE "LIBKVER_MACHINE"
+#endif
+
+/*
+ * How to override the machine processor architecture, e.g. "i386".
+ * Used by sysctl hw.machine_arch, uname -p.
+ */
+#ifndef PATH_LIBKVER_MACHINE_ARCH
+#define PATH_LIBKVER_MACHINE_ARCH "/libkver_machine_arch"
+#endif
+#ifndef VAR_LIBKVER_MACHINE_ARCH
+#define VAR_LIBKVER_MACHINE_ARCH "LIBKVER_MACHINE_ARCH"
+#endif
+
static struct kver {
+ char ostype[_SYS_NMLN];
char osrelease[_SYS_NMLN];
int osrevision;
char version[_SYS_NMLN];
+ char machine[_SYS_NMLN];
+ char machine_arch[_SYS_NMLN];
} kver = {
- "", KVER_NOT_INITIALIZED_OSRELEASE, ""
+ .osrevision = KVER_NOT_INITIALIZED_OSRELEASE
};
static struct utsname real_utsname;
@@ -48,7 +92,7 @@ static struct utsname real_utsname;
#define SYSCTL_STRING(oldp, oldlenp, str) \
if (oldlenp) { \
- len = strlen(str) + 1; \
+ size_t len = strlen(str) + 1; \
if (!oldp) \
*oldlenp = len; \
else { \
@@ -129,40 +173,109 @@ str2osrevision(char *s)
return KVER_INVALID_OSRELEASE;
}
+/*
+ * Initialise one element of struct kver.
+ *
+ * The result is based on getenv(envvarname), or readlink(linkname),
+ * or defaultval. If the provided defaultval is NULL, then the empty
+ * string is used.
+ *
+ * Returns 1 if a non-default value was used, 0 if a default was used.
+ */
+static int
+kver_init_var(char *dst, size_t dstlen, const char *envvar,
+ const char *linkname, const char *defaultval)
+{
+ ssize_t len;
+ char *v;
+
+ v = getenv(envvar);
+ if (v) {
+ (void) strlcpy(dst, v, dstlen);
+ return 1;
+ }
+ len = readlink(linkname, dst, dstlen);
+ if (len > 0) {
+ dst[len] = '\0';
+ return 1;
+ }
+ if (defaultval) {
+ (void) strlcpy(dst, defaultval, dstlen);
+ return 0;
+ }
+ dst[0] = '\0';
+ return 0;
+}
+
static void
kver_initialize(void)
{
char *v;
int i;
+ int nok = 0;
+ char buf[PATH_MAX + 1];
kver.osrevision = KVER_INVALID_OSRELEASE; /* init done */
- v = getenv(VAR_LIBKVER_OSRELEASE);
- if (v == NULL) {
- char b[MAXPATHLEN + 1];
- i = readlink(PATH_LIBKVER_OSRELEASE, b, sizeof b - 1);
- if (i <= 0) {
- v = NULL;
- } else {
- b[i] = '\0';
- v = b;
- }
+
+ if (_uname(&real_utsname) != 0) {
+ warn("libkver: uname");
+ return;
}
- if (v == NULL) {
+
+ /*
+ * For each variable that can be overridden: try the
+ * environment variable, then try the symlink, or fall back
+ * to the unmodified (existing) value.
+ */
+ nok += kver_init_var(kver.ostype, sizeof(kver.ostype),
+ VAR_LIBKVER_OSTYPE, PATH_LIBKVER_OSTYPE,
+ real_utsname.sysname);
+ nok += kver_init_var(kver.osrelease, sizeof(kver.osrelease),
+ VAR_LIBKVER_OSRELEASE, PATH_LIBKVER_OSRELEASE,
+ real_utsname.release);
+ nok += kver_init_var(kver.machine, sizeof(kver.machine),
+ VAR_LIBKVER_MACHINE, PATH_LIBKVER_MACHINE,
+ real_utsname.machine);
+ nok += kver_init_var(kver.machine_arch, sizeof(kver.machine_arch),
+ VAR_LIBKVER_MACHINE_ARCH, PATH_LIBKVER_MACHINE_ARCH,
+ "");
+
+ /*
+ * warning if the default was used for all variables. no warning
+ * if at least one non-default value was used.
+ */
+ if (nok == 0) {
warnx("libkver: not configured");
return;
}
- if (_uname(&real_utsname) != 0) {
- warn("libkver: uname");
- return;
+
+ /* machine_arch is not in struct utsname, so get default from sysctl */
+ if (kver.machine_arch[0] == '\0') {
+ int mib[] = { CTL_HW, HW_MACHINE_ARCH, 0 };
+ int len = sizeof(kver.machine_arch);
+ int err;
+
+ err = _sysctl(mib, 2, kver.machine_arch, &len, NULL, 0);
+ if (err < 0) {
+ warn("libkver: sysctl hw.machine_arch");
+ return;
+ }
}
- kver.osrevision = str2osrevision(v);
+
+ /* combine several strings to create kver.version */
+ (void) snprintf(kver.version, sizeof(kver.version), KVER_VERSION_FMT,
+ kver.ostype, kver.osrelease, kver.machine);
+
+ /*
+ * Convert string osrelease to integer osrevision.
+ * This must be the last thing we do, so that any failure
+ * resuls in kver.osrelease being set to KVER_INVALID_OSRELEASE.
+ */
+ kver.osrevision = str2osrevision(kver.osrelease);
if (kver.osrevision == KVER_INVALID_OSRELEASE) {
- warnx("libkver: invalid version: %s", v);
- return;
+ warnx("libkver: cannot convert osrelease to osrevision: %s",
+ kver.osrelease);
}
- (void) strncpy(kver.osrelease, v, _SYS_NMLN);
- kver.osrelease[_SYS_NMLN - 1] = '\0';
- (void) snprintf(kver.version, _SYS_NMLN, KVER_VERSION_FMT,
- kver.osrelease, real_utsname.machine);
+
return;
}
@@ -170,6 +283,8 @@ int
sysctl(SYSCTL_CONST int *name, u_int namelen, void *oldp, size_t * oldlenp,
const void *newp, size_t newlen)
{
+ int r = 0;
+
_DIAGASSERT(name != NULL);
if (newp != (void *) NULL)
@@ -181,10 +296,12 @@ sysctl(SYSCTL_CONST int *name, u_int namelen, void *oldp, size_t * oldlenp,
if (KVER_BADLY_INITIALIZED || namelen != 2)
goto real;
- if (name[0] == CTL_KERN) {
- size_t len;
- int r = 0;
+ switch (name[0]) {
+ case CTL_KERN: {
switch (name[1]) {
+ case KERN_OSTYPE:
+ SYSCTL_STRING(oldp, oldlenp, kver.ostype);
+ return (r);
case KERN_OSRELEASE:
SYSCTL_STRING(oldp, oldlenp, kver.osrelease);
return (r);
@@ -205,6 +322,17 @@ sysctl(SYSCTL_CONST int *name, u_int namelen, void *oldp, size_t * oldlenp,
return (r);
}
}
+ case CTL_HW: {
+ switch (name[1]) {
+ case HW_MACHINE:
+ SYSCTL_STRING(oldp, oldlenp, kver.machine);
+ return (r);
+ case HW_MACHINE_ARCH:
+ SYSCTL_STRING(oldp, oldlenp, kver.machine_arch);
+ return (r);
+ }
+ }
+ }
real: return (_sysctl(name, namelen, oldp, oldlenp, newp, newlen));
}
@@ -217,10 +345,10 @@ uname(struct utsname * n)
if (KVER_BADLY_INITIALIZED)
return _uname(n);
- (void) strncpy(n->sysname, real_utsname.sysname, _SYS_NMLN);
+ (void) strncpy(n->sysname, kver.ostype, _SYS_NMLN);
(void) strncpy(n->nodename, real_utsname.nodename, _SYS_NMLN);
(void) strncpy(n->release, kver.osrelease, _SYS_NMLN);
(void) strncpy(n->version, kver.version, _SYS_NMLN);
- (void) strncpy(n->machine, real_utsname.machine, _SYS_NMLN);
+ (void) strncpy(n->machine, kver.machine, _SYS_NMLN);
return 0;
}