mirror of
https://github.com/opnsense/src.git
synced 2026-06-11 01:30:30 -04:00
Reintegrate head revisions r273096-r277147
Sponsored by: The FreeBSD Foundation
This commit is contained in:
commit
8f0ea33f2b
10631 changed files with 942496 additions and 538837 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
166
Makefile.inc1
166
Makefile.inc1
|
|
@ -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} \
|
||||
|
|
|
|||
|
|
@ -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
129
UPDATING
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
18
bin/cat/tests/Makefile
Normal 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>
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ SRCS= df.c vfslist.c
|
|||
|
||||
CFLAGS+= -I${MOUNT}
|
||||
|
||||
DPADD= ${LIBUTIL}
|
||||
LDADD= -lutil
|
||||
LIBADD= xo util
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
|||
|
|
@ -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 ,
|
||||
|
|
|
|||
124
bin/df/df.c
124
bin/df/df.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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; \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
PROG= pkill
|
||||
|
||||
DPADD= ${LIBKVM}
|
||||
LDADD= -lkvm
|
||||
LIBADD= kvm
|
||||
|
||||
LINKS= ${BINDIR}/pkill ${BINDIR}/pgrep
|
||||
MLINKS= pkill.1 pgrep.1
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
203
bin/sh/parser.c
203
bin/sh/parser.c
|
|
@ -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.
|
||||
|
|
|
|||
37
bin/sh/sh.1
37
bin/sh/sh.1
|
|
@ -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 .
|
||||
|
|
|
|||
9
bin/sh/tests/builtins/getopts9.0
Normal file
9
bin/sh/tests/builtins/getopts9.0
Normal 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
|
||||
3
bin/sh/tests/builtins/getopts9.0.stdout
Normal file
3
bin/sh/tests/builtins/getopts9.0.stdout
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
0:a:
|
||||
0:b:
|
||||
1:?:
|
||||
|
|
@ -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
|
||||
|
|
|
|||
7
bin/sh/tests/execution/set-x4.0
Normal file
7
bin/sh/tests/execution/set-x4.0
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
26
bin/sh/tests/expansion/redir1.0
Normal file
26
bin/sh/tests/expansion/redir1.0
Normal 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))
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
7
bin/sh/tests/parameters/positional6.0
Normal file
7
bin/sh/tests/parameters/positional6.0
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# $FreeBSD$
|
||||
|
||||
IFS=?
|
||||
set p r
|
||||
v=pqrs
|
||||
r=${v#"$*"}
|
||||
[ "$r" = pqrs ]
|
||||
8
bin/sh/tests/parameters/positional7.0
Normal file
8
bin/sh/tests/parameters/positional7.0
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# $FreeBSD$
|
||||
|
||||
set -- / ''
|
||||
IFS=*
|
||||
set -- "$*"
|
||||
IFS=:
|
||||
args="$*"
|
||||
[ "$#:$args" = "1:/*" ]
|
||||
|
|
@ -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
|
||||
|
|
|
|||
16
bin/sh/tests/parser/line-cont1.0
Normal file
16
bin/sh/tests/parser/line-cont1.0
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# $FreeBSD$
|
||||
|
||||
i\
|
||||
f
|
||||
t\
|
||||
r\
|
||||
u\
|
||||
e
|
||||
t\
|
||||
h\
|
||||
e\
|
||||
n
|
||||
:
|
||||
\
|
||||
f\
|
||||
i
|
||||
18
bin/sh/tests/parser/line-cont10.0
Normal file
18
bin/sh/tests/parser/line-cont10.0
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# $FreeBSD$
|
||||
|
||||
v=XaaaXbbbX
|
||||
[ "${v\
|
||||
#\
|
||||
*\
|
||||
a}.${v\
|
||||
#\
|
||||
#\
|
||||
*\
|
||||
a}.${v\
|
||||
%\
|
||||
b\
|
||||
*}.${v\
|
||||
%\
|
||||
%\
|
||||
b\
|
||||
*}" = aaXbbbX.XbbbX.XaaaXbb.XaaaX ]
|
||||
23
bin/sh/tests/parser/line-cont11.0
Normal file
23
bin/sh/tests/parser/line-cont11.0
Normal 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
|
||||
4
bin/sh/tests/parser/line-cont2.0
Normal file
4
bin/sh/tests/parser/line-cont2.0
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# $FreeBSD$
|
||||
|
||||
[ "a\
|
||||
b" = ab ]
|
||||
7
bin/sh/tests/parser/line-cont3.0
Normal file
7
bin/sh/tests/parser/line-cont3.0
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# $FreeBSD$
|
||||
|
||||
v=`printf %s 'a\
|
||||
b'`
|
||||
w="`printf %s 'c\
|
||||
d'`"
|
||||
[ "$v$w" = abcd ]
|
||||
8
bin/sh/tests/parser/line-cont4.0
Normal file
8
bin/sh/tests/parser/line-cont4.0
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# $FreeBSD$
|
||||
|
||||
v=abcd
|
||||
[ "$\
|
||||
v.$\
|
||||
{v}.${\
|
||||
v}.${v\
|
||||
}" = abcd.abcd.abcd.abcd ]
|
||||
14
bin/sh/tests/parser/line-cont5.0
Normal file
14
bin/sh/tests/parser/line-cont5.0
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# $FreeBSD$
|
||||
|
||||
bad=1
|
||||
case x in
|
||||
x\
|
||||
) ;\
|
||||
; *) exit 7
|
||||
esac &\
|
||||
& bad= &\
|
||||
& : >\
|
||||
>/dev/null
|
||||
|
||||
false |\
|
||||
| [ -z "$bad" ]
|
||||
23
bin/sh/tests/parser/line-cont6.0
Normal file
23
bin/sh/tests/parser/line-cont6.0
Normal 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" ]
|
||||
7
bin/sh/tests/parser/line-cont7.0
Normal file
7
bin/sh/tests/parser/line-cont7.0
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# $FreeBSD$
|
||||
|
||||
[ "$(\
|
||||
(
|
||||
1\
|
||||
+ 1)\
|
||||
)" = 2 ]
|
||||
6
bin/sh/tests/parser/line-cont8.0
Normal file
6
bin/sh/tests/parser/line-cont8.0
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# $FreeBSD$
|
||||
|
||||
set -- a b c d e f g h i j
|
||||
[ "${1\
|
||||
0\
|
||||
}" = j ]
|
||||
6
bin/sh/tests/parser/line-cont9.0
Normal file
6
bin/sh/tests/parser/line-cont9.0
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# $FreeBSD$
|
||||
|
||||
[ "${$\
|
||||
:\
|
||||
+\
|
||||
xyz}" = xyz ]
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
1140
cddl/contrib/opensolaris/lib/libctf/common/ctf.5
Normal file
1140
cddl/contrib/opensolaris/lib/libctf/common/ctf.5
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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 ||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
|||
403
cddl/contrib/opensolaris/lib/libnvpair/nvpair_json.c
Normal file
403
cddl/contrib/opensolaris/lib/libnvpair/nvpair_json.c
Normal 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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 *, ...);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ SRCS= libnvpair.c \
|
|||
nvpair_alloc_system.c \
|
||||
nvpair_alloc_fixed.c \
|
||||
nvpair.c \
|
||||
nvpair_json.c \
|
||||
fnvpair.c
|
||||
|
||||
WARNS?= 0
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
***********************
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"}
|
||||
|
|
|
|||
649
contrib/atf/atf-c++/atf-c++.3
Normal file
649
contrib/atf/atf-c++/atf-c++.3
Normal 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
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in a new issue