Reintegrate head revisions r273096-r277147

Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Glen Barber 2015-01-13 21:29:24 +00:00
commit 8f0ea33f2b
10631 changed files with 942496 additions and 538837 deletions

View file

@ -4,7 +4,7 @@
The compilation of software known as FreeBSD is distributed under the
following terms:
Copyright (c) 1992-2014 The FreeBSD Project. All rights reserved.
Copyright (c) 1992-2015 The FreeBSD Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

View file

@ -48,8 +48,6 @@ cd(4) ken Pre-commit review requested.
pass(4) ken Pre-commit review requested.
ch(4) ken Pre-commit review requested.
em(4) jfv Pre-commit review requested.
bxe(4) davidch Pre-commit review requested.
tdfx(4) cokane Just keep me informed of changes, try not to break it.
sendmail gshapiro Pre-commit review requested.
etc/mail gshapiro Pre-commit review requested.
Keep in sync with -STABLE.
@ -78,10 +76,11 @@ inetd dwmalone Recommends pre-commit review.
contrib/smbfs bp Open for in-tree committs. In case of functional
changes pre-commit review requested.
contrib/pf glebius Pre-commit review recommended.
binutils obrien Insists on BU blocked from unapproved commits
file obrien Insists to keep file blocked from other's unapproved
commits
contrib/bzip2 obrien Pre-commit review required.
contrib/netbsd-tests freebsd-testing,ngie Pre-commit review requested.
contrib/pjdfstest freebsd-testing,ngie Pre-commit review requested.
geom_concat pjd Pre-commit review preferred.
geom_eli pjd Pre-commit review preferred.
geom_gate pjd Pre-commit review preferred.
@ -118,7 +117,6 @@ lib/libc/stdtime edwin Heads-up appreciated, since parts of this code
is maintained by a third party source.
sbin/routed bms Pre-commit review; notify vendor at rhyolite.com
isci(4) jimharris Pre-commit review requested.
3dfx cokane Pre-commit review preferred.
cmx daniel@roe.ch Pre-commit review preferred.
filemon obrien Pre-commit review preferred.
sysdoc trhodes Pre-commit review preferred.

View file

@ -97,11 +97,24 @@ SUBDIR+=contrib/ofed
#
SUBDIR+=etc
# These are last, since it is nice to at least get the base system
# rebuilt before you do them.
.for _DIR in ${LOCAL_LIB_DIRS} ${LOCAL_DIRS}
# Local directories are last, since it is nice to at least get the base
# system rebuilt before you do them.
.for _DIR in ${LOCAL_DIRS}
.if exists(${.CURDIR}/${_DIR}/Makefile)
SUBDIR+= ${_DIR}
SUBDIR+= ${_DIR}
.endif
.endfor
# Add LOCAL_LIB_DIRS, but only if they will not be picked up as a SUBDIR
# of a LOCAL_DIRS directory. This allows LOCAL_DIRS=foo and
# LOCAL_LIB_DIRS=foo/lib to behave as expected.
.for _DIR in ${LOCAL_DIRS:M*/} ${LOCAL_DIRS:N*/:S|$|/|}
_REDUNDENT_LIB_DIRS+= ${LOCAL_LIB_DIRS:M${_DIR}*}
.endfor
.for _DIR in ${LOCAL_LIB_DIRS}
.if empty(_REDUNDENT_LIB_DIRS:M${_DIR}) && exists(${.CURDIR}/${_DIR}/Makefile)
SUBDIR+= ${_DIR}
.else
.warning ${_DIR} not added to SUBDIR list. See UPDATING 20141121.
.endif
.endfor
.endif
@ -247,10 +260,11 @@ BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \
DESTDIR= \
BOOTSTRAPPING=${OSRELDATE} \
SSP_CFLAGS= \
MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \
MK_HTML=no NO_LINT=yes MK_MAN=no \
-DNO_PIC MK_PROFILE=no -DNO_SHARED \
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \
MK_CLANG_FULL=no MK_LLDB=no MK_TESTS=no
MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \
MK_LLDB=no MK_TESTS=no
# build-tools stage
TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \
@ -260,7 +274,9 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \
BOOTSTRAPPING=${OSRELDATE} \
SSP_CFLAGS= \
-DNO_LINT \
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no MK_CLANG_FULL=no MK_LLDB=no MK_TESTS=no
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \
MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \
MK_LLDB=no MK_TESTS=no
# cross-tools stage
XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \
@ -277,7 +293,7 @@ KTMAKE= TOOLS_PREFIX=${WORLDTMP} MAKEOBJDIRPREFIX=${WORLDTMP} \
DESTDIR= \
BOOTSTRAPPING=${OSRELDATE} \
SSP_CFLAGS= \
MK_HTML=no MK_INFO=no -DNO_LINT MK_MAN=no \
MK_HTML=no -DNO_LINT MK_MAN=no \
-DNO_PIC MK_PROFILE=no -DNO_SHARED \
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no
@ -323,8 +339,9 @@ X${BINUTIL}?= ${CROSS_BINUTILS_PREFIX}${${BINUTIL}}
X${BINUTIL}?= ${${BINUTIL}}
.endif
.endfor
WMAKEENV+= CC="${XCC} ${XFLAGS}" CXX="${XCXX} ${XFLAGS}" \
CPP="${XCPP} ${XFLAGS}" \
WMAKEENV+= CC="${XCC} ${XCFLAGS}" CXX="${XCXX} ${XCFLAGS} ${XCXXFLAGS}" \
DEPFLAGS="${DEPFLAGS}" \
CPP="${XCPP} ${XCFLAGS}" \
AS="${XAS}" AR="${XAR}" LD="${XLD}" NM=${XNM} \
OBJDUMP=${XOBJDUMP} OBJCOPY="${XOBJCOPY}" \
RANLIB=${XRANLIB} STRINGS=${XSTRINGS} \
@ -350,11 +367,13 @@ TARGET_ABI= gnueabi
.endif
.endif
.if defined(X_COMPILER_TYPE) && ${X_COMPILER_TYPE} == gcc
XFLAGS+= -isystem ${WORLDTMP}/usr/include -L${WORLDTMP}/usr/lib
XCFLAGS+= -isystem ${WORLDTMP}/usr/include -L${WORLDTMP}/usr/lib
XCXXFLAGS+= -I${WORLDTMP}/usr/include/c++/v1 -std=gnu++11 -L${WORLDTMP}/../lib/libc++
DEPFLAGS+= -I${WORLDTMP}/usr/include/c++/v1
.else
TARGET_ABI?= unknown
TARGET_TRIPLE?= ${TARGET_ARCH:C/amd64/x86_64/}-${TARGET_ABI}-freebsd11.0
XFLAGS+= -target ${TARGET_TRIPLE}
XCFLAGS+= -target ${TARGET_TRIPLE}
.endif
.endif
@ -419,7 +438,7 @@ LIB32WMAKEFLAGS+= CC="${XCC} ${LIB32FLAGS}" \
MK_TESTS=no
LIB32WMAKE= ${LIB32WMAKEENV} ${MAKE} ${LIB32WMAKEFLAGS} \
MK_MAN=no MK_INFO=no MK_HTML=no
MK_MAN=no MK_HTML=no
LIB32IMAKE= ${LIB32WMAKE:NINSTALL=*:NDESTDIR=*:N_LDSCRIPTROOT=*} \
MK_TOOLCHAIN=no ${IMAKE_INSTALL}
.endif
@ -510,8 +529,9 @@ _worldtmp:
-p ${WORLDTMP}/usr/lib >/dev/null
.endif
.if ${MK_TESTS} != "no"
mkdir -p ${WORLDTMP}${TESTSBASE}
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \
-p ${WORLDTMP}/usr >/dev/null
-p ${WORLDTMP}${TESTSBASE} >/dev/null
.endif
.for _mtree in ${LOCAL_MTREE}
mtree -deU -f ${.CURDIR}/${_mtree} -p ${WORLDTMP} > /dev/null
@ -570,8 +590,8 @@ _libraries:
@echo ">>> stage 4.2: building libraries"
@echo "--------------------------------------------------------------"
${_+_}cd ${.CURDIR}; \
${WMAKE} -DNO_FSCHG MK_HTML=no MK_INFO=no -DNO_LINT MK_MAN=no \
MK_PROFILE=no MK_TESTS=no libraries
${WMAKE} -DNO_FSCHG MK_HTML=no -DNO_LINT MK_MAN=no \
MK_PROFILE=no MK_TESTS=no MK_TESTS_SUPPORT=${MK_TESTS} libraries
_depend:
@echo
@echo "--------------------------------------------------------------"
@ -688,6 +708,11 @@ buildworld_epilogue:
buildenvvars:
@echo ${WMAKEENV:Q}
.if ${.TARGETS:Mbuildenv}
.if ${.MAKEFLAGS:M-j}
.error The buildenv target is incompatible with -j
.endif
.endif
buildenv:
@echo Entering world for ${TARGET_ARCH}:${TARGET}
@cd ${.CURDIR} && env ${WMAKEENV} ${BUILDENV_SHELL} || true
@ -759,9 +784,6 @@ __installcheck_UGID:
#
# Required install tools to be saved in a scratch dir for safety.
#
.if ${MK_INFO} != "no"
_install-info= install-info
.endif
.if ${MK_ZONEINFO} != "no"
_zoneinfo= zic tzsetup
.endif
@ -769,9 +791,14 @@ _zoneinfo= zic tzsetup
ITOOLS= [ awk cap_mkdb cat chflags chmod chown \
date echo egrep find grep id install ${_install-info} \
ln lockf make mkdir mtree mv pwd_mkdb \
rm sed services_mkdb sh sysctl test true uname wc ${_zoneinfo} \
rm sed services_mkdb sh strip sysctl test true uname wc ${_zoneinfo} \
${LOCAL_ITOOLS}
# Needed for share/man
.if ${MK_MAN} != "no"
ITOOLS+=makewhatis
.endif
#
# distributeworld
#
@ -840,8 +867,9 @@ distributeworld installworld: _installcheck_world
-p ${DESTDIR}/${DISTDIR}/${dist}/usr/lib >/dev/null
.endif
.if ${MK_TESTS} != "no" && ${dist} == "tests"
-mkdir -p ${DESTDIR}/${DISTDIR}/${dist}${TESTSBASE}
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \
-p ${DESTDIR}/${DISTDIR}/${dist}/usr >/dev/null
-p ${DESTDIR}/${DISTDIR}/${dist}${TESTSBASE} >/dev/null
.endif
.if defined(NO_ROOT)
${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.root.dist | \
@ -1394,9 +1422,19 @@ _kgzip= usr.sbin/kgzip
.endif
# If we're given an XAS, don't build binutils.
.if ${XAS:M/*} == "" && ${MK_BINUTILS_BOOTSTRAP} != "no"
.if ${XAS:M/*} == ""
.if ${MK_BINUTILS_BOOTSTRAP} != "no"
_binutils= gnu/usr.bin/binutils
.endif
.if ${MK_ELFTOOLCHAIN_TOOLS} != "no"
_elftctools= lib/libelftc \
usr.bin/addr2line \
usr.bin/elfcopy \
usr.bin/nm \
usr.bin/size \
usr.bin/strings
.endif
.endif
# If an full path to an external cross compiler is given, don't build
# a cross compiler.
@ -1415,6 +1453,7 @@ cross-tools: .MAKE
${_clang_libs} \
${_clang} \
${_binutils} \
${_elftctools} \
${_cc} \
usr.bin/xlint/lint1 usr.bin/xlint/lint2 usr.bin/xlint/xlint \
${_btxld} \
@ -1438,31 +1477,79 @@ NXBMAKE= ${NXBENV} ${MAKE} \
MACHINE=${TARGET} MACHINE_ARCH=${TARGET_ARCH} \
MK_GDB=no MK_TESTS=no \
SSP_CFLAGS= \
MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \
MK_HTML=no NO_LINT=yes MK_MAN=no \
-DNO_PIC MK_PROFILE=no -DNO_SHARED \
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \
MK_CLANG_FULL=no MK_LLDB=no
MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \
MK_LLDB=no
native-xtools: .MAKE
mkdir -p ${OBJTREE}/nxb-bin/bin
mkdir -p ${OBJTREE}/nxb-bin/sbin
mkdir -p ${OBJTREE}/nxb-bin/usr
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \
-p ${OBJTREE}/nxb-bin/usr >/dev/null
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \
-p ${OBJTREE}/nxb-bin/usr/include >/dev/null
.for _tool in \
bin/cat \
bin/chmod \
bin/cp \
bin/csh \
bin/echo \
bin/expr \
bin/hostname \
bin/ln \
bin/ls \
bin/mkdir \
bin/mv \
bin/ps \
bin/realpath \
bin/rm \
bin/rmdir \
bin/sh \
bin/sleep \
${_clang_tblgen} \
usr.bin/ar \
${_binutils} \
${_elftctools} \
${_cc} \
${_gcc_tools} \
${_clang_libs} \
${_clang} \
sbin/md5 \
sbin/sysctl \
gnu/usr.bin/diff \
usr.bin/awk \
usr.bin/basename \
usr.bin/bmake \
usr.bin/bzip2 \
usr.bin/cmp \
usr.bin/dirname \
usr.bin/env \
usr.bin/fetch \
usr.bin/find \
usr.bin/grep \
usr.bin/gzip \
usr.bin/id \
usr.bin/lex \
usr.bin/lorder \
usr.bin/mktemp \
usr.bin/mt \
usr.bin/patch \
usr.bin/sed \
usr.bin/yacc
usr.bin/sort \
usr.bin/tar \
usr.bin/touch \
usr.bin/tr \
usr.bin/true \
usr.bin/uniq \
usr.bin/unzip \
usr.bin/xargs \
usr.bin/xinstall \
usr.bin/xz \
usr.bin/yacc \
usr.sbin/chown
${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all,install)"; \
cd ${.CURDIR}/${_tool} && \
${NXBMAKE} DIRPRFX=${_tool}/ obj && \
@ -1532,9 +1619,9 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \
${_kerberos5_lib_libhx509} ${_kerberos5_lib_libkrb5} \
${_kerberos5_lib_libroken} \
${_kerberos5_lib_libwind} \
${_lib_atf} \
lib/libbz2 ${_libcom_err} lib/libcrypt \
lib/libelf lib/libexpat \
lib/libfigpar \
${_lib_libgssapi} \
lib/libkiconv lib/libkvm lib/liblzma lib/libmd lib/libnv \
${_lib_libcapsicum} \
@ -1549,7 +1636,8 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \
${_cddl_lib_libctf} \
lib/libutil lib/libpjdlog ${_lib_libypclnt} lib/libz lib/msun \
${_secure_lib_libcrypto} ${_lib_libldns} \
${_secure_lib_libssh} ${_secure_lib_libssl}
${_secure_lib_libssh} ${_secure_lib_libssl} \
gnu/lib/libdialog
.if ${MK_GNUCXX} != "no"
_prebuild_libs+= gnu/lib/libstdc++ gnu/lib/libsupc++
gnu/lib/libstdc++__L: lib/msun__L
@ -1558,15 +1646,6 @@ gnu/lib/libsupc++__L: gnu/lib/libstdc++__L
lib/libgeom__L: lib/libexpat__L
.if defined(WITH_ATF) || ${MK_TESTS} != "no"
.if !defined(WITH_ATF)
# Ensure that the ATF libraries will be built during make libraries, even
# though they will have WITHOUT_TESTS
MAKE+= -DWITH_ATF
.endif
_lib_atf= lib/atf
.endif
.if ${MK_LIBTHR} != "no"
_lib_libthr= lib/libthr
.endif
@ -1676,6 +1755,8 @@ _lib_libypclnt= lib/libypclnt
lib/libradius__L: lib/libmd__L
.endif
gnu/lib/libdialog__L: lib/msun__L lib/ncurses/ncursesw__L
.for _lib in ${_prereq_libs}
${_lib}__PL: .PHONY .MAKE
.if exists(${.CURDIR}/${_lib})
@ -1888,7 +1969,8 @@ check-old: check-old-files check-old-libs check-old-dirs
# showconfig - show build configuration.
#
showconfig:
@${MAKE} -n -f src.opts.mk -V dummy -dg1 2>&1 | grep ^MK_ | sort
@(${MAKE} -n -f ${.CURDIR}/sys/conf/kern.opts.mk -V dummy -dg1; \
${MAKE} -n -f ${.CURDIR}/share/mk/src.opts.mk -V dummy -dg1) 2>&1 | grep ^MK_ | sort -u
.if !empty(KRNLOBJDIR) && !empty(KERNCONF)
DTBOUTPUTPATH= ${KRNLOBJDIR}/${KERNCONF}/
@ -1924,7 +2006,7 @@ XDEV_CPUTYPE?=${CPUTYPE}
XDEV_CPUTYPE?=${TARGET_CPUTYPE}
.endif
NOFUN=-DNO_FSCHG MK_HTML=no MK_INFO=no -DNO_LINT \
NOFUN=-DNO_FSCHG MK_HTML=no -DNO_LINT \
MK_MAN=no MK_NLS=no MK_PROFILE=no \
MK_KERBEROS=no MK_RESCUE=no MK_TESTS=no MK_WARNS=no \
TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
@ -1969,7 +2051,8 @@ _xb-worldtmp:
_xb-bootstrap-tools:
.for _tool in \
${_clang_tblgen}
${_clang_tblgen} \
${_gperf}
${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all,install)"; \
cd ${.CURDIR}/${_tool} && \
${CDMAKE} DIRPRFX=${_tool}/ obj && \
@ -1985,6 +2068,7 @@ _xb-build-tools:
_xb-cross-tools:
.for _tool in \
${_binutils} \
${_elftctools} \
usr.bin/ar \
${_clang_libs} \
${_clang} \
@ -2006,8 +2090,9 @@ _xi-mtree:
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \
-p ${XDDESTDIR}/usr/include >/dev/null
.if ${MK_TESTS} != "no"
mkdir -p ${XDDESTDIR}${TESTSBASE}
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \
-p ${XDDESTDIR}/usr >/dev/null
-p ${XDDESTDIR}${TESTSBASE} >/dev/null
.endif
.ORDER: xdev-build _xi-mtree _xi-cross-tools _xi-includes _xi-libraries
@ -2017,6 +2102,7 @@ _xi-cross-tools:
@echo "_xi-cross-tools"
.for _tool in \
${_binutils} \
${_elftctools} \
usr.bin/ar \
${_clang_libs} \
${_clang} \

View file

@ -38,14 +38,142 @@
# xargs -n1 | sort | uniq -d;
# done
# 20150102: removal of texinfo
OLD_FILES+=usr/bin/info
OLD_FILES+=usr/bin/infokey
OLD_FILES+=usr/bin/install-info
OLD_FILES+=usr/bin/makeinfo
OLD_FILES+=usr/bin/texindex
OLD_FILES+=usr/share/info/am-utils.info.gz
OLD_FILES+=usr/share/info/as-utils.info.gz
OLD_FILES+=usr/share/info/binutils.info.gz
OLD_FILES+=usr/share/info/com_err.info.gz
OLD_FILES+=usr/share/info/diff.info.gz
OLD_FILES+=usr/share/info/gdb.info.gz
OLD_FILES+=usr/share/info/gdbint.info.gz
OLD_FILES+=usr/share/info/gperf.info.gz
OLD_FILES+=usr/share/info/grep.info.gz
OLD_FILES+=usr/share/info/groff.info.gz
OLD_FILES+=usr/share/info/heimdal.info.gz
OLD_FILES+=usr/share/info/history.info.gz
OLD_FILES+=usr/share/info/info-stnd.info.gz
OLD_FILES+=usr/share/info/info.info.gz
OLD_FILES+=usr/share/info/ld.info.gz
OLD_FILES+=usr/share/info/regex.info.gz
OLD_FILES+=usr/share/info/rluserman.info.gz
OLD_FILES+=usr/share/info/stabs.info.gz
OLD_FILES+=usr/share/info/texinfo.info.gz
OLD_FILES+=usr/share/man/man1/info.1.gz
OLD_FILES+=usr/share/man/man1/infokey.1.gz
OLD_FILES+=usr/share/man/man1/install-info.1.gz
OLD_FILES+=usr/share/man/man1/makeinfo.1.gz
OLD_FILES+=usr/share/man/man1/texindex.1.gz
OLD_FILES+=usr/share/man/man5/info.5.gz
OLD_FILES+=usr/share/man/man5/texinfo.5.gz
# 20141231: new clang import which bumps version from 3.4.1 to 3.5.0.
OLD_FILES+=usr/include/clang/3.4.1/__wmmintrin_aes.h
OLD_FILES+=usr/include/clang/3.4.1/__wmmintrin_pclmul.h
OLD_FILES+=usr/include/clang/3.4.1/altivec.h
OLD_FILES+=usr/include/clang/3.4.1/ammintrin.h
OLD_FILES+=usr/include/clang/3.4.1/arm_neon.h
OLD_FILES+=usr/include/clang/3.4.1/avx2intrin.h
OLD_FILES+=usr/include/clang/3.4.1/avxintrin.h
OLD_FILES+=usr/include/clang/3.4.1/bmi2intrin.h
OLD_FILES+=usr/include/clang/3.4.1/bmiintrin.h
OLD_FILES+=usr/include/clang/3.4.1/cpuid.h
OLD_FILES+=usr/include/clang/3.4.1/emmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/f16cintrin.h
OLD_FILES+=usr/include/clang/3.4.1/fma4intrin.h
OLD_FILES+=usr/include/clang/3.4.1/fmaintrin.h
OLD_FILES+=usr/include/clang/3.4.1/immintrin.h
OLD_FILES+=usr/include/clang/3.4.1/lzcntintrin.h
OLD_FILES+=usr/include/clang/3.4.1/mm3dnow.h
OLD_FILES+=usr/include/clang/3.4.1/mm_malloc.h
OLD_FILES+=usr/include/clang/3.4.1/mmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/module.map
OLD_FILES+=usr/include/clang/3.4.1/nmmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/pmmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/popcntintrin.h
OLD_FILES+=usr/include/clang/3.4.1/prfchwintrin.h
OLD_FILES+=usr/include/clang/3.4.1/rdseedintrin.h
OLD_FILES+=usr/include/clang/3.4.1/rtmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/shaintrin.h
OLD_FILES+=usr/include/clang/3.4.1/smmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/tbmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/tmmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/wmmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/x86intrin.h
OLD_FILES+=usr/include/clang/3.4.1/xmmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/xopintrin.h
OLD_DIRS+=usr/include/clang/3.4.1
# 20141226: Remove gpib/ieee488
OLD_FILES+=usr/include/dev/ieee488/ibfoo_int.h
OLD_FILES+=usr/include/dev/ieee488/tnt4882.h
OLD_FILES+=usr/include/dev/ieee488/ugpib.h
OLD_FILES+=usr/include/dev/ieee488/upd7210.h
OLD_DIRS+=usr/include/dev/ieee488
OLD_FILES+=usr/include/gpib/gpib.h
OLD_DIRS+=usr/include/gpib
OLD_FILES+=usr/lib/libgpib.a
OLD_FILES+=usr/lib/libgpib_p.a
OLD_FILES+=usr/lib/libgpib.so
OLD_LIBS+=usr/lib/libgpib.so.3
OLD_FILES+=usr/lib/libgpib_p.a
OLD_FILES+=share/man/man4/pcii.4.gz
OLD_FILES+=share/man/man4/gpib.4.gz
OLD_FILES+=share/man/man4/tnt4882.4.gz
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64"
OLD_FILES+=usr/lib32/libgpib.a
OLD_FILES+=usr/lib32/libgpib_p.a
OLD_FILES+=usr/lib32/libgpib.so
OLD_LIBS+=usr/lib32/libgpib.so.3
.endif
# 20141224: libxo moved to /lib
OLD_LIBS+=usr/lib/libxo.so.0
# 20141223: remove in6_gif.h, in_gif.h and if_stf.h
OLD_FILES+=usr/include/net/if_stf.h
OLD_FILES+=usr/include/netinet/in_gif.h
OLD_FILES+=usr/include/netinet6/in6_gif.h
# 20141202: update to mandoc CVS 20141201
OLD_FILES+=usr.bin/preconv
OLD_FILES+=share/man/man1/preconv.1.gz
# 20141129: mrouted rc.d scripts removed from base
OLD_FILES+=etc/rc.d/mrouted
# 20141126: convert sbin/mdconfig/tests to ATF format tests
OLD_FILES+=usr/tests/sbin/mdconfig/legacy_test
OLD_FILES+=usr/tests/sbin/mdconfig/mdconfig.test
OLD_FILES+=usr/tests/sbin/mdconfig/run.pl
# 20141126: remove xform_ipip decapsulation fallback
OLD_FILES+=usr/include/netipsec/ipip_var.h
# 20141109: faith/faithd removal
OLD_FILES+=etc/rc.d/faith
OLD_FILES+=usr/share/man/man4/faith.4.gz
OLD_FILES+=usr/share/man/man4/if_faith.4.gz
OLD_FILES+=usr/sbin/faithd
OLD_FILES+=usr/share/man/man8/faithd.8.gz
# 20141107: overhaul if_gre(4)
OLD_FILES+=usr/include/netinet/ip_gre.h
# 20141102: postrandom obsoleted by new /dev/random code
OLD_FILES+=etc/rc.d/postrandom
# 20141031: initrandom obsoleted by new /dev/random code
OLD_FILES+=etc/rc.d/initrandom
# 20141028: debug files accidentally installed as directory name
OLD_FILES+=usr/lib/debug/usr/lib/i18n
OLD_FILES+=usr/lib/debug/usr/lib/private
OLD_FILES+=usr/lib/debug/usr/lib32/i18n
OLD_FILES+=usr/lib/debug/usr/lib32/private
# 20141015: OpenSSL 1.0.1j import
OLD_FILES+=usr/share/openssl/man/man3/CMS_sign_add1_signer.3.gz
# 20140922: sleepq_calc_signal_retval.9 and sleepq_catch_signals.9 removed
OLD_FILES+=usr/share/man/man9/sleepq_calc_signal_retval.9.gz
OLD_FILES+=usr/share/man/man9/sleepq_catch_signals.9.gz
# 20140917: hv_kvpd rc.d script removed in favor of devd configuration
OLD_FILES+=etc/rc.d/hv_kvpd
# 20140917: libnv was accidentally being installed to /usr/lib instead of /lib
OLD_LIBS+=usr/lib/libnv.a
OLD_LIBS+=usr/lib/libnv.so.0
# 20140829: rc.d/kerberos removed
OLD_FILES+=etc/rc.d/kerberos
# 20140814: libopie version bump
OLD_LIBS+=usr/lib/libopie.so.7
OLD_LIBS+=usr/lib32/libopie.so.7
@ -114,10 +242,12 @@ OLD_FILES+=usr/include/readline/chardefs.h
OLD_FILES+=usr/include/readline/history.h
OLD_FILES+=usr/include/readline/keymaps.h
OLD_FILES+=usr/include/readline/readline.h
OLD_FILES+=usr/include/readline/tilde.h
OLD_FILES+=usr/include/readline/rlconf.h
OLD_FILES+=usr/include/readline/rlstdc.h
OLD_FILES+=usr/include/readline/rltypedefs.h
OLD_FILES+=usr/include/readline/rltypedefs.h
OLD_DIRS+=usr/include/readline
OLD_FILES+=usr/share/info/readline.info.gz
OLD_FILES+=usr/share/man/man3/readline.3.gz
# 20140625: csup removal
@ -177,8 +307,6 @@ OLD_DIRS+=usr/include/clang/3.4
# 20140505: Bogusly installing src.opts.mk
OLD_FILES+=usr/share/mk/src.opts.mk
# 20140505: Reject PR kern/187551
OLD_DIRS+=usr/tests/sbin/ifconfig
OLD_FILES+=usr/tests/sbin/ifconfig/Kyuafile
OLD_FILES+=usr/tests/sbin/ifconfig/fibs_test
# 20140502: Removal of lindev(4)
OLD_FILES+=usr/share/man/man4/lindev.4.gz
@ -364,7 +492,6 @@ OLD_FILES+=usr/share/man/man1/atf-report.1.gz
OLD_FILES+=usr/share/man/man1/atf-run.1.gz
OLD_FILES+=usr/share/man/man1/atf-version.1.gz
OLD_FILES+=usr/share/man/man5/atf-formats.5.gz
OLD_FILES+=usr/share/man/man7/atf.7.gz
OLD_FILES+=usr/share/xml/atf/tests-results.dtd
OLD_FILES+=usr/share/xsl/atf/tests-results.xsl
# 20131009: freebsd-version moved from /libexec to /bin
@ -598,6 +725,7 @@ OLD_FILES+=var/named/etc/namedb/master/localhost-forward.db
OLD_FILES+=var/named/etc/namedb/master/localhost-reverse.db
#OLD_FILES+=var/named/etc/namedb/named.conf # intentionally left out
OLD_FILES+=var/named/etc/namedb/named.root
OLD_DIRS+=var/named/etc/namedb/working
OLD_DIRS+=var/named/etc/namedb/slave
OLD_DIRS+=var/named/var
OLD_DIRS+=var/named/var/dump

129
UPDATING
View file

@ -31,6 +31,128 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
20150107:
ELF tools addr2line, elfcopy (strip), nm, size, and strings are now
taken from the ELF Tool Chain project rather than GNU binutils. They
should be drop-in replacements, with the addition of arm64 support.
The WITHOUT_ELFTOOLCHAIN_TOOLS= knob may be used to obtain the
binutils tools, if necessary.
20150105:
The default Unbound configuration now enables remote control
using a local socket. Users who have already enabled the
local_unbound service should regenerate their configuration
by running "service local_unbound setup" as root.
20150102:
The GNU texinfo and GNU info pages have been removed.
To be able to view GNU info pages please install texinfo from ports.
20141231:
Clang, llvm and lldb have been upgraded to 3.5.0 release.
As of this release, a prerequisite for building clang, llvm and lldb is
a C++11 capable compiler and C++11 standard library. This means that to
be able to successfully build the cross-tools stage of buildworld, with
clang as the bootstrap compiler, your system compiler or cross compiler
should either be clang 3.3 or later, or gcc 4.8 or later, and your
system C++ library should be libc++, or libdstdc++ from gcc 4.8 or
later.
On any standard FreeBSD 10.x or 11.x installation, where clang and
libc++ are on by default (that is, on x86 or arm), this should work out
of the box.
On 9.x installations where clang is enabled by default, e.g. on x86 and
powerpc, libc++ will not be enabled by default, so libc++ should be
built (with clang) and installed first. If both clang and libc++ are
missing, build clang first, then use it to build libc++.
On 8.x and earlier installations, upgrade to 9.x first, and then follow
the instructions for 9.x above.
Sparc64 and mips users are unaffected, as they still use gcc 4.2.1 by
default, and do not build clang.
Many embedded systems are resource constrained, and will not be able to
build clang in a reasonable time, or in some cases at all. In those
cases, cross building bootable systems on amd64 is a workaround.
This new version of clang introduces a number of new warnings, of which
the following are most likely to appear:
-Wabsolute-value
This warns in two cases, for both C and C++:
* When the code is trying to take the absolute value of an unsigned
quantity, which is effectively a no-op, and almost never what was
intended. The code should be fixed, if at all possible. If you are
sure that the unsigned quantity can be safely cast to signed, without
loss of information or undefined behavior, you can add an explicit
cast, or disable the warning.
* When the code is trying to take an absolute value, but the called
abs() variant is for the wrong type, which can lead to truncation.
If you want to disable the warning instead of fixing the code, please
make sure that truncation will not occur, or it might lead to unwanted
side-effects.
-Wtautological-undefined-compare and
-Wundefined-bool-conversion
These warn when C++ code is trying to compare 'this' against NULL, while
'this' should never be NULL in well-defined C++ code. However, there is
some legacy (pre C++11) code out there, which actively abuses this
feature, which was less strictly defined in previous C++ versions.
Squid and openjdk do this, for example. The warning can be turned off
for C++98 and earlier, but compiling the code in C++11 mode might result
in unexpected behavior; for example, the parts of the program that are
unreachable could be optimized away.
20141222:
The old NFS client and server (kernel options NFSCLIENT, NFSSERVER)
kernel sources have been removed. The .h files remain, since some
utilities include them. This will need to be fixed later.
If "mount -t oldnfs ..." is attempted, it will fail.
If the "-o" option on mountd(8), nfsd(8) or nfsstat(1) is used,
the utilities will report errors.
20141121:
The handling of LOCAL_LIB_DIRS has been altered to skip addition of
directories to top level SUBDIR variable when their parent
directory is included in LOCAL_DIRS. Users with build systems with
such hierarchies and without SUBDIR entries in the parent
directory Makefiles should add them or add the directories to
LOCAL_DIRS.
20141109:
faith(4) and faithd(8) have been removed from the base system. Faith
has been obsolete for a very long time.
20141104:
vt(4), the new console driver, is enabled by default. It brings
support for Unicode and double-width characters, as well as
support for UEFI and integration with the KMS kernel video
drivers.
You may need to update your console settings in /etc/rc.conf,
most probably the keymap. During boot, /etc/rc.d/syscons will
indicate what you need to do.
vt(4) still has issues and lacks some features compared to
syscons(4). See the wiki for up-to-date information:
https://wiki.freebsd.org/Newcons
If you want to keep using syscons(4), you can do so by adding
the following line to /boot/loader.conf:
kern.vty=sc
20141102:
pjdfstest has been integrated into kyua as an opt-in test suite.
Please see share/doc/pjdfstest/README for more details on how to
execute it.
20141009:
gperf has been removed from the base system for architectures
that use clang. Ports that require gperf will obtain it from the
@ -50,7 +172,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
20140729:
The ofwfb driver, used to provide a graphics console on PowerPC when
using vt(4), no longer allows mmap() of all of physical memory. This
using vt(4), no longer allows mmap() of all physical memory. This
will prevent Xorg on PowerPC with some ATI graphics cards from
initializing properly unless x11-servers/xorg-server is updated to
1.12.4_8 or newer.
@ -71,6 +193,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
The GNU texinfo and GNU info pages are not built and installed
anymore, WITH_INFO knob has been added to allow to built and install
them again.
UPDATE: see 20150102 entry on texinfo's removal
20140708:
The GNU readline library is now an INTERNALLIB - that is, it is
@ -810,8 +933,8 @@ COMMON ITEMS:
2.) update the ZFS boot block on your boot drive
The following example updates the ZFS boot block on the first
partition (freebsd-boot) of a GPT partitioned drive ad0:
"gpart bootcode -p /boot/gptzfsboot -i 1 ad0"
partition (freebsd-boot) of a GPT partitioned drive ada0:
"gpart bootcode -p /boot/gptzfsboot -i 1 ada0"
Non-boot pools do not need these updates.

View file

@ -1,6 +1,12 @@
# @(#)Makefile 8.1 (Berkeley) 5/31/93
# $FreeBSD$
.include <src.opts.mk>
PROG= cat
.if ${MK_TESTS} != "no"
SUBDIR+= tests
.endif
.include <bsd.prog.mk>

18
bin/cat/tests/Makefile Normal file
View file

@ -0,0 +1,18 @@
# $FreeBSD$
OBJTOP= ${.OBJDIR}/../../..
SRCTOP= ${.CURDIR}/../../..
TESTSRC= ${SRCTOP}/contrib/netbsd-tests/bin/cat
TESTSDIR= ${TESTSBASE}/bin/cat
NETBSD_ATF_TESTS_SH= cat_test
FILESDIR= ${TESTSDIR}
FILES= d_align.in
FILES+= d_align.out
.include <netbsd-tests.test.mk>
.include <bsd.test.mk>

View file

@ -40,8 +40,7 @@ MLINKS= csh.1 tcsh.1
# utilities of the same name are handled with the associated manpage,
# builtin.1 in share/man/man1/.
DPADD= ${LIBTERMCAPW} ${LIBCRYPT}
LDADD= -ltermcapw -lcrypt
LIBADD= termcapw crypt
LINKS= ${BINDIR}/csh ${BINDIR}/tcsh

View file

@ -9,7 +9,6 @@ SRCS= df.c vfslist.c
CFLAGS+= -I${MOUNT}
DPADD= ${LIBUTIL}
LDADD= -lutil
LIBADD= xo util
.include <bsd.prog.mk>

View file

@ -29,7 +29,7 @@
.\" @(#)df.1 8.3 (Berkeley) 5/8/95
.\" $FreeBSD$
.\"
.Dd January 16, 2014
.Dd November 6, 2014
.Dt DF 1
.Os
.Sh NAME
@ -37,6 +37,7 @@
.Nd display free disk space
.Sh SYNOPSIS
.Nm
.Op Fl -libxo
.Op Fl b | g | H | h | k | m | P
.Op Fl acilnT
.Op Fl \&,
@ -193,7 +194,9 @@ If the value is outside, it will be set to the appropriate limit.
.Xr statfs 2 ,
.Xr getbsize 3 ,
.Xr getmntinfo 3 ,
.Xr libxo 3 ,
.Xr localeconv 3 ,
.Xr xo_parse_args 3 ,
.Xr fstab 5 ,
.Xr mount 8 ,
.Xr pstat 8 ,

View file

@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include <libxo/xo.h>
#include "extern.h"
@ -82,7 +83,7 @@ static char *getmntpt(const char *);
static int int64width(int64_t);
static char *makenetvfslist(void);
static void prthuman(const struct statfs *, int64_t);
static void prthumanval(int64_t);
static void prthumanval(const char *, int64_t);
static intmax_t fsbtoblk(int64_t, uint64_t, u_long);
static void prtstat(struct statfs *, struct maxwidths *);
static size_t regetmntinfo(struct statfs **, long, const char **);
@ -119,6 +120,11 @@ main(int argc, char *argv[])
totalbuf.f_bsize = DEV_BSIZE;
strlcpy(totalbuf.f_mntfromname, "total", MNAMELEN);
vfslist = NULL;
argc = xo_parse_args(argc, argv);
if (argc < 0)
exit(1);
while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T,")) != -1)
switch (ch) {
case 'a':
@ -161,7 +167,7 @@ main(int argc, char *argv[])
break;
case 'l':
if (vfslist != NULL)
errx(1, "-l and -t are mutually exclusive.");
xo_errx(1, "-l and -t are mutually exclusive.");
vfslist = makevfslist(makenetvfslist());
lflag = 1;
break;
@ -174,9 +180,9 @@ main(int argc, char *argv[])
break;
case 't':
if (lflag)
errx(1, "-l and -t are mutually exclusive.");
xo_errx(1, "-l and -t are mutually exclusive.");
if (vfslist != NULL)
errx(1, "only one -t option may be specified");
xo_errx(1, "only one -t option may be specified");
fstype = optarg;
vfslist = makevfslist(optarg);
break;
@ -202,16 +208,19 @@ main(int argc, char *argv[])
/* just the filesystems specified on the command line */
mntbuf = malloc(argc * sizeof(*mntbuf));
if (mntbuf == NULL)
err(1, "malloc()");
xo_err(1, "malloc()");
mntsize = 0;
/* continued in for loop below */
}
xo_open_container("storage-system-information");
xo_open_list("filesystem");
/* iterate through specified filesystems */
for (; *argv; argv++) {
if (stat(*argv, &stbuf) < 0) {
if ((mntpt = getmntpt(*argv)) == NULL) {
warn("%s", *argv);
xo_warn("%s", *argv);
rv = 1;
continue;
}
@ -220,20 +229,20 @@ main(int argc, char *argv[])
mdev.fspec = *argv;
mntpath = strdup("/tmp/df.XXXXXX");
if (mntpath == NULL) {
warn("strdup failed");
xo_warn("strdup failed");
rv = 1;
continue;
}
mntpt = mkdtemp(mntpath);
if (mntpt == NULL) {
warn("mkdtemp(\"%s\") failed", mntpath);
xo_warn("mkdtemp(\"%s\") failed", mntpath);
rv = 1;
free(mntpath);
continue;
}
if (mount(fstype, mntpt, MNT_RDONLY,
&mdev) != 0) {
warn("%s", *argv);
xo_warn("%s", *argv);
rv = 1;
(void)rmdir(mntpt);
free(mntpath);
@ -244,7 +253,7 @@ main(int argc, char *argv[])
if (cflag)
addstat(&totalbuf, &statfsbuf);
} else {
warn("%s", *argv);
xo_warn("%s", *argv);
rv = 1;
}
(void)unmount(mntpt, 0);
@ -260,7 +269,7 @@ main(int argc, char *argv[])
* implement nflag here.
*/
if (statfs(mntpt, &statfsbuf) < 0) {
warn("%s", mntpt);
xo_warn("%s", mntpt);
rv = 1;
continue;
}
@ -294,8 +303,14 @@ main(int argc, char *argv[])
for (i = 0; i < mntsize; i++)
if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0)
prtstat(&mntbuf[i], &maxwidths);
xo_close_list("filesystem");
if (cflag)
prtstat(&totalbuf, &maxwidths);
xo_close_container("storage-system-information");
xo_finish();
return (rv);
}
@ -341,7 +356,7 @@ regetmntinfo(struct statfs **mntbufp, long mntsize, const char **vfslist)
if (nflag || error < 0)
if (i != j) {
if (error < 0)
warnx("%s stats possibly stale",
xo_warnx("%s stats possibly stale",
mntbuf[i].f_mntonname);
mntbuf[j] = mntbuf[i];
}
@ -354,13 +369,13 @@ static void
prthuman(const struct statfs *sfsp, int64_t used)
{
prthumanval(sfsp->f_blocks * sfsp->f_bsize);
prthumanval(used * sfsp->f_bsize);
prthumanval(sfsp->f_bavail * sfsp->f_bsize);
prthumanval(" {:blocks/%6s}", sfsp->f_blocks * sfsp->f_bsize);
prthumanval(" {:used/%6s}", used * sfsp->f_bsize);
prthumanval(" {:available/%6s}", sfsp->f_bavail * sfsp->f_bsize);
}
static void
prthumanval(int64_t bytes)
prthumanval(const char *fmt, int64_t bytes)
{
char buf[6];
int flags;
@ -372,14 +387,15 @@ prthumanval(int64_t bytes)
humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1),
bytes, "", HN_AUTOSCALE, flags);
(void)printf(" %6s", buf);
xo_attr("value", "%lld", (long long) bytes);
xo_emit(fmt, buf);
}
/*
* Print an inode count in "human-readable" format.
*/
static void
prthumanvalinode(int64_t bytes)
prthumanvalinode(const char *fmt, int64_t bytes)
{
char buf[6];
int flags;
@ -389,7 +405,8 @@ prthumanvalinode(int64_t bytes)
humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1),
bytes, "", HN_AUTOSCALE, flags);
(void)printf(" %5s", buf);
xo_attr("value", "%lld", (long long) bytes);
xo_emit(fmt, buf);
}
/*
@ -434,70 +451,77 @@ prtstat(struct statfs *sfsp, struct maxwidths *mwp)
mwp->used = imax(mwp->used, (int)strlen("Used"));
mwp->avail = imax(mwp->avail, (int)strlen("Avail"));
(void)printf("%-*s", mwp->mntfrom, "Filesystem");
xo_emit("{T:/%-*s}", mwp->mntfrom, "Filesystem");
if (Tflag)
(void)printf(" %-*s", mwp->fstype, "Type");
(void)printf(" %*s %*s %*s Capacity", mwp->total, header,
mwp->used, "Used", mwp->avail, "Avail");
xo_emit(" {T:/%-*s}", mwp->fstype, "Type");
xo_emit(" {T:/%*s} {T:/%*s} {T:/%*s} Capacity",
mwp->total, header,
mwp->used, "Used", mwp->avail, "Avail");
if (iflag) {
mwp->iused = imax(hflag ? 0 : mwp->iused,
(int)strlen(" iused"));
mwp->ifree = imax(hflag ? 0 : mwp->ifree,
(int)strlen("ifree"));
(void)printf(" %*s %*s %%iused",
xo_emit(" {T:/%*s} {T:/%*s} {T:\%iused}",
mwp->iused - 2, "iused", mwp->ifree, "ifree");
}
(void)printf(" Mounted on\n");
xo_emit(" {T:Mounted on}\n");
}
xo_open_instance("filesystem");
/* Check for 0 block size. Can this happen? */
if (sfsp->f_bsize == 0) {
warnx ("File system %s does not have a block size, assuming 512.",
xo_warnx ("File system %s does not have a block size, assuming 512.",
sfsp->f_mntonname);
sfsp->f_bsize = 512;
}
(void)printf("%-*s", mwp->mntfrom, sfsp->f_mntfromname);
xo_emit("{tk:name/%-*s}", mwp->mntfrom, sfsp->f_mntfromname);
if (Tflag)
(void)printf(" %-*s", mwp->fstype, sfsp->f_fstypename);
xo_emit(" {:type/%-*s}", mwp->fstype, sfsp->f_fstypename);
used = sfsp->f_blocks - sfsp->f_bfree;
availblks = sfsp->f_bavail + used;
if (hflag) {
prthuman(sfsp, used);
} else {
if (thousands)
format = " %*j'd %*j'd %*j'd";
format = " {t:total-blocks/%*j'd} {t:used-blocks/%*j'd} "
"{t:available-blocks/%*j'd}";
else
format = " %*jd %*jd %*jd";
(void)printf(format,
format = " {t:total-blocks/%*jd} {t:used-blocks/%*jd} "
"{t:available-blocks/%*jd}";
xo_emit(format,
mwp->total, fsbtoblk(sfsp->f_blocks,
sfsp->f_bsize, blocksize),
mwp->used, fsbtoblk(used, sfsp->f_bsize, blocksize),
mwp->avail, fsbtoblk(sfsp->f_bavail,
sfsp->f_bsize, blocksize));
}
(void)printf(" %5.0f%%",
xo_emit(" {:used-percent/%5.0f}{U:%%}",
availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
if (iflag) {
inodes = sfsp->f_files;
used = inodes - sfsp->f_ffree;
if (hflag) {
(void)printf(" ");
prthumanvalinode(used);
prthumanvalinode(sfsp->f_ffree);
xo_emit(" ");
prthumanvalinode(" {:inodes-used/%5s}", used);
prthumanvalinode(" {:inodes-free/%5s}", sfsp->f_ffree);
} else {
if (thousands)
format = " %*j'd %*j'd";
format = " {:inodes-used/%*j'd} {:inodes-free/%*j'd}";
else
format = " %*jd %*jd";
(void)printf(format, mwp->iused, (intmax_t)used,
format = " {:inodes-used/%*jd} {:inodes-free/%*jd}";
xo_emit(format, mwp->iused, (intmax_t)used,
mwp->ifree, (intmax_t)sfsp->f_ffree);
}
(void)printf(" %4.0f%% ", inodes == 0 ? 100.0 :
(double)used / (double)inodes * 100.0);
xo_emit(" {:inodes-used-percent/%4.0f}{U:%%} ",
inodes == 0 ? 100.0 :
(double)used / (double)inodes * 100.0);
} else
(void)printf(" ");
xo_emit(" ");
if (strncmp(sfsp->f_mntfromname, "total", MNAMELEN) != 0)
(void)printf(" %s", sfsp->f_mntonname);
(void)printf("\n");
xo_emit(" {:mounted-on}", sfsp->f_mntonname);
xo_emit("\n");
xo_close_instance("filesystem");
}
static void
@ -564,7 +588,7 @@ static void
usage(void)
{
(void)fprintf(stderr,
xo_error(
"usage: df [-b | -g | -H | -h | -k | -m | -P] [-acilnT] [-t type] [-,]\n"
" [file | filesystem ...]\n");
exit(EX_USAGE);
@ -579,24 +603,24 @@ makenetvfslist(void)
int cnt, i, maxvfsconf;
if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) {
warn("sysctl(vfs.conflist)");
xo_warn("sysctl(vfs.conflist)");
return (NULL);
}
xvfsp = malloc(buflen);
if (xvfsp == NULL) {
warnx("malloc failed");
xo_warnx("malloc failed");
return (NULL);
}
keep_xvfsp = xvfsp;
if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) {
warn("sysctl(vfs.conflist)");
xo_warn("sysctl(vfs.conflist)");
free(keep_xvfsp);
return (NULL);
}
maxvfsconf = buflen / sizeof(struct xvfsconf);
if ((listptr = malloc(sizeof(char*) * maxvfsconf)) == NULL) {
warnx("malloc failed");
xo_warnx("malloc failed");
free(keep_xvfsp);
return (NULL);
}
@ -605,7 +629,7 @@ makenetvfslist(void)
if (xvfsp->vfc_flags & VFCF_NETWORK) {
listptr[cnt++] = strdup(xvfsp->vfc_name);
if (listptr[cnt-1] == NULL) {
warnx("malloc failed");
xo_warnx("malloc failed");
free(listptr);
free(keep_xvfsp);
return (NULL);
@ -617,7 +641,7 @@ makenetvfslist(void)
if (cnt == 0 ||
(str = malloc(sizeof(char) * (32 * cnt + cnt + 2))) == NULL) {
if (cnt > 0)
warnx("malloc failed");
xo_warnx("malloc failed");
free(listptr);
free(keep_xvfsp);
return (NULL);

View file

@ -9,8 +9,7 @@ MLINKS= ed.1 red.1
.if ${MK_OPENSSL} != "no" && ${MK_ED_CRYPTO} != "no"
CFLAGS+=-DDES
DPADD= ${LIBCRYPTO}
LDADD= -lcrypto
LIBADD= crypto
.endif
.include <bsd.prog.mk>

View file

@ -5,8 +5,7 @@ MAN = freebsd-version.1
CLEANFILES = freebsd-version.sh
NEWVERS = ${.CURDIR}/../../sys/conf/newvers.sh
freebsd-version.sh.in: ${NEWVERS}
freebsd-version.sh: ${.CURDIR}/freebsd-version.sh.in
freebsd-version.sh: ${.CURDIR}/freebsd-version.sh.in ${NEWVERS}
eval $$(egrep '^(TYPE|REVISION|BRANCH)=' ${NEWVERS}) ; \
if ! sed -e "\
s/@@TYPE@@/$${TYPE}/g; \

View file

@ -29,7 +29,7 @@
.\" @(#)symlink.7 8.3 (Berkeley) 3/31/94
.\" $FreeBSD$
.\"
.Dd April 25, 2010
.Dd December 29, 2014
.Dt SYMLINK 7
.Os
.Sh NAME
@ -219,7 +219,7 @@ would change the ownership of
.Dq Li slink
itself.
.Pp
There are four exceptions to this rule.
There are five exceptions to this rule.
The
.Xr mv 1
and
@ -262,13 +262,12 @@ a file tree.)
.Pp
The
.Xr file 1
command is also an exception to this rule.
The
.Xr file 1
command does not follow symbolic links named as argument by default.
The
.Xr file 1
command does follow symbolic links named as argument if
and
.Xr stat 1
commands are also exceptions to this rule.
These
commands do not follow symbolic links named as argument by default,
but do follow symbolic links named as argument if the
.Fl L
option is specified.
.Pp

View file

@ -5,14 +5,12 @@
PROG= ls
SRCS= cmp.c ls.c print.c util.c
DPADD= ${LIBUTIL}
LDADD= -lutil
LIBADD= util
.if !defined(RELEASE_CRUNCH) && \
${MK_LS_COLORS} != no
CFLAGS+= -DCOLORLS
DPADD+= ${LIBTERMCAPW}
LDADD+= -ltermcapw
LIBADD+= termcapw
.endif
.include <bsd.prog.mk>

View file

@ -5,8 +5,7 @@
PROG= pkill
DPADD= ${LIBKVM}
LDADD= -lkvm
LIBADD= kvm
LINKS= ${BINDIR}/pkill ${BINDIR}/pgrep
MLINKS= pkill.1 pgrep.1

View file

@ -11,7 +11,6 @@ SRCS= fmt.c keyword.c nlist.c print.c ps.c
# on large systems.
#
CFLAGS+=-DLAZY_PS
DPADD= ${LIBM} ${LIBKVM} ${LIBJAIL}
LDADD= -lm -lkvm -ljail
LIBADD= m kvm jail
.include <bsd.prog.mk>

View file

@ -29,7 +29,7 @@
.\" @(#)ps.1 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
.Dd August 27, 2014
.Dd December 9, 2014
.Dt PS 1
.Os
.Sh NAME
@ -332,6 +332,7 @@ the include file
.It Dv "P_SINGLE_BOUNDARY" Ta No "0x400000" Ta "Threads should suspend at user boundary"
.It Dv "P_HWPMC" Ta No "0x800000" Ta "Process is using HWPMCs"
.It Dv "P_JAILED" Ta No "0x1000000" Ta "Process is in jail"
.It Dv "P_TOTAL_STOP" Ta No "0x2000000" Ta "Stopped for system suspend"
.It Dv "P_INEXEC" Ta No "0x4000000" Ta "Process is in execve()"
.It Dv "P_STATCHILD" Ta No "0x8000000" Ta "Child process stopped or exited"
.It Dv "P_INMEM" Ta No "0x10000000" Ta "Loaded into memory"

View file

@ -14,11 +14,7 @@ MAN= rmail.8
WARNS?= 2
CFLAGS+=-I${SENDMAIL_DIR}/include -I.
LIBSMDIR= ${.OBJDIR}/../../lib/libsm
LIBSM= ${LIBSMDIR}/libsm.a
DPADD= ${LIBSM}
LDADD= ${LIBSM}
LIBADD= sm
SRCS+= sm_os.h
CLEANFILES+=sm_os.h

View file

@ -18,8 +18,7 @@ SRCS= ${SHSRCS} ${GENSRCS} ${GENHDRS}
# utilities of the same name are handled with the associated manpage,
# builtin.1 in share/man/man1/.
DPADD= ${LIBEDIT} ${LIBTERMCAPW}
LDADD= -ledit -ltermcapw
LIBADD= edit
CFLAGS+=-DSHELL -I. -I${.CURDIR}
# for debug:

View file

@ -90,13 +90,14 @@ exraise(int e)
/*
* Called from trap.c when a SIGINT is received. (If the user specifies
* that SIGINT is to be trapped or ignored using the trap builtin, then
* this routine is not called.) Suppressint is nonzero when interrupts
* are held using the INTOFF macro. If SIGINTs are not suppressed and
* the shell is not a root shell, then we want to be terminated if we
* get here, as if we were terminated directly by a SIGINT. Arrange for
* this here.
* Called from trap.c when a SIGINT is received and not suppressed, or when
* an interrupt is pending and interrupts are re-enabled using INTON.
* (If the user specifies that SIGINT is to be trapped or ignored using the
* trap builtin, then this routine is not called.) Suppressint is nonzero
* when interrupts are held using the INTOFF macro. If SIGINTs are not
* suppressed and the shell is not a root shell, then we want to be
* terminated if we get here, as if we were terminated directly by a SIGINT.
* Arrange for this here.
*/
void
@ -104,16 +105,6 @@ onint(void)
{
sigset_t sigs;
/*
* The !in_dotrap here is safe. The only way we can arrive here
* with in_dotrap set is that a trap handler set SIGINT to SIG_DFL
* and killed itself.
*/
if (suppressint && !in_dotrap) {
intpending++;
return;
}
intpending = 0;
sigemptyset(&sigs);
sigprocmask(SIG_SETMASK, &sigs, NULL);
@ -130,6 +121,7 @@ onint(void)
else {
signal(SIGINT, SIG_DFL);
kill(getpid(), SIGINT);
_exit(128 + SIGINT);
}
}
@ -139,6 +131,8 @@ vwarning(const char *msg, va_list ap)
{
if (commandname)
outfmt(out2, "%s: ", commandname);
else if (arg0)
outfmt(out2, "%s: ", arg0);
doformat(out2, msg, ap);
out2fmt_flush("\n");
}

View file

@ -75,11 +75,12 @@ extern volatile sig_atomic_t intpending;
#define is_int_on() suppressint
#define SETINTON(s) suppressint = (s)
#define FORCEINTON {suppressint = 0; if (intpending) onint();}
#define SET_PENDING_INT intpending = 1
#define CLEAR_PENDING_INT intpending = 0
#define int_pending() intpending
void exraise(int) __dead2;
void onint(void);
void onint(void) __dead2;
void warning(const char *, ...) __printflike(1, 2);
void error(const char *, ...) __printf0like(1, 2) __dead2;
void exerror(int, const char *, ...) __printf0like(2, 3) __dead2;

View file

@ -539,13 +539,13 @@ expredir(union node *n)
case NFROMTO:
case NAPPEND:
case NCLOBBER:
expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
expandarg(redir->nfile.fname, &fn, EXP_TILDE);
redir->nfile.expfname = fn.list->text;
break;
case NFROMFD:
case NTOFD:
if (redir->ndup.vname) {
expandarg(redir->ndup.vname, &fn, EXP_TILDE | EXP_REDIR);
expandarg(redir->ndup.vname, &fn, EXP_TILDE);
fixredir(redir, fn.list->text, 1);
}
break;
@ -774,15 +774,7 @@ xtracecommand(struct arglist *varlist, struct arglist *arglist)
for (sp = arglist->list ; sp ; sp = sp->next) {
if (sep != 0)
out2c(' ');
/* Disambiguate command looking like assignment. */
if (sp == arglist->list &&
strchr(sp->text, '=') != NULL &&
strchr(sp->text, '\'') == NULL) {
out2c('\'');
out2str(sp->text);
out2c('\'');
} else
out2qstr(sp->text);
out2qstr(sp->text);
sep = ' ';
}
out2c('\n');
@ -1039,6 +1031,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
shellparam.reset = 1;
shellparam.nparam = argc - 1;
shellparam.p = argv + 1;
shellparam.optp = NULL;
shellparam.optnext = NULL;
INTOFF;
savelocalvars = localvars;

View file

@ -171,17 +171,12 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
STPUTC('\0', expdest);
p = grabstackstr(expdest);
exparg.lastp = &exparg.list;
/*
* TODO - EXP_REDIR
*/
if (flag & EXP_FULL) {
ifsbreakup(p, &exparg);
*exparg.lastp = NULL;
exparg.lastp = &exparg.list;
expandmeta(exparg.list, flag);
} else {
if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
rmescapes(p);
sp = (struct strlist *)stalloc(sizeof (struct strlist));
sp->text = p;
*exparg.lastp = sp;
@ -209,7 +204,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
* expansion, and tilde expansion if requested via EXP_TILDE/EXP_VARTILDE.
* Processing ends at a CTLENDVAR or CTLENDARI character as well as '\0'.
* This is used to expand word in ${var+word} etc.
* If EXP_FULL, EXP_CASE or EXP_REDIR are set, keep and/or generate CTLESC
* If EXP_FULL or EXP_CASE are set, keep and/or generate CTLESC
* characters to allow for further processing.
* If EXP_FULL is set, also preserve CTLQUOTEMARK characters.
*/
@ -217,7 +212,7 @@ static char *
argstr(char *p, int flag)
{
char c;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); /* do CTLESC */
int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */
int firsteq = 1;
int split_lit;
int lit_quoted;
@ -303,7 +298,7 @@ exptilde(char *p, int flag)
char c, *startp = p;
struct passwd *pw;
char *home;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
int quotes = flag & (EXP_FULL | EXP_CASE);
while ((c = *p) != '\0') {
switch(c) {
@ -337,7 +332,7 @@ done:
if (home == NULL || *home == '\0')
return (startp);
if (quotes)
STPUTS_QUOTES(home, SQSYNTAX, expdest);
STPUTS_QUOTES(home, DQSYNTAX, expdest);
else
STPUTS(home, expdest);
return (p);
@ -437,7 +432,7 @@ expbackq(union node *cmd, int quoted, int flag)
char lastc;
int startloc = dest - stackblock();
char const *syntax = quoted? DQSYNTAX : BASESYNTAX;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
int quotes = flag & (EXP_FULL | EXP_CASE);
size_t nnl;
INTOFF;
@ -637,7 +632,7 @@ evalvar(char *p, int flag)
int varlen;
int varlenb;
int easy;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
int quotes = flag & (EXP_FULL | EXP_CASE);
varflags = (unsigned char)*p++;
subtype = varflags & VSTYPE;
@ -878,30 +873,28 @@ varvalue(const char *name, int quoted, int subtype, int flag)
int num;
char *p;
int i;
char sep;
char sep[2];
char **ap;
switch (*name) {
case '$':
num = rootpid;
goto numvar;
break;
case '?':
num = oexitstatus;
goto numvar;
break;
case '#':
num = shellparam.nparam;
goto numvar;
break;
case '!':
num = backgndpidval();
numvar:
expdest = cvtnum(num, expdest);
break;
case '-':
for (i = 0 ; i < NOPTS ; i++) {
if (optlist[i].val)
STPUTC(optlist[i].letter, expdest);
}
break;
return;
case '@':
if (flag & EXP_FULL && quoted) {
for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
@ -909,22 +902,25 @@ numvar:
if (*ap)
STPUTC('\0', expdest);
}
break;
return;
}
/* FALLTHROUGH */
case '*':
if (ifsset())
sep = ifsval()[0];
sep[0] = ifsval()[0];
else
sep = ' ';
sep[0] = ' ';
sep[1] = '\0';
for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
strtodest(p, flag, subtype, quoted);
if (!*ap)
break;
if (sep || (flag & EXP_FULL && !quoted && **ap != '\0'))
STPUTC(sep, expdest);
if (sep[0])
strtodest(sep, flag, subtype, quoted);
else if (flag & EXP_FULL && !quoted && **ap != '\0')
STPUTC('\0', expdest);
}
break;
return;
default:
if (is_digit(*name)) {
num = atoi(name);
@ -933,11 +929,12 @@ numvar:
else if (num > 0 && num <= shellparam.nparam)
p = shellparam.p[num - 1];
else
break;
return;
strtodest(p, flag, subtype, quoted);
}
break;
return;
}
expdest = cvtnum(num, expdest);
}
@ -1102,27 +1099,25 @@ expandmeta(struct strlist *str, int flag __unused)
struct strlist **savelastp;
struct strlist *sp;
char c;
/* TODO - EXP_REDIR */
while (str) {
if (fflag)
goto nometa;
p = str->text;
for (;;) { /* fast check for meta chars */
if ((c = *p++) == '\0')
goto nometa;
if (c == '*' || c == '?' || c == '[')
break;
}
savelastp = exparg.lastp;
INTOFF;
expmeta(expdir, str->text);
INTON;
if (!fflag) {
p = str->text;
for (; (c = *p) != '\0'; p++) {
/* fast check for meta chars */
if (c == '*' || c == '?' || c == '[') {
INTOFF;
expmeta(expdir, str->text);
INTON;
break;
}
}
}
if (exparg.lastp == savelastp) {
/*
* no matches
*/
nometa:
*exparg.lastp = str;
rmescapes(str->text);
exparg.lastp = &str->next;

View file

@ -50,7 +50,6 @@ struct arglist {
#define EXP_FULL 0x1 /* perform word splitting & file globbing */
#define EXP_TILDE 0x2 /* do normal tilde expansion */
#define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
#define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
#define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
#define EXP_SPLIT_LIT 0x20 /* IFS split literal text ${v+-a b c} */
#define EXP_LIT_QUOTED 0x40 /* for EXP_SPLIT_LIT, start off quoted */

View file

@ -592,23 +592,23 @@ getjob_nonotfound(const char *name)
if (name == NULL) {
#if JOBS
currentjob: if ((jp = getcurjob(NULL)) == NULL)
error("No current job");
return (jp);
name = "%+";
#else
error("No current job");
#endif
} else if (name[0] == '%') {
}
if (name[0] == '%') {
if (is_digit(name[1])) {
jobno = number(name + 1);
if (jobno > 0 && jobno <= njobs
&& jobtab[jobno - 1].used != 0)
return &jobtab[jobno - 1];
#if JOBS
} else if (name[1] == '%' && name[2] == '\0') {
goto currentjob;
} else if (name[1] == '+' && name[2] == '\0') {
goto currentjob;
} else if ((name[1] == '%' || name[1] == '+') &&
name[2] == '\0') {
if ((jp = getcurjob(NULL)) == NULL)
error("No current job");
return (jp);
} else if (name[1] == '-' && name[2] == '\0') {
if ((jp = getcurjob(NULL)) == NULL ||
(jp = getcurjob(jp)) == NULL)
@ -1287,14 +1287,44 @@ commandtext(union node *n)
}
static void
cmdtxtdogroup(union node *n)
{
cmdputs("; do ");
cmdtxt(n);
cmdputs("; done");
}
static void
cmdtxtredir(union node *n, const char *op, int deffd)
{
char s[2];
if (n->nfile.fd != deffd) {
s[0] = n->nfile.fd + '0';
s[1] = '\0';
cmdputs(s);
}
cmdputs(op);
if (n->type == NTOFD || n->type == NFROMFD) {
if (n->ndup.dupfd >= 0)
s[0] = n->ndup.dupfd + '0';
else
s[0] = '-';
s[1] = '\0';
cmdputs(s);
} else {
cmdtxt(n->nfile.fname);
}
}
static void
cmdtxt(union node *n)
{
union node *np;
struct nodelist *lp;
const char *p;
int i;
char s[2];
if (n == NULL)
return;
@ -1339,14 +1369,13 @@ cmdtxt(union node *n)
break;
case NWHILE:
cmdputs("while ");
goto until;
cmdtxt(n->nbinary.ch1);
cmdtxtdogroup(n->nbinary.ch2);
break;
case NUNTIL:
cmdputs("until ");
until:
cmdtxt(n->nbinary.ch1);
cmdputs("; do ");
cmdtxt(n->nbinary.ch2);
cmdputs("; done");
cmdtxtdogroup(n->nbinary.ch2);
break;
case NFOR:
cmdputs("for ");
@ -1381,36 +1410,25 @@ until:
cmdputs(n->narg.text);
break;
case NTO:
p = ">"; i = 1; goto redir;
cmdtxtredir(n, ">", 1);
break;
case NAPPEND:
p = ">>"; i = 1; goto redir;
cmdtxtredir(n, ">>", 1);
break;
case NTOFD:
p = ">&"; i = 1; goto redir;
cmdtxtredir(n, ">&", 1);
break;
case NCLOBBER:
p = ">|"; i = 1; goto redir;
cmdtxtredir(n, ">|", 1);
break;
case NFROM:
p = "<"; i = 0; goto redir;
cmdtxtredir(n, "<", 0);
break;
case NFROMTO:
p = "<>"; i = 0; goto redir;
cmdtxtredir(n, "<>", 0);
break;
case NFROMFD:
p = "<&"; i = 0; goto redir;
redir:
if (n->nfile.fd != i) {
s[0] = n->nfile.fd + '0';
s[1] = '\0';
cmdputs(s);
}
cmdputs(p);
if (n->type == NTOFD || n->type == NFROMFD) {
if (n->ndup.dupfd >= 0)
s[0] = n->ndup.dupfd + '0';
else
s[0] = '-';
s[1] = '\0';
cmdputs(s);
} else {
cmdtxt(n->nfile.fname);
}
cmdtxtredir(n, "<&", 0);
break;
case NHERE:
case NXHERE:

View file

@ -325,6 +325,7 @@ setparam(char **argv)
shellparam.malloc = 1;
shellparam.nparam = nparam;
shellparam.p = newparam;
shellparam.optp = NULL;
shellparam.reset = 1;
shellparam.optnext = NULL;
}
@ -344,6 +345,11 @@ freeparam(struct shparam *param)
ckfree(*ap);
ckfree(param->p);
}
if (param->optp) {
for (ap = param->optp ; *ap ; ap++)
ckfree(*ap);
ckfree(param->optp);
}
}
@ -417,20 +423,33 @@ getoptsreset(const char *value)
int
getoptscmd(int argc, char **argv)
{
char **optbase = NULL;
char **optbase = NULL, **ap;
int i;
if (argc < 3)
error("usage: getopts optstring var [arg]");
else if (argc == 3)
optbase = shellparam.p;
else
optbase = &argv[3];
if (shellparam.reset == 1) {
INTOFF;
if (shellparam.optp) {
for (ap = shellparam.optp ; *ap ; ap++)
ckfree(*ap);
ckfree(shellparam.optp);
shellparam.optp = NULL;
}
if (argc > 3) {
shellparam.optp = ckmalloc((argc - 2) * sizeof *ap);
memset(shellparam.optp, '\0', (argc - 2) * sizeof *ap);
for (i = 0; i < argc - 3; i++)
shellparam.optp[i] = savestr(argv[i + 3]);
}
INTON;
optbase = argc == 3 ? shellparam.p : shellparam.optp;
shellparam.optnext = optbase;
shellparam.optptr = NULL;
shellparam.reset = 0;
}
} else
optbase = shellparam.optp ? shellparam.optp : shellparam.p;
return getopts(argv[1], argv[2], optbase, &shellparam.optnext,
&shellparam.optptr);

View file

@ -38,6 +38,7 @@ struct shparam {
unsigned char malloc; /* if parameter list dynamically allocated */
unsigned char reset; /* if getopts has been reset */
char **p; /* parameter list */
char **optp; /* parameter list for getopts */
char **optnext; /* next parameter to be processed by getopts */
char *optptr; /* used by getopts */
};

View file

@ -54,6 +54,8 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <wchar.h>
#include <wctype.h>
#include "shell.h"
#include "syntax.h"
@ -111,43 +113,86 @@ outstr(const char *p, struct output *file)
outbin(p, strlen(p), file);
}
static void
byteseq(int ch, struct output *file)
{
char seq[4];
seq[0] = '\\';
seq[1] = (ch >> 6 & 0x3) + '0';
seq[2] = (ch >> 3 & 0x7) + '0';
seq[3] = (ch & 0x7) + '0';
outbin(seq, 4, file);
}
static void
outdqstr(const char *p, struct output *file)
{
const char *end;
mbstate_t mbs;
size_t clen;
wchar_t wc;
memset(&mbs, '\0', sizeof(mbs));
end = p + strlen(p);
outstr("$'", file);
while ((clen = mbrtowc(&wc, p, end - p + 1, &mbs)) != 0) {
if (clen == (size_t)-2) {
while (p < end)
byteseq(*p++, file);
break;
}
if (clen == (size_t)-1) {
memset(&mbs, '\0', sizeof(mbs));
byteseq(*p++, file);
continue;
}
if (wc == L'\n')
outcslow('\n', file), p++;
else if (wc == L'\r')
outstr("\\r", file), p++;
else if (wc == L'\t')
outstr("\\t", file), p++;
else if (!iswprint(wc)) {
for (; clen > 0; clen--)
byteseq(*p++, file);
} else {
if (wc == L'\'' || wc == L'\\')
outcslow('\\', file);
outbin(p, clen, file);
p += clen;
}
}
outcslow('\'', file);
}
/* Like outstr(), but quote for re-input into the shell. */
void
outqstr(const char *p, struct output *file)
{
char ch;
int inquotes;
int i;
if (p[0] == '\0') {
outstr("''", file);
return;
}
/* Caller will handle '=' if necessary */
if (p[strcspn(p, "|&;<>()$`\\\"' \t\n*?[~#")] == '\0' ||
for (i = 0; p[i] != '\0'; i++) {
if ((p[i] > '\0' && p[i] < ' ' && p[i] != '\n') ||
(p[i] & 0x80) != 0 || p[i] == '\'') {
outdqstr(p, file);
return;
}
}
if (p[strcspn(p, "|&;<>()$`\\\" \n*?[~#=")] == '\0' ||
strcmp(p, "[") == 0) {
outstr(p, file);
return;
}
inquotes = 0;
while ((ch = *p++) != '\0') {
switch (ch) {
case '\'':
/* Can't quote single quotes inside single quotes. */
if (inquotes)
outcslow('\'', file);
inquotes = 0;
outstr("\\'", file);
break;
default:
if (!inquotes)
outcslow('\'', file);
inquotes = 1;
outc(ch, file);
}
}
if (inquotes)
outcslow('\'', file);
outcslow('\'', file);
outstr(p, file);
outcslow('\'', file);
}
void

View file

@ -125,6 +125,7 @@ static void consumetoken(int);
static void synexpect(int) __dead2;
static void synerror(const char *) __dead2;
static void setprompt(int);
static int pgetc_linecont(void);
static void *
@ -889,7 +890,9 @@ xxreadtoken(void)
continue;
}
pungetc();
goto breakloop;
/* FALLTHROUGH */
default:
return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
case '\n':
plinno++;
needprompt = doprompt;
@ -897,17 +900,17 @@ xxreadtoken(void)
case PEOF:
RETURN(TEOF);
case '&':
if (pgetc() == '&')
if (pgetc_linecont() == '&')
RETURN(TAND);
pungetc();
RETURN(TBACKGND);
case '|':
if (pgetc() == '|')
if (pgetc_linecont() == '|')
RETURN(TOR);
pungetc();
RETURN(TPIPE);
case ';':
c = pgetc();
c = pgetc_linecont();
if (c == ';')
RETURN(TENDCASE);
else if (c == '&')
@ -918,12 +921,8 @@ xxreadtoken(void)
RETURN(TLP);
case ')':
RETURN(TRP);
default:
goto breakloop;
}
}
breakloop:
return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
#undef RETURN
}
@ -978,6 +977,63 @@ checkend(int c, const char *eofmark, int striptabs)
}
/*
* Parse a redirection operator. The variable "out" points to a string
* specifying the fd to be redirected. The variable "c" contains the
* first character of the redirection operator.
*/
static void
parseredir(char *out, int c)
{
char fd = *out;
union node *np;
np = (union node *)stalloc(sizeof (struct nfile));
if (c == '>') {
np->nfile.fd = 1;
c = pgetc_linecont();
if (c == '>')
np->type = NAPPEND;
else if (c == '&')
np->type = NTOFD;
else if (c == '|')
np->type = NCLOBBER;
else {
np->type = NTO;
pungetc();
}
} else { /* c == '<' */
np->nfile.fd = 0;
c = pgetc_linecont();
if (c == '<') {
if (sizeof (struct nfile) != sizeof (struct nhere)) {
np = (union node *)stalloc(sizeof (struct nhere));
np->nfile.fd = 0;
}
np->type = NHERE;
heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
heredoc->here = np;
if ((c = pgetc_linecont()) == '-') {
heredoc->striptabs = 1;
} else {
heredoc->striptabs = 0;
pungetc();
}
} else if (c == '&')
np->type = NFROMFD;
else if (c == '>')
np->type = NFROMTO;
else {
np->type = NFROM;
pungetc();
}
}
if (fd != '\0')
np->nfile.fd = digit_val(fd);
redirnode = np;
}
/*
* Called to parse command substitutions.
*/
@ -1039,25 +1095,12 @@ parsebackq(char *out, struct nodelist **pbqlist,
needprompt = 0;
}
CHECKSTRSPACE(2, oout);
switch (c = pgetc()) {
case '`':
goto done;
c = pgetc_linecont();
if (c == '`')
break;
switch (c) {
case '\\':
if ((c = pgetc()) == '\n') {
plinno++;
if (doprompt)
setprompt(2);
else
setprompt(0);
/*
* If eating a newline, avoid putting
* the newline into the new character
* stream (via the USTPUTC after the
* switch).
*/
continue;
}
c = pgetc();
if (c != '\\' && c != '`' && c != '$'
&& (!dblquote || c != '"'))
USTPUTC('\\', oout);
@ -1078,7 +1121,6 @@ parsebackq(char *out, struct nodelist **pbqlist,
}
USTPUTC(c, oout);
}
done:
USTPUTC('\0', oout);
olen = oout - stackblock();
INTOFF;
@ -1309,7 +1351,6 @@ readcstyleesc(char *out)
* will run code that appears at the end of readtoken1.
*/
#define PARSEREDIR() {goto parseredir; parseredir_return:;}
#define PARSESUB() {goto parsesub; parsesub_return:;}
#define PARSEARITH() {goto parsearith; parsearith_return:;}
@ -1454,7 +1495,7 @@ readtoken1(int firstc, char const *initialsyntax, const char *eofmark,
USTPUTC(c, out);
--state[level].parenlevel;
} else {
if (pgetc() == ')') {
if (pgetc_linecont() == ')') {
if (level > 0 &&
state[level].category == TSTATE_ARITH) {
level--;
@ -1509,7 +1550,7 @@ endword:
&& quotef == 0
&& len <= 2
&& (*out == '\0' || is_digit(*out))) {
PARSEREDIR();
parseredir(out, c);
return lasttoken = TREDIR;
} else {
pungetc();
@ -1523,63 +1564,6 @@ endword:
/* end of readtoken routine */
/*
* Parse a redirection operator. The variable "out" points to a string
* specifying the fd to be redirected. The variable "c" contains the
* first character of the redirection operator.
*/
parseredir: {
char fd = *out;
union node *np;
np = (union node *)stalloc(sizeof (struct nfile));
if (c == '>') {
np->nfile.fd = 1;
c = pgetc();
if (c == '>')
np->type = NAPPEND;
else if (c == '&')
np->type = NTOFD;
else if (c == '|')
np->type = NCLOBBER;
else {
np->type = NTO;
pungetc();
}
} else { /* c == '<' */
np->nfile.fd = 0;
c = pgetc();
if (c == '<') {
if (sizeof (struct nfile) != sizeof (struct nhere)) {
np = (union node *)stalloc(sizeof (struct nhere));
np->nfile.fd = 0;
}
np->type = NHERE;
heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
heredoc->here = np;
if ((c = pgetc()) == '-') {
heredoc->striptabs = 1;
} else {
heredoc->striptabs = 0;
pungetc();
}
} else if (c == '&')
np->type = NFROMFD;
else if (c == '>')
np->type = NFROMTO;
else {
np->type = NFROM;
pungetc();
}
}
if (fd != '\0')
np->nfile.fd = digit_val(fd);
redirnode = np;
goto parseredir_return;
}
/*
* Parse a substitution. At this point, we have read the dollar sign
* and nothing else.
@ -1597,9 +1581,9 @@ parsesub: {
int length;
int c1;
c = pgetc();
c = pgetc_linecont();
if (c == '(') { /* $(command) or $((arith)) */
if (pgetc() == '(') {
if (pgetc_linecont() == '(') {
PARSEARITH();
} else {
pungetc();
@ -1617,7 +1601,7 @@ parsesub: {
flags = 0;
if (c == '{') {
bracketed_name = 1;
c = pgetc();
c = pgetc_linecont();
subtype = 0;
}
varname:
@ -1625,7 +1609,7 @@ varname:
length = 0;
do {
STPUTC(c, out);
c = pgetc();
c = pgetc_linecont();
length++;
} while (!is_eof(c) && is_in_name(c));
if (length == 6 &&
@ -1644,22 +1628,22 @@ varname:
if (bracketed_name) {
do {
STPUTC(c, out);
c = pgetc();
c = pgetc_linecont();
} while (is_digit(c));
} else {
STPUTC(c, out);
c = pgetc();
c = pgetc_linecont();
}
} else if (is_special(c)) {
c1 = c;
c = pgetc();
c = pgetc_linecont();
if (subtype == 0 && c1 == '#') {
subtype = VSLENGTH;
if (strchr(types, c) == NULL && c != ':' &&
c != '#' && c != '%')
goto varname;
c1 = c;
c = pgetc();
c = pgetc_linecont();
if (c1 != '}' && c == '}') {
pungetc();
c = c1;
@ -1684,7 +1668,7 @@ varname:
switch (c) {
case ':':
flags |= VSNUL;
c = pgetc();
c = pgetc_linecont();
/*FALLTHROUGH*/
default:
p = strchr(types, c);
@ -1704,7 +1688,7 @@ varname:
int cc = c;
subtype = c == '#' ? VSTRIMLEFT :
VSTRIMRIGHT;
c = pgetc();
c = pgetc_linecont();
if (c == cc)
subtype++;
else
@ -1895,6 +1879,8 @@ synerror(const char *msg)
{
if (commandname)
outfmt(out2, "%s: %d: ", commandname, startlinno);
else if (arg0)
outfmt(out2, "%s: ", arg0);
outfmt(out2, "Syntax error: %s\n", msg);
error((char *)NULL);
}
@ -1913,6 +1899,29 @@ setprompt(int which)
}
}
static int
pgetc_linecont(void)
{
int c;
while ((c = pgetc_macro()) == '\\') {
c = pgetc();
if (c == '\n') {
plinno++;
if (doprompt)
setprompt(2);
else
setprompt(0);
} else {
pungetc();
/* Allow the backslash to be pushed back. */
pushstring("\\", 1, NULL);
return (pgetc());
}
}
return (c);
}
/*
* called by editline -- any expansions to the prompt
* should be added here.

View file

@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
.Dd September 21, 2014
.Dd November 14, 2014
.Dt SH 1
.Os
.Sh NAME
@ -795,10 +795,13 @@ should indicate the various exit codes and what they mean.
Additionally, the built-in commands return exit codes, as does
an executed shell function.
.Pp
If a command is terminated by a signal, its exit status is 128 plus
the signal number.
Signal numbers are defined in the header file
.In sys/signal.h .
If a command is terminated by a signal, its exit status is greater than 128.
The signal name can be found by passing the exit status to
.Li kill -l .
.Pp
If there is no command word,
the exit status is the exit status of the last command substitution executed,
or zero if the command does not contain any command substitutions.
.Ss Complex Commands
Complex commands are combinations of simple commands
with control operators or keywords, together creating a larger complex
@ -818,7 +821,8 @@ function definition
.El
.Pp
Unless otherwise stated, the exit status of a command is
that of the last simple command executed by the command.
that of the last simple command executed by the command,
or zero if no simple command was executed.
.Ss Pipelines
A pipeline is a sequence of one or more commands separated
by the control operator
@ -902,6 +906,8 @@ The format for running a command in background is:
If the shell is not interactive, the standard input of an
asynchronous command is set to
.Pa /dev/null .
.Pp
The exit status is zero.
.Ss Lists (Generally Speaking)
A list is a sequence of zero or more commands separated by
newlines, semicolons, or ampersands,
@ -940,6 +946,13 @@ command is:
.Ic fi
.Ed
.Pp
The exit status is that of selected
.Ic then
or
.Ic else
list,
or zero if no list was selected.
.Pp
The syntax of the
.Ic while
command is:
@ -960,6 +973,9 @@ in place of
which causes it to
repeat until the exit status of the first list is zero.
.Pp
The exit status is that of the last execution of the second list,
or zero if it was never executed.
.Pp
The syntax of the
.Ic for
command is:
@ -1040,10 +1056,6 @@ continuing until a list terminated with
or the end of the
.Ic case
command.
The exit code of the
.Ic case
command is the exit code of the last command executed in the list or
zero if no patterns were matched.
.Ss Grouping Commands Together
Commands may be grouped by writing either
.Pp
@ -1131,6 +1143,8 @@ and the syntax is:
The
.Ic local
command is implemented as a built-in command.
The exit status is zero
unless the command is not in a function or a variable name is invalid.
.Pp
When a variable is made local, it inherits the initial
value and exported and readonly flags from the variable
@ -2522,7 +2536,8 @@ and so on,
decreasing the value of
.Li $#
by one.
If there are zero positional parameters, shifting does not do anything.
For portability, shifting if there are zero positional parameters
should be avoided, since the shell may abort.
.It Ic test
A built-in equivalent of
.Xr test 1 .

View file

@ -0,0 +1,9 @@
# $FreeBSD$
args='-ab'
getopts ab opt $args
echo $?:$opt:$OPTARG
for dummy in dummy1 dummy2; do
getopts ab opt $args
echo $?:$opt:$OPTARG
done

View file

@ -0,0 +1,3 @@
0:a:
0:b:
1:?:

View file

@ -44,6 +44,7 @@ FILES+= set-n4.0
FILES+= set-x1.0
FILES+= set-x2.0
FILES+= set-x3.0
FILES+= set-x4.0
FILES+= shellproc1.0
FILES+= subshell1.0 subshell1.0.stdout
FILES+= subshell2.0

View file

@ -0,0 +1,7 @@
# $FreeBSD$
key=`printf '\r\t\001\200\300'`
r=`{ set -x; : "$key"; } 2>&1 >/dev/null`
case $r in
*[![:print:]]*) echo fail; exit 3
esac

View file

@ -72,6 +72,7 @@ FILES+= plus-minus7.0
FILES+= plus-minus8.0
FILES+= question1.0
FILES+= readonly1.0
FILES+= redir1.0
FILES+= set-u1.0
FILES+= set-u2.0
FILES+= set-u3.0

View file

@ -0,0 +1,26 @@
# $FreeBSD$
bad=0
for i in 0 1 2 3; do
for j in 0 1 2 3 4 5 6 7; do
for k in 0 1 2 3 4 5 6 7; do
case $i$j$k in
000) continue ;;
esac
set -- "$(printf \\$i$j$k@)"
set -- "${1%@}"
ff=
for f in /dev/null /dev/zero /; do
if [ -e "$f" ] && [ ! -e "$f$1" ]; then
ff=$f
fi
done
[ -n "$ff" ] || continue
if { true <$ff$1; } 2>/dev/null; then
echo "Bad: $i$j$k ($ff)" >&2
: $((bad += 1))
fi
done
done
done
exit $((bad ? 2 : 0))

View file

@ -18,6 +18,8 @@ FILES+= positional2.0
FILES+= positional3.0
FILES+= positional4.0
FILES+= positional5.0
FILES+= positional6.0
FILES+= positional7.0
FILES+= pwd1.0
FILES+= pwd2.0

View file

@ -0,0 +1,7 @@
# $FreeBSD$
IFS=?
set p r
v=pqrs
r=${v#"$*"}
[ "$r" = pqrs ]

View file

@ -0,0 +1,8 @@
# $FreeBSD$
set -- / ''
IFS=*
set -- "$*"
IFS=:
args="$*"
[ "$#:$args" = "1:/*" ]

View file

@ -55,6 +55,17 @@ FILES+= heredoc9.0
FILES+= heredoc10.0
FILES+= heredoc11.0
FILES+= heredoc12.0
FILES+= line-cont1.0
FILES+= line-cont2.0
FILES+= line-cont3.0
FILES+= line-cont4.0
FILES+= line-cont5.0
FILES+= line-cont6.0
FILES+= line-cont7.0
FILES+= line-cont8.0
FILES+= line-cont9.0
FILES+= line-cont10.0
FILES+= line-cont11.0
FILES+= no-space1.0
FILES+= no-space2.0
FILES+= only-redir1.0

View file

@ -0,0 +1,16 @@
# $FreeBSD$
i\
f
t\
r\
u\
e
t\
h\
e\
n
:
\
f\
i

View file

@ -0,0 +1,18 @@
# $FreeBSD$
v=XaaaXbbbX
[ "${v\
#\
*\
a}.${v\
#\
#\
*\
a}.${v\
%\
b\
*}.${v\
%\
%\
b\
*}" = aaXbbbX.XbbbX.XaaaXbb.XaaaX ]

View file

@ -0,0 +1,23 @@
# $FreeBSD$
T=$(mktemp "${TMPDIR:-/tmp}/sh-test.XXXXXXXX") || exit
trap 'rm -f -- "$T"' 0
w='#A'
# A naive pgetc_linecont() would push back two characters here, which
# fails if a new buffer is read between the two characters.
c='${w#\#}'
c=$c$c$c$c
c=$c$c$c$c
c=$c$c$c$c
c=$c$c$c$c
c=$c$c$c$c
c=$c$c$c$c
printf 'v=%s\n' "$c" >"$T"
. "$T"
if [ "${#v}" != 4096 ]; then
echo "Length is bad (${#v})"
exit 3
fi
case $v in
*[!A]*) echo "Content is bad"; exit 3 ;;
esac

View file

@ -0,0 +1,4 @@
# $FreeBSD$
[ "a\
b" = ab ]

View file

@ -0,0 +1,7 @@
# $FreeBSD$
v=`printf %s 'a\
b'`
w="`printf %s 'c\
d'`"
[ "$v$w" = abcd ]

View file

@ -0,0 +1,8 @@
# $FreeBSD$
v=abcd
[ "$\
v.$\
{v}.${\
v}.${v\
}" = abcd.abcd.abcd.abcd ]

View file

@ -0,0 +1,14 @@
# $FreeBSD$
bad=1
case x in
x\
) ;\
; *) exit 7
esac &\
& bad= &\
& : >\
>/dev/null
false |\
| [ -z "$bad" ]

View file

@ -0,0 +1,23 @@
# $FreeBSD$
v0\
=abc
v=$(cat <\
<\
E\
O\
F
${v0}d
EOF
)
w=$(cat <\
<\
-\
EOF
efgh
EOF
)
[ "$v.$w" = "abcd.efgh" ]

View file

@ -0,0 +1,7 @@
# $FreeBSD$
[ "$(\
(
1\
+ 1)\
)" = 2 ]

View file

@ -0,0 +1,6 @@
# $FreeBSD$
set -- a b c d e f g h i j
[ "${1\
0\
}" = j ]

View file

@ -0,0 +1,6 @@
# $FreeBSD$
[ "${$\
:\
+\
xyz}" = xyz ]

View file

@ -75,7 +75,7 @@ __FBSDID("$FreeBSD$");
static char sigmode[NSIG]; /* current value of signal */
volatile sig_atomic_t pendingsig; /* indicates some signal received */
volatile sig_atomic_t pendingsig_waitcmd; /* indicates SIGINT/SIGQUIT received */
int in_dotrap; /* do we execute in a trap handler? */
static int in_dotrap; /* do we execute in a trap handler? */
static char *volatile trap[NSIG]; /* trap handler commands */
static volatile sig_atomic_t gotsig[NSIG];
/* indicates specified signal received */
@ -380,7 +380,15 @@ onsig(int signo)
{
if (signo == SIGINT && trap[SIGINT] == NULL) {
onint();
/*
* The !in_dotrap here is safe. The only way we can arrive
* here with in_dotrap set is that a trap handler set SIGINT to
* SIG_DFL and killed itself.
*/
if (suppressint && !in_dotrap)
SET_PENDING_INT;
else
onint();
return;
}

View file

@ -35,7 +35,6 @@
extern volatile sig_atomic_t pendingsig;
extern volatile sig_atomic_t pendingsig_waitcmd;
extern int in_dotrap;
void clear_traps(void);
int have_traps(void);

View file

@ -233,12 +233,11 @@ tpool_create(uint_t min_threads, uint_t max_threads, uint_t linger,
return (NULL);
}
tpool = malloc(sizeof (*tpool));
tpool = calloc(1, sizeof (*tpool));
if (tpool == NULL) {
errno = ENOMEM;
return (NULL);
}
bzero(tpool, sizeof(*tpool));
(void) pthread_mutex_init(&tpool->tp_mutex, NULL);
(void) pthread_cond_init(&tpool->tp_busycv, NULL);
(void) pthread_cond_init(&tpool->tp_workcv, NULL);
@ -267,9 +266,8 @@ tpool_dispatch(tpool_t *tpool, void (*func)(void *), void *arg)
{
tpool_job_t *job;
if ((job = malloc(sizeof (*job))) == NULL)
if ((job = calloc(1, sizeof (*job))) == NULL)
return (-1);
bzero(job, sizeof(*job));
job->tpj_next = NULL;
job->tpj_func = func;
job->tpj_arg = arg;

View file

@ -1,11 +0,0 @@
#include <stdlib.h>
#include <sys/sdt.h>
#include "prov.h"
int
main(int argc, char **argv, char **envp)
{
envp[0] = (char*)0xff;
TESTER_ENTRY();
return 0;
}

View file

@ -77,9 +77,11 @@
#ifndef lint
extern boolean_t zfs_recover;
extern uint64_t zfs_arc_max, zfs_arc_meta_limit;
extern int zfs_vdev_async_read_max_active;
#else
boolean_t zfs_recover;
uint64_t zfs_arc_max, zfs_arc_meta_limit;
int zfs_vdev_async_read_max_active;
#endif
const char cmdname[] = "zdb";
@ -1182,7 +1184,7 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
print_indirect(bp, zb, dnp);
if (BP_GET_LEVEL(bp) > 0 && !BP_IS_HOLE(bp)) {
uint32_t flags = ARC_WAIT;
arc_flags_t flags = ARC_FLAG_WAIT;
int i;
blkptr_t *cbp;
int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT;
@ -1882,8 +1884,8 @@ dump_dir(objset_t *os)
if (dds.dds_type == DMU_OST_META) {
dds.dds_creation_txg = TXG_INITIAL;
usedobjs = BP_GET_FILL(os->os_rootbp);
refdbytes = os->os_spa->spa_dsl_pool->
dp_mos_dir->dd_phys->dd_used_bytes;
refdbytes = dsl_dir_phys(os->os_spa->spa_dsl_pool->dp_mos_dir)->
dd_used_bytes;
} else {
dmu_objset_space(os, &refdbytes, &scratch, &usedobjs, &scratch);
}
@ -2145,6 +2147,8 @@ dump_label(const char *dev)
(void) close(fd);
}
static uint64_t num_large_blocks;
/*ARGSUSED*/
static int
dump_one_dir(const char *dsname, void *arg)
@ -2157,6 +2161,8 @@ dump_one_dir(const char *dsname, void *arg)
(void) printf("Could not open %s, error %d\n", dsname, error);
return (0);
}
if (dmu_objset_ds(os)->ds_large_blocks)
num_large_blocks++;
dump_dir(os);
dmu_objset_disown(os, FTAG);
fuid_table_destroy();
@ -2167,7 +2173,7 @@ dump_one_dir(const char *dsname, void *arg)
/*
* Block statistics.
*/
#define PSIZE_HISTO_SIZE (SPA_MAXBLOCKSIZE / SPA_MINBLOCKSIZE + 1)
#define PSIZE_HISTO_SIZE (SPA_OLD_MAXBLOCKSIZE / SPA_MINBLOCKSIZE + 2)
typedef struct zdb_blkstats {
uint64_t zb_asize;
uint64_t zb_lsize;
@ -2232,7 +2238,15 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
zb->zb_lsize += BP_GET_LSIZE(bp);
zb->zb_psize += BP_GET_PSIZE(bp);
zb->zb_count++;
zb->zb_psize_histogram[BP_GET_PSIZE(bp) >> SPA_MINBLOCKSHIFT]++;
/*
* The histogram is only big enough to record blocks up to
* SPA_OLD_MAXBLOCKSIZE; larger blocks go into the last,
* "other", bucket.
*/
int idx = BP_GET_PSIZE(bp) >> SPA_MINBLOCKSHIFT;
idx = MIN(idx, SPA_OLD_MAXBLOCKSIZE / SPA_MINBLOCKSIZE + 1);
zb->zb_psize_histogram[idx]++;
zb->zb_gangs += BP_COUNT_GANG(bp);
@ -2384,8 +2398,14 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
zcb->zcb_readfails = 0;
if (dump_opt['b'] < 5 &&
gethrtime() > zcb->zcb_lastprint + NANOSEC) {
/* only call gethrtime() every 100 blocks */
static int iters;
if (++iters > 100)
iters = 0;
else
return (0);
if (dump_opt['b'] < 5 && gethrtime() > zcb->zcb_lastprint + NANOSEC) {
uint64_t now = gethrtime();
char buf[10];
uint64_t bytes = zcb->zcb_type[ZB_TOTAL][ZDB_OT_TOTAL].zb_asize;
@ -2494,6 +2514,14 @@ zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
(longlong_t)vd->vdev_ms_count);
msp->ms_ops = &zdb_metaslab_ops;
/*
* We don't want to spend the CPU
* manipulating the size-ordered
* tree, so clear the range_tree
* ops.
*/
msp->ms_tree->rt_ops = NULL;
VERIFY0(space_map_load(msp->ms_sm,
msp->ms_tree, SM_ALLOC));
msp->ms_loaded = B_TRUE;
@ -2930,6 +2958,7 @@ dump_zpool(spa_t *spa)
dump_metaslab_groups(spa);
if (dump_opt['d'] || dump_opt['i']) {
uint64_t refcount;
dump_dir(dp->dp_meta_objset);
if (dump_opt['d'] >= 3) {
dump_bpobj(&spa->spa_deferred_bpobj,
@ -2949,8 +2978,21 @@ dump_zpool(spa_t *spa)
}
(void) dmu_objset_find(spa_name(spa), dump_one_dir,
NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
(void) feature_get_refcount(spa,
&spa_feature_table[SPA_FEATURE_LARGE_BLOCKS], &refcount);
if (num_large_blocks != refcount) {
(void) printf("large_blocks feature refcount mismatch: "
"expected %lld != actual %lld\n",
(longlong_t)num_large_blocks,
(longlong_t)refcount);
rc = 2;
} else {
(void) printf("Verified large_blocks feature refcount "
"is correct (%llu)\n", (longlong_t)refcount);
}
}
if (dump_opt['b'] || dump_opt['c'])
if (rc == 0 && (dump_opt['b'] || dump_opt['c']))
rc = dump_block_stats(spa);
if (rc == 0)
@ -3508,6 +3550,13 @@ main(int argc, char **argv)
*/
zfs_arc_max = zfs_arc_meta_limit = 256 * 1024 * 1024;
/*
* "zdb -c" uses checksum-verifying scrub i/os which are async reads.
* "zdb -b" uses traversal prefetch which uses async reads.
* For good performance, let several of them be active at once.
*/
zfs_vdev_async_read_max_active = 10;
kernel_init(FREAD);
g_zfs = libzfs_init();
ASSERT(g_zfs != NULL);

View file

@ -23,14 +23,15 @@
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
.\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org>
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
.\" Copyright (c) 2013 Nexenta Systems, Inc. All Rights Reserved.
.\" Copyright (c) 2014, Joyent, Inc. All rights reserved.
.\" Copyright (c) 2013, Steven Hartland <smh@FreeBSD.org>
.\" Copyright (c) 2014 Nexenta Systems, Inc. All Rights Reserved.
.\" Copyright (c) 2014, Xin LI <delphij@FreeBSD.org>
.\" Copyright (c) 2014, The FreeBSD Foundation, All Rights Reserved.
.\"
.\" $FreeBSD$
.\"
.Dd June 30, 2014
.Dd December 12, 2014
.Dt ZFS 8
.Os
.Sh NAME
@ -179,12 +180,12 @@
.Ar bookmark
.Nm
.Cm send
.Op Fl DnPpRve
.Op Fl DnPpRveL
.Op Fl i Ar snapshot | Fl I Ar snapshot
.Ar snapshot
.Nm
.Cm send
.Op Fl e
.Op Fl eL
.Op Fl i Ar snapshot Ns | Ns bookmark
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Nm
@ -1187,6 +1188,12 @@ systems is strongly discouraged, and may adversely affect performance.
.Pp
The size specified must be a power of two greater than or equal to 512 and less
than or equal to 128 Kbytes.
If the
.Sy large_blocks
feature is enabled on the pool, the size may be up to 1 Mbyte.
See
.Xr zpool-features 7
for details on ZFS feature flags.
.Pp
Changing the file system's
.Sy recordsize
@ -1785,7 +1792,7 @@ descendent file systems.
Recursively destroy all clones of these snapshots, including the clones,
snapshots, and children.
If this flag is specified, the
.Op fl d
.Fl d
flag will have no effect.
.It Fl n
Do a dry-run ("No-op") deletion. No data will be deleted. This is useful in
@ -2477,7 +2484,7 @@ feature.
.It Xo
.Nm
.Cm send
.Op Fl DnPpRve
.Op Fl DnPpRveL
.Op Fl i Ar snapshot | Fl I Ar snapshot
.Ar snapshot
.Xc
@ -2549,6 +2556,22 @@ be used regardless of the dataset's
property, but performance will be much better if the filesystem uses a
dedup-capable checksum (eg.
.Sy sha256 ) .
.It Fl L
Generate a stream which may contain blocks larger than 128KB.
This flag
has no effect if the
.Sy large_blocks
pool feature is disabled, or if the
.Sy recordsize
property of this filesystem has never been set above 128KB.
The receiving system must have the
.Sy large_blocks
pool feature enabled as well.
See
.Xr zpool-features 7
for details on ZFS feature flags and the
.Sy large_blocks
feature.
.It Fl e
Generate a more compact stream by using WRITE_EMBEDDED records for blocks
which are stored more compactly on disk by the
@ -2596,7 +2619,7 @@ on future versions of
.It Xo
.Nm
.Cm send
.Op Fl e
.Op Fl eL
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Xc
@ -2622,6 +2645,22 @@ specified as the last component of the name
If the incremental target is a clone, the incremental source can
be the origin snapshot, or an earlier snapshot in the origin's filesystem,
or the origin's origin, etc.
.It Fl L
Generate a stream which may contain blocks larger than 128KB.
This flag
has no effect if the
.Sy large_blocks
pool feature is disabled, or if the
.Sy recordsize
property of this filesystem has never been set above 128KB.
The receiving system must have the
.Sy large_blocks
pool feature enabled as well.
See
.Xr zpool-features 7
for details on ZFS feature flags and the
.Sy large_blocks
feature.
.It Fl e
Generate a more compact stream by using WRITE_EMBEDDED records for blocks
which are stored more compactly on disk by the
@ -3466,10 +3505,9 @@ are also displayed.
.Bd -literal -offset 2n
.Li # Ic zfs allow cindys create,destroy,mount,snapshot tank/cindys
.Li # Ic zfs allow tank/cindys
-------------------------------------------------------------
Local+Descendent permissions on (tank/cindys)
user cindys create,destroy,mount,snapshot
-------------------------------------------------------------
---- Permissions on tank/cindys --------------------------------------
Local+Descendent permissions:
user cindys create,destroy,mount,snapshot
.Ed
.It Sy Example 18 No Delegating Create Time Permissions on a Tn ZFS No Dataset
.Pp
@ -3485,12 +3523,11 @@ are also displayed.
.Li # Ic zfs allow staff create,mount tank/users
.Li # Ic zfs allow -c destroy tank/users
.Li # Ic zfs allow tank/users
-------------------------------------------------------------
Create time permissions on (tank/users)
create,destroy
Local+Descendent permissions on (tank/users)
group staff create,mount
-------------------------------------------------------------
---- Permissions on tank/users ---------------------------------------
Permission sets:
destroy
Local+Descendent permissions:
group staff create,mount
.Ed
.It Xo
.Sy Example 19
@ -3508,14 +3545,11 @@ are also displayed.
.Li # Ic zfs allow -s @pset create,destroy,snapshot,mount tank/users
.Li # Ic zfs allow staff @pset tank/users
.Li # Ic zfs allow tank/users
-------------------------------------------------------------
Permission sets on (tank/users)
---- Permissions on tank/users ---------------------------------------
Permission sets:
@pset create,destroy,mount,snapshot
Create time permissions on (tank/users)
create,destroy
Local+Descendent permissions on (tank/users)
group staff @pset,create,mount
-------------------------------------------------------------
Local+Descendent permissions:
group staff @pset
.Ed
.It Sy Example 20 No Delegating Property Permissions on a Tn ZFS No Dataset
.Pp
@ -3527,16 +3561,15 @@ file system. The permissions on
are also displayed.
.Bd -literal -offset 2n
.Li # Ic zfs allow cindys quota,reservation users/home
.Li # Ic zfs allow cindys
-------------------------------------------------------------
Local+Descendent permissions on (users/home)
.Li # Ic zfs allow users/home
---- Permissions on users/home ---------------------------------------
Local+Descendent permissions:
user cindys quota,reservation
-------------------------------------------------------------
.Li # Ic su - cindys
.Li cindys% Ic zfs set quota=10G users/home/marks
.Li cindys% Ic zfs get quota users/home/marks
NAME PROPERTY VALUE SOURCE
users/home/marks quota 10G local
NAME PROPERTY VALUE SOURCE
users/home/marks quota 10G local
.Ed
.It Sy Example 21 No Removing ZFS Delegated Permissions on a Tn ZFS No Dataset
.Pp
@ -3550,14 +3583,11 @@ are also displayed.
.Bd -literal -offset 2n
.Li # Ic zfs unallow staff snapshot tank/users
.Li # Ic zfs allow tank/users
-------------------------------------------------------------
Permission sets on (tank/users)
---- Permissions on tank/users ---------------------------------------
Permission sets:
@pset create,destroy,mount,snapshot
Create time permissions on (tank/users)
create,destroy
Local+Descendent permissions on (tank/users)
group staff @pset,create,mount
-------------------------------------------------------------
Local+Descendent permissions:
group staff @pset
.Ed
.It Sy Example 22 Showing the differences between a snapshot and a ZFS Dataset
.Pp

View file

@ -68,6 +68,7 @@
#ifdef sun
#include <aclutils.h>
#include <directory.h>
#include <idmap.h>
#endif
#include "zfs_iter.h"
@ -274,9 +275,9 @@ get_usage(zfs_help_t idx)
case HELP_ROLLBACK:
return (gettext("\trollback [-rRf] <snapshot>\n"));
case HELP_SEND:
return (gettext("\tsend [-DnPpRve] [-[iI] snapshot] "
return (gettext("\tsend [-DnPpRvLe] [-[iI] snapshot] "
"<snapshot>\n"
"\tsend [-e] [-i snapshot|bookmark] "
"\tsend [-Le] [-i snapshot|bookmark] "
"<filesystem|volume|snapshot>\n"));
case HELP_SET:
return (gettext("\tset <property=value> "
@ -2390,10 +2391,9 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space)
/* SMB */
char sid[ZFS_MAXNAMELEN + 32];
uid_t id;
uint64_t classes;
#ifdef sun
int err;
directory_error_t e;
int flag = IDMAP_REQ_FLG_USE_CACHE;
#endif
smbentity = B_TRUE;
@ -2416,10 +2416,13 @@ userspace_cb(void *arg, const char *domain, uid_t rid, uint64_t space)
if (err == 0) {
rid = id;
if (!cb->cb_sid2posix) {
e = directory_name_from_sid(NULL, sid, &name,
&classes);
if (e != NULL)
directory_error_free(e);
if (type == USTYPE_SMB_USR) {
(void) idmap_getwinnamebyuid(rid, flag,
&name, NULL);
} else {
(void) idmap_getwinnamebygid(rid, flag,
&name, NULL);
}
if (name == NULL)
name = sid;
}
@ -3709,7 +3712,7 @@ zfs_do_send(int argc, char **argv)
boolean_t extraverbose = B_FALSE;
/* check options */
while ((c = getopt(argc, argv, ":i:I:RDpvnPe")) != -1) {
while ((c = getopt(argc, argv, ":i:I:RDpvnPLe")) != -1) {
switch (c) {
case 'i':
if (fromname)
@ -3744,6 +3747,9 @@ zfs_do_send(int argc, char **argv)
case 'n':
flags.dryrun = B_TRUE;
break;
case 'L':
flags.largeblock = B_TRUE;
break;
case 'e':
flags.embed_data = B_TRUE;
break;
@ -3800,6 +3806,8 @@ zfs_do_send(int argc, char **argv)
if (zhp == NULL)
return (1);
if (flags.largeblock)
lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK;
if (flags.embed_data)
lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;

View file

@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd July 1, 2014
.Dd November 10, 2014
.Dt ZPOOL-FEATURES 7
.Os
.Sh NAME
@ -427,6 +427,33 @@ This feature becomes
as soon as it is enabled and will
never return to being
.Sy enabled .
.It Sy large_blocks
.Bl -column "READ\-ONLY COMPATIBLE" "org.open-zfs:large_block"
.It GUID Ta org.open-zfs:large_block
.It READ\-ONLY COMPATIBLE Ta no
.It DEPENDENCIES Ta extensible_dataset
.El
.Pp
The
.Sy large_block
feature allows the record size on a dataset to be
set larger than 128KB.
.Pp
This feature becomes
.Sy active
once a
.Sy recordsize
property has been set larger than 128KB, and will return to being
.Sy enabled
once all filesystems that have ever had their recordsize larger than 128KB
are destroyed.
.Pp
Please note that booting from datasets that have recordsize greater than
128KB is
.Em NOT
supported by the
.Fx
boot loader.
.El
.Sh SEE ALSO
.Xr zpool 8

View file

@ -4509,11 +4509,12 @@ zpool_do_status(int argc, char **argv)
}
typedef struct upgrade_cbdata {
int cb_first;
char cb_poolname[ZPOOL_MAXNAMELEN];
int cb_argc;
uint64_t cb_version;
char **cb_argv;
boolean_t cb_first;
boolean_t cb_unavail;
char cb_poolname[ZPOOL_MAXNAMELEN];
int cb_argc;
uint64_t cb_version;
char **cb_argv;
} upgrade_cbdata_t;
#ifdef __FreeBSD__
@ -4629,6 +4630,14 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
boolean_t printnl = B_FALSE;
int ret;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
(void) fprintf(stderr, gettext("cannot upgrade '%s': pool is "
"currently unavailable.\n\n"), zpool_get_name(zhp));
cbp->cb_unavail = B_TRUE;
/* Allow iteration to continue. */
return (0);
}
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
&version) == 0);
@ -4689,6 +4698,26 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
return (0);
}
static int
upgrade_list_unavail(zpool_handle_t *zhp, void *arg)
{
upgrade_cbdata_t *cbp = arg;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
if (cbp->cb_first) {
(void) fprintf(stderr, gettext("The following pools "
"are unavailable and cannot be upgraded as this "
"time.\n\n"));
(void) fprintf(stderr, gettext("POOL\n"));
(void) fprintf(stderr, gettext("------------\n"));
cbp->cb_first = B_FALSE;
}
(void) printf(gettext("%s\n"), zpool_get_name(zhp));
cbp->cb_unavail = B_TRUE;
}
return (0);
}
static int
upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
{
@ -4696,6 +4725,15 @@ upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
nvlist_t *config;
uint64_t version;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
/*
* This will have been reported by upgrade_list_unavail so
* just allow iteration to continue.
*/
cbp->cb_unavail = B_TRUE;
return (0);
}
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
&version) == 0);
@ -4729,6 +4767,15 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
nvlist_t *config;
uint64_t version;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
/*
* This will have been reported by upgrade_list_unavail so
* just allow iteration to continue.
*/
cbp->cb_unavail = B_TRUE;
return (0);
}
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
&version) == 0);
@ -4782,10 +4829,17 @@ upgrade_one(zpool_handle_t *zhp, void *data)
uint64_t cur_version;
int ret;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
(void) fprintf(stderr, gettext("cannot upgrade '%s': pool is "
"is currently unavailable.\n\n"), zpool_get_name(zhp));
cbp->cb_unavail = B_TRUE;
return (1);
}
if (strcmp("log", zpool_get_name(zhp)) == 0) {
(void) printf(gettext("'log' is now a reserved word\n"
"Pool 'log' must be renamed using export and import"
" to upgrade.\n"));
" to upgrade.\n\n"));
return (1);
}
@ -4829,7 +4883,7 @@ upgrade_one(zpool_handle_t *zhp, void *data)
#endif /* __FreeBSD __*/
} else if (cur_version == SPA_VERSION) {
(void) printf(gettext("Pool '%s' already has all "
"supported features enabled.\n"),
"supported features enabled.\n\n"),
zpool_get_name(zhp));
}
}
@ -4986,11 +5040,13 @@ zpool_do_upgrade(int argc, char **argv)
ret = zpool_iter(g_zfs, upgrade_cb, &cb);
if (ret == 0 && cb.cb_first) {
if (cb.cb_version == SPA_VERSION) {
(void) printf(gettext("All pools are already "
"formatted using feature flags.\n\n"));
(void) printf(gettext("Every feature flags "
(void) printf(gettext("All %spools are already "
"formatted using feature flags.\n\n"),
cb.cb_unavail ? gettext("available ") : "");
(void) printf(gettext("Every %sfeature flags "
"pool already has all supported features "
"enabled.\n"));
"enabled.\n"),
cb.cb_unavail ? gettext("available ") : "");
} else {
(void) printf(gettext("All pools are already "
"formatted with version %llu or higher.\n"),
@ -4998,13 +5054,22 @@ zpool_do_upgrade(int argc, char **argv)
}
}
} else if (argc == 0) {
cb.cb_first = B_TRUE;
ret = zpool_iter(g_zfs, upgrade_list_unavail, &cb);
assert(ret == 0);
if (!cb.cb_first) {
(void) fprintf(stderr, "\n");
}
cb.cb_first = B_TRUE;
ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
assert(ret == 0);
if (cb.cb_first) {
(void) printf(gettext("All pools are formatted "
"using feature flags.\n\n"));
(void) printf(gettext("All %spools are formatted using "
"feature flags.\n\n"), cb.cb_unavail ?
gettext("available ") : "");
} else {
(void) printf(gettext("\nUse 'zpool upgrade -v' "
"for a list of available legacy versions.\n"));
@ -5015,13 +5080,14 @@ zpool_do_upgrade(int argc, char **argv)
assert(ret == 0);
if (cb.cb_first) {
(void) printf(gettext("Every feature flags pool has "
"all supported features enabled.\n"));
(void) printf(gettext("Every %sfeature flags pool has "
"all supported features enabled.\n"),
cb.cb_unavail ? gettext("available ") : "");
} else {
(void) printf(gettext("\n"));
}
} else {
ret = for_each_pool(argc, argv, B_FALSE, NULL,
ret = for_each_pool(argc, argv, B_TRUE, NULL,
upgrade_one, &cb);
}

View file

@ -54,7 +54,6 @@ uint64_t total_stream_len = 0;
FILE *send_stream = 0;
boolean_t do_byteswap = B_FALSE;
boolean_t do_cksum = B_TRUE;
#define INITIAL_BUFLEN (1<<20)
static void
usage(void)
@ -67,6 +66,18 @@ usage(void)
exit(1);
}
static void *
safe_malloc(size_t size)
{
void *rv = malloc(size);
if (rv == NULL) {
(void) fprintf(stderr, "ERROR; failed to allocate %zu bytes\n",
size);
abort();
}
return (rv);
}
/*
* ssread - send stream read.
*
@ -158,7 +169,7 @@ print_block(char *buf, int length)
int
main(int argc, char *argv[])
{
char *buf = malloc(INITIAL_BUFLEN);
char *buf = safe_malloc(SPA_MAXBLOCKSIZE);
uint64_t drr_record_count[DRR_NUMTYPES] = { 0 };
uint64_t total_records = 0;
dmu_replay_record_t thedrr;
@ -307,9 +318,9 @@ main(int argc, char *argv[])
nvlist_t *nv;
int sz = drr->drr_payloadlen;
if (sz > INITIAL_BUFLEN) {
if (sz > SPA_MAXBLOCKSIZE) {
free(buf);
buf = malloc(sz);
buf = safe_malloc(sz);
}
(void) ssread(buf, sz, &zc);
if (ferror(send_stream))

View file

@ -987,9 +987,15 @@ ztest_spa_get_ashift() {
static int
ztest_random_blocksize(void)
{
// Choose a block size >= the ashift.
uint64_t block_shift =
ztest_random(SPA_MAXBLOCKSHIFT - ztest_spa_get_ashift() + 1);
uint64_t block_shift;
/*
* Choose a block size >= the ashift.
* If the SPA supports new MAXBLOCKSIZE, test up to 1MB blocks.
*/
int maxbs = SPA_OLD_MAXBLOCKSHIFT;
if (spa_maxblocksize(ztest_spa) == SPA_MAXBLOCKSIZE)
maxbs = 20;
block_shift = ztest_random(maxbs - ztest_spa_get_ashift() + 1);
return (1 << (SPA_MINBLOCKSHIFT + block_shift));
}
@ -4789,7 +4795,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
char path0[MAXPATHLEN];
char pathrand[MAXPATHLEN];
size_t fsize;
int bshift = SPA_MAXBLOCKSHIFT + 2; /* don't scrog all labels */
int bshift = SPA_OLD_MAXBLOCKSHIFT + 2; /* don't scrog all labels */
int iters = 1000;
int maxfaults;
int mirror_save;

File diff suppressed because it is too large Load diff

View file

@ -110,7 +110,7 @@ dtrace_dof_init(void)
Elf32_Ehdr *elf;
#endif
dof_helper_t dh;
Link_map *lmp;
Link_map *lmp = NULL;
#if defined(sun)
Lmid_t lmid;
#else
@ -127,6 +127,7 @@ dtrace_dof_init(void)
int efd;
char *s;
size_t shstridx;
uint64_t aligned_filesz;
#endif
if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL)
@ -171,6 +172,7 @@ dtrace_dof_init(void)
if (s != NULL && strcmp(s, ".SUNW_dof") == 0) {
dofdata = elf_getdata(scn, NULL);
dof = dofdata->d_buf;
break;
}
}
}
@ -182,7 +184,9 @@ dtrace_dof_init(void)
}
while ((char *) dof < (char *) dofdata->d_buf + dofdata->d_size) {
dof_next = (void *) ((char *) dof + dof->dofh_filesz);
aligned_filesz = (shdr.sh_addralign == 0 ? dof->dofh_filesz :
roundup2(dof->dofh_filesz, shdr.sh_addralign));
dof_next = (void *) ((char *) dof + aligned_filesz);
#endif
if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 ||

View file

@ -469,7 +469,7 @@ dof_add_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
* locally so an alternate symbol is added for the purpose
* of this relocation.
*/
if (pip->pi_rname[0] == '\0')
if (pip->pi_rname == NULL)
dofr.dofr_name = dofpr.dofpr_func;
else
dofr.dofr_name = dof_add_string(ddo, pip->pi_rname);

View file

@ -685,8 +685,8 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
elf_file.ehdr.e_machine = EM_ARM;
#elif defined(__mips__)
elf_file.ehdr.e_machine = EM_MIPS;
#elif defined(__powerpc__)
elf_file.ehdr.e_machine = EM_PPC;
#elif defined(__powerpc64__)
elf_file.ehdr.e_machine = EM_PPC64;
#elif defined(__sparc)
elf_file.ehdr.e_machine = EM_SPARCV9;
#elif defined(__i386) || defined(__amd64)
@ -784,21 +784,32 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
static int
dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
GElf_Sym *sym)
GElf_Sym *sym, int uses_funcdesc, Elf *elf)
{
int i, ret = -1;
Elf64_Addr symval;
Elf_Scn *opd_scn;
Elf_Data *opd_desc;
GElf_Sym s;
for (i = 0; i < nsym && gelf_getsym(data_sym, i, sym) != NULL; i++) {
if (GELF_ST_TYPE(sym->st_info) == STT_FUNC &&
shn == sym->st_shndx &&
sym->st_value <= addr &&
addr < sym->st_value + sym->st_size) {
if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL)
return (0);
if (GELF_ST_TYPE(sym->st_info) == STT_FUNC) {
symval = sym->st_value;
if (uses_funcdesc) {
opd_scn = elf_getscn(elf, sym->st_shndx);
opd_desc = elf_rawdata(opd_scn, NULL);
symval =
*(uint64_t*)((char *)opd_desc->d_buf + symval);
}
if ((uses_funcdesc || shn == sym->st_shndx) &&
symval <= addr &&
addr < symval + sym->st_size) {
if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL)
return (0);
ret = 0;
s = *sym;
ret = 0;
s = *sym;
}
}
}
@ -1375,7 +1386,8 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
continue;
if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
shdr_rel.sh_info, &fsym) != 0) {
shdr_rel.sh_info, &fsym,
(emachine1 == EM_PPC64), elf) != 0) {
dt_strtab_destroy(strtab);
goto err;
}
@ -1536,7 +1548,8 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
p = strhyphenate(p + 3); /* strlen("___") */
if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
shdr_rel.sh_info, &fsym) != 0)
shdr_rel.sh_info, &fsym,
(emachine1 == EM_PPC64), elf) != 0)
goto err;
if (fsym.st_name > data_str->d_size)

View file

@ -1211,13 +1211,13 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
#if defined(__FreeBSD__)
if (sh.sh_size == 0)
continue;
if (is_elf_obj && (sh.sh_type == SHT_PROGBITS ||
sh.sh_type == SHT_NOBITS)) {
if (sh.sh_type == SHT_PROGBITS || sh.sh_type == SHT_NOBITS) {
alignmask = sh.sh_addralign - 1;
mapbase += alignmask;
mapbase &= ~alignmask;
sh.sh_addr = mapbase;
dmp->dm_sec_offsets[elf_ndxscn(sp)] = sh.sh_addr;
if (is_elf_obj)
dmp->dm_sec_offsets[elf_ndxscn(sp)] = sh.sh_addr;
mapbase += sh.sh_size;
}
#endif

View file

@ -520,6 +520,8 @@ dt_probe_destroy(dt_probe_t *prp)
for (pip = prp->pr_inst; pip != NULL; pip = pip_next) {
pip_next = pip->pi_next;
dt_free(dtp, pip->pi_rname);
dt_free(dtp, pip->pi_fname);
dt_free(dtp, pip->pi_offs);
dt_free(dtp, pip->pi_enoffs);
dt_free(dtp, pip);
@ -543,8 +545,9 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
for (pip = prp->pr_inst; pip != NULL; pip = pip->pi_next) {
if (strcmp(pip->pi_fname, fname) == 0 &&
((rname == NULL && pip->pi_rname[0] == '\0') ||
(rname != NULL && strcmp(pip->pi_rname, rname)) == 0))
((rname == NULL && pip->pi_rname == NULL) ||
(rname != NULL && pip->pi_rname != NULL &&
strcmp(pip->pi_rname, rname) == 0)))
break;
}
@ -552,28 +555,18 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
if ((pip = dt_zalloc(dtp, sizeof (*pip))) == NULL)
return (-1);
if ((pip->pi_offs = dt_zalloc(dtp,
sizeof (uint32_t))) == NULL) {
dt_free(dtp, pip);
return (-1);
}
if ((pip->pi_offs = dt_zalloc(dtp, sizeof (uint32_t))) == NULL)
goto nomem;
if ((pip->pi_enoffs = dt_zalloc(dtp,
sizeof (uint32_t))) == NULL) {
dt_free(dtp, pip->pi_offs);
dt_free(dtp, pip);
return (-1);
}
sizeof (uint32_t))) == NULL)
goto nomem;
(void) strlcpy(pip->pi_fname, fname, sizeof (pip->pi_fname));
if (rname != NULL) {
if (strlen(rname) + 1 > sizeof (pip->pi_rname)) {
dt_free(dtp, pip->pi_offs);
dt_free(dtp, pip);
return (dt_set_errno(dtp, EDT_COMPILER));
}
(void) strcpy(pip->pi_rname, rname);
}
if ((pip->pi_fname = strdup(fname)) == NULL)
goto nomem;
if (rname != NULL && (pip->pi_rname = strdup(rname)) == NULL)
goto nomem;
pip->pi_noffs = 0;
pip->pi_maxoffs = 1;
@ -618,6 +611,13 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
(*offs)[(*noffs)++] = offset;
return (0);
nomem:
dt_free(dtp, pip->pi_fname);
dt_free(dtp, pip->pi_enoffs);
dt_free(dtp, pip->pi_offs);
dt_free(dtp, pip);
return (dt_set_errno(dtp, EDT_NOMEM));
}
/*

View file

@ -64,8 +64,8 @@ typedef struct dt_probe_iter {
} dt_probe_iter_t;
typedef struct dt_probe_instance {
char pi_fname[DTRACE_FUNCNAMELEN]; /* function name */
char pi_rname[DTRACE_FUNCNAMELEN + 20]; /* mangled relocation name */
char *pi_fname; /* function name */
char *pi_rname; /* mangled relocation name */
uint32_t *pi_offs; /* offsets into the function */
uint32_t *pi_enoffs; /* is-enabled offsets */
uint_t pi_noffs; /* number of offsets */

View file

@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
#ifndef _LIBNVPAIR_H
@ -46,6 +47,7 @@ extern int nvpair_value_match_regex(nvpair_t *, int, char *, regex_t *,
char **);
extern void nvlist_print(FILE *, nvlist_t *);
extern int nvlist_print_json(FILE *, nvlist_t *);
extern void dump_nvlist(nvlist_t *, int);
/*

View file

@ -0,0 +1,403 @@
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright (c) 2014, Joyent, Inc.
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <wchar.h>
#include <sys/debug.h>
#include "libnvpair.h"
#define FPRINTF(fp, ...) \
do { \
if (fprintf(fp, __VA_ARGS__) < 0) \
return (-1); \
} while (0)
/*
* When formatting a string for JSON output we must escape certain characters,
* as described in RFC4627. This applies to both member names and
* DATA_TYPE_STRING values.
*
* This function will only operate correctly if the following conditions are
* met:
*
* 1. The input String is encoded in the current locale.
*
* 2. The current locale includes the Basic Multilingual Plane (plane 0)
* as defined in the Unicode standard.
*
* The output will be entirely 7-bit ASCII (as a subset of UTF-8) with all
* representable Unicode characters included in their escaped numeric form.
*/
static int
nvlist_print_json_string(FILE *fp, const char *input)
{
mbstate_t mbr;
wchar_t c;
size_t sz;
bzero(&mbr, sizeof (mbr));
FPRINTF(fp, "\"");
while ((sz = mbrtowc(&c, input, MB_CUR_MAX, &mbr)) > 0) {
switch (c) {
case '"':
FPRINTF(fp, "\\\"");
break;
case '\n':
FPRINTF(fp, "\\n");
break;
case '\r':
FPRINTF(fp, "\\r");
break;
case '\\':
FPRINTF(fp, "\\\\");
break;
case '\f':
FPRINTF(fp, "\\f");
break;
case '\t':
FPRINTF(fp, "\\t");
break;
case '\b':
FPRINTF(fp, "\\b");
break;
default:
if ((c >= 0x00 && c <= 0x1f) ||
(c > 0x7f && c <= 0xffff)) {
/*
* Render both Control Characters and Unicode
* characters in the Basic Multilingual Plane
* as JSON-escaped multibyte characters.
*/
FPRINTF(fp, "\\u%04x", (int)(0xffff & c));
} else if (c >= 0x20 && c <= 0x7f) {
/*
* Render other 7-bit ASCII characters directly
* and drop other, unrepresentable characters.
*/
FPRINTF(fp, "%c", (int)(0xff & c));
}
break;
}
input += sz;
}
if (sz == (size_t)-1 || sz == (size_t)-2) {
/*
* We last read an invalid multibyte character sequence,
* so return an error.
*/
return (-1);
}
FPRINTF(fp, "\"");
return (0);
}
/*
* Dump a JSON-formatted representation of an nvlist to the provided FILE *.
* This routine does not output any new-lines or additional whitespace other
* than that contained in strings, nor does it call fflush(3C).
*/
int
nvlist_print_json(FILE *fp, nvlist_t *nvl)
{
nvpair_t *curr;
boolean_t first = B_TRUE;
FPRINTF(fp, "{");
for (curr = nvlist_next_nvpair(nvl, NULL); curr;
curr = nvlist_next_nvpair(nvl, curr)) {
data_type_t type = nvpair_type(curr);
if (!first)
FPRINTF(fp, ",");
else
first = B_FALSE;
if (nvlist_print_json_string(fp, nvpair_name(curr)) == -1)
return (-1);
FPRINTF(fp, ":");
switch (type) {
case DATA_TYPE_STRING: {
char *string = fnvpair_value_string(curr);
if (nvlist_print_json_string(fp, string) == -1)
return (-1);
break;
}
case DATA_TYPE_BOOLEAN: {
FPRINTF(fp, "true");
break;
}
case DATA_TYPE_BOOLEAN_VALUE: {
FPRINTF(fp, "%s", fnvpair_value_boolean_value(curr) ==
B_TRUE ? "true" : "false");
break;
}
case DATA_TYPE_BYTE: {
FPRINTF(fp, "%hhu", fnvpair_value_byte(curr));
break;
}
case DATA_TYPE_INT8: {
FPRINTF(fp, "%hhd", fnvpair_value_int8(curr));
break;
}
case DATA_TYPE_UINT8: {
FPRINTF(fp, "%hhu", fnvpair_value_uint8_t(curr));
break;
}
case DATA_TYPE_INT16: {
FPRINTF(fp, "%hd", fnvpair_value_int16(curr));
break;
}
case DATA_TYPE_UINT16: {
FPRINTF(fp, "%hu", fnvpair_value_uint16(curr));
break;
}
case DATA_TYPE_INT32: {
FPRINTF(fp, "%d", fnvpair_value_int32(curr));
break;
}
case DATA_TYPE_UINT32: {
FPRINTF(fp, "%u", fnvpair_value_uint32(curr));
break;
}
case DATA_TYPE_INT64: {
FPRINTF(fp, "%lld",
(long long)fnvpair_value_int64(curr));
break;
}
case DATA_TYPE_UINT64: {
FPRINTF(fp, "%llu",
(unsigned long long)fnvpair_value_uint64(curr));
break;
}
case DATA_TYPE_HRTIME: {
hrtime_t val;
VERIFY0(nvpair_value_hrtime(curr, &val));
FPRINTF(fp, "%llu", (unsigned long long)val);
break;
}
case DATA_TYPE_DOUBLE: {
double val;
VERIFY0(nvpair_value_double(curr, &val));
FPRINTF(fp, "%f", val);
break;
}
case DATA_TYPE_NVLIST: {
if (nvlist_print_json(fp,
fnvpair_value_nvlist(curr)) == -1)
return (-1);
break;
}
case DATA_TYPE_STRING_ARRAY: {
char **val;
uint_t valsz, i;
VERIFY0(nvpair_value_string_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
if (nvlist_print_json_string(fp, val[i]) == -1)
return (-1);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_NVLIST_ARRAY: {
nvlist_t **val;
uint_t valsz, i;
VERIFY0(nvpair_value_nvlist_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
if (nvlist_print_json(fp, val[i]) == -1)
return (-1);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_BOOLEAN_ARRAY: {
boolean_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_boolean_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, val[i] == B_TRUE ?
"true" : "false");
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_BYTE_ARRAY: {
uchar_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_byte_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%hhu", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_UINT8_ARRAY: {
uint8_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint8_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%hhu", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_INT8_ARRAY: {
int8_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int8_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%hhd", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_UINT16_ARRAY: {
uint16_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint16_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%hu", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_INT16_ARRAY: {
int16_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int16_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%hd", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_UINT32_ARRAY: {
uint32_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint32_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%u", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_INT32_ARRAY: {
int32_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int32_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%d", val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_UINT64_ARRAY: {
uint64_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint64_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%llu",
(unsigned long long)val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_INT64_ARRAY: {
int64_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int64_array(curr, &val, &valsz));
FPRINTF(fp, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
FPRINTF(fp, ",");
FPRINTF(fp, "%lld", (long long)val[i]);
}
FPRINTF(fp, "]");
break;
}
case DATA_TYPE_UNKNOWN:
return (-1);
}
}
FPRINTF(fp, "}");
return (0);
}

View file

@ -609,6 +609,9 @@ typedef struct sendflags {
/* show progress (ie. -v) */
boolean_t progress;
/* large blocks (>128K) are permitted */
boolean_t largeblock;
/* WRITE_EMBEDDED records of type DATA are permitted */
boolean_t embed_data;
} sendflags_t;

View file

@ -1080,21 +1080,36 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
break;
}
case ZFS_PROP_RECORDSIZE:
case ZFS_PROP_VOLBLOCKSIZE:
/* must be power of two within SPA_{MIN,MAX}BLOCKSIZE */
case ZFS_PROP_RECORDSIZE:
{
int maxbs = SPA_MAXBLOCKSIZE;
if (zhp != NULL) {
maxbs = zpool_get_prop_int(zhp->zpool_hdl,
ZPOOL_PROP_MAXBLOCKSIZE, NULL);
}
/*
* Volumes are limited to a volblocksize of 128KB,
* because they typically service workloads with
* small random writes, which incur a large performance
* penalty with large blocks.
*/
if (prop == ZFS_PROP_VOLBLOCKSIZE)
maxbs = SPA_OLD_MAXBLOCKSIZE;
/*
* The value must be a power of two between
* SPA_MINBLOCKSIZE and maxbs.
*/
if (intval < SPA_MINBLOCKSIZE ||
intval > SPA_MAXBLOCKSIZE || !ISP2(intval)) {
intval > maxbs || !ISP2(intval)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' must be power of 2 from %u "
"to %uk"), propname,
(uint_t)SPA_MINBLOCKSIZE,
(uint_t)SPA_MAXBLOCKSIZE >> 10);
"'%s' must be power of 2 from 512B "
"to %uKB"), propname, maxbs >> 10);
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
goto error;
}
break;
}
case ZFS_PROP_MLSLABEL:
{
#ifdef sun
@ -1471,7 +1486,9 @@ zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err,
break;
case ERANGE:
if (prop == ZFS_PROP_COMPRESSION) {
case EDOM:
if (prop == ZFS_PROP_COMPRESSION ||
prop == ZFS_PROP_RECORDSIZE) {
(void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"property setting is not allowed on "
"bootable datasets"));
@ -2598,7 +2615,7 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
boolean_t isuser;
domain[0] = '\0';
*ridp = 0;
/* Figure out the property type ({user|group}{quota|space}) */
for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) {
if (strncmp(propname, zfs_userquota_prop_prefixes[type],
@ -2620,23 +2637,46 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
* It's a SID name (eg "user@domain") that needs to be
* turned into S-1-domainID-RID.
*/
directory_error_t e;
int flag = 0;
idmap_stat stat, map_stat;
uid_t pid;
idmap_rid_t rid;
idmap_get_handle_t *gh = NULL;
stat = idmap_get_create(&gh);
if (stat != IDMAP_SUCCESS) {
idmap_get_destroy(gh);
return (ENOMEM);
}
if (zoned && getzoneid() == GLOBAL_ZONEID)
return (ENOENT);
if (isuser) {
e = directory_sid_from_user_name(NULL,
cp, &numericsid);
stat = idmap_getuidbywinname(cp, NULL, flag, &pid);
if (stat < 0)
return (ENOENT);
stat = idmap_get_sidbyuid(gh, pid, flag, &numericsid,
&rid, &map_stat);
} else {
e = directory_sid_from_group_name(NULL,
cp, &numericsid);
stat = idmap_getgidbywinname(cp, NULL, flag, &pid);
if (stat < 0)
return (ENOENT);
stat = idmap_get_sidbygid(gh, pid, flag, &numericsid,
&rid, &map_stat);
}
if (e != NULL) {
directory_error_free(e);
if (stat < 0) {
idmap_get_destroy(gh);
return (ENOENT);
}
stat = idmap_get_mappings(gh);
idmap_get_destroy(gh);
if (stat < 0) {
return (ENOENT);
}
if (numericsid == NULL)
return (ENOENT);
cp = numericsid;
*ridp = rid;
/* will be further decoded below */
#else /* !sun */
return (ENOENT);
@ -2646,12 +2686,15 @@ userquota_propname_decode(const char *propname, boolean_t zoned,
if (strncmp(cp, "S-1-", 4) == 0) {
/* It's a numeric SID (eg "S-1-234-567-89") */
(void) strlcpy(domain, cp, domainlen);
cp = strrchr(domain, '-');
*cp = '\0';
cp++;
errno = 0;
*ridp = strtoull(cp, &end, 10);
if (*ridp == 0) {
cp = strrchr(domain, '-');
*cp = '\0';
cp++;
*ridp = strtoull(cp, &end, 10);
} else {
end = "";
}
if (numericsid) {
free(numericsid);
numericsid = NULL;
@ -3197,9 +3240,7 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
case EDOM:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"volume block size must be power of 2 from "
"%u to %uk"),
(uint_t)SPA_MINBLOCKSIZE,
(uint_t)SPA_MAXBLOCKSIZE >> 10);
"512B to 128KB"));
return (zfs_error(hdl, EZFS_BADPROP, errbuf));

View file

@ -24,7 +24,7 @@
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
*/
#include <stdio.h>
@ -193,9 +193,6 @@ zfs_iter_bookmarks(zfs_handle_t *zhp, zfs_iter_f func, void *data)
fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_CREATETXG));
fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_CREATION));
/* Allocate an nvlist to hold the bookmarks. */
bmarks = fnvlist_alloc();
if ((err = lzc_get_bookmarks(zhp->zfs_name, props, &bmarks)) != 0)
goto out;

View file

@ -256,7 +256,8 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
break;
case ZPOOL_PROP_HEALTH:
(void) strlcpy(buf, "FAULTED", len);
(void) strlcpy(buf,
zpool_pool_state_to_name(POOL_STATE_UNAVAIL), len);
break;
case ZPOOL_PROP_GUID:

View file

@ -215,7 +215,7 @@ static void *
cksummer(void *arg)
{
dedup_arg_t *dda = arg;
char *buf = malloc(1<<20);
char *buf = zfs_alloc(dda->dedup_hdl, SPA_MAXBLOCKSIZE);
dmu_replay_record_t thedrr;
dmu_replay_record_t *drr = &thedrr;
struct drr_begin *drrb = &thedrr.drr_u.drr_begin;
@ -280,9 +280,9 @@ cksummer(void *arg)
DMU_COMPOUNDSTREAM && drr->drr_payloadlen != 0) {
int sz = drr->drr_payloadlen;
if (sz > 1<<20) {
free(buf);
buf = malloc(sz);
if (sz > SPA_MAXBLOCKSIZE) {
buf = zfs_realloc(dda->dedup_hdl, buf,
SPA_MAXBLOCKSIZE, sz);
}
(void) ssread(buf, sz, ofp);
if (ferror(stdin))
@ -815,7 +815,7 @@ typedef struct send_dump_data {
char prevsnap[ZFS_MAXNAMELEN];
uint64_t prevsnap_obj;
boolean_t seenfrom, seento, replicate, doall, fromorigin;
boolean_t verbose, dryrun, parsable, progress, embed_data;
boolean_t verbose, dryrun, parsable, progress, embed_data, large_block;
int outfd;
boolean_t err;
nvlist_t *fss;
@ -1163,6 +1163,8 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
}
enum lzc_send_flags flags = 0;
if (sdd->large_block)
flags |= LZC_SEND_FLAG_LARGE_BLOCK;
if (sdd->embed_data)
flags |= LZC_SEND_FLAG_EMBED_DATA;
@ -1511,6 +1513,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
sdd.parsable = flags->parsable;
sdd.progress = flags->progress;
sdd.dryrun = flags->dryrun;
sdd.large_block = flags->largeblock;
sdd.embed_data = flags->embed_data;
sdd.filter_cb = filter_func;
sdd.filter_cb_arg = cb_arg;
@ -2545,7 +2548,7 @@ static int
recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
{
dmu_replay_record_t *drr;
void *buf = malloc(1<<20);
void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE);
char errbuf[1024];
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,

View file

@ -502,6 +502,10 @@ lzc_get_holds(const char *snapname, nvlist_t **holdsp)
*
* "fd" is the file descriptor to write the send stream to.
*
* If "flags" contains LZC_SEND_FLAG_LARGE_BLOCK, the stream is permitted
* to contain DRR_WRITE records with drr_length > 128K, and DRR_OBJECT
* records with drr_blksz > 128K.
*
* If "flags" contains LZC_SEND_FLAG_EMBED_DATA, the stream is permitted
* to contain DRR_WRITE_EMBEDDED records with drr_etype==BP_EMBEDDED_TYPE_DATA,
* which the receiving system must support (as indicated by support
@ -518,6 +522,8 @@ lzc_send(const char *snapname, const char *from, int fd,
fnvlist_add_int32(args, "fd", fd);
if (from != NULL)
fnvlist_add_string(args, "fromsnap", from);
if (flags & LZC_SEND_FLAG_LARGE_BLOCK)
fnvlist_add_boolean(args, "largeblockok");
if (flags & LZC_SEND_FLAG_EMBED_DATA)
fnvlist_add_boolean(args, "embedok");
err = lzc_ioctl(ZFS_IOC_SEND_NEW, snapname, args, NULL);

View file

@ -54,7 +54,8 @@ int lzc_release(nvlist_t *, nvlist_t **);
int lzc_get_holds(const char *, nvlist_t **);
enum lzc_send_flags {
LZC_SEND_FLAG_EMBED_DATA = 1 << 0
LZC_SEND_FLAG_EMBED_DATA = 1 << 0,
LZC_SEND_FLAG_LARGE_BLOCK = 1 << 1
};
int lzc_send(const char *, const char *, int, enum lzc_send_flags);

View file

@ -24,6 +24,8 @@
*/
/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
* Copyright (c) 2014 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@ -32,8 +34,10 @@ int taskq_now;
taskq_t *system_taskq;
#define TASKQ_ACTIVE 0x00010000
#define TASKQ_NAMELEN 31
struct taskq {
char tq_name[TASKQ_NAMELEN + 1];
kmutex_t tq_lock;
krwlock_t tq_threadlock;
kcondvar_t tq_dispatch_cv;
@ -136,6 +140,7 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags)
t->tqent_prev->tqent_next = t;
t->tqent_func = func;
t->tqent_arg = arg;
t->tqent_flags = 0;
cv_signal(&tq->tq_dispatch_cv);
mutex_exit(&tq->tq_lock);
return (1);
@ -245,6 +250,7 @@ taskq_create(const char *name, int nthreads, pri_t pri,
cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL);
cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL);
cv_init(&tq->tq_maxalloc_cv, NULL, CV_DEFAULT, NULL);
(void) strncpy(tq->tq_name, name, TASKQ_NAMELEN + 1);
tq->tq_flags = flags | TASKQ_ACTIVE;
tq->tq_active = nthreads;
tq->tq_nthreads = nthreads;

View file

@ -26,8 +26,6 @@
#ifndef _CTFTOOLS_H
#define _CTFTOOLS_H
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Functions and data structures used in the manipulation of stabs and CTF data
*/
@ -39,6 +37,8 @@
#include <gelf.h>
#include <pthread.h>
#include <sys/ccompile.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -435,8 +435,8 @@ int streq(const char *, const char *);
int findelfsecidx(Elf *, const char *, const char *);
size_t elf_ptrsz(Elf *);
char *mktmpname(const char *, const char *);
void terminate(const char *, ...);
void aborterr(const char *, ...);
void terminate(const char *, ...) __NORETURN;
void aborterr(const char *, ...) __NORETURN;
void set_terminate_cleanup(void (*)(void));
void elfterminate(const char *, const char *, ...);
void warning(const char *, ...);

View file

@ -766,7 +766,8 @@ die_array_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
debug(3, "trying to resolve array %d (cont %d)\n", tdp->t_id,
tdp->t_ardef->ad_contents->t_id);
if ((sz = tdesc_size(tdp->t_ardef->ad_contents)) == 0) {
if ((sz = tdesc_size(tdp->t_ardef->ad_contents)) == 0 &&
(tdp->t_ardef->ad_contents->t_flags & TDESC_F_RESOLVED) == 0) {
debug(3, "unable to resolve array %s (%d) contents %d\n",
tdesc_name(tdp), tdp->t_id,
tdp->t_ardef->ad_contents->t_id);
@ -1138,12 +1139,17 @@ die_sou_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private)
/*
* For empty members, or GCC/C99 flexible array
* members, a size of 0 is correct.
* members, a size of 0 is correct. Structs and unions
* consisting of flexible array members will also have
* size 0.
*/
if (mt->t_members == NULL)
continue;
if (mt->t_type == ARRAY && mt->t_ardef->ad_nelems == 0)
continue;
if ((mt->t_flags & TDESC_F_RESOLVED) != 0 &&
(mt->t_type == STRUCT || mt->t_type == UNION))
continue;
dw->dw_nunres++;
return (1);

View file

@ -287,19 +287,11 @@ equiv_su(tdesc_t *stdp, tdesc_t *ttdp, equiv_data_t *ed)
while (ml1 && ml2) {
if (ml1->ml_offset != ml2->ml_offset ||
strcmp(ml1->ml_name, ml2->ml_name) != 0)
strcmp(ml1->ml_name, ml2->ml_name) != 0 ||
ml1->ml_size != ml2->ml_size ||
!equiv_node(ml1->ml_type, ml2->ml_type, ed))
return (0);
/*
* Don't do the recursive equivalency checking more than
* we have to.
*/
if (olm1 == NULL || olm1->ml_type->t_id != ml1->ml_type->t_id) {
if (ml1->ml_size != ml2->ml_size ||
!equiv_node(ml1->ml_type, ml2->ml_type, ed))
return (0);
}
olm1 = ml1;
ml1 = ml1->ml_next;
ml2 = ml2->ml_next;

View file

@ -16,6 +16,7 @@ SRCS= ctf_create.c \
ctf_subr.c \
ctf_types.c \
ctf_util.c
MAN= ctf.5
WARNS?= 0
CFLAGS+= -DCTF_OLD_VERSIONS

View file

@ -116,6 +116,7 @@ typedef struct tcpsinfo {
uint32_t tcps_rto; /* round-trip timeout, msec */
uint32_t tcps_mss; /* max segment size */
int tcps_retransmit; /* retransmit send event, boolean */
int tcps_srtt; /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */
} tcpsinfo_t;
/*
@ -197,9 +198,10 @@ translator tcpsinfo_t < struct tcpcb *p > {
tcps_cwnd_ssthresh = p == NULL ? -1 : p->snd_ssthresh;
tcps_sack_fack = p == NULL ? 0 : p->snd_fack;
tcps_sack_snxt = p == NULL ? 0 : p->sack_newdata;
tcps_rto = p == NULL ? -1 : p->t_rxtcur / 1000; /* XXX */
tcps_rto = p == NULL ? -1 : (p->t_rxtcur * 1000) / `hz;
tcps_mss = p == NULL ? -1 : p->t_maxseg;
tcps_retransmit = p == NULL ? -1 : p->t_rxtshift > 0 ? 1 : 0;
tcps_srtt = p == NULL ? -1 : p->t_srtt; /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */
};
#pragma D binding "1.6.3" translator

View file

@ -9,6 +9,7 @@ SRCS= libnvpair.c \
nvpair_alloc_system.c \
nvpair_alloc_fixed.c \
nvpair.c \
nvpair_json.c \
fnvpair.c
WARNS?= 0

View file

@ -74,8 +74,8 @@ Write the output to file in
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
.Xr ctfmerge 1 ,
.Xr ctfdump 1
.Xr ctfdump 1 ,
.Xr ctfmerge 1
.Sh HISTORY
The
.Nm

View file

@ -1,22 +1,12 @@
*/*/Atffile
*/*/Makefile*
*/Atffile
*/Makefile*
*/*.m4
*/*.pc.in
Atffile
INSTALL
Makefile*
aclocal.m4
admin/
atf-config/
atf-report/
atf-run/
atf-version/
bconfig.h.in
config.h.in
bootstrap/
configure*
doc/atf-formats.5
doc/atf.7.in
m4/
tools/

View file

@ -1,6 +1,62 @@
Major changes between releases Automated Testing Framework
===========================================================================
Changes in version 0.21
***********************
Released on October 23rd, 2014.
* Restored the atf(7) manual page to serve as a reference to all the other
manual pages shipped by ATF.
* Added the -s flag to atf-sh to support specifying the shell interpreter
to be used.
* Removed ATF_WORKDIR. The only remaining consumers have been converted to
use the standard TMPDIR environment variable. As a benefit, and because
Kyua forces the TMPDIR to live within the test case's work directory,
any stale files left behind by ATF will be automatically cleaned up.
* Documented the environment variables recognized by each component in the
relevant manual pages. This information was lost with the atf-config(1)
removal.
* Added a new "require.diskspace" metadata property to test cases so that
they can specify the minimum amount of disk space required for the test
to run.
* Renamed the atf-{c,c++,sh}-api(3) manual pages to atf-{c,c++,sh}(3) for
discoverability purposes. Symbolic links are provided for the time
being to still make the old names visible.
* Issue #5: Recommend the (expected, actual) idiom for calls to the test
macros in the manual pages.
* Issue #7: Stopped catching unhandled exceptions in atf-c++ tests. This
propagates the crash to the caller, which in turn allows it to obtain
proper debugging information. In particular, Kyua should now be able to
extract a stacktrace pinpointing the problem.
* Issue #8: Fixed atf-c/macros_test:use test failures spotted by the clang
that ships with FreeBSD 11.0-CURRENT.
* Issue #12: Improved documentation of atf-sh(3) and atf-check(1) by better
explaining how they relate to each other.
* Issue #14: Stopped setting 'set -e' in atf-sh. This setting was
initially added as a way to enable a "strict" mode in the library and to
make test cases fail fast when they run unprotected commands. However,
doing so in the library is surprising as the responsibility of enabling
'set -e' should be on the user's code. Also, 'set -e' introduces
inconsistent behavior on subshells and users do not expect that.
* Issue #15: Fixed atf_utils_{fork,wait} to support nested calls.
* Issue #16: Fixed test failures (by removing a long-standing hack) on
systems that lack \e support in printf(1).
* Issue #19: Removed stale references to atf-config and atf-run.
Changes in version 0.20
***********************

View file

@ -1,6 +1,3 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
@ -25,12 +22,11 @@
// 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 !defined(_ATF_CXX_HPP_)
#define _ATF_CXX_HPP_
#if !defined(ATF_CXX_HPP)
#define ATF_CXX_HPP
#include <atf-c++/macros.hpp>
#include <atf-c++/utils.hpp>
#endif // !defined(_ATF_CXX_HPP_)
#endif // !defined(ATF_CXX_HPP)

View file

@ -5,7 +5,6 @@ test_suite("atf")
atf_test_program{name="atf_c++_test"}
atf_test_program{name="build_test"}
atf_test_program{name="check_test"}
atf_test_program{name="config_test"}
atf_test_program{name="macros_test"}
atf_test_program{name="pkg_config_test"}
atf_test_program{name="tests_test"}

View file

@ -0,0 +1,649 @@
.\" Copyright (c) 2008 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 October 13, 2014
.Dt ATF-C++ 3
.Os
.Sh NAME
.Nm atf-c++ ,
.Nm ATF_ADD_TEST_CASE ,
.Nm ATF_CHECK_ERRNO ,
.Nm ATF_FAIL ,
.Nm ATF_INIT_TEST_CASES ,
.Nm ATF_PASS ,
.Nm ATF_REQUIRE ,
.Nm ATF_REQUIRE_EQ ,
.Nm ATF_REQUIRE_ERRNO ,
.Nm ATF_REQUIRE_IN ,
.Nm ATF_REQUIRE_MATCH ,
.Nm ATF_REQUIRE_NOT_IN ,
.Nm ATF_REQUIRE_THROW ,
.Nm ATF_REQUIRE_THROW_RE ,
.Nm ATF_SKIP ,
.Nm ATF_TEST_CASE ,
.Nm ATF_TEST_CASE_BODY ,
.Nm ATF_TEST_CASE_CLEANUP ,
.Nm ATF_TEST_CASE_HEAD ,
.Nm ATF_TEST_CASE_NAME ,
.Nm ATF_TEST_CASE_USE ,
.Nm ATF_TEST_CASE_WITH_CLEANUP ,
.Nm ATF_TEST_CASE_WITHOUT_HEAD ,
.Nm atf::utils::cat_file ,
.Nm atf::utils::compare_file ,
.Nm atf::utils::copy_file ,
.Nm atf::utils::create_file ,
.Nm atf::utils::file_exists ,
.Nm atf::utils::fork ,
.Nm atf::utils::grep_collection ,
.Nm atf::utils::grep_file ,
.Nm atf::utils::grep_string ,
.Nm atf::utils::redirect ,
.Nm atf::utils::wait
.Nd C++ API to write ATF-based test programs
.Sh SYNOPSIS
.In atf-c++.hpp
.Fn ATF_ADD_TEST_CASE "tcs" "name"
.Fn ATF_CHECK_ERRNO "expected_errno" "bool_expression"
.Fn ATF_FAIL "reason"
.Fn ATF_INIT_TEST_CASES "tcs"
.Fn ATF_PASS
.Fn ATF_REQUIRE "expression"
.Fn ATF_REQUIRE_EQ "expected_expression" "actual_expression"
.Fn ATF_REQUIRE_ERRNO "expected_errno" "bool_expression"
.Fn ATF_REQUIRE_IN "element" "collection"
.Fn ATF_REQUIRE_MATCH "regexp" "string_expression"
.Fn ATF_REQUIRE_NOT_IN "element" "collection"
.Fn ATF_REQUIRE_THROW "expected_exception" "statement"
.Fn ATF_REQUIRE_THROW_RE "expected_exception" "regexp" "statement"
.Fn ATF_SKIP "reason"
.Fn ATF_TEST_CASE "name"
.Fn ATF_TEST_CASE_BODY "name"
.Fn ATF_TEST_CASE_CLEANUP "name"
.Fn ATF_TEST_CASE_HEAD "name"
.Fn ATF_TEST_CASE_NAME "name"
.Fn ATF_TEST_CASE_USE "name"
.Fn ATF_TEST_CASE_WITH_CLEANUP "name"
.Fn ATF_TEST_CASE_WITHOUT_HEAD "name"
.Ft void
.Fo atf::utils::cat_file
.Fa "const std::string& path"
.Fa "const std::string& prefix"
.Fc
.Ft bool
.Fo atf::utils::compare_file
.Fa "const std::string& path"
.Fa "const std::string& contents"
.Fc
.Ft void
.Fo atf::utils::copy_file
.Fa "const std::string& source"
.Fa "const std::string& destination"
.Fc
.Ft void
.Fo atf::utils::create_file
.Fa "const std::string& path"
.Fa "const std::string& contents"
.Fc
.Ft void
.Fo atf::utils::file_exists
.Fa "const std::string& path"
.Fc
.Ft pid_t
.Fo atf::utils::fork
.Fa "void"
.Fc
.Ft bool
.Fo atf::utils::grep_collection
.Fa "const std::string& regexp"
.Fa "const Collection& collection"
.Fc
.Ft bool
.Fo atf::utils::grep_file
.Fa "const std::string& regexp"
.Fa "const std::string& path"
.Fc
.Ft bool
.Fo atf::utils::grep_string
.Fa "const std::string& regexp"
.Fa "const std::string& path"
.Fc
.Ft void
.Fo atf::utils::redirect
.Fa "const int fd"
.Fa "const std::string& path"
.Fc
.Ft void
.Fo atf::utils::wait
.Fa "const pid_t pid"
.Fa "const int expected_exit_status"
.Fa "const std::string& expected_stdout"
.Fa "const std::string& expected_stderr"
.Fc
.Sh DESCRIPTION
ATF provides a C++ programming interface to implement test programs.
C++-based test programs follow this template:
.Bd -literal -offset indent
extern "C" {
.Ns ... C-specific includes go here ...
}
.Ns ... C++-specific includes go here ...
#include <atf-c++.hpp>
ATF_TEST_CASE(tc1);
ATF_TEST_CASE_HEAD(tc1)
{
... first test case's header ...
}
ATF_TEST_CASE_BODY(tc1)
{
... first test case's body ...
}
ATF_TEST_CASE_WITH_CLEANUP(tc2);
ATF_TEST_CASE_HEAD(tc2)
{
... second test case's header ...
}
ATF_TEST_CASE_BODY(tc2)
{
... second test case's body ...
}
ATF_TEST_CASE_CLEANUP(tc2)
{
... second test case's cleanup ...
}
ATF_TEST_CASE(tc3);
ATF_TEST_CASE_BODY(tc3)
{
... third test case's body ...
}
.Ns ... additional test cases ...
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, tc1);
ATF_ADD_TEST_CASE(tcs, tc2);
ATF_ADD_TEST_CASE(tcs, tc3);
... add additional test cases ...
}
.Ed
.Ss Definition of test cases
Test cases have an identifier and are composed of three different parts:
the header, the body and an optional cleanup routine, all of which are
described in
.Xr atf-test-case 4 .
To define test cases, one can use the
.Fn ATF_TEST_CASE ,
.Fn ATF_TEST_CASE_WITH_CLEANUP
or the
.Fn ATF_TEST_CASE_WITHOUT_HEAD
macros, which take a single parameter specifiying the test case's
name.
.Fn ATF_TEST_CASE ,
requires to define a head and a body for the test case,
.Fn ATF_TEST_CASE_WITH_CLEANUP
requires to define a head, a body and a cleanup for the test case and
.Fn ATF_TEST_CASE_WITHOUT_HEAD
requires only a body for the test case.
It is important to note that these
.Em do not
set the test case up for execution when the program is run.
In order to do so, a later registration is needed through the
.Fn ATF_ADD_TEST_CASE
macro detailed in
.Sx Program initialization .
.Pp
Later on, one must define the three parts of the body by means of three
functions.
Their headers are given by the
.Fn ATF_TEST_CASE_HEAD ,
.Fn ATF_TEST_CASE_BODY
and
.Fn ATF_TEST_CASE_CLEANUP
macros, all of which take the test case's name.
Following each of these, a block of code is expected, surrounded by the
opening and closing brackets.
.Pp
Additionally, the
.Fn ATF_TEST_CASE_NAME
macro can be used to obtain the name of the class corresponding to a
particular test case, as the name is internally manged by the library to
prevent clashes with other user identifiers.
Similarly, the
.Fn ATF_TEST_CASE_USE
macro can be executed on a particular test case to mark it as "used" and
thus prevent compiler warnings regarding unused symbols.
Note that
.Em you should never have to use these macros during regular operation.
.Ss Program initialization
The library provides a way to easily define the test program's
.Fn main
function.
You should never define one on your own, but rely on the
library to do it for you.
This is done by using the
.Fn ATF_INIT_TEST_CASES
macro, which is passed the name of the list that will hold the test cases.
This name can be whatever you want as long as it is a valid variable value.
.Pp
After the macro, you are supposed to provide the body of a function, which
should only use the
.Fn ATF_ADD_TEST_CASE
macro to register the test cases the test program will execute.
The first parameter of this macro matches the name you provided in the
former call.
.Ss Header definitions
The test case's header can define the meta-data by using the
.Fn set_md_var
method, which takes two parameters: the first one specifies the
meta-data variable to be set and the second one specifies its value.
Both of them are strings.
.Ss Configuration variables
The test case has read-only access to the current configuration variables
by means of the
.Ft bool
.Fn has_config_var
and the
.Ft std::string
.Fn get_config_var
methods, which can be called in any of the three parts of a test case.
.Ss Access to the source directory
It is possible to get the path to the test case's source directory from any
of its three components by querying the
.Sq srcdir
configuration variable.
.Ss Requiring programs
Aside from the
.Va require.progs
meta-data variable available in the header only, one can also check for
additional programs in the test case's body by using the
.Fn require_prog
function, which takes the base name or full path of a single binary.
Relative paths are forbidden.
If it is not found, the test case will be automatically skipped.
.Ss Test case finalization
The test case finalizes either when the body reaches its end, at which
point the test is assumed to have
.Em passed ,
or at any explicit call to
.Fn ATF_PASS ,
.Fn ATF_FAIL
or
.Fn ATF_SKIP .
These three macros terminate the execution of the test case immediately.
The cleanup routine will be processed afterwards in a completely automated
way, regardless of the test case's termination reason.
.Pp
.Fn ATF_PASS
does not take any parameters.
.Fn ATF_FAIL
and
.Fn ATF_SKIP
take a single string that describes why the test case failed or
was skipped, respectively.
It is very important to provide a clear error message in both cases so that
the user can quickly know why the test did not pass.
.Ss Expectations
Everything explained in the previous section changes when the test case
expectations are redefined by the programmer.
.Pp
Each test case has an internal state called
.Sq expect
that describes what the test case expectations are at any point in time.
The value of this property can change during execution by any of:
.Bl -tag -width indent
.It Fn expect_death "reason"
Expects the test case to exit prematurely regardless of the nature of the
exit.
.It Fn expect_exit "exitcode" "reason"
Expects the test case to exit cleanly.
If
.Va exitcode
is not
.Sq -1 ,
the runtime engine will validate that the exit code of the test case
matches the one provided in this call.
Otherwise, the exact value will be ignored.
.It Fn expect_fail "reason"
Any failure (be it fatal or non-fatal) raised in this mode is recorded.
However, such failures do not report the test case as failed; instead, the
test case finalizes cleanly and is reported as
.Sq expected failure ;
this report includes the provided
.Fa reason
as part of it.
If no error is raised while running in this mode, then the test case is
reported as
.Sq failed .
.Pp
This mode is useful to reproduce actual known bugs in tests.
Whenever the developer fixes the bug later on, the test case will start
reporting a failure, signaling the developer that the test case must be
adjusted to the new conditions.
In this situation, it is useful, for example, to set
.Fa reason
as the bug number for tracking purposes.
.It Fn expect_pass
This is the normal mode of execution.
In this mode, any failure is reported as such to the user and the test case
is marked as
.Sq failed .
.It Fn expect_race "reason"
Any failure or timeout during the execution of the test case will be
considered as if a race condition has been triggered and reported as such.
If no problems arise, the test will continue execution as usual.
.It Fn expect_signal "signo" "reason"
Expects the test case to terminate due to the reception of a signal.
If
.Va signo
is not
.Sq -1 ,
the runtime engine will validate that the signal that terminated the test
case matches the one provided in this call.
Otherwise, the exact value will be ignored.
.It Fn expect_timeout "reason"
Expects the test case to execute for longer than its timeout.
.El
.Ss Helper macros for common checks
The library provides several macros that are very handy in multiple
situations.
These basically check some condition after executing a given statement or
processing a given expression and, if the condition is not met, they
automatically call
.Fn ATF_FAIL
with an appropriate error message.
.Pp
.Fn ATF_REQUIRE
takes an expression and raises a failure if it evaluates to false.
.Pp
.Fn ATF_REQUIRE_EQ
takes two expressions and raises a failure if the two do not evaluate to
the same exact value.
The common style is to put the expected value in the first parameter and the
actual value in the second parameter.
.Pp
.Fn ATF_REQUIRE_IN
takes an element and a collection and validates that the element is present in
the collection.
.Pp
.Fn ATF_REQUIRE_MATCH
takes a regular expression and a string and raises a failure if the regular
expression does not match the string.
.Pp
.Fn ATF_REQUIRE_NOT_IN
takes an element and a collection and validates that the element is not present
in the collection.
.Pp
.Fn ATF_REQUIRE_THROW
takes the name of an exception and a statement and raises a failure if
the statement does not throw the specified exception.
.Fn ATF_REQUIRE_THROW_RE
takes the name of an exception, a regular expresion and a statement and raises a
failure if the statement does not throw the specified exception and if the
message of the exception does not match the regular expression.
.Pp
.Fn ATF_CHECK_ERRNO
and
.Fn ATF_REQUIRE_ERRNO
take, first, the error code that the check is expecting to find in the
.Va errno
variable and, second, a boolean expression that, if evaluates to true,
means that a call failed and
.Va errno
has to be checked against the first value.
.Ss Utility functions
The following functions are provided as part of the
.Nm
API to simplify the creation of a variety of tests.
In particular, these are useful to write tests for command-line interfaces.
.Pp
.Ft void
.Fo atf::utils::cat_file
.Fa "const std::string& path"
.Fa "const std::string& prefix"
.Fc
.Bd -ragged -offset indent
Prints the contents of
.Fa path
to the standard output, prefixing every line with the string in
.Fa prefix .
.Ed
.Pp
.Ft bool
.Fo atf::utils::compare_file
.Fa "const std::string& path"
.Fa "const std::string& contents"
.Fc
.Bd -ragged -offset indent
Returns true if the given
.Fa path
matches exactly the expected inlined
.Fa contents .
.Ed
.Pp
.Ft void
.Fo atf::utils::copy_file
.Fa "const std::string& source"
.Fa "const std::string& destination"
.Fc
.Bd -ragged -offset indent
Copies the file
.Fa source
to
.Fa destination .
The permissions of the file are preserved during the code.
.Ed
.Pp
.Ft void
.Fo atf::utils::create_file
.Fa "const std::string& path"
.Fa "const std::string& contents"
.Fc
.Bd -ragged -offset indent
Creates
.Fa file
with the text given in
.Fa contents .
.Ed
.Pp
.Ft void
.Fo atf::utils::file_exists
.Fa "const std::string& path"
.Fc
.Bd -ragged -offset indent
Checks if
.Fa path
exists.
.Ed
.Pp
.Ft pid_t
.Fo atf::utils::fork
.Fa "void"
.Fc
.Bd -ragged -offset indent
Forks a process and redirects the standard output and standard error of the
child to files for later validation with
.Fn atf::utils::wait .
Fails the test case if the fork fails, so this does not return an error.
.Ed
.Pp
.Ft bool
.Fo atf::utils::grep_collection
.Fa "const std::string& regexp"
.Fa "const Collection& collection"
.Fc
.Bd -ragged -offset indent
Searches for the regular expression
.Fa regexp
in any of the strings contained in the
.Fa collection .
This is a template that accepts any one-dimensional container of strings.
.Ed
.Pp
.Ft bool
.Fo atf::utils::grep_file
.Fa "const std::string& regexp"
.Fa "const std::string& path"
.Fc
.Bd -ragged -offset indent
Searches for the regular expression
.Fa regexp
in the file
.Fa path .
The variable arguments are used to construct the regular expression.
.Ed
.Pp
.Ft bool
.Fo atf::utils::grep_string
.Fa "const std::string& regexp"
.Fa "const std::string& str"
.Fc
.Bd -ragged -offset indent
Searches for the regular expression
.Fa regexp
in the string
.Fa str .
.Ed
.Ft void
.Fo atf::utils::redirect
.Fa "const int fd"
.Fa "const std::string& path"
.Fc
.Bd -ragged -offset indent
Redirects the given file descriptor
.Fa fd
to the file
.Fa path .
This function exits the process in case of an error and does not properly mark
the test case as failed.
As a result, it should only be used in subprocesses of the test case; specially
those spawned by
.Fn atf::utils::fork .
.Ed
.Pp
.Ft void
.Fo atf::utils::wait
.Fa "const pid_t pid"
.Fa "const int expected_exit_status"
.Fa "const std::string& expected_stdout"
.Fa "const std::string& expected_stderr"
.Fc
.Bd -ragged -offset indent
Waits and validates the result of a subprocess spawned with
.Fn atf::utils::wait .
The validation involves checking that the subprocess exited cleanly and returned
the code specified in
.Fa expected_exit_status
and that its standard output and standard error match the strings given in
.Fa expected_stdout
and
.Fa expected_stderr .
.Pp
If any of the
.Fa expected_stdout
or
.Fa expected_stderr
strings are prefixed with
.Sq save: ,
then they specify the name of the file into which to store the stdout or stderr
of the subprocess, and no comparison is performed.
.Ed
.Sh ENVIRONMENT
The following variables are recognized by
.Nm
but should not be overridden other than for testing purposes:
.Pp
.Bl -tag -width ATFXBUILDXCXXFLAGSXX -compact
.It Va ATF_BUILD_CC
Path to the C compiler.
.It Va ATF_BUILD_CFLAGS
C compiler flags.
.It Va ATF_BUILD_CPP
Path to the C/C++ preprocessor.
.It Va ATF_BUILD_CPPFLAGS
C/C++ preprocessor flags.
.It Va ATF_BUILD_CXX
Path to the C++ compiler.
.It Va ATF_BUILD_CXXFLAGS
C++ compiler flags.
.El
.Sh EXAMPLES
The following shows a complete test program with a single test case that
validates the addition operator:
.Bd -literal -offset indent
#include <atf-c++.hpp>
ATF_TEST_CASE(addition);
ATF_TEST_CASE_HEAD(addition)
{
set_md_var("descr", "Sample tests for the addition operator");
}
ATF_TEST_CASE_BODY(addition)
{
ATF_REQUIRE_EQ(0, 0 + 0);
ATF_REQUIRE_EQ(1, 0 + 1);
ATF_REQUIRE_EQ(1, 1 + 0);
ATF_REQUIRE_EQ(2, 1 + 1);
ATF_REQUIRE_EQ(300, 100 + 200);
}
ATF_TEST_CASE(open_failure);
ATF_TEST_CASE_HEAD(open_failure)
{
set_md_var("descr", "Sample tests for the open function");
}
ATF_TEST_CASE_BODY(open_failure)
{
ATF_REQUIRE_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
}
ATF_TEST_CASE(known_bug);
ATF_TEST_CASE_HEAD(known_bug)
{
set_md_var("descr", "Reproduces a known bug");
}
ATF_TEST_CASE_BODY(known_bug)
{
expect_fail("See bug number foo/bar");
ATF_REQUIRE_EQ(3, 1 + 1);
expect_pass();
ATF_REQUIRE_EQ(3, 1 + 2);
}
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, addition);
ATF_ADD_TEST_CASE(tcs, open_failure);
ATF_ADD_TEST_CASE(tcs, known_bug);
}
.Ed
.Sh SEE ALSO
.Xr atf-test-program 1 ,
.Xr atf-test-case 4

View file

@ -1,6 +1,3 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
@ -25,11 +22,10 @@
// 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 "macros.hpp"
#include <atf-c++.hpp>
#include "detail/test_helpers.hpp"
#include "atf-c++/detail/test_helpers.hpp"
// ------------------------------------------------------------------------
// Tests cases for the header file.

View file

@ -1,6 +1,3 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
@ -25,7 +22,8 @@
// 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 "atf-c++/build.hpp"
extern "C" {
#include "atf-c/build.h"
@ -33,10 +31,8 @@ extern "C" {
#include "atf-c/utils.h"
}
#include "build.hpp"
#include "detail/exceptions.hpp"
#include "detail/process.hpp"
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/process.hpp"
namespace impl = atf::build;
#define IMPL_NAME "atf::build"

View file

@ -1,6 +1,3 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
@ -25,10 +22,9 @@
// 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 !defined(_ATF_CXX_BUILD_HPP_)
#define _ATF_CXX_BUILD_HPP_
#if !defined(ATF_CXX_BUILD_HPP)
#define ATF_CXX_BUILD_HPP
#include <string>
@ -54,4 +50,4 @@ process::argv_array cxx_o(const std::string&, const std::string&,
} // namespace build
} // namespace atf
#endif // !defined(_ATF_CXX_BUILD_HPP_)
#endif // !defined(ATF_CXX_BUILD_HPP)

View file

@ -1,6 +1,3 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2009 The NetBSD Foundation, Inc.
// All rights reserved.
//
@ -25,31 +22,25 @@
// 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 "atf-c++/build.hpp"
#include <cstring>
#include <iostream>
#include "../atf-c/h_build.h"
#include <atf-c++.hpp>
#include "build.hpp"
#include "config.hpp"
#include "macros.hpp"
extern "C" {
#include "atf-c/h_build.h"
}
#include "detail/env.hpp"
#include "detail/process.hpp"
#include "detail/test_helpers.hpp"
#include "atf-c++/detail/env.hpp"
#include "atf-c++/detail/process.hpp"
// ------------------------------------------------------------------------
// Auxiliary functions.
// ------------------------------------------------------------------------
namespace atf {
namespace config {
void __reinit(void);
}
}
template< class C >
void
print_col(const char* prefix, const C& c)
@ -168,7 +159,6 @@ ATF_TEST_CASE_BODY(c_o)
verbose_set_env("ATF_BUILD_CC", test->cc);
verbose_set_env("ATF_BUILD_CFLAGS", test->cflags);
verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
atf::config::__reinit();
atf::process::argv_array argv =
atf::build::c_o(test->sfile, test->ofile,
@ -190,7 +180,6 @@ ATF_TEST_CASE_BODY(cpp)
verbose_set_env("ATF_BUILD_CPP", test->cpp);
verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
atf::config::__reinit();
atf::process::argv_array argv =
atf::build::cpp(test->sfile, test->ofile,
@ -213,7 +202,6 @@ ATF_TEST_CASE_BODY(cxx_o)
verbose_set_env("ATF_BUILD_CXX", test->cxx);
verbose_set_env("ATF_BUILD_CXXFLAGS", test->cxxflags);
verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
atf::config::__reinit();
atf::process::argv_array argv =
atf::build::cxx_o(test->sfile, test->ofile,
@ -222,12 +210,6 @@ ATF_TEST_CASE_BODY(cxx_o)
}
}
// ------------------------------------------------------------------------
// Tests cases for the header file.
// ------------------------------------------------------------------------
HEADER_TC(include, "atf-c++/build.hpp");
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
@ -241,7 +223,4 @@ ATF_INIT_TEST_CASES(tcs)
ATF_ADD_TEST_CASE(tcs, c_o);
ATF_ADD_TEST_CASE(tcs, cpp);
ATF_ADD_TEST_CASE(tcs, cxx_o);
// Add the test cases for the header file.
ATF_ADD_TEST_CASE(tcs, include);
}

View file

@ -1,6 +1,3 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
@ -25,7 +22,8 @@
// 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 "atf-c++/check.hpp"
#include <cstring>
@ -34,11 +32,9 @@ extern "C" {
#include "atf-c/error.h"
}
#include "check.hpp"
#include "detail/exceptions.hpp"
#include "detail/process.hpp"
#include "detail/sanity.hpp"
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/process.hpp"
#include "atf-c++/detail/sanity.hpp"
namespace impl = atf::check;
#define IMPL_NAME "atf::check"

View file

@ -1,6 +1,3 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
@ -25,10 +22,9 @@
// 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 !defined(_ATF_CXX_CHECK_HPP_)
#define _ATF_CXX_CHECK_HPP_
#if !defined(ATF_CXX_CHECK_HPP)
#define ATF_CXX_CHECK_HPP
extern "C" {
#include <atf-c/check.h>
@ -132,4 +128,4 @@ check_result test_constructor(void);
} // namespace check
} // namespace atf
#endif // !defined(_ATF_CXX_CHECK_HPP_)
#endif // !defined(ATF_CXX_CHECK_HPP)

View file

@ -1,6 +1,3 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// All rights reserved.
//
@ -25,7 +22,8 @@
// 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 "atf-c++/check.hpp"
extern "C" {
#include <fcntl.h>
@ -43,14 +41,11 @@ extern "C" {
#include <atf-c++.hpp>
#include "check.hpp"
#include "config.hpp"
#include "utils.hpp"
#include "detail/fs.hpp"
#include "detail/process.hpp"
#include "detail/test_helpers.hpp"
#include "detail/text.hpp"
#include "atf-c++/detail/fs.hpp"
#include "atf-c++/detail/process.hpp"
#include "atf-c++/detail/test_helpers.hpp"
#include "atf-c++/detail/text.hpp"
#include "atf-c++/utils.hpp"
// ------------------------------------------------------------------------
// Auxiliary functions.
@ -374,7 +369,7 @@ ATF_TEST_CASE_HEAD(exec_unknown)
ATF_TEST_CASE_BODY(exec_unknown)
{
std::vector< std::string > argv;
argv.push_back(atf::config::get("atf_workdir") + "/non-existent");
argv.push_back("/foo/bar/non-existent");
atf::process::argv_array argva(argv);
std::auto_ptr< atf::check::check_result > r = atf::check::exec(argva);
@ -382,12 +377,6 @@ ATF_TEST_CASE_BODY(exec_unknown)
ATF_REQUIRE_EQ(r->exitcode(), 127);
}
// ------------------------------------------------------------------------
// Tests cases for the header file.
// ------------------------------------------------------------------------
HEADER_TC(include, "atf-c++/check.hpp");
// ------------------------------------------------------------------------
// Main.
// ------------------------------------------------------------------------
@ -402,7 +391,4 @@ ATF_INIT_TEST_CASES(tcs)
ATF_ADD_TEST_CASE(tcs, exec_exitstatus);
ATF_ADD_TEST_CASE(tcs, exec_stdout_stderr);
ATF_ADD_TEST_CASE(tcs, exec_unknown);
// Add the test cases for the header file.
ATF_ADD_TEST_CASE(tcs, include);
}

View file

@ -1,119 +0,0 @@
//
// Automated Testing Framework (atf)
//
// Copyright (c) 2007 The NetBSD Foundation, Inc.
// 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <map>
extern "C" {
#include "atf-c/config.h"
}
#include "config.hpp"
#include "detail/env.hpp"
#include "detail/sanity.hpp"
static std::map< std::string, std::string > m_variables;
//
// Adds all predefined standard build-time variables to the m_variables
// map, considering the values a user may have provided in the environment.
//
// Can only be called once during the program's lifetime.
//
static
void
init_variables(void)
{
PRE(m_variables.empty());
m_variables["atf_build_cc"] = atf_config_get("atf_build_cc");
m_variables["atf_build_cflags"] = atf_config_get("atf_build_cflags");
m_variables["atf_build_cpp"] = atf_config_get("atf_build_cpp");
m_variables["atf_build_cppflags"] = atf_config_get("atf_build_cppflags");
m_variables["atf_build_cxx"] = atf_config_get("atf_build_cxx");
m_variables["atf_build_cxxflags"] = atf_config_get("atf_build_cxxflags");
m_variables["atf_includedir"] = atf_config_get("atf_includedir");
m_variables["atf_libexecdir"] = atf_config_get("atf_libexecdir");
m_variables["atf_pkgdatadir"] = atf_config_get("atf_pkgdatadir");
m_variables["atf_shell"] = atf_config_get("atf_shell");
m_variables["atf_workdir"] = atf_config_get("atf_workdir");
POST(!m_variables.empty());
}
const std::string&
atf::config::get(const std::string& varname)
{
if (m_variables.empty())
init_variables();
PRE(has(varname));
return m_variables[varname];
}
const std::map< std::string, std::string >&
atf::config::get_all(void)
{
if (m_variables.empty())
init_variables();
return m_variables;
}
bool
atf::config::has(const std::string& varname)
{
if (m_variables.empty())
init_variables();
return m_variables.find(varname) != m_variables.end();
}
extern "C" {
void __atf_config_reinit(void);
}
namespace atf {
namespace config {
//
// Auxiliary function for the t_config test program so that it can
// revert the configuration's global status to an empty state and
// do new tests from there on.
//
// Ideally this shouldn't be part of the production library... but
// this is so small that it does not matter.
//
void
__reinit(void)
{
__atf_config_reinit();
m_variables.clear();
}
} // namespace config
} // namespace atf

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