Catch up with head, primarily for the 1.14.4.0 firmware.

This commit is contained in:
Navdeep Parhar 2015-08-13 22:01:13 +00:00
commit ab875b713d
3152 changed files with 851720 additions and 131659 deletions

View File

@ -1,5 +1,6 @@
{
"project.name": "S",
"repository.callsign" : "S",
"phabricator.uri" : "https://reviews.freebsd.org/",
"history.immutable" : true
}

View File

@ -102,7 +102,7 @@
# Note: we use this awkward construct to be compatible with FreeBSD's
# old make used in 10.0 and 9.2 and earlier.
.if defined(MK_META_MODE) && ${MK_META_MODE} == "yes"
.if defined(MK_META_MODE) && ${MK_META_MODE} == "yes" && !make(showconfig)
# targets/Makefile plays the role of top-level
.include "targets/Makefile"
.else
@ -408,7 +408,7 @@ UNIVERSE_TARGET?= buildworld
.endif
KERNSRCDIR?= ${.CURDIR}/sys
targets:
targets: .PHONY
@echo "Supported TARGET/TARGET_ARCH pairs for world and kernel targets"
.for target in ${TARGETS}
.for target_arch in ${TARGET_ARCHES_${target}}
@ -538,7 +538,9 @@ MK_META_MODE= no
MK_STAGING= no
# tell meta.autodep.mk to not even think about updating anything.
UPDATE_DEPENDFILE= NO
.if !make(showconfig)
.export MK_META_MODE MK_STAGING UPDATE_DEPENDFILE
.endif
.if make(universe)
# we do not want a failure of one branch abort all.

View File

@ -219,11 +219,16 @@ INSTALLTMP!= /usr/bin/mktemp -d -u -t install
# 2. build-tools stage [TMAKE]
# This stage is responsible for creating the object
# tree and building any tools that are needed during
# the build process.
# the build process. Some programs are listed during
# this phase because they build binaires to generate
# files needed to build these programs. This stage also
# builds the 'build-tools' target rather than 'all'.
# 3. cross-tools stage [XMAKE]
# This stage is responsible for creating any tools that
# are needed for building the system. A cross-compiler is one
# of them.
# of them. This differs from build tools in two ways:
# 1. the 'all' target is built rather than 'build-tools'
# 2. these tools are installed into TMPPATH for stage 4.
# 4. world stage [WMAKE]
# This stage actually builds the world.
# 5. install stage (optional) [IMAKE]
@ -297,7 +302,6 @@ KTMAKE= TOOLS_PREFIX=${WORLDTMP} MAKEOBJDIRPREFIX=${WORLDTMP} \
# world stage
WMAKEENV= ${CROSSENV} \
_SHLIBDIRPREFIX=${WORLDTMP} \
_LDSCRIPTROOT= \
VERSION="${VERSION}" \
INSTALL="sh ${.CURDIR}/tools/install.sh" \
@ -439,7 +443,6 @@ LIB32FLAGS+= --sysroot=${WORLDTMP}
# Yes, the flags are redundant.
LIB32WMAKEENV+= MAKEOBJDIRPREFIX=${LIB32_OBJTREE} \
_SHLIBDIRPREFIX=${LIB32TMP} \
_LDSCRIPTROOT=${LIB32TMP} \
VERSION="${VERSION}" \
INSTALL="sh ${.CURDIR}/tools/install.sh" \
@ -809,7 +812,7 @@ __installcheck_UGID:
_zoneinfo= zic tzsetup
.endif
ITOOLS= [ awk cap_mkdb cat chflags chmod chown \
ITOOLS= [ awk cap_mkdb cat chflags chmod chown cmp cp \
date echo egrep find grep id install ${_install-info} \
ln lockf make mkdir mtree mv pwd_mkdb \
rm sed services_mkdb sh strip sysctl test true uname wc ${_zoneinfo} \
@ -1227,16 +1230,23 @@ update:
#
#
# legacy: Build compatibility shims for the next three targets. This is a minimal
# set of tools and shims necessary to compensate for older systems which don't have
# the APIs that the targets built in bootstrap-tools, build-tools or cross-tools.
# legacy: Build compatibility shims for the next three targets. This is a
# minimal set of tools and shims necessary to compensate for older systems
# which don't have the APIs required by the targets built in bootstrap-tools,
# build-tools or cross-tools.
#
# ELF Tool Chain libraries are needed for ELF tools and dtrace tools.
.if ${BOOTSTRAPPING} < 1100006
_elftoolchain_libs= lib/libelf lib/libdwarf
.endif
legacy:
.if ${BOOTSTRAPPING} < 800107 && ${BOOTSTRAPPING} != 0
@echo "ERROR: Source upgrades from versions prior to 8.0 not supported."; \
false
.endif
.for _tool in tools/build
.for _tool in tools/build ${_elftoolchain_libs}
${_+_}@${ECHODIR} "===> ${_tool} (obj,includes,depend,all,install)"; \
cd ${.CURDIR}/${_tool} && \
${MAKE} DIRPRFX=${_tool}/ obj && \
@ -1299,7 +1309,8 @@ _lex= usr.bin/lex
# r277259 crunchide: Correct 64-bit section header offset
# r281674 crunchide: always include both 32- and 64-bit ELF support
.if ${BOOTSTRAPPING} < 1100071
# r285986 crunchen: use STRIPBIN rather than STRIP
.if ${BOOTSTRAPPING} < 1100078
_crunch= usr.sbin/crunch
.endif
@ -1334,13 +1345,12 @@ ${_bt}-usr.bin/clang/tblgen: ${_bt}-lib/clang/libllvmtablegen ${_bt}-lib/clang/l
# pre libdwarf
.if ${BOOTSTRAPPING} < 1100006 || (${MACHINE} != ${TARGET} || \
${MACHINE_ARCH} != ${TARGET_ARCH})
_elftoolchain_libs= lib/libelf lib/libdwarf
.if ${MK_CDDL} != "no"
_dtrace_tools= cddl/usr.bin/sgsmsg cddl/lib/libctf cddl/usr.bin/ctfconvert \
cddl/usr.bin/ctfmerge
${_bt}-cddl/usr.bin/ctfconvert: ${_bt}-lib/libelf ${_bt}-lib/libdwarf ${_bt}-cddl/lib/libctf
${_bt}-cddl/usr.bin/ctfmerge: ${_bt}-lib/libelf ${_bt}-lib/libdwarf ${_bt}-cddl/lib/libctf
${_bt}-cddl/usr.bin/ctfconvert: ${_bt}-cddl/lib/libctf
${_bt}-cddl/usr.bin/ctfmerge: ${_bt}-cddl/lib/libctf
.endif
.endif
@ -1383,7 +1393,6 @@ bootstrap-tools: .PHONY
.for _tool in \
${_clang_tblgen} \
${_kerberos5_bootstrap_tools} \
${_elftoolchain_libs} \
${_dtrace_tools} \
${_strfile} \
${_gperf} \
@ -1429,17 +1438,18 @@ _gcc_tools= gnu/usr.bin/cc/cc_tools
.endif
.if ${MK_RESCUE} != "no"
_rescue= rescue/rescue
# rescue includes programs that have build-tools targets
_rescue=rescue/rescue
.endif
build-tools: .MAKE
.for _tool in \
bin/csh \
bin/sh \
${_rescue} \
${LOCAL_TOOL_DIRS} \
lib/ncurses/ncurses \
lib/ncurses/ncursesw \
${_rescue} \
${_share} \
usr.bin/awk \
lib/libmagic \
@ -1483,8 +1493,6 @@ _btxld= usr.sbin/btxld
.if ${XAS:M/*} == ""
.if ${MK_BINUTILS_BOOTSTRAP} != "no"
_binutils= gnu/usr.bin/binutils
.endif
.if ${MK_ELFTOOLCHAIN_TOOLS} != "no"
_elftctools= lib/libelftc \
usr.bin/elfcopy \
usr.bin/nm \
@ -1494,7 +1502,7 @@ _elftctools= lib/libelftc \
# cross-build on a FreeBSD 10 host:
_elftctools+= usr.bin/addr2line
.endif
.elif ${TARGET_ARCH} != ${MACHINE_ARCH} && ${MK_ELFTOOLCHAIN_TOOLS} != "no"
.elif ${TARGET_ARCH} != ${MACHINE_ARCH} && ${MK_BINUTILS_BOOTSTRAP} != "no"
# If cross-building with an external binutils we still need to build strip for
# the target (for at least crunchide).
_elftctools= lib/libelftc \
@ -1768,9 +1776,9 @@ cddl/lib/libctf__L: lib/libz__L
.endif
# cddl/lib/libdtrace requires lib/libproc and lib/librtld_db; it's only built
# on select architectures though (see cddl/lib/Makefile)
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" || \
${MACHINE_CPUARCH} == "mips" || ${MACHINE_CPUARCH} == "powerpc" || \
${MACHINE_CPUARCH} == "arm"
.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_ARCH} == "amd64" || \
${MACHINE_CPUARCH} == "arm" || ${MACHINE_ARCH} == "i386" || \
${MACHINE_CPUARCH} == "mips" || ${MACHINE_CPUARCH} == "powerpc"
_prebuild_libs+= lib/libproc lib/librtld_db
.endif
@ -2123,7 +2131,6 @@ XDTP?=/usr/${XDDIR}
CDBENV=MAKEOBJDIRPREFIX=${MAKEOBJDIRPREFIX}/${XDDIR} \
INSTALL="sh ${.CURDIR}/tools/install.sh"
CDENV= ${CDBENV} \
_SHLIBDIRPREFIX=${XDDESTDIR} \
TOOLS_PREFIX=${XDTP}
CD2CFLAGS=-isystem ${XDDESTDIR}/usr/include -L${XDDESTDIR}/usr/lib \
--sysroot=${XDDESTDIR}/ -B${XDDESTDIR}/usr/libexec \

View File

@ -38,6 +38,83 @@
# xargs -n1 | sort | uniq -d;
# done
# 20150802: Remove netbsd's test on pw(8)
OLD_FILES+=usr/tests/usr.sbin/pw/pw_test
# 20150719: Remove libarchive.pc
OLD_FILES+=usr/libdata/pkgconfig/libarchive.pc
# 20150705: Rename DTrace provider man pages.
OLD_FILES+=usr/share/man/man4/dtrace-io.4.gz
OLD_FILES+=usr/share/man/man4/dtrace-ip.4.gz
OLD_FILES+=usr/share/man/man4/dtrace-proc.4.gz
OLD_FILES+=usr/share/man/man4/dtrace-sched.4.gz
OLD_FILES+=usr/share/man/man4/dtrace-tcp.4.gz
OLD_FILES+=usr/share/man/man4/dtrace-udp.4.gz
# 20150604: Move nvlist man pages to section 9.
OLD_FILES+=usr/share/man/man3/libnv.3.gz
OLD_FILES+=usr/share/man/man3/nvlist.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_add_binary.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_add_bool.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_add_descriptor.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_add_null.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_add_number.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_add_nvlist.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_add_string.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_add_stringf.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_add_stringv.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_clone.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_create.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_destroy.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_dump.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_empty.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_error.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_exists.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_exists_binary.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_exists_bool.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_exists_descriptor.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_exists_null.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_exists_number.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_exists_nvlist.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_exists_string.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_exists_type.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_fdump.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_flags.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_free.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_free_binary.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_free_bool.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_free_descriptor.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_free_null.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_free_number.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_free_nvlist.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_free_string.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_free_type.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_get_binary.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_get_bool.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_get_descriptor.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_get_number.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_get_nvlist.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_get_parent.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_get_string.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_move_binary.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_move_descriptor.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_move_nvlist.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_move_string.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_next.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_pack.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_recv.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_send.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_set_error.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_size.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_take_binary.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_take_bool.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_take_descriptor.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_take_number.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_take_nvlist.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_take_string.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_unpack.3.gz
OLD_FILES+=usr/share/man/man3/nvlist_xfer.3.gz
# 20150702: Remove duplicated nvlist includes.
OLD_FILES+=usr/include/dnv.h
OLD_FILES+=usr/include/nv.h
# 20150528: PCI IOV device driver methods moved to a separate kobj interface.
OLD_FILES+=usr/share/man/man9/PCI_ADD_VF.9.gz
OLD_FILES+=usr/share/man/man9/PCI_INIT_IOV.9.gz
@ -1020,6 +1097,7 @@ OLD_FILES+=usr/include/lwres/net.h
OLD_FILES+=usr/include/lwres/netdb.h
OLD_FILES+=usr/include/lwres/platform.h
OLD_FILES+=usr/include/lwres/result.h
OLD_FILES+=usr/include/lwres/string.h
OLD_FILES+=usr/include/lwres/version.h
OLD_FILES+=usr/lib/liblwres.a
OLD_FILES+=usr/lib/liblwres.so

132
UPDATING
View File

@ -31,27 +31,108 @@ 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".)
20150616:
/etc/make.conf now included earlier.
sys.mk now includes /etc/make.conf and {local,src}.sys.mk earlier
than previously.
This makes it simple to interpose external toolchains etc.
However it may cause problems for users who have things like::
20150813:
The WITHOUT_ELFTOOLCHAIN_TOOLS src.conf(5) knob has been retired.
Control over building the ELF Tool Chain tools is now provided by
the WITHOUT_TOOLCHAIN knob.
INSTALL+= something
20150810:
The polarity of Pulse Per Second (PPS) capture events with the
uart(4) driver has been corrected. Prior to this change the PPS
"assert" event corresponded to the trailing edge of a positive PPS
pulse and the "clear" event was the leading edge of the next pulse.
in /etc/make.conf, since INSTALL is not yet defined.
A safe fix for that is to have::
As the width of a PPS pulse in a typical GPS receiver is on the
order of 1 millisecond, most users will not notice any significant
difference with this change.
INSTALL?= install
INSTALL+= something
Anyone who has compensated for the historical polarity reversal by
configuring a negative offset equal to the pulse width will need to
remove that workaround.
20150809:
The default group assigned to /dev/dri entries has been changed
from 'wheel' to 'video' with the id of '44'. If you want to have
access to the dri devices please add yourself to the video group
with:
# pw groupmod video -m $USER
20150806:
The menu.rc and loader.rc files will now be replaced during
upgrades. Please migrate local changes to menu.rc.local and
loader.rc.local instead.
20150805:
GNU Binutils versions of addr2line, c++filt, nm, readelf, size,
strings and strip have been removed. The src.conf(5) knob
WITHOUT_ELFTOOLCHAIN_TOOLS no longer provides the binutils tools.
20150728:
As ZFS requires more kernel stack pages than is the default on some
architectures e.g. i386, it now warns if KSTACK_PAGES is less than
ZFS_MIN_KSTACK_PAGES (which is 4 at the time of writing).
Please consider using 'options KSTACK_PAGES=X' where X is greater
than or equal to ZFS_MIN_KSTACK_PAGES i.e. 4 in such configurations.
20150706:
sendmail has been updated to 8.15.2. Starting with FreeBSD 11.0
and sendmail 8.15, sendmail uses uncompressed IPv6 addresses by
default, i.e., they will not contain "::". For example, instead
of ::1, it will be 0:0:0:0:0:0:0:1. This permits a zero subnet
to have a more specific match, such as different map entries for
IPv6:0:0 vs IPv6:0. This change requires that configuration
data (including maps, files, classes, custom ruleset, etc.) must
use the same format, so make certain such configuration data is
upgrading. As a very simple check search for patterns like
'IPv6:[0-9a-fA-F:]*::' and 'IPv6::'. To return to the old
behavior, set the m4 option confUSE_COMPRESSED_IPV6_ADDRESSES or
the cf option UseCompressedIPv6Addresses.
20150630:
The default kernel entropy-processing algorithm is now
Fortuna, replacing Yarrow.
Assuming you have 'device random' in your kernel config
file, the configurations allow a kernel option to override
this default. You may choose *ONE* of:
options RANDOM_YARROW # Legacy /dev/random algorithm.
options RANDOM_DUMMY # Blocking-only driver.
If you have neither, you get Fortuna. For most people,
read no further, Fortuna will give a /dev/random that works
like it always used to, and the difference will be irrelevant.
If you remove 'device random', you get *NO* kernel-processed
entopy at all. This may be acceptable to folks building
embedded systems, but has complications. Carry on reading,
and it is assumed you know what you need.
*PLEASE* read random(4) and random(9) if you are in the
habit of tweeking kernel configs, and/or if you are a member
of the embedded community, wanting specific and not-usual
behaviour from your security subsystems.
NOTE!! If you use RANDOM_DUMMY and/or have no 'device
random', you will NOT have a functioning /dev/random, and
many cryptographic features will not work, including SSH.
You may also find strange behaviour from the random(3) set
of library functions, in particular sranddev(3), srandomdev(3)
and arc4random(3). The reason for this is that the KERN_ARND
sysctl only returns entropy if it thinks it has some to
share, and with RANDOM_DUMMY or no 'device random' this
will never happen.
20150623:
An additional fix for the issue described in the 20150614 sendmail
entry below has been been committed in revision 284717.
which is equivalent to previous behavior.
20150616:
FreeBSD's old make (fmake) has been removed from the system. It is
available as the devel/fmake port or via pkg install fmake.
20150615:
The fix for the issue described in the 20150614 sendmail entry
below has been been committed in revision 284436. The work
@ -74,7 +155,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
this interoperability, sendmail can be configured to use a
2048 bit DH parameter by:
1. Edit /etc/mail/`hostname`.mc
1. Edit /etc/mail/`hostname`.mc
2. If a setting for confDH_PARAMETERS does not exist or
exists and is set to a string beginning with '5',
replace it with '2'.
@ -180,14 +261,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
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.
binutils tools, if necessary. See 20150805 for updated information.
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.
@ -533,6 +614,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
or
# pkg install pkg; ldd /usr/local/sbin/pkg | grep bsdyml
20131010:
The stable/10 branch has been created in subversion from head
revision r256279.
20131010:
The rc.d/jail script has been updated to support jail(8)
configuration file. The "jail_<jname>_*" rc.conf(5) variables
@ -578,7 +663,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
The GNU Compiler Collection and C++ standard library (libstdc++)
are no longer built by default on platforms where clang is the system
compiler. You can enable them with the WITH_GCC and WITH_GNUCXX
options in src.conf.
options in src.conf.
20130905:
The PROCDESC kernel option is now part of the GENERIC kernel
@ -932,7 +1017,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
20120727:
The sparc64 ZFS loader has been changed to no longer try to auto-
detect ZFS providers based on diskN aliases but now requires these
to be explicitly listed in the OFW boot-device environment variable.
to be explicitly listed in the OFW boot-device environment variable.
20120712:
The OpenSSL has been upgraded to 1.0.1c. Any binaries requiring
@ -1076,6 +1161,13 @@ COMMON ITEMS:
around can lead to problems if pam has changed too much from your
starting point to allow continued authentication after the upgrade.
This file should be read as a log of events. When a later event changes
information of a prior event, the prior event should not be deleted.
Instead, a pointer to the entry with the new information should be
placed in the old entry. Readers of this file should also sanity check
older entries before relying on them blindly. Authors of new entries
should write them with this in mind.
ZFS notes
---------
When upgrading the boot ZFS pool to a new version, always follow
@ -1246,7 +1338,7 @@ FORMAT:
This file contains a list, in reverse chronological order, of major
breakages in tracking -current. It is not guaranteed to be a complete
list of such breakages, and only contains entries since October 10, 2007.
list of such breakages, and only contains entries since September 23, 2011.
If you need to see UPDATING entries from before that date, you will need
to fetch an UPDATING file from an older FreeBSD release.

View File

@ -416,6 +416,7 @@ if necessary, to a 1MiB boundary:
.Sh SEE ALSO
.Xr cp 1 ,
.Xr mt 1 ,
.Xr recoverdisk 1 ,
.Xr tr 1 ,
.Xr geom 4
.Sh STANDARDS

View File

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

View File

@ -119,7 +119,7 @@ static int f_nofollow; /* don't follow symbolic link arguments */
int f_nonprint; /* show unprintables as ? */
static int f_nosort; /* don't sort output */
int f_notabs; /* don't use tab-separated multi-col output */
static int f_numericonly; /* don't convert uid/gid to name */
int f_numericonly; /* don't convert uid/gid to name */
int f_octal; /* show unprintables as \xxx */
int f_octal_escape; /* like f_octal but use C escapes if possible */
static int f_recursive; /* ls subdirectories also */
@ -158,6 +158,7 @@ main(int argc, char *argv[])
struct winsize win;
int ch, fts_options, notused;
char *p;
const char *errstr = NULL;
#ifdef COLORLS
char termcapbuf[1024]; /* termcap definition buffer */
char tcapbuf[512]; /* capability buffer */
@ -170,7 +171,7 @@ main(int argc, char *argv[])
if (isatty(STDOUT_FILENO)) {
termwidth = 80;
if ((p = getenv("COLUMNS")) != NULL && *p != '\0')
termwidth = atoi(p);
termwidth = strtonum(p, 0, INT_MAX, &errstr);
else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) != -1 &&
win.ws_col > 0)
termwidth = win.ws_col;
@ -180,9 +181,12 @@ main(int argc, char *argv[])
/* retrieve environment variable, in case of explicit -C */
p = getenv("COLUMNS");
if (p)
termwidth = atoi(p);
termwidth = strtonum(p, 0, INT_MAX, &errstr);
}
if (errstr)
termwidth = 80;
fts_options = FTS_PHYSICAL;
if (getenv("LS_SAMESORT"))
f_samesort = 1;
@ -191,6 +195,7 @@ main(int argc, char *argv[])
if (argc < 0)
return (1);
xo_set_flags(NULL, XOF_COLUMNS);
xo_set_version(LS_XO_VERSION);
while ((ch = getopt(argc, argv,
"1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {

View File

@ -37,6 +37,8 @@
#define HUMANVALSTR_LEN 5
#define LS_XO_VERSION "1"
extern long blocksize; /* block size units */
extern int f_accesstime; /* use time of last access */
@ -58,6 +60,7 @@ extern int f_statustime; /* use time of last mode change */
extern int f_thousands; /* show file sizes with thousands separators */
extern char *f_timeformat; /* user-specified time format */
extern int f_notabs; /* don't use tab-separated multi-col output */
extern int f_numericonly; /* don't convert uid/gid to name */
extern int f_type; /* add type character for non-regular files */
#ifdef COLORLS
extern int f_color; /* add type in color for non-regular files */

View File

@ -171,7 +171,7 @@ printlong(const DISPLAY *dp)
xo_open_list("entry");
for (p = dp->list; p; p = p->fts_link) {
char *name;
char *name, *type;
if (IS_NOPRINT(p))
continue;
xo_open_instance("entry");
@ -180,22 +180,46 @@ printlong(const DISPLAY *dp)
if (name)
xo_emit("{ke:name/%hs}", name);
if (f_inode)
xo_emit("{:inode/%*ju} ",
xo_emit("{t:inode/%*ju} ",
dp->s_inode, (uintmax_t)sp->st_ino);
if (f_size)
xo_emit("{:blocks/%*jd} ",
xo_emit("{t:blocks/%*jd} ",
dp->s_block, howmany(sp->st_blocks, blocksize));
strmode(sp->st_mode, buf);
aclmode(buf, p);
np = p->fts_pointer;
xo_attr("value", "%03o", (int) sp->st_mode & ALLPERMS);
xo_emit("{t:mode/%s} {:links/%*u} {:user/%-*s} {:group/%-*s} ",
buf, dp->s_nlink, sp->st_nlink,
dp->s_user, np->user, dp->s_group, np->group);
if (f_numericonly) {
xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*u} {td:user/%-*s}{e:user/%ju} {td:group/%-*s}{e:group/%ju} ",
buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, sp->st_nlink,
dp->s_user, np->user, (uintmax_t)sp->st_uid, dp->s_group, np->group, (uintmax_t)sp->st_gid);
} else {
xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*u} {t:user/%-*s} {t:group/%-*s} ",
buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, sp->st_nlink,
dp->s_user, np->user, dp->s_group, np->group);
}
if (S_ISBLK(sp->st_mode))
asprintf(&type, "block");
if (S_ISCHR(sp->st_mode))
asprintf(&type, "character");
if (S_ISDIR(sp->st_mode))
asprintf(&type, "directory");
if (S_ISFIFO(sp->st_mode))
asprintf(&type, "fifo");
if (S_ISLNK(sp->st_mode))
asprintf(&type, "symlink");
if (S_ISREG(sp->st_mode))
asprintf(&type, "regular");
if (S_ISSOCK(sp->st_mode))
asprintf(&type, "socket");
if (S_ISWHT(sp->st_mode))
asprintf(&type, "whiteout");
xo_emit("{e:type/%s}", type);
free(type);
if (f_flags)
xo_emit("{:flags/%-*s} ", dp->s_flags, np->flags);
if (f_label)
xo_emit("{:label/%-*s} ", dp->s_label, np->label);
xo_emit("{t:label/%-*s} ", dp->s_label, np->label);
if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
printdev(dp->s_size, sp->st_rdev);
else
@ -238,6 +262,7 @@ printstream(const DISPLAY *dp)
FTSENT *p;
int chcnt;
xo_open_list("entry");
for (p = dp->list, chcnt = 0; p; p = p->fts_link) {
if (p->fts_number == NO_PRINT)
continue;
@ -247,12 +272,15 @@ printstream(const DISPLAY *dp)
xo_emit("\n");
chcnt = 0;
}
xo_open_instance("file");
chcnt += printaname(p, dp->s_inode, dp->s_block);
xo_close_instance("file");
if (p->fts_link) {
xo_emit(", ");
chcnt += 2;
}
}
xo_close_list("entry");
if (chcnt)
xo_emit("\n");
}
@ -369,10 +397,10 @@ printaname(const FTSENT *p, u_long inodefield, u_long sizefield)
sp = p->fts_statp;
chcnt = 0;
if (f_inode)
chcnt += xo_emit("{:inode/%*ju} ",
chcnt += xo_emit("{t:inode/%*ju} ",
(int)inodefield, (uintmax_t)sp->st_ino);
if (f_size)
chcnt += xo_emit("{:size/%*jd} ",
chcnt += xo_emit("{t:size/%*jd} ",
(int)sizefield, howmany(sp->st_blocks, blocksize));
#ifdef COLORLS
if (f_color)
@ -425,9 +453,11 @@ printtime(const char *field, time_t ftime)
format = d_first ? "%e %b %Y" : "%b %e %Y";
strftime(longstring, sizeof(longstring), format, localtime(&ftime));
snprintf(fmt, sizeof(fmt), "{:%s/%%hs} ", field);
snprintf(fmt, sizeof(fmt), "{d:%s/%%hs} ", field);
xo_attr("value", "%ld", (long) ftime);
xo_emit(fmt, longstring);
snprintf(fmt, sizeof(fmt), "{en:%s/%%ld}", field);
xo_emit(fmt, (long) ftime);
}
static int
@ -456,7 +486,7 @@ printtype(u_int mode)
xo_emit("{D:=}{e:type/socket}");
return (1);
case S_IFWHT:
xo_emit("{D:%}{e:type/whiteout}");
xo_emit("{D:%%}{e:type/whiteout}");
return (1);
default:
break;

View File

@ -122,7 +122,7 @@ main(int argc, char *argv[])
*/
if (stat(argv[argc - 1], &sb) || !S_ISDIR(sb.st_mode)) {
if (argc > 2)
usage();
errx(1, "%s is not a directory", argv[argc - 1]);
exit(do_move(argv[0], argv[1]));
}

View File

@ -738,9 +738,9 @@ Display information on all system processes:
.Xr procstat 1 ,
.Xr w 1 ,
.Xr kvm 3 ,
.Xr libxo 3
.Xr libxo 3 ,
.Xr strftime 3 ,
.Xr xo_parse_args 3
.Xr xo_parse_args 3 ,
.Xr mac 4 ,
.Xr procfs 5 ,
.Xr pstat 8 ,

View File

@ -248,7 +248,7 @@ hashalias(const char *p)
{
unsigned int hashval;
hashval = *p << 4;
hashval = (unsigned char)*p << 4;
while (*p)
hashval+= *p++;
return &atab[hashval % ATABSIZE];

View File

@ -522,17 +522,16 @@ static struct tblentry **lastcmdentry;
static struct tblentry *
cmdlookup(const char *name, int add)
{
int hashval;
unsigned int hashval;
const char *p;
struct tblentry *cmdp;
struct tblentry **pp;
size_t len;
p = name;
hashval = *p << 4;
hashval = (unsigned char)*p << 4;
while (*p)
hashval += *p++;
hashval &= 0x7FFF;
pp = &cmdtable[hashval % CMDTABLESIZE];
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
if (equal(cmdp->cmdname, name))

View File

@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
.Dd April 18, 2015
.Dd July 11, 2015
.Dt SH 1
.Os
.Sh NAME
@ -2846,6 +2846,4 @@ The
utility does not recognize multibyte characters other than UTF-8.
Splitting using
.Va IFS
and the line editing library
.Xr editline 3
do not recognize multibyte characters.
does not recognize multibyte characters.

View File

@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -61,7 +62,7 @@ main(int argc, char *argv[])
struct info i;
enum FMT fmt;
int ch;
const char *file;
const char *file, *errstr = NULL;
fmt = NOTSET;
i.fd = STDIN_FILENO;
@ -130,7 +131,9 @@ args: argc -= optind;
if (isdigit(**argv)) {
speed_t speed;
speed = atoi(*argv);
speed = strtonum(*argv, 0, UINT_MAX, &errstr);
if (errstr)
err(1, "speed");
cfsetospeed(&i.t, speed);
cfsetispeed(&i.t, speed);
i.set = 1;

View File

@ -34,7 +34,7 @@
*
*/
lockstat:kernel:mtx_lock:adaptive-acquire
lockstat:::adaptive-acquire
{
mutex_owned();
exit(1);

View File

@ -34,7 +34,7 @@
*
*/
lockstat:kernel:mtx_lock:adaptive-acquire
lockstat:::adaptive-acquire
{
mutex_owned((kmutex_t *)arg0, 99);
exit(1);

View File

@ -36,7 +36,7 @@
*/
lockstat:kernel:mtx_lock:adaptive-acquire
lockstat:::adaptive-acquire
{
mutex_type_adaptive();
exit(1);

View File

@ -35,7 +35,7 @@
*/
lockstat:kernel:mtx_lock:adaptive-acquire
lockstat:::adaptive-acquire
{
mutex_type_adaptive((kmutex_t *)arg0, 99);
exit(1);

View File

@ -48,7 +48,7 @@ BEGIN
i = 0;
}
lockstat::mtx_lock:adaptive-acquire
lockstat:::adaptive-acquire
{
ptr = mutex_owner((struct mtx *)arg0);

View File

@ -44,7 +44,7 @@ BEGIN
ret = -99;
}
mtx_lock:adaptive-acquire
lockstat:::adaptive-acquire
{
ret = mutex_type_adaptive((struct mtx *)arg0);
i++;

View File

@ -1,4 +1,4 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
#
# CDDL HEADER START
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
#
# CDDL HEADER START
#

View File

@ -58,12 +58,25 @@ fi
dtrace=$1
local=127.0.0.1
tcpport=22
DIR=/var/tmp/dtest.$$
tcpport=1024
bound=5000
while [ $tcpport -lt $bound ]; do
nc -z $local $tcpport >/dev/null || break
tcpport=$(($tcpport + 1))
done
if [ $tcpport -eq $bound ]; then
echo "couldn't find an available TCP port"
exit 1
fi
mkdir $DIR
cd $DIR
# nc will exit when the connection is closed.
nc -l $local $tcpport &
cat > test.pl <<-EOPERL
use IO::Socket;
my \$s = IO::Socket::INET->new(
@ -76,7 +89,7 @@ cat > test.pl <<-EOPERL
sleep(2);
EOPERL
$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
BEGIN
{
ipsend = tcpsend = ipreceive = tcpreceive = 0;

View File

@ -79,7 +79,7 @@ cat > test.pl <<-EOPERL
sleep(2);
EOPERL
$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
BEGIN
{
ipsend = tcpsend = ipreceive = tcpreceive = 0;

View File

@ -82,7 +82,7 @@ cat > test.pl <<-EOPERL
sleep(2);
EOPERL
$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
BEGIN
{
ipsend = tcpsend = ipreceive = tcpreceive = 0;

View File

@ -87,7 +87,7 @@ cat > test.pl <<-EOPERL
sleep(2);
EOPERL
$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
$dtrace -c 'perl test.pl' -qs /dev/stdin <<EODTRACE
BEGIN
{
ipsend = tcpsend = ipreceive = tcpreceive = 0;

View File

@ -196,17 +196,17 @@ static ls_event_info_t g_event_info[LS_MAX_EVENTS] = {
"lockstat:::spin-release", NULL,
"lockstat:::spin-acquire" },
{ 'H', "Lock", "R/W writer hold", "nsec",
"lockstat::rw_wunlock:rw-release", NULL,
"lockstat::rw_wlock:rw-acquire" },
"lockstat:::rw-release", "arg1 == 0",
"lockstat:::rw-acquire" },
{ 'H', "Lock", "R/W reader hold", "nsec",
"lockstat::rw_runlock:rw-release", NULL,
"lockstat::rw_rlock:rw-acquire" },
"lockstat:::rw-release", "arg1 == 1",
"lockstat:::rw-acquire" },
{ 'H', "Lock", "SX shared hold", "nsec",
"lockstat::sx_sunlock:sx-release", NULL,
"lockstat::sx_slock:sx-acquire" },
"lockstat:::sx-release", "arg1 == 0",
"lockstat:::sx-acquire" },
{ 'H', "Lock", "SX exclusive hold", "nsec",
"lockstat::sx_xunlock:sx-release", NULL,
"lockstat::sx_xlock:sx-acquire" },
"lockstat:::sx-release", "arg1 == 1",
"lockstat:::sx-acquire" },
{ 'H', "Lock", "Unknown event (type 38)", "units" },
{ 'H', "Lock", "Unknown event (type 39)", "units" },
{ 'H', "Lock", "Unknown event (type 40)", "units" },

View File

@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
*/
#include <stdio.h>
@ -95,6 +95,8 @@ static int zopt_objects = 0;
static libzfs_handle_t *g_zfs;
static uint64_t max_inflight = 1000;
static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *);
/*
* These libumem hooks provide a reasonable set of defaults for the allocator's
* debugging facilities.
@ -418,6 +420,79 @@ dump_zap(objset_t *os, uint64_t object, void *data, size_t size)
zap_cursor_fini(&zc);
}
static void
dump_bpobj(objset_t *os, uint64_t object, void *data, size_t size)
{
bpobj_phys_t *bpop = data;
char bytes[32], comp[32], uncomp[32];
if (bpop == NULL)
return;
zdb_nicenum(bpop->bpo_bytes, bytes);
zdb_nicenum(bpop->bpo_comp, comp);
zdb_nicenum(bpop->bpo_uncomp, uncomp);
(void) printf("\t\tnum_blkptrs = %llu\n",
(u_longlong_t)bpop->bpo_num_blkptrs);
(void) printf("\t\tbytes = %s\n", bytes);
if (size >= BPOBJ_SIZE_V1) {
(void) printf("\t\tcomp = %s\n", comp);
(void) printf("\t\tuncomp = %s\n", uncomp);
}
if (size >= sizeof (*bpop)) {
(void) printf("\t\tsubobjs = %llu\n",
(u_longlong_t)bpop->bpo_subobjs);
(void) printf("\t\tnum_subobjs = %llu\n",
(u_longlong_t)bpop->bpo_num_subobjs);
}
if (dump_opt['d'] < 5)
return;
for (uint64_t i = 0; i < bpop->bpo_num_blkptrs; i++) {
char blkbuf[BP_SPRINTF_LEN];
blkptr_t bp;
int err = dmu_read(os, object,
i * sizeof (bp), sizeof (bp), &bp, 0);
if (err != 0) {
(void) printf("got error %u from dmu_read\n", err);
break;
}
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), &bp);
(void) printf("\t%s\n", blkbuf);
}
}
/* ARGSUSED */
static void
dump_bpobj_subobjs(objset_t *os, uint64_t object, void *data, size_t size)
{
dmu_object_info_t doi;
VERIFY0(dmu_object_info(os, object, &doi));
uint64_t *subobjs = kmem_alloc(doi.doi_max_offset, KM_SLEEP);
int err = dmu_read(os, object, 0, doi.doi_max_offset, subobjs, 0);
if (err != 0) {
(void) printf("got error %u from dmu_read\n", err);
kmem_free(subobjs, doi.doi_max_offset);
return;
}
int64_t last_nonzero = -1;
for (uint64_t i = 0; i < doi.doi_max_offset / 8; i++) {
if (subobjs[i] != 0)
last_nonzero = i;
}
for (int64_t i = 0; i <= last_nonzero; i++) {
(void) printf("\t%llu\n", (longlong_t)subobjs[i]);
}
kmem_free(subobjs, doi.doi_max_offset);
}
/*ARGSUSED*/
static void
dump_ddt_zap(objset_t *os, uint64_t object, void *data, size_t size)
@ -1397,7 +1472,7 @@ dump_bpobj_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
}
static void
dump_bpobj(bpobj_t *bpo, char *name, int indent)
dump_full_bpobj(bpobj_t *bpo, char *name, int indent)
{
char bytes[32];
char comp[32];
@ -1411,11 +1486,12 @@ dump_bpobj(bpobj_t *bpo, char *name, int indent)
zdb_nicenum(bpo->bpo_phys->bpo_comp, comp);
zdb_nicenum(bpo->bpo_phys->bpo_uncomp, uncomp);
(void) printf(" %*s: object %llu, %llu local blkptrs, "
"%llu subobjs, %s (%s/%s comp)\n",
"%llu subobjs in object %llu, %s (%s/%s comp)\n",
indent * 8, name,
(u_longlong_t)bpo->bpo_object,
(u_longlong_t)bpo->bpo_phys->bpo_num_blkptrs,
(u_longlong_t)bpo->bpo_phys->bpo_num_subobjs,
(u_longlong_t)bpo->bpo_phys->bpo_subobjs,
bytes, comp, uncomp);
for (uint64_t i = 0; i < bpo->bpo_phys->bpo_num_subobjs; i++) {
@ -1432,7 +1508,7 @@ dump_bpobj(bpobj_t *bpo, char *name, int indent)
error, (u_longlong_t)subobj);
continue;
}
dump_bpobj(&subbpo, "subobj", indent + 1);
dump_full_bpobj(&subbpo, "subobj", indent + 1);
bpobj_close(&subbpo);
}
} else {
@ -1466,7 +1542,7 @@ dump_deadlist(dsl_deadlist_t *dl)
return;
if (dl->dl_oldfmt) {
dump_bpobj(&dl->dl_bpobj, "old-format deadlist", 0);
dump_full_bpobj(&dl->dl_bpobj, "old-format deadlist", 0);
return;
}
@ -1491,7 +1567,7 @@ dump_deadlist(dsl_deadlist_t *dl)
(void) snprintf(buf, sizeof (buf), "mintxg %llu -> "
"obj %llu", (longlong_t)dle->dle_mintxg,
(longlong_t)dle->dle_bpobj.bpo_object);
dump_bpobj(&dle->dle_bpobj, buf, 0);
dump_full_bpobj(&dle->dle_bpobj, buf, 0);
} else {
(void) printf("mintxg %llu -> obj %llu\n",
(longlong_t)dle->dle_mintxg,
@ -1682,8 +1758,8 @@ static object_viewer_t *object_viewer[DMU_OT_NUMTYPES + 1] = {
dump_uint64, /* object array */
dump_none, /* packed nvlist */
dump_packed_nvlist, /* packed nvlist size */
dump_none, /* bplist */
dump_none, /* bplist header */
dump_none, /* bpobj */
dump_bpobj, /* bpobj header */
dump_none, /* SPA space map header */
dump_none, /* SPA space map */
dump_none, /* ZIL intent log */
@ -1730,7 +1806,7 @@ static object_viewer_t *object_viewer[DMU_OT_NUMTYPES + 1] = {
dump_zap, /* deadlist */
dump_none, /* deadlist hdr */
dump_zap, /* dsl clones */
dump_none, /* bpobj subobjs */
dump_bpobj_subobjs, /* bpobj subobjs */
dump_unknown, /* Unknown type, must be last */
};
@ -2145,7 +2221,7 @@ dump_label(const char *dev)
(void) close(fd);
}
static uint64_t num_large_blocks;
static uint64_t dataset_feature_count[SPA_FEATURES];
/*ARGSUSED*/
static int
@ -2159,8 +2235,15 @@ 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++;
for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
if (!dmu_objset_ds(os)->ds_feature_inuse[f])
continue;
ASSERT(spa_feature_table[f].fi_flags &
ZFEATURE_FLAG_PER_DATASET);
dataset_feature_count[f]++;
}
dump_dir(os);
dmu_objset_disown(os, FTAG);
fuid_table_destroy();
@ -2352,6 +2435,9 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
dmu_object_type_t type;
boolean_t is_metadata;
if (bp == NULL)
return (0);
if (dump_opt['b'] >= 5 && bp->blk_birth > 0) {
char blkbuf[BP_SPRINTF_LEN];
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
@ -2841,7 +2927,7 @@ zdb_ddt_add_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
avl_index_t where;
zdb_ddt_entry_t *zdde, zdde_search;
if (BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp))
if (bp == NULL || BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp))
return (0);
if (dump_opt['S'] > 1 && zb->zb_level == ZB_ROOT_LEVEL) {
@ -2956,13 +3042,13 @@ 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,
dump_full_bpobj(&spa->spa_deferred_bpobj,
"Deferred frees", 0);
if (spa_version(spa) >= SPA_VERSION_DEADLISTS) {
dump_bpobj(&spa->spa_dsl_pool->dp_free_bpobj,
dump_full_bpobj(
&spa->spa_dsl_pool->dp_free_bpobj,
"Pool snapshot frees", 0);
}
@ -2977,17 +3063,29 @@ 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);
for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
uint64_t refcount;
if (!(spa_feature_table[f].fi_flags &
ZFEATURE_FLAG_PER_DATASET)) {
ASSERT0(dataset_feature_count[f]);
continue;
}
(void) feature_get_refcount(spa,
&spa_feature_table[f], &refcount);
if (dataset_feature_count[f] != refcount) {
(void) printf("%s feature refcount mismatch: "
"%lld datasets != %lld refcount\n",
spa_feature_table[f].fi_uname,
(longlong_t)dataset_feature_count[f],
(longlong_t)refcount);
rc = 2;
} else {
(void) printf("Verified %s feature refcount "
"of %llu is correct\n",
spa_feature_table[f].fi_uname,
(longlong_t)refcount);
}
}
}
if (rc == 0 && (dump_opt['b'] || dump_opt['c']))

View File

@ -27,11 +27,11 @@
.\" 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.
.\" Copyright (c) 2014-2015, The FreeBSD Foundation, All Rights Reserved.
.\"
.\" $FreeBSD$
.\"
.Dd December 12, 2014
.Dd July 30, 2015
.Dt ZFS 8
.Os
.Sh NAME
@ -191,11 +191,13 @@
.Nm
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Nm
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Op Fl d | e
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Ar filesystem
.Nm
.Cm allow
@ -938,8 +940,24 @@ not be used by any other dataset.
Disabling checksums is
.Em NOT
a recommended practice.
.It Sy compression Ns = Ns Cm on | off | lzjb | gzip | gzip- Ns Ar N | zle | Cm lz4
Controls the compression algorithm used for this dataset. The
.It Sy compression Ns = Ns Cm on | off | lzjb | gzip | gzip- Ns Ar N | Cm zle | Cm lz4
Controls the compression algorithm used for this dataset.
Setting compression to
.Cm on
indicates that the current default compression algorithm should be used.
The default balances compression and decompression speed, with compression
ratio and is expected to work well on a wide variety of workloads.
Unlike all other settings for this property, on does not select a fixed
compression type.
As new compression algorithms are added to ZFS and enabled on a pool, the
default compression algorithm may change.
The current default compression algorthm is either
.Cm lzjb
or, if the
.Sy lz4_compress
feature is enabled,
.Cm lz4 .
The
.Cm lzjb
compression algorithm is optimized for performance while providing decent data
compression. Setting compression to
@ -2689,6 +2707,7 @@ feature.
.Nm
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Xc
.It Xo
@ -2696,6 +2715,7 @@ feature.
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Op Fl d | e
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Ar filesystem
.Xc
.Pp
@ -2780,6 +2800,10 @@ receive operation.
Do not actually receive the stream. This can be useful in conjunction with the
.Fl v
option to verify the name the receive operation would use.
.It Fl o Sy origin Ns = Ns Ar snapshot
Forces the stream to be received as a clone of the given snapshot.
This is only valid if the stream is an incremental stream whose source
is the same as the provided origin.
.It Fl F
Force a rollback of the file system to the most recent snapshot before
performing the receive operation. If receiving an incremental replication

View File

@ -264,8 +264,9 @@ get_usage(zfs_help_t idx)
return (gettext("\tpromote <clone-filesystem>\n"));
case HELP_RECEIVE:
return (gettext("\treceive|recv [-vnFu] <filesystem|volume|"
"snapshot>\n"
"\treceive|recv [-vnFu] [-d | -e] <filesystem>\n"));
"snapshot>\n"
"\treceive|recv [-vnFu] [-o origin=<snapshot>] [-d | -e] "
"<filesystem>\n"));
case HELP_RENAME:
return (gettext("\trename [-f] <filesystem|volume|snapshot> "
"<filesystem|volume|snapshot>\n"
@ -791,7 +792,7 @@ zfs_do_create(int argc, char **argv)
nomem();
break;
case 'o':
if (parseprop(props, optarg))
if (parseprop(props, optarg) != 0)
goto error;
break;
case 's':
@ -3659,7 +3660,7 @@ zfs_do_snapshot(int argc, char **argv)
while ((c = getopt(argc, argv, "ro:")) != -1) {
switch (c) {
case 'o':
if (parseprop(props, optarg))
if (parseprop(props, optarg) != 0)
return (1);
break;
case 'r':
@ -3918,10 +3919,19 @@ zfs_do_receive(int argc, char **argv)
{
int c, err;
recvflags_t flags = { 0 };
nvlist_t *props;
nvpair_t *nvp = NULL;
if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
nomem();
/* check options */
while ((c = getopt(argc, argv, ":denuvF")) != -1) {
while ((c = getopt(argc, argv, ":o:denuvF")) != -1) {
switch (c) {
case 'o':
if (parseprop(props, optarg) != 0)
return (1);
break;
case 'd':
flags.isprefix = B_TRUE;
break;
@ -3966,6 +3976,13 @@ zfs_do_receive(int argc, char **argv)
usage(B_FALSE);
}
while ((nvp = nvlist_next_nvpair(props, nvp))) {
if (strcmp(nvpair_name(nvp), "origin") != 0) {
(void) fprintf(stderr, gettext("invalid option"));
usage(B_FALSE);
}
}
if (isatty(STDIN_FILENO)) {
(void) fprintf(stderr,
gettext("Error: Backup stream can not be read "
@ -3974,7 +3991,7 @@ zfs_do_receive(int argc, char **argv)
return (1);
}
err = zfs_receive(g_zfs, argv[0], &flags, STDIN_FILENO, NULL);
err = zfs_receive(g_zfs, argv[0], props, &flags, STDIN_FILENO, NULL);
return (err != 0);
}

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
@ -294,8 +294,8 @@ zhack_feature_enable_sync(void *arg, dmu_tx_t *tx)
feature_enable_sync(spa, feature, tx);
spa_history_log_internal(spa, "zhack enable feature", tx,
"name=%s can_readonly=%u",
feature->fi_guid, feature->fi_can_readonly);
"guid=%s flags=%x",
feature->fi_guid, feature->fi_flags);
}
static void
@ -314,9 +314,7 @@ zhack_do_feature_enable(int argc, char **argv)
*/
desc = NULL;
feature.fi_uname = "zhack";
feature.fi_mos = B_FALSE;
feature.fi_can_readonly = B_FALSE;
feature.fi_activate_on_enable = B_FALSE;
feature.fi_flags = 0;
feature.fi_depends = nodeps;
feature.fi_feature = SPA_FEATURE_NONE;
@ -324,7 +322,7 @@ zhack_do_feature_enable(int argc, char **argv)
while ((c = getopt(argc, argv, "rmd:")) != -1) {
switch (c) {
case 'r':
feature.fi_can_readonly = B_TRUE;
feature.fi_flags |= ZFEATURE_FLAG_READONLY_COMPAT;
break;
case 'd':
desc = strdup(optarg);
@ -413,7 +411,7 @@ zhack_do_feature_ref(int argc, char **argv)
* disk later.
*/
feature.fi_uname = "zhack";
feature.fi_mos = B_FALSE;
feature.fi_flags = 0;
feature.fi_desc = NULL;
feature.fi_depends = nodeps;
feature.fi_feature = SPA_FEATURE_NONE;
@ -422,7 +420,7 @@ zhack_do_feature_ref(int argc, char **argv)
while ((c = getopt(argc, argv, "md")) != -1) {
switch (c) {
case 'm':
feature.fi_mos = B_TRUE;
feature.fi_flags |= ZFEATURE_FLAG_MOS;
break;
case 'd':
decr = B_TRUE;
@ -455,10 +453,10 @@ zhack_do_feature_ref(int argc, char **argv)
if (0 == zap_contains(mos, spa->spa_feat_for_read_obj,
feature.fi_guid)) {
feature.fi_can_readonly = B_FALSE;
feature.fi_flags &= ~ZFEATURE_FLAG_READONLY_COMPAT;
} else if (0 == zap_contains(mos, spa->spa_feat_for_write_obj,
feature.fi_guid)) {
feature.fi_can_readonly = B_TRUE;
feature.fi_flags |= ZFEATURE_FLAG_READONLY_COMPAT;
} else {
fatal(spa, FTAG, "feature is not enabled: %s", feature.fi_guid);
}

View File

@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2012 by Frederik Wessels. All rights reserved.
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
@ -4986,7 +4986,8 @@ zpool_do_upgrade(int argc, char **argv)
"---------------\n");
for (i = 0; i < SPA_FEATURES; i++) {
zfeature_info_t *fi = &spa_feature_table[i];
const char *ro = fi->fi_can_readonly ?
const char *ro =
(fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ?
" (read-only compatible)" : "";
(void) printf("%-37s%s\n", fi->fi_uname, ro);

View File

@ -25,7 +25,7 @@
*/
/*
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2013, 2014 by Delphix. All rights reserved.
*/
#include <ctype.h>
@ -34,6 +34,7 @@
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <stddef.h>
#include <sys/dmu.h>
#include <sys/zfs_ioctl.h>
@ -83,7 +84,6 @@ safe_malloc(size_t size)
*
* Read while computing incremental checksum
*/
static size_t
ssread(void *buf, size_t len, zio_cksum_t *cksum)
{
@ -92,7 +92,7 @@ ssread(void *buf, size_t len, zio_cksum_t *cksum)
if ((outlen = fread(buf, len, 1, send_stream)) == 0)
return (0);
if (do_cksum && cksum) {
if (do_cksum) {
if (do_byteswap)
fletcher_4_incremental_byteswap(buf, len, cksum);
else
@ -102,6 +102,34 @@ ssread(void *buf, size_t len, zio_cksum_t *cksum)
return (outlen);
}
static size_t
read_hdr(dmu_replay_record_t *drr, zio_cksum_t *cksum)
{
ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
size_t r = ssread(drr, sizeof (*drr) - sizeof (zio_cksum_t), cksum);
if (r == 0)
return (0);
zio_cksum_t saved_cksum = *cksum;
r = ssread(&drr->drr_u.drr_checksum.drr_checksum,
sizeof (zio_cksum_t), cksum);
if (r == 0)
return (0);
if (!ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.drr_checksum.drr_checksum) &&
!ZIO_CHECKSUM_EQUAL(saved_cksum,
drr->drr_u.drr_checksum.drr_checksum)) {
fprintf(stderr, "invalid checksum\n");
(void) printf("Incorrect checksum in record header.\n");
(void) printf("Expected checksum = %llx/%llx/%llx/%llx\n",
saved_cksum.zc_word[0],
saved_cksum.zc_word[1],
saved_cksum.zc_word[2],
saved_cksum.zc_word[3]);
exit(1);
}
return (sizeof (*drr));
}
/*
* Print part of a block in ASCII characters
*/
@ -183,8 +211,10 @@ main(int argc, char *argv[])
struct drr_free *drrf = &thedrr.drr_u.drr_free;
struct drr_spill *drrs = &thedrr.drr_u.drr_spill;
struct drr_write_embedded *drrwe = &thedrr.drr_u.drr_write_embedded;
struct drr_checksum *drrc = &thedrr.drr_u.drr_checksum;
char c;
boolean_t verbose = B_FALSE;
boolean_t very_verbose = B_FALSE;
boolean_t first = B_TRUE;
/*
* dump flag controls whether the contents of any modified data blocks
@ -202,11 +232,14 @@ main(int argc, char *argv[])
do_cksum = B_FALSE;
break;
case 'v':
if (verbose)
very_verbose = B_TRUE;
verbose = B_TRUE;
break;
case 'd':
dump = B_TRUE;
verbose = B_TRUE;
very_verbose = B_TRUE;
break;
case ':':
(void) fprintf(stderr,
@ -230,7 +263,7 @@ main(int argc, char *argv[])
send_stream = stdin;
pcksum = zc;
while (ssread(drr, sizeof (dmu_replay_record_t), &zc)) {
while (read_hdr(drr, &zc)) {
/*
* If this is the first DMU record being processed, check for
@ -432,7 +465,7 @@ main(int argc, char *argv[])
if (verbose) {
(void) printf("WRITE object = %llu type = %u "
"checksum type = %u\n"
"offset = %llu length = %llu "
" offset = %llu length = %llu "
"props = %llx\n",
(u_longlong_t)drrw->drr_object,
drrw->drr_type,
@ -476,9 +509,9 @@ main(int argc, char *argv[])
if (verbose) {
(void) printf("WRITE_BYREF object = %llu "
"checksum type = %u props = %llx\n"
"offset = %llu length = %llu\n"
" offset = %llu length = %llu\n"
"toguid = %llx refguid = %llx\n"
"refobject = %llu refoffset = %llu\n",
" refobject = %llu refoffset = %llu\n",
(u_longlong_t)drrwbr->drr_object,
drrwbr->drr_checksumtype,
(u_longlong_t)drrwbr->drr_key.ddk_prop,
@ -538,7 +571,7 @@ main(int argc, char *argv[])
if (verbose) {
(void) printf("WRITE_EMBEDDED object = %llu "
"offset = %llu length = %llu\n"
"toguid = %llx comp = %u etype = %u "
" toguid = %llx comp = %u etype = %u "
"lsize = %u psize = %u\n",
(u_longlong_t)drrwe->drr_object,
(u_longlong_t)drrwe->drr_offset,
@ -553,6 +586,13 @@ main(int argc, char *argv[])
P2ROUNDUP(drrwe->drr_psize, 8), &zc);
break;
}
if (drr->drr_type != DRR_BEGIN && very_verbose) {
(void) printf(" checksum = %llx/%llx/%llx/%llx\n",
(longlong_t)drrc->drr_checksum.zc_word[0],
(longlong_t)drrc->drr_checksum.zc_word[1],
(longlong_t)drrc->drr_checksum.zc_word[2],
(longlong_t)drrc->drr_checksum.zc_word[3]);
}
pcksum = zc;
}
free(buf);

View File

@ -3586,7 +3586,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
*/
n = ztest_random(regions) * stride + ztest_random(width);
s = 1 + ztest_random(2 * width - 1);
dmu_prefetch(os, bigobj, n * chunksize, s * chunksize);
dmu_prefetch(os, bigobj, 0, n * chunksize, s * chunksize,
ZIO_PRIORITY_SYNC_READ);
/*
* Pick a random index and compute the offsets into packobj and bigobj.
@ -5705,8 +5706,10 @@ ztest_run(ztest_shared_t *zs)
* Right before closing the pool, kick off a bunch of async I/O;
* spa_close() should wait for it to complete.
*/
for (uint64_t object = 1; object < 50; object++)
dmu_prefetch(spa->spa_meta_objset, object, 0, 1ULL << 20);
for (uint64_t object = 1; object < 50; object++) {
dmu_prefetch(spa->spa_meta_objset, object, 0, 0, 1ULL << 20,
ZIO_PRIORITY_SYNC_READ);
}
spa_close(spa, FTAG);
@ -5905,6 +5908,7 @@ ztest_init(ztest_shared_t *zs)
}
VERIFY3U(0, ==, spa_create(ztest_opts.zo_pool, nvroot, props, NULL));
nvlist_free(nvroot);
nvlist_free(props);
VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
zs->zs_metaslab_sz =

View File

@ -0,0 +1,139 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2014 Howard Su
* Copyright 2015 George V. Neville-Neil
* Copyright 2015 Ruslan Bukin <br@bsdpad.com>
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <libgen.h>
#include <dt_impl.h>
#include <dt_pid.h>
#if !defined(sun)
#include <libproc_compat.h>
#endif
/*ARGSUSED*/
int
dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
{
ftp->ftps_type = DTFTP_ENTRY;
ftp->ftps_pc = (uintptr_t)symp->st_value;
ftp->ftps_size = (size_t)symp->st_size;
ftp->ftps_noffs = 1;
ftp->ftps_offs[0] = 0;
if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
strerror(errno));
return (dt_set_errno(dtp, errno));
}
return (1);
}
int
dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
{
dt_dprintf("%s: unimplemented\n", __func__);
return (DT_PROC_ERR);
}
/*ARGSUSED*/
int
dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
{
if (!ALIGNED_POINTER(off, 4))
return (DT_PROC_ALIGN);
ftp->ftps_type = DTFTP_OFFSETS;
ftp->ftps_pc = (uintptr_t)symp->st_value;
ftp->ftps_size = (size_t)symp->st_size;
ftp->ftps_noffs = 1;
ftp->ftps_offs[0] = off;
if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
strerror(errno));
return (dt_set_errno(dtp, errno));
}
return (1);
}
/*ARGSUSED*/
int
dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
{
ulong_t i;
ftp->ftps_type = DTFTP_OFFSETS;
ftp->ftps_pc = (uintptr_t)symp->st_value;
ftp->ftps_size = (size_t)symp->st_size;
ftp->ftps_noffs = 0;
/*
* If we're matching against everything, just iterate through each
* instruction in the function, otherwise look for matching offset
* names by constructing the string and comparing it against the
* pattern.
*/
if (strcmp("*", pattern) == 0) {
for (i = 0; i < symp->st_size; i += 4) {
ftp->ftps_offs[ftp->ftps_noffs++] = i;
}
} else {
char name[sizeof (i) * 2 + 1];
for (i = 0; i < symp->st_size; i += 4) {
(void) sprintf(name, "%lx", i);
if (gmatch(name, pattern))
ftp->ftps_offs[ftp->ftps_noffs++] = i;
}
}
if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
strerror(errno));
return (dt_set_errno(dtp, errno));
}
return (ftp->ftps_noffs);
}

View File

@ -227,7 +227,10 @@ prepare_elf32(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf32_t *dep)
s = &dofs[dofrh->dofr_tgtsec];
for (j = 0; j < nrel; j++) {
#if defined(__arm__)
#if defined(__aarch64__)
/* XXX */
printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
#elif defined(__arm__)
/* XXX */
printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
#elif defined(__i386) || defined(__amd64)
@ -426,7 +429,9 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
s = &dofs[dofrh->dofr_tgtsec];
for (j = 0; j < nrel; j++) {
#if defined(__arm__)
#if defined(__aarch64__)
/* XXX */
#elif defined(__arm__)
/* XXX */
#elif defined(__mips__)
/* XXX */
@ -822,7 +827,16 @@ dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
return (ret);
}
#if defined(__arm__)
#if defined(__aarch64__)
/* XXX */
static int
dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
uint32_t *off)
{
printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
return (0);
}
#elif defined(__arm__)
/* XXX */
static int
dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,

View File

@ -1348,6 +1348,7 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv,
dtrace_aggdesc_t *agg;
caddr_t lim = (caddr_t)buf + len, limit;
char format[64] = "%";
size_t ret;
int i, aggrec, curagg = -1;
uint64_t normal;
@ -1379,7 +1380,9 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv,
int prec = pfd->pfd_prec;
int rval;
const char *start;
char *f = format + 1; /* skip initial '%' */
size_t fmtsz = sizeof(format) - 1;
const dtrace_recdesc_t *rec;
dt_pfprint_f *func;
caddr_t addr;
@ -1536,6 +1539,7 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv,
break;
}
start = f;
if (pfd->pfd_flags & DT_PFCONV_ALT)
*f++ = '#';
if (pfd->pfd_flags & DT_PFCONV_ZPAD)
@ -1548,6 +1552,7 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv,
*f++ = '\'';
if (pfd->pfd_flags & DT_PFCONV_SPACE)
*f++ = ' ';
fmtsz -= f - start;
/*
* If we're printing a stack and DT_PFCONV_LEFT is set, we
@ -1558,13 +1563,20 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv,
if (func == pfprint_stack && (pfd->pfd_flags & DT_PFCONV_LEFT))
width = 0;
if (width != 0)
f += snprintf(f, sizeof (format), "%d", ABS(width));
if (width != 0) {
ret = snprintf(f, fmtsz, "%d", ABS(width));
f += ret;
fmtsz = MAX(0, fmtsz - ret);
}
if (prec > 0)
f += snprintf(f, sizeof (format), ".%d", prec);
if (prec > 0) {
ret = snprintf(f, fmtsz, ".%d", prec);
f += ret;
fmtsz = MAX(0, fmtsz - ret);
}
(void) strcpy(f, pfd->pfd_fmt);
if (strlcpy(f, pfd->pfd_fmt, fmtsz) >= fmtsz)
return (dt_set_errno(dtp, EDT_COMPILER));
pfd->pfd_rec = rec;
if (func(dtp, fp, format, pfd, addr, size, normal) < 0)

View File

@ -668,8 +668,8 @@ typedef struct recvflags {
boolean_t nomount;
} recvflags_t;
extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t *,
int, avl_tree_t *);
extern int zfs_receive(libzfs_handle_t *, const char *, nvlist_t *,
recvflags_t *, int, avl_tree_t *);
typedef enum diff_flags {
ZFS_DIFF_PARSEABLE = 0x1,

View File

@ -3535,7 +3535,7 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
}
static int
zbookmark_compare(const void *a, const void *b)
zbookmark_mem_compare(const void *a, const void *b)
{
return (memcmp(a, b, sizeof (zbookmark_phys_t)));
}
@ -3598,7 +3598,7 @@ zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
zc.zc_nvlist_dst_size;
count -= zc.zc_nvlist_dst_size;
qsort(zb, count, sizeof (zbookmark_phys_t), zbookmark_compare);
qsort(zb, count, sizeof (zbookmark_phys_t), zbookmark_mem_compare);
verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);

View File

@ -64,8 +64,9 @@ extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *);
/* We need to use something for ENODATA. */
#define ENODATA EIDRM
static int zfs_receive_impl(libzfs_handle_t *, const char *, recvflags_t *,
int, const char *, nvlist_t *, avl_tree_t *, char **, int, uint64_t *);
static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *,
recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **, int,
uint64_t *);
static const zio_cksum_t zero_cksum = { 0 };
@ -188,10 +189,28 @@ ddt_update(libzfs_handle_t *hdl, dedup_table_t *ddt, zio_cksum_t *cs,
}
static int
cksum_and_write(const void *buf, uint64_t len, zio_cksum_t *zc, int outfd)
dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
zio_cksum_t *zc, int outfd)
{
fletcher_4_incremental_native(buf, len, zc);
return (write(outfd, buf, len));
ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
fletcher_4_incremental_native(drr,
offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
if (drr->drr_type != DRR_BEGIN) {
ASSERT(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
drr_checksum.drr_checksum));
drr->drr_u.drr_checksum.drr_checksum = *zc;
}
fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
sizeof (zio_cksum_t), zc);
if (write(outfd, drr, sizeof (*drr)) == -1)
return (errno);
if (payload_len != 0) {
fletcher_4_incremental_native(payload, payload_len, zc);
if (write(outfd, payload, payload_len) == -1)
return (errno);
}
return (0);
}
/*
@ -218,26 +237,18 @@ cksummer(void *arg)
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;
struct drr_end *drre = &thedrr.drr_u.drr_end;
struct drr_object *drro = &thedrr.drr_u.drr_object;
struct drr_write *drrw = &thedrr.drr_u.drr_write;
struct drr_spill *drrs = &thedrr.drr_u.drr_spill;
struct drr_write_embedded *drrwe = &thedrr.drr_u.drr_write_embedded;
FILE *ofp;
int outfd;
dmu_replay_record_t wbr_drr = {0};
struct drr_write_byref *wbr_drrr = &wbr_drr.drr_u.drr_write_byref;
dedup_table_t ddt;
zio_cksum_t stream_cksum;
uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
uint64_t numbuckets;
ddt.max_ddt_size =
MAX((physmem * MAX_DDT_PHYSMEM_PERCENT)/100,
SMALLEST_POSSIBLE_MAX_DDT_MB<<20);
MAX((physmem * MAX_DDT_PHYSMEM_PERCENT) / 100,
SMALLEST_POSSIBLE_MAX_DDT_MB << 20);
numbuckets = ddt.max_ddt_size/(sizeof (dedup_entry_t));
numbuckets = ddt.max_ddt_size / (sizeof (dedup_entry_t));
/*
* numbuckets must be a power of 2. Increase number to
@ -253,32 +264,29 @@ cksummer(void *arg)
ddt.numhashbits = high_order_bit(numbuckets) - 1;
ddt.ddt_full = B_FALSE;
/* Initialize the write-by-reference block. */
wbr_drr.drr_type = DRR_WRITE_BYREF;
wbr_drr.drr_payloadlen = 0;
outfd = dda->outputfd;
ofp = fdopen(dda->inputfd, "r");
while (ssread(drr, sizeof (dmu_replay_record_t), ofp) != 0) {
while (ssread(drr, sizeof (*drr), ofp) != 0) {
switch (drr->drr_type) {
case DRR_BEGIN:
{
int fflags;
struct drr_begin *drrb = &drr->drr_u.drr_begin;
int fflags;
int sz = 0;
ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
ASSERT3U(drrb->drr_magic, ==, DMU_BACKUP_MAGIC);
/* set the DEDUP feature flag for this stream */
fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
fflags |= (DMU_BACKUP_FEATURE_DEDUP |
DMU_BACKUP_FEATURE_DEDUPPROPS);
DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);
if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
&stream_cksum, outfd) == -1)
goto out;
if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
DMU_COMPOUNDSTREAM && drr->drr_payloadlen != 0) {
int sz = drr->drr_payloadlen;
sz = drr->drr_payloadlen;
if (sz > SPA_MAXBLOCKSIZE) {
buf = zfs_realloc(dda->dedup_hdl, buf,
@ -287,64 +295,60 @@ cksummer(void *arg)
(void) ssread(buf, sz, ofp);
if (ferror(stdin))
perror("fread");
if (cksum_and_write(buf, sz, &stream_cksum,
outfd) == -1)
goto out;
}
if (dump_record(drr, buf, sz, &stream_cksum,
outfd) != 0)
goto out;
break;
}
case DRR_END:
{
struct drr_end *drre = &drr->drr_u.drr_end;
/* use the recalculated checksum */
ZIO_SET_CHECKSUM(&drre->drr_checksum,
stream_cksum.zc_word[0], stream_cksum.zc_word[1],
stream_cksum.zc_word[2], stream_cksum.zc_word[3]);
if ((write(outfd, drr,
sizeof (dmu_replay_record_t))) == -1)
drre->drr_checksum = stream_cksum;
if (dump_record(drr, NULL, 0, &stream_cksum,
outfd) != 0)
goto out;
break;
}
case DRR_OBJECT:
{
if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
&stream_cksum, outfd) == -1)
goto out;
struct drr_object *drro = &drr->drr_u.drr_object;
if (drro->drr_bonuslen > 0) {
(void) ssread(buf,
P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8),
ofp);
if (cksum_and_write(buf,
P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8),
&stream_cksum, outfd) == -1)
goto out;
}
if (dump_record(drr, buf,
P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8),
&stream_cksum, outfd) != 0)
goto out;
break;
}
case DRR_SPILL:
{
if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
&stream_cksum, outfd) == -1)
goto out;
struct drr_spill *drrs = &drr->drr_u.drr_spill;
(void) ssread(buf, drrs->drr_length, ofp);
if (cksum_and_write(buf, drrs->drr_length,
&stream_cksum, outfd) == -1)
if (dump_record(drr, buf, drrs->drr_length,
&stream_cksum, outfd) != 0)
goto out;
break;
}
case DRR_FREEOBJECTS:
{
if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
&stream_cksum, outfd) == -1)
if (dump_record(drr, NULL, 0, &stream_cksum,
outfd) != 0)
goto out;
break;
}
case DRR_WRITE:
{
struct drr_write *drrw = &drr->drr_u.drr_write;
dataref_t dataref;
(void) ssread(buf, drrw->drr_length, ofp);
@ -382,7 +386,13 @@ cksummer(void *arg)
if (ddt_update(dda->dedup_hdl, &ddt,
&drrw->drr_key.ddk_cksum, drrw->drr_key.ddk_prop,
&dataref)) {
dmu_replay_record_t wbr_drr = {0};
struct drr_write_byref *wbr_drrr =
&wbr_drr.drr_u.drr_write_byref;
/* block already present in stream */
wbr_drr.drr_type = DRR_WRITE_BYREF;
wbr_drrr->drr_object = drrw->drr_object;
wbr_drrr->drr_offset = drrw->drr_offset;
wbr_drrr->drr_length = drrw->drr_length;
@ -402,19 +412,13 @@ cksummer(void *arg)
wbr_drrr->drr_key.ddk_prop =
drrw->drr_key.ddk_prop;
if (cksum_and_write(&wbr_drr,
sizeof (dmu_replay_record_t), &stream_cksum,
outfd) == -1)
if (dump_record(&wbr_drr, NULL, 0,
&stream_cksum, outfd) != 0)
goto out;
} else {
/* block not previously seen */
if (cksum_and_write(drr,
sizeof (dmu_replay_record_t), &stream_cksum,
outfd) == -1)
goto out;
if (cksum_and_write(buf,
drrw->drr_length,
&stream_cksum, outfd) == -1)
if (dump_record(drr, buf, drrw->drr_length,
&stream_cksum, outfd) != 0)
goto out;
}
break;
@ -422,28 +426,27 @@ cksummer(void *arg)
case DRR_WRITE_EMBEDDED:
{
if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
&stream_cksum, outfd) == -1)
goto out;
struct drr_write_embedded *drrwe =
&drr->drr_u.drr_write_embedded;
(void) ssread(buf,
P2ROUNDUP((uint64_t)drrwe->drr_psize, 8), ofp);
if (cksum_and_write(buf,
if (dump_record(drr, buf,
P2ROUNDUP((uint64_t)drrwe->drr_psize, 8),
&stream_cksum, outfd) == -1)
&stream_cksum, outfd) != 0)
goto out;
break;
}
case DRR_FREE:
{
if (cksum_and_write(drr, sizeof (dmu_replay_record_t),
&stream_cksum, outfd) == -1)
if (dump_record(drr, NULL, 0, &stream_cksum,
outfd) != 0)
goto out;
break;
}
default:
(void) printf("INVALID record type 0x%x\n",
(void) fprintf(stderr, "INVALID record type 0x%x\n",
drr->drr_type);
/* should never happen, so assert */
assert(B_FALSE);
@ -1470,18 +1473,11 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
sizeof (drr.drr_u.drr_begin.drr_toname),
"%s@%s", zhp->zfs_name, tosnap);
drr.drr_payloadlen = buflen;
err = cksum_and_write(&drr, sizeof (drr), &zc, outfd);
/* write header nvlist */
if (err != -1 && packbuf != NULL) {
err = cksum_and_write(packbuf, buflen, &zc,
outfd);
}
err = dump_record(&drr, packbuf, buflen, &zc, outfd);
free(packbuf);
if (err == -1) {
err = errno;
if (err != 0)
goto stderr_out;
}
/* write end record */
bzero(&drr, sizeof (drr));
@ -1714,6 +1710,8 @@ recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen,
int rv;
int len = ilen;
assert(ilen <= SPA_MAXBLOCKSIZE);
do {
rv = read(fd, cp, len);
cp += rv;
@ -2501,7 +2499,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
* zfs_receive_one() will take care of it (ie,
* recv_skip() and return 0).
*/
error = zfs_receive_impl(hdl, destname, flags, fd,
error = zfs_receive_impl(hdl, destname, NULL, flags, fd,
sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd,
action_handlep);
if (error == ENODATA) {
@ -2634,9 +2632,9 @@ recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
*/
static int
zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
recvflags_t *flags, dmu_replay_record_t *drr,
dmu_replay_record_t *drr_noswap, const char *sendfs,
nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv,
avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
uint64_t *action_handlep)
{
zfs_cmd_t zc = { 0 };
@ -2801,10 +2799,15 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
}
if (flags->verbose)
(void) printf("found clone origin %s\n", zc.zc_string);
} else if (originsnap) {
(void) strncpy(zc.zc_string, originsnap, ZFS_MAXNAMELEN);
if (flags->verbose)
(void) printf("using provided clone origin %s\n",
zc.zc_string);
}
stream_wantsnewfs = (drrb->drr_fromguid == 0 ||
(drrb->drr_flags & DRR_FLAG_CLONE));
(drrb->drr_flags & DRR_FLAG_CLONE) || originsnap);
if (stream_wantsnewfs) {
/*
@ -3182,9 +3185,10 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
}
static int
zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
int infd, const char *sendfs, nvlist_t *stream_nv, avl_tree_t *stream_avl,
char **top_zfs, int cleanup_fd, uint64_t *action_handlep)
zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
const char *originsnap, recvflags_t *flags, int infd, const char *sendfs,
nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
uint64_t *action_handlep)
{
int err;
dmu_replay_record_t drr, drr_noswap;
@ -3203,6 +3207,12 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
"(%s) does not exist"), tosnap);
return (zfs_error(hdl, EZFS_NOENT, errbuf));
}
if (originsnap &&
!zfs_dataset_exists(hdl, originsnap, ZFS_TYPE_DATASET)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified origin fs "
"(%s) does not exist"), originsnap);
return (zfs_error(hdl, EZFS_NOENT, errbuf));
}
/* read in the BEGIN record */
if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
@ -3275,14 +3285,14 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
*cp = '\0';
sendfs = nonpackage_sendfs;
}
return (zfs_receive_one(hdl, infd, tosnap, flags,
&drr, &drr_noswap, sendfs, stream_nv, stream_avl,
top_zfs, cleanup_fd, action_handlep));
return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
&drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs,
cleanup_fd, action_handlep));
} else {
assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
DMU_COMPOUNDSTREAM);
return (zfs_receive_package(hdl, infd, tosnap, flags,
&drr, &zcksum, top_zfs, cleanup_fd, action_handlep));
return (zfs_receive_package(hdl, infd, tosnap, flags, &drr,
&zcksum, top_zfs, cleanup_fd, action_handlep));
}
}
@ -3293,18 +3303,24 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
* (-1 will override -2).
*/
int
zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
int infd, avl_tree_t *stream_avl)
zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
recvflags_t *flags, int infd, avl_tree_t *stream_avl)
{
char *top_zfs = NULL;
int err;
int cleanup_fd;
uint64_t action_handle = 0;
char *originsnap = NULL;
if (props) {
err = nvlist_lookup_string(props, "origin", &originsnap);
if (err && err != ENOENT)
return (err);
}
cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
VERIFY(cleanup_fd >= 0);
err = zfs_receive_impl(hdl, tosnap, flags, infd, NULL, NULL,
err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL,
stream_avl, &top_zfs, cleanup_fd, &action_handle);
VERIFY(0 == close(cleanup_fd));

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
@ -532,18 +532,30 @@ lzc_send(const char *snapname, const char *from, int fd,
}
/*
* If fromsnap is NULL, a full (non-incremental) stream will be estimated.
* "from" can be NULL, a snapshot, or a bookmark.
*
* If from is NULL, a full (non-incremental) stream will be estimated. This
* is calculated very efficiently.
*
* If from is a snapshot, lzc_send_space uses the deadlists attached to
* each snapshot to efficiently estimate the stream size.
*
* If from is a bookmark, the indirect blocks in the destination snapshot
* are traversed, looking for blocks with a birth time since the creation TXG of
* the snapshot this bookmark was created from. This will result in
* significantly more I/O and be less efficient than a send space estimation on
* an equivalent snapshot.
*/
int
lzc_send_space(const char *snapname, const char *fromsnap, uint64_t *spacep)
lzc_send_space(const char *snapname, const char *from, uint64_t *spacep)
{
nvlist_t *args;
nvlist_t *result;
int err;
args = fnvlist_alloc();
if (fromsnap != NULL)
fnvlist_add_string(args, "fromsnap", fromsnap);
if (from != NULL)
fnvlist_add_string(args, "from", from);
err = lzc_ioctl(ZFS_IOC_SEND_SPACE, snapname, args, &result);
nvlist_free(args);
if (err == 0)

View File

@ -135,8 +135,18 @@ extern int aok;
/*
* DTrace SDT probes have different signatures in userland than they do in
* kernel. If they're being used in kernel code, re-define them out of
* the kernel. If they're being used in kernel code, re-define them out of
* existence for their counterparts in libzpool.
*
* Here's an example of how to use the set-error probes in userland:
* zfs$target:::set-error /arg0 == EBUSY/ {stack();}
*
* Here's an example of how to use DTRACE_PROBE probes in userland:
* If there is a probe declared as follows:
* DTRACE_PROBE2(zfs__probe_name, uint64_t, blkid, dnode_t *, dn);
* Then you can use it as follows:
* zfs$target:::probe2 /copyinstr(arg0) == "zfs__probe_name"/
* {printf("%u %p\n", arg1, arg2);}
*/
#ifdef DTRACE_PROBE

View File

@ -26,9 +26,9 @@ _libzpool= libzpool
.endif
.endif
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" || \
${MACHINE_CPUARCH} == "mips" || ${MACHINE_CPUARCH} == "powerpc" || \
${MACHINE_CPUARCH} == "arm"
.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_ARCH} == "amd64" || \
${MACHINE_CPUARCH} == "arm" || ${MACHINE_ARCH} == "i386" || \
${MACHINE_CPUARCH} == "mips" || ${MACHINE_CPUARCH} == "powerpc"
_drti= drti
_libdtrace= libdtrace
.endif

View File

@ -69,27 +69,31 @@ CFLAGS+= -I${.OBJDIR} -I${.CURDIR} \
#CFLAGS+= -DYYDEBUG
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
.if ${MACHINE_CPUARCH} == "aarch64"
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/aarch64
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/aarch64
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/aarch64
.elif ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/dev/dtrace/x86
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel -DDIS_MEM
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/i386
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/${MACHINE_ARCH}
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/x86
.elif ${MACHINE_CPUARCH} == "sparc64"
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/sparc
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/sparc
.elif ${MACHINE_CPUARCH} == "mips"
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/mips
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/mips
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/mips
.elif ${MACHINE_CPUARCH} == "arm"
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/arm
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/arm
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/arm
.elif ${MACHINE_CPUARCH} == "mips"
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/mips
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/mips
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/mips
.elif ${MACHINE_CPUARCH} == "powerpc"
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/powerpc
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/powerpc
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/powerpc
.elif ${MACHINE_CPUARCH} == "sparc64"
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/sparc
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/sparc
.else
# temporary hack
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel

View File

@ -25,8 +25,7 @@
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#pragma D depends_on module kernel
#pragma D depends_on provider io
typedef struct devinfo {

View File

@ -25,6 +25,7 @@
* Copyright (c) 2013 Mark Johnston <markj@freebsd.org>
*/
#pragma D depends_on module kernel
#pragma D depends_on provider ip
/*

View File

@ -30,6 +30,7 @@
#pragma D depends_on library ip.d
#pragma D depends_on library net.d
#pragma D depends_on module kernel
#pragma D depends_on module nfs
typedef struct nfsv4opinfo {

View File

@ -30,7 +30,8 @@
#pragma D depends_on library ip.d
#pragma D depends_on library net.d
#pragma D depends_on module nfs.d
#pragma D depends_on library nfs.d
#pragma D depends_on module kernel
#pragma D depends_on module nfssrv
#pragma D binding "1.5" translator

View File

@ -28,6 +28,8 @@
* Use is subject to license terms.
*/
#pragma D depends_on module kernel
typedef struct psinfo {
int pr_nlwp; /* number of threads */
pid_t pr_pid; /* unique process id */

View File

@ -28,8 +28,6 @@
* Use is subject to license terms.
*/
#pragma ident "@(#)regs.d.in 1.1 04/09/28 SMI"
inline int R_GS = 0;
#pragma D binding "1.0" R_GS
inline int R_FS = 1;

View File

@ -27,9 +27,7 @@
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#pragma D depends_on module unix
#pragma D depends_on module kernel
#pragma D depends_on provider sched
struct cpuinfo {

View File

@ -21,6 +21,7 @@
* $FreeBSD$
*/
#pragma D depends_on module kernel
#pragma D depends_on module siftr
#pragma D depends_on provider tcp

View File

@ -26,6 +26,7 @@
*/
#pragma D depends_on library ip.d
#pragma D depends_on module kernel
#pragma D depends_on provider tcp
/*

View File

@ -26,6 +26,7 @@
*/
#pragma D depends_on library ip.d
#pragma D depends_on module kernel
#pragma D depends_on provider udp
/*

View File

@ -7,10 +7,10 @@ LIB= nvpair
SRCS= libnvpair.c \
nvpair_alloc_system.c \
nvpair_alloc_fixed.c \
nvpair.c \
nvpair_json.c \
fnvpair.c
opensolaris_fnvpair.c \
opensolaris_nvpair.c \
opensolaris_nvpair_alloc_fixed.c
WARNS?= 0
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include

View File

@ -30,7 +30,7 @@ _plockstat= plockstat
.endif
.endif
.if ${MACHINE_CPUARCH} == "arm"
.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
_dtrace= dtrace
_dtruss= dtruss
_lockstat= lockstat

View File

@ -1,5 +1,7 @@
# $FreeBSD$
.include <src.opts.mk>
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/dtrace
PROG= dtrace
@ -22,4 +24,8 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
LIBADD= dtrace
.if ${MK_DTRACE_TESTS} != "no"
SUBDIR+= tests
.endif
.include <bsd.prog.mk>

View File

@ -1,4 +1,63 @@
-*- coding: utf-8 -*-
Changes for APR 1.5.2
*) SECURITY: CVE-2015-1829 (cve.mitre.org)
APR applications using APR named pipe support on Windows can be
vulnerable to a pipe squatting attack from a local process; the extent
of the vulnerability, when present, depends on the application.
Initial analysis and report was provided by John Hernandez of Casaba
Security via HP SSRT Security Alert. [Yann Ylavic]
*) apr_atomic: Fix errors when building on Visual Studio 2013 while
maintaining the ability to build on Visual Studio 6 with Windows
Server 2003 R2 SDK. PR 57191. [Gregg Smith]
*) Switch to generic atomics for early/unpatched Solaris 10 not exporting
some atomic functions. PR 55418. [Yann Ylavic]
*) apr_file_mktemp() on HP-UX: Remove limitation of 26 temporary files
per process. PR 57677. [Jeff Trawick]
*) apr_escape: Correctly calculate the size of the returned string in
apr_escape_path and set the correct return value in case we actually
escape the string. [<aduryagin gmail.com>] PR 57230.
*) pollcb on Windows: Handle calls with no file/socket descriptors.
Follow up to PR 49882. [Jeff Trawick, Yann Ylavic]
*) apr_poll(cb): fix error paths returned values and leaks. [Yann Ylavic]
*) apr_thread_cond_*wait() on BeOS: Fix broken logic. PR 45800.
[Jochen Voss (no e-mail)]
*) apr_skiplist: Optimize the number of allocations by reusing pooled or
malloc()ed nodes for the lifetime of the skiplist. [Yann Ylavic]
*) apr_skiplist: Fix possible multiple-free() on the same value in
apr_skiplist_remove_all(). [Yann Ylavic]
*) apr_pollset: On z/OS, threadsafe apr_pollset_poll() may return
"EDC8102I Operation would block" under load.
[Pat Odonnell <patod us.ibm.com>]
*) On z/OS, apr_sockaddr_info_get() with family == APR_UNSPEC was not
returning IPv4 addresses if any IPv6 addresses were returned.
[Eric Covener]
*) Windows cmake build: Fix an incompatibility with cmake 2.8.12 and
later. [Jeff Trawick]
*) apr_global_mutex/apr_proc_mutex: Resolve failures with the
POSIX sem implementation in environments which receive signals.
[Jeff Trawick]
*) apr_skiplist: Fix potential corruption of skiplists leading to
results or crashes. [Takashi Sato <takashi tks st>, Eric Covener]
PR 56654.
*) Improve platform detection by updating config.guess and config.sub.
[Rainer Jung]
Changes for APR 1.5.1
*) apr_os_proc_mutex_get() on Unix: Avoid segfault for cross-
@ -37,8 +96,8 @@ Changes for APR 1.5.1
*) Correct a regression in 1.5.0 which affected out-of-tree
builds on Unix. [Rainer Jung]
*) Improve platform detection for bundled expat by updating
config.guess and config.sub. [Rainer Jung]
*) Improve platform detection by updating config.guess and config.sub.
[Rainer Jung]
Changes for APR 1.5.0

View File

@ -234,6 +234,7 @@ SET(APR_TEST_SOURCES
test/testprocmutex.c
test/testrand.c
test/testshm.c
test/testskiplist.c
test/testsleep.c
test/testsock.c
test/testsockets.c
@ -252,7 +253,6 @@ SET(APR_TEST_SOURCES
SET(install_targets)
SET(install_bin_pdb)
SET(install_lib_pdb)
# libapr-1 is shared, apr-1 is static
ADD_LIBRARY(libapr-1 SHARED ${APR_SOURCES} ${APR_PUBLIC_HEADERS_GENERATED} libapr.rc)
@ -264,7 +264,6 @@ ADD_DEPENDENCIES(libapr-1 test_char_header)
ADD_LIBRARY(apr-1 STATIC ${APR_SOURCES} ${APR_PUBLIC_HEADERS_GENERATED})
SET(install_targets ${install_targets} apr-1)
SET(install_lib_pdb ${install_lib_pdb} ${PROJECT_BINARY_DIR}/apr-1.pdb)
TARGET_LINK_LIBRARIES(apr-1 ${APR_SYSTEM_LIBS})
SET_TARGET_PROPERTIES(apr-1 PROPERTIES COMPILE_DEFINITIONS "APR_DECLARE_STATIC;WINNT")
ADD_DEPENDENCIES(apr-1 test_char_header)
@ -272,12 +271,10 @@ ADD_DEPENDENCIES(apr-1 test_char_header)
# libaprapp-1 and aprapp-1 are static
ADD_LIBRARY(libaprapp-1 STATIC misc/win32/apr_app.c misc/win32/internal.c ${APR_PUBLIC_HEADERS_GENERATED})
SET(install_targets ${install_targets} libaprapp-1)
SET(install_lib_pdb ${install_lib_pdb} ${PROJECT_BINARY_DIR}/libaprapp-1.pdb)
SET_TARGET_PROPERTIES(libaprapp-1 PROPERTIES COMPILE_DEFINITIONS "APR_APP;WINNT")
ADD_LIBRARY(aprapp-1 STATIC misc/win32/apr_app.c misc/win32/internal.c ${APR_PUBLIC_HEADERS_GENERATED})
SET(install_targets ${install_targets} aprapp-1)
SET(install_lib_pdb ${install_lib_pdb} ${PROJECT_BINARY_DIR}/aprapp-1.pdb)
SET_TARGET_PROPERTIES(aprapp-1 PROPERTIES COMPILE_DEFINITIONS "APR_DECLARE_STATIC;APR_APP;WINNT")
IF(APR_BUILD_TESTAPR)
@ -394,10 +391,6 @@ IF(INSTALL_PDB)
INSTALL(FILES ${install_bin_pdb}
DESTINATION bin
CONFIGURATIONS RelWithDebInfo Debug)
INSTALL(FILES ${install_lib_pdb}
DESTINATION lib
CONFIGURATIONS RelWithDebInfo Debug)
ENDIF()
INSTALL(FILES ${APR_PUBLIC_HEADERS_STATIC} ${APR_PUBLIC_HEADERS_GENERATED} DESTINATION include)

View File

@ -129,11 +129,11 @@ check: $(TARGET_LIB)
etags:
etags `find . -name '*.[ch]'`
make_tools_dir:
$(APR_MKDIR) tools
OBJECTS_gen_test_char = tools/gen_test_char.lo $(LOCAL_LIBS)
tools/gen_test_char.lo: make_tools_dir
tools/gen_test_char.lo: tools/gen_test_char.c
$(APR_MKDIR) tools
$(LT_COMPILE)
tools/gen_test_char@EXEEXT@: $(OBJECTS_gen_test_char)
$(LINK_PROG) $(OBJECTS_gen_test_char) $(ALL_LIBS)

View File

@ -1,5 +1,5 @@
Apache Portable Runtime
Copyright (c) 2000-2014 The Apache Software Foundation.
Copyright (c) 2000-2015 The Apache Software Foundation.
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

View File

@ -50,6 +50,7 @@ include $(APR_WORK)/build/NWGNUhead.inc
#
XINCDIRS += \
$(APR)/include \
$(APR)/include/private \
$(APR)/include/arch/NetWare \
$(APR)/include/arch/unix \
$(APR)/memory/unix \
@ -293,11 +294,13 @@ FILES_nlm_exports = \
FILES_lib_objs = \
$(OBJDIR)/apr_atomic.o \
$(OBJDIR)/apr_cpystrn.o \
$(OBJDIR)/apr_escape.o \
$(OBJDIR)/apr_fnmatch.o \
$(OBJDIR)/apr_getpass.o \
$(OBJDIR)/apr_hash.o \
$(OBJDIR)/apr_pools.o \
$(OBJDIR)/apr_random.o \
$(OBJDIR)/apr_skiplist.o \
$(OBJDIR)/apr_snprintf.o \
$(OBJDIR)/apr_strings.o \
$(OBJDIR)/apr_strnatcmp.o \
@ -407,7 +410,7 @@ endif
vpath %.c atomic/netware:strings:tables:passwd:lib:time/unix
vpath %.c file_io/unix:locks/netware:misc/netware:misc/unix:threadproc/netware
vpath %.c poll/unix:shmem/unix:support/unix:random/unix
vpath %.c dso/netware:memory/unix:mmap/unix:user/netware
vpath %.c dso/netware:memory/unix:mmap/unix:user/netware:encoding
# Use the win32 network_io if Winsock is being used
ifndef USE_STDSOCKETS

View File

@ -907,69 +907,6 @@ SOURCE=.\include\apr_version.h
# Begin Source File
SOURCE=.\include\apr_want.h
!IF "$(CFG)" == "apr - Win32 Release"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\LibR\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ELSEIF "$(CFG)" == "apr - Win32 Debug"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\LibD\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ELSEIF "$(CFG)" == "apr - Win32 Release9x"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\9x\LibR\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ELSEIF "$(CFG)" == "apr - Win32 Debug9x"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\9x\LibD\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ELSEIF "$(CFG)" == "apr - x64 Release"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\x64\LibR\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ELSEIF "$(CFG)" == "apr - x64 Debug"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\x64\LibD\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ENDIF
# End Source File
# End Group
# End Target

View File

@ -3,7 +3,7 @@
Summary: Apache Portable Runtime library
Name: apr
Version: 1.5.1
Version: 1.5.2
Release: 1
License: Apache Software License
Group: System Environment/Libraries
@ -76,7 +76,7 @@ rm -rf $RPM_BUILD_ROOT
%defattr(-,root,root,-)
%doc docs/APRDesign.html docs/canonical_filenames.html
%doc docs/incomplete_types docs/non_apr_programs
%doc --parents html
%doc html
%{_bindir}/apr*config
%{_libdir}/libapr-%{aprver}.*a
%{_libdir}/libapr-%{aprver}.so

View File

@ -251,7 +251,7 @@ file_io/win32/filestat.lo: file_io/win32/filestat.c .make.dirs include/apr_alloc
file_io/win32/filesys.lo: file_io/win32/filesys.c .make.dirs include/apr_allocator.h include/apr_errno.h include/apr_general.h include/apr_pools.h include/apr_strings.h include/apr_thread_mutex.h include/apr_want.h
file_io/win32/flock.lo: file_io/win32/flock.c .make.dirs
file_io/win32/open.lo: file_io/win32/open.c .make.dirs include/apr_allocator.h include/apr_dso.h include/apr_errno.h include/apr_file_info.h include/apr_file_io.h include/apr_general.h include/apr_global_mutex.h include/apr_inherit.h include/apr_network_io.h include/apr_pools.h include/apr_portable.h include/apr_proc_mutex.h include/apr_shm.h include/apr_strings.h include/apr_tables.h include/apr_thread_mutex.h include/apr_thread_proc.h include/apr_time.h include/apr_user.h include/apr_want.h
file_io/win32/pipe.lo: file_io/win32/pipe.c .make.dirs include/apr_allocator.h include/apr_errno.h include/apr_file_info.h include/apr_file_io.h include/apr_general.h include/apr_inherit.h include/apr_pools.h include/apr_strings.h include/apr_tables.h include/apr_thread_mutex.h include/apr_time.h include/apr_user.h include/apr_want.h
file_io/win32/pipe.lo: file_io/win32/pipe.c .make.dirs include/apr_allocator.h include/apr_errno.h include/apr_escape.h include/apr_file_info.h include/apr_file_io.h include/apr_general.h include/apr_inherit.h include/apr_pools.h include/apr_strings.h include/apr_tables.h include/apr_thread_mutex.h include/apr_time.h include/apr_user.h include/apr_want.h
file_io/win32/readwrite.lo: file_io/win32/readwrite.c .make.dirs include/apr_allocator.h include/apr_errno.h include/apr_file_info.h include/apr_file_io.h include/apr_general.h include/apr_inherit.h include/apr_lib.h include/apr_pools.h include/apr_strings.h include/apr_tables.h include/apr_thread_mutex.h include/apr_time.h include/apr_user.h include/apr_want.h
file_io/win32/seek.lo: file_io/win32/seek.c .make.dirs include/apr_allocator.h include/apr_errno.h include/apr_file_info.h include/apr_file_io.h include/apr_general.h include/apr_inherit.h include/apr_pools.h include/apr_tables.h include/apr_thread_mutex.h include/apr_time.h include/apr_user.h include/apr_want.h

73
contrib/apr/configure vendored
View File

@ -6802,10 +6802,10 @@ if test "x$apr_preload_done" != "xyes" ; then
*-apple-darwin*)
if test "x$CPPFLAGS" = "x"; then
test "x$silent" != "xyes" && echo " setting CPPFLAGS to \"-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -no-cpp-precomp\""
CPPFLAGS="-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -no-cpp-precomp"
test "x$silent" != "xyes" && echo " setting CPPFLAGS to \"-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK\""
CPPFLAGS="-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK"
else
apr_addto_bugger="-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -no-cpp-precomp"
apr_addto_bugger="-DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK"
for i in $apr_addto_bugger; do
apr_addto_duplicate="0"
for j in $CPPFLAGS; do
@ -18794,7 +18794,34 @@ if test "${enable_nonportable_atomics+set}" = set; then :
else
case $host_cpu in
i[456]86) force_generic_atomics=yes ;;
*) force_generic_atomics=no ;;
*) force_generic_atomics=no
case $host in
*solaris2.10*)
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <atomic.h>
int
main ()
{
void *ptr = NULL; atomic_cas_ptr(&ptr, NULL, NULL);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
else
force_generic_atomics=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
if test $force_generic_atomics = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: nonportable atomic support disabled, system needs Patch-ID 118884 or 118885" >&5
$as_echo "$as_me: nonportable atomic support disabled, system needs Patch-ID 118884 or 118885" >&6;}
fi
;;
esac
;;
esac
fi
@ -22292,7 +22319,7 @@ else
fi
done
for ac_func in getpass getpassphrase gmtime_r localtime_r mkstemp
for ac_func in getpass getpassphrase gmtime_r localtime_r
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -22304,6 +22331,23 @@ _ACEOF
fi
done
case $host in
*-hp-hpux*)
;;
*)
for ac_func in mkstemp
do :
ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp"
if test "x$ac_cv_func_mkstemp" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_MKSTEMP 1
_ACEOF
fi
done
;;
esac
@ -23902,7 +23946,7 @@ _ACEOF
if test "${ac_cv_sizeof_off_t}${apr_cv_use_lfs64}" = "4yes"; then
# Enable LFS
aprlfs=1
for ac_func in mmap64 sendfile64 sendfilev64 mkstemp64 readdir64_r
for ac_func in mmap64 sendfile64 sendfilev64 readdir64_r
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -23914,6 +23958,23 @@ _ACEOF
fi
done
case $host in
*-hp-hpux*)
;;
*)
for ac_func in mkstemp64
do :
ac_fn_c_check_func "$LINENO" "mkstemp64" "ac_cv_func_mkstemp64"
if test "x$ac_cv_func_mkstemp64" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_MKSTEMP64 1
_ACEOF
fi
done
;;
esac
elif test "${ac_cv_sizeof_off_t}" != "${ac_cv_sizeof_size_t}"; then
# unsure of using -gt above is as portable, can can't forsee where
# off_t can legitimately be smaller than size_t

View File

@ -640,7 +640,20 @@ AC_ARG_ENABLE(nonportable-atomics,
],
[case $host_cpu in
i[[456]]86) force_generic_atomics=yes ;;
*) force_generic_atomics=no ;;
*) force_generic_atomics=no
case $host in
*solaris2.10*)
AC_TRY_COMPILE(
[#include <atomic.h>],
[void *ptr = NULL; atomic_cas_ptr(&ptr, NULL, NULL);],,
[force_generic_atomics=yes]
)
if test $force_generic_atomics = yes; then
AC_MSG_NOTICE([nonportable atomic support disabled, system needs Patch-ID 118884 or 118885])
fi
;;
esac
;;
esac
])
@ -1400,7 +1413,15 @@ if test "$native_mmap_emul" = "1"; then
mmap="1"
fi
AC_CHECK_FUNCS(memmove, [ have_memmove="1" ], [have_memmove="0" ])
AC_CHECK_FUNCS([getpass getpassphrase gmtime_r localtime_r mkstemp])
AC_CHECK_FUNCS([getpass getpassphrase gmtime_r localtime_r])
case $host in
*-hp-hpux*)
dnl mkstemp is limited to 26 temporary files (a-z); use APR replacement
;;
*)
AC_CHECK_FUNCS(mkstemp)
;;
esac
AC_SUBST(fork)
AC_SUBST(have_inet_addr)
@ -1801,7 +1822,15 @@ APR_CHECK_SIZEOF_EXTENDED([#include <sys/types.h>], off_t, 8)
if test "${ac_cv_sizeof_off_t}${apr_cv_use_lfs64}" = "4yes"; then
# Enable LFS
aprlfs=1
AC_CHECK_FUNCS([mmap64 sendfile64 sendfilev64 mkstemp64 readdir64_r])
AC_CHECK_FUNCS([mmap64 sendfile64 sendfilev64 readdir64_r])
case $host in
*-hp-hpux*)
dnl mkstemp64 is limited to 26 temporary files (a-z); use APR replacement
;;
*)
AC_CHECK_FUNCS(mkstemp64)
;;
esac
elif test "${ac_cv_sizeof_off_t}" != "${ac_cv_sizeof_size_t}"; then
# unsure of using -gt above is as portable, can can't forsee where
# off_t can legitimately be smaller than size_t

View File

@ -436,6 +436,8 @@ APR_DECLARE(apr_status_t) apr_escape_path(char *escaped, const char *path,
while ((c = *s) && slen) {
if (TEST_CHAR(c, T_OS_ESCAPE_PATH)) {
d = c2x(c, '%', d);
size += 2;
found = 1;
}
else {
*d++ = c;

View File

@ -40,7 +40,9 @@ extern "C" {
/**
* apr_skiplist_compare is the function type that must be implemented
* per object type that is used in a skip list for comparisons to maintain
* order
* order. A value <0 indicates placement after this node; a value of 0
* indicates collision with this exact node; a value >0 indicates placement
* before this node.
* */
typedef int (*apr_skiplist_compare) (void *, void *);
@ -171,7 +173,8 @@ APR_DECLARE(void *) apr_skiplist_next(apr_skiplist *sl, apr_skiplistnode **iter)
APR_DECLARE(void *) apr_skiplist_previous(apr_skiplist *sl, apr_skiplistnode **iter);
/**
* Insert an element into the skip list using the specified comparison function.
* Insert an element into the skip list using the specified comparison function
* if it does not already exist.
* @param sl The skip list
* @param data The element to insert
* @param comp The comparison function to use for placement into the skip list
@ -180,7 +183,8 @@ APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl,
void *data, apr_skiplist_compare comp);
/**
* Insert an element into the skip list using the existing comparison function.
* Insert an element into the skip list using the existing comparison function
* if it does not already exist (as determined by the comparison function)
* @param sl The skip list
* @param data The element to insert
* @remark If no comparison function has been set for the skip list, the element
@ -190,7 +194,7 @@ APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert(apr_skiplist* sl, void *data
/**
* Remove an element from the skip list using the specified comparison function for
* locating the element.
* locating the element. In the case of duplicates, the 1st entry will be removed.
* @param sl The skip list
* @param data The element to remove
* @param myfree A function to be called for each removed element
@ -203,7 +207,7 @@ APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sl, void *data,
/**
* Remove an element from the skip list using the existing comparison function for
* locating the element.
* locating the element. In the case of duplicates, the 1st entry will be removed.
* @param sl The skip list
* @param data The element to remove
* @param myfree A function to be called for each removed element
@ -229,7 +233,7 @@ APR_DECLARE(void) apr_skiplist_remove_all(apr_skiplist *sl, apr_skiplist_freefun
APR_DECLARE(void) apr_skiplist_destroy(apr_skiplist *sl, apr_skiplist_freefunc myfree);
/**
* Return the first element in the skip list, leaving the element in the skip list.
* Return the first element in the skip list, removing the element from the skip list.
* @param sl The skip list
* @param myfree A function to be called for the removed element
* @remark NULL will be returned if there are no elements

View File

@ -38,7 +38,7 @@
*/
#define APR_COPYRIGHT "Copyright (c) 2000-2014 The Apache Software " \
#define APR_COPYRIGHT "Copyright (c) 2000-2015 The Apache Software " \
"Foundation or its licensors, as applicable."
/* The numeric compile-time version constants. These constants are the
@ -62,7 +62,7 @@
* The Patch Level never includes API changes, simply bug fixes.
* Reset to 0 when upgrading APR_MINOR_VERSION
*/
#define APR_PATCH_VERSION 1
#define APR_PATCH_VERSION 2
/**
* The symbol APR_IS_DEV_VERSION is only defined for internal,

View File

@ -765,7 +765,7 @@ SOURCE=.\include\apr_escape.h
# Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
InputPath=.\include\apr_escape.h
".\Release\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
cl.exe /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\Release\gen_test_char /Fe.\Release\gen_test_char.exe .\tools\gen_test_char.c
.\Release\gen_test_char.exe > .\include\apr_escape_test_char.h
@ -776,7 +776,7 @@ InputPath=.\include\apr_escape.h
# Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
InputPath=.\include\apr_escape.h
".\Debug\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
cl.exe /nologo /W3 /EHsc /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\Debug\gen_test_char /Fe.\Debug\gen_test_char.exe .\tools\gen_test_char.c
.\Debug\gen_test_char.exe > .\include\apr_escape_test_char.h
@ -787,7 +787,7 @@ InputPath=.\include\apr_escape.h
# Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
InputPath=.\include\apr_escape.h
".\9x\Release\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
cl.exe /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\9x\Release\gen_test_char /Fe.\9x\Release\gen_test_char.exe .\tools\gen_test_char.c
.\9x\Release\gen_test_char.exe > .\include\apr_escape_test_char.h
@ -798,7 +798,7 @@ InputPath=.\include\apr_escape.h
# Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
InputPath=.\include\apr_escape.h
".\9x\Debug\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
cl.exe /nologo /W3 /EHsc /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\9x\Debug\gen_test_char /Fe.\9x\Debug\gen_test_char.exe .\tools\gen_test_char.c
.\9x\Debug\gen_test_char.exe > .\include\apr_escape_test_char.h
@ -809,7 +809,7 @@ InputPath=.\include\apr_escape.h
# Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
InputPath=.\include\apr_escape.h
".\x64\Release\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
cl.exe /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\x64\Release\gen_test_char /Fe.\x64\Release\gen_test_char.exe .\tools\gen_test_char.c
.\x64\Release\gen_test_char.exe > .\include\apr_escape_test_char.h
@ -820,7 +820,7 @@ InputPath=.\include\apr_escape.h
# Begin Custom Build - Creating gen_test_char.exe and apr_escape_test_char.h
InputPath=.\include\apr_escape.h
".\x64\Debug\gen_test_char.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
cl.exe /nologo /W3 /EHsc /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /I ".\include" /Fo.\x64\Debug\gen_test_char /Fe.\x64\Debug\gen_test_char.exe .\tools\gen_test_char.c
.\x64\Debug\gen_test_char.exe > .\include\apr_escape_test_char.h
@ -952,69 +952,6 @@ SOURCE=.\include\apr_version.h
# Begin Source File
SOURCE=.\include\apr_want.h
!IF "$(CFG)" == "libapr - Win32 Release"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ELSEIF "$(CFG)" == "libapr - Win32 Debug"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ELSEIF "$(CFG)" == "libapr - Win32 Release9x"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ELSEIF "$(CFG)" == "libapr - Win32 Debug9x"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ELSEIF "$(CFG)" == "libapr - x64 Release"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ELSEIF "$(CFG)" == "libapr - x64 Debug"
# Begin Custom Build
InputPath=.\include\apr_want.h
".\include\apr_escape_test_char.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
type .\include\apr.hw > .\include\apr.h
# End Custom Build
!ENDIF
# End Source File
# End Group
# Begin Source File

View File

@ -114,7 +114,9 @@ static apr_status_t proc_mutex_posix_create(apr_proc_mutex_t *new_mutex,
usec = apr_time_usec(now);
apr_snprintf(semname, sizeof(semname), "/ApR.%lxZ%lx", sec, usec);
}
psem = sem_open(semname, O_CREAT | O_EXCL, 0644, 1);
do {
psem = sem_open(semname, O_CREAT | O_EXCL, 0644, 1);
} while (psem == (sem_t *)SEM_FAILED && errno == EINTR);
if (psem == (sem_t *)SEM_FAILED) {
if (errno == ENAMETOOLONG) {
/* Oh well, good try */
@ -122,7 +124,9 @@ static apr_status_t proc_mutex_posix_create(apr_proc_mutex_t *new_mutex,
} else {
return errno;
}
psem = sem_open(semname, O_CREAT | O_EXCL, 0644, 1);
do {
psem = sem_open(semname, O_CREAT | O_EXCL, 0644, 1);
} while (psem == (sem_t *)SEM_FAILED && errno == EINTR);
}
if (psem == (sem_t *)SEM_FAILED) {
@ -140,7 +144,12 @@ static apr_status_t proc_mutex_posix_create(apr_proc_mutex_t *new_mutex,
static apr_status_t proc_mutex_posix_acquire(apr_proc_mutex_t *mutex)
{
if (sem_wait(mutex->psem_interproc) < 0) {
int rc;
do {
rc = sem_wait(mutex->psem_interproc);
} while (rc < 0 && errno == EINTR);
if (rc < 0) {
return errno;
}
mutex->curr_locked = 1;
@ -149,7 +158,12 @@ static apr_status_t proc_mutex_posix_acquire(apr_proc_mutex_t *mutex)
static apr_status_t proc_mutex_posix_tryacquire(apr_proc_mutex_t *mutex)
{
if (sem_trywait(mutex->psem_interproc) < 0) {
int rc;
do {
rc = sem_trywait(mutex->psem_interproc);
} while (rc < 0 && errno == EINTR);
if (rc < 0) {
if (errno == EAGAIN) {
return APR_EBUSY;
}

View File

@ -1135,21 +1135,12 @@ APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *pool, const char *fmt, va_list ap)
* room to hold the NUL terminator.
*/
if (ps.node->first_avail == ps.node->endp) {
if (psprintf_flush(&ps.vbuff) == -1) {
if (pool->abort_fn) {
pool->abort_fn(APR_ENOMEM);
}
return NULL;
}
if (psprintf_flush(&ps.vbuff) == -1)
goto error;
}
if (apr_vformatter(psprintf_flush, &ps.vbuff, fmt, ap) == -1) {
if (pool->abort_fn)
pool->abort_fn(APR_ENOMEM);
return NULL;
}
if (apr_vformatter(psprintf_flush, &ps.vbuff, fmt, ap) == -1)
goto error;
strp = ps.vbuff.curpos;
*strp++ = '\0';
@ -1195,6 +1186,15 @@ APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *pool, const char *fmt, va_list ap)
list_insert(active, node);
return strp;
error:
if (pool->abort_fn)
pool->abort_fn(APR_ENOMEM);
if (ps.got_a_new_node) {
ps.node->next = ps.free;
allocator_free(pool->allocator, ps.node);
}
return NULL;
}

View File

@ -39,6 +39,8 @@ static char *stuffbuffer(char *buf, apr_size_t bufsize, const char *s)
static char *apr_error_string(apr_status_t statcode)
{
switch (statcode) {
case APR_ENOSTAT:
return "Could not perform a stat on the file.";
case APR_ENOPOOL:
return "A new pool could not be created.";
case APR_EBADDATE:
@ -73,7 +75,10 @@ static char *apr_error_string(apr_status_t statcode)
return "The specified IP address is invalid.";
case APR_EBADMASK:
return "The specified network mask is invalid.";
case APR_ESYMNOTFOUND:
return "Could not find the requested symbol.";
case APR_ENOTENOUGHENTROPY:
return "Not enough entropy to continue.";
case APR_INCHILD:
return
"Your code just forked, and you are currently executing in the "
@ -128,10 +133,12 @@ static char *apr_error_string(apr_status_t statcode)
return "The given path is misformatted or contained invalid characters";
case APR_EPATHWILD:
return "The given path contained wildcard characters";
case APR_EBUSY:
return "The given lock was busy.";
case APR_EPROC_UNKNOWN:
return "The process is not recognized.";
case APR_EGENERAL:
return "Internal error";
return "Internal error (specific information not available)";
default:
return "Error string not specified yet";
}

View File

@ -325,6 +325,16 @@ static apr_status_t call_resolver(apr_sockaddr_t **sa,
hints.ai_flags = AI_ADDRCONFIG;
}
#endif
#ifdef __MVS__
/* z/OS will not return IPv4 address under AF_UNSPEC if any IPv6 results
* are returned, w/o AI_ALL.
*/
if (family == APR_UNSPEC) {
hints.ai_flags |= AI_ALL;
}
#endif
if(hostname == NULL) {
#ifdef AI_PASSIVE
/* If hostname is NULL, assume we are trying to bind to all

View File

@ -145,13 +145,22 @@ apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type,
#ifndef HAVE_SOCK_CLOEXEC
{
int flags;
apr_status_t rv;
if ((flags = fcntl((*new)->socketdes, F_GETFD)) == -1)
return errno;
if ((flags = fcntl((*new)->socketdes, F_GETFD)) == -1) {
rv = errno;
close((*new)->socketdes);
(*new)->socketdes = -1;
return rv;
}
flags |= FD_CLOEXEC;
if (fcntl((*new)->socketdes, F_SETFD, flags) == -1)
return errno;
if (fcntl((*new)->socketdes, F_SETFD, flags) == -1) {
rv = errno;
close((*new)->socketdes);
(*new)->socketdes = -1;
return rv;
}
}
#endif
@ -306,13 +315,22 @@ apr_status_t apr_socket_accept(apr_socket_t **new, apr_socket_t *sock,
#ifndef HAVE_ACCEPT4
{
int flags;
apr_status_t rv;
if ((flags = fcntl((*new)->socketdes, F_GETFD)) == -1)
return errno;
if ((flags = fcntl((*new)->socketdes, F_GETFD)) == -1) {
rv = errno;
close((*new)->socketdes);
(*new)->socketdes = -1;
return rv;
}
flags |= FD_CLOEXEC;
if (fcntl((*new)->socketdes, F_SETFD, flags) == -1)
return errno;
if (fcntl((*new)->socketdes, F_SETFD, flags) == -1) {
rv = errno;
close((*new)->socketdes);
(*new)->socketdes = -1;
return rv;
}
}
#endif

View File

@ -104,14 +104,22 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
#ifndef HAVE_EPOLL_CREATE1
{
int flags;
int fd_flags;
if ((flags = fcntl(fd, F_GETFD)) == -1)
return errno;
if ((fd_flags = fcntl(fd, F_GETFD)) == -1) {
rv = errno;
close(fd);
pollset->p = NULL;
return rv;
}
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1)
return errno;
fd_flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, fd_flags) == -1) {
rv = errno;
close(fd);
pollset->p = NULL;
return rv;
}
}
#endif
@ -122,11 +130,13 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
((rv = apr_thread_mutex_create(&pollset->p->ring_lock,
APR_THREAD_MUTEX_DEFAULT,
p)) != APR_SUCCESS)) {
close(fd);
pollset->p = NULL;
return rv;
}
#else
if (flags & APR_POLLSET_THREADSAFE) {
close(fd);
pollset->p = NULL;
return APR_ENOTIMPL;
}
@ -345,14 +355,23 @@ static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
#ifndef HAVE_EPOLL_CREATE1
{
int flags;
int fd_flags;
apr_status_t rv;
if ((flags = fcntl(fd, F_GETFD)) == -1)
return errno;
if ((fd_flags = fcntl(fd, F_GETFD)) == -1) {
rv = errno;
close(fd);
pollcb->fd = -1;
return rv;
}
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1)
return errno;
fd_flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, fd_flags) == -1) {
rv = errno;
close(fd);
pollcb->fd = -1;
return rv;
}
}
#endif

View File

@ -115,12 +115,20 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
{
int flags;
if ((flags = fcntl(pollset->p->kqueue_fd, F_GETFD)) == -1)
return errno;
if ((flags = fcntl(pollset->p->kqueue_fd, F_GETFD)) == -1) {
rv = errno;
close(pollset->p->kqueue_fd);
pollset->p = NULL;
return rv;
}
flags |= FD_CLOEXEC;
if (fcntl(pollset->p->kqueue_fd, F_SETFD, flags) == -1)
return errno;
if (fcntl(pollset->p->kqueue_fd, F_SETFD, flags) == -1) {
rv = errno;
close(pollset->p->kqueue_fd);
pollset->p = NULL;
return rv;
}
}
pollset->p->result_set = apr_palloc(p, pollset->p->setsize * sizeof(apr_pollfd_t));
@ -338,13 +346,22 @@ static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
{
int flags;
apr_status_t rv;
if ((flags = fcntl(fd, F_GETFD)) == -1)
return errno;
if ((flags = fcntl(fd, F_GETFD)) == -1) {
rv = errno;
close(fd);
pollcb->fd = -1;
return rv;
}
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1)
return errno;
if (fcntl(fd, F_SETFD, flags) == -1) {
rv = errno;
close(fd);
pollcb->fd = -1;
return rv;
}
}
pollcb->fd = fd;

View File

@ -240,26 +240,25 @@ static apr_status_t impl_pollset_poll(apr_pollset_t *pollset,
{
int ret;
apr_status_t rv = APR_SUCCESS;
#ifdef WIN32
apr_interval_time_t orig_timeout = timeout;
#endif
if (timeout > 0) {
timeout /= 1000;
}
#ifdef WIN32
/* WSAPoll() requires at least one socket. */
if (pollset->nelts == 0) {
*num = 0;
if (orig_timeout > 0) {
apr_sleep(orig_timeout);
if (timeout > 0) {
apr_sleep(timeout);
return APR_TIMEUP;
}
return APR_SUCCESS;
}
if (timeout > 0) {
timeout /= 1000;
}
ret = WSAPoll(pollset->p->pollset, pollset->nelts, (int)timeout);
#else
if (timeout > 0) {
timeout /= 1000;
}
ret = poll(pollset->p->pollset, pollset->nelts, timeout);
#endif
(*num) = ret;
@ -398,12 +397,23 @@ static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb,
apr_status_t rv = APR_SUCCESS;
apr_uint32_t i;
#ifdef WIN32
/* WSAPoll() requires at least one socket. */
if (pollcb->nelts == 0) {
if (timeout > 0) {
apr_sleep(timeout);
return APR_TIMEUP;
}
return APR_SUCCESS;
}
if (timeout > 0) {
timeout /= 1000;
}
#ifdef WIN32
ret = WSAPoll(pollcb->pollset.ps, pollcb->nelts, (int)timeout);
#else
if (timeout > 0) {
timeout /= 1000;
}
ret = poll(pollcb->pollset.ps, pollcb->nelts, timeout);
#endif
if (ret < 0) {

View File

@ -136,6 +136,9 @@ APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb,
}
pollcb->provider = provider;
}
else if (rv != APR_SUCCESS) {
return rv;
}
*ret_pollcb = pollcb;
return APR_SUCCESS;

View File

@ -188,12 +188,20 @@ static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
{
int flags;
if ((flags = fcntl(pollset->p->port_fd, F_GETFD)) == -1)
return errno;
if ((flags = fcntl(pollset->p->port_fd, F_GETFD)) == -1) {
rv = errno;
close(pollset->p->port_fd);
pollset->p = NULL;
return rv;
}
flags |= FD_CLOEXEC;
if (fcntl(pollset->p->port_fd, F_SETFD, flags) == -1)
return errno;
if (fcntl(pollset->p->port_fd, F_SETFD, flags) == -1) {
rv = errno;
close(pollset->p->port_fd);
pollset->p = NULL;
return rv;
}
}
pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
@ -478,13 +486,22 @@ static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
{
int flags;
apr_status_t rv;
if ((flags = fcntl(pollcb->fd, F_GETFD)) == -1)
return errno;
if ((flags = fcntl(pollcb->fd, F_GETFD)) == -1) {
rv = errno;
close(pollcb->fd);
pollcb->fd = -1;
return rv;
}
flags |= FD_CLOEXEC;
if (fcntl(pollcb->fd, F_SETFD, flags) == -1)
return errno;
if (fcntl(pollcb->fd, F_SETFD, flags) == -1) {
rv = errno;
close(pollcb->fd);
pollcb->fd = -1;
return rv;
}
}
pollcb->pollset.port = apr_palloc(p, size * sizeof(port_event_t));

View File

@ -272,7 +272,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
APR_THREAD_MUTEX_DEFAULT,
p) != APR_SUCCESS) {
DBG1(1, "apr_thread_mutex_create returned %d\n", rv);
pollset = NULL;
pollset->p = NULL;
return rv;
}
rv = msgget(IPC_PRIVATE, S_IWUSR+S_IRUSR); /* user r/w perms */
@ -280,7 +280,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
#if DEBUG
perror(__FUNCTION__ " msgget returned < 0 ");
#endif
pollset = NULL;
pollset->p = NULL;
return rv;
}
@ -292,7 +292,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
APR_RING_INIT(&priv->prior_ready_ring, asio_elem_t, link);
#else /* APR doesn't have threads but caller wants a threadsafe pollset */
pollset = NULL;
pollset->p = NULL;
return APR_ENOTIMPL;
#endif
@ -304,6 +304,7 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
priv->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
if ((!priv->pollset) || (!priv->query_set)) {
pollset->p = NULL;
return APR_ENOMEM;
}
}
@ -314,6 +315,10 @@ static apr_status_t asio_pollset_create(apr_pollset_t *pollset,
priv->size = size;
priv->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
if (!priv->result_set) {
if (flags & APR_POLLSET_THREADSAFE) {
msgctl(priv->msg_q, IPC_RMID, NULL);
}
pollset->p = NULL;
return APR_ENOMEM;
}
@ -379,6 +384,7 @@ static apr_status_t asio_pollset_add(apr_pollset_t *pollset,
APR_RING_REMOVE(elem, link);
DBG1(3, "used recycled memory at %08p\n", elem);
elem->state = ASIO_INIT;
elem->a.aio_cflags = 0;
}
else {
elem = (asio_elem_t *) apr_pcalloc(pollset->pool, sizeof(asio_elem_t));
@ -659,6 +665,7 @@ static apr_status_t asio_pollset_poll(apr_pollset_t *pollset,
if (ret == 1) {
DBG(4, "asyncio() completed inline\n");
/* it's ready now */
elem->state = ASIO_COMPLETE;
APR_RING_INSERT_TAIL(&(priv->ready_ring), elem, asio_elem_t,
link);
}

View File

@ -25,12 +25,18 @@
#include "apr_skiplist.h"
typedef struct {
apr_skiplistnode **data;
size_t size, pos;
apr_pool_t *p;
} apr_skiplist_q;
struct apr_skiplist {
apr_skiplist_compare compare;
apr_skiplist_compare comparek;
int height;
int preheight;
int size;
size_t size;
apr_skiplistnode *top;
apr_skiplistnode *bottom;
/* These two are needed for appending */
@ -38,6 +44,8 @@ struct apr_skiplist {
apr_skiplistnode *bottomend;
apr_skiplist *index;
apr_array_header_t *memlist;
apr_skiplist_q nodes_q,
stack_q;
apr_pool_t *pool;
};
@ -52,20 +60,15 @@ struct apr_skiplistnode {
apr_skiplist *sl;
};
#ifndef MIN
#define MIN(a,b) ((a<b)?(a):(b))
#endif
static int get_b_rand(void)
{
static int ph = 32; /* More bits than we will ever use */
static apr_uint32_t randseq;
static int randseq;
if (ph > 31) { /* Num bits in return of rand() */
ph = 0;
randseq = (apr_uint32_t) rand();
randseq = rand();
}
ph++;
return ((randseq & (1 << (ph - 1))) >> (ph - 1));
return randseq & (1 << ph++);
}
typedef struct {
@ -103,7 +106,7 @@ APR_DECLARE(void *) apr_skiplist_alloc(apr_skiplist *sl, size_t size)
memlist++;
}
/* no free chunks */
ptr = apr_pcalloc(sl->pool, size);
ptr = apr_palloc(sl->pool, size);
if (!ptr) {
return ptr;
}
@ -122,7 +125,7 @@ APR_DECLARE(void *) apr_skiplist_alloc(apr_skiplist *sl, size_t size)
return ptr;
}
else {
return calloc(1, size);
return malloc(size);
}
}
@ -149,27 +152,73 @@ APR_DECLARE(void) apr_skiplist_free(apr_skiplist *sl, void *mem)
}
}
static apr_status_t skiplist_qpush(apr_skiplist_q *q, apr_skiplistnode *m)
{
if (q->pos >= q->size) {
apr_skiplistnode **data;
size_t size = (q->pos) ? q->pos * 2 : 32;
if (q->p) {
data = apr_palloc(q->p, size * sizeof(*data));
if (data) {
memcpy(data, q->data, q->pos * sizeof(*data));
}
}
else {
data = realloc(q->data, size * sizeof(*data));
}
if (!data) {
return APR_ENOMEM;
}
q->data = data;
q->size = size;
}
q->data[q->pos++] = m;
return APR_SUCCESS;
}
static APR_INLINE apr_skiplistnode *skiplist_qpop(apr_skiplist_q *q)
{
return (q->pos > 0) ? q->data[--q->pos] : NULL;
}
static APR_INLINE void skiplist_qclear(apr_skiplist_q *q)
{
q->pos = 0;
}
static apr_skiplistnode *skiplist_new_node(apr_skiplist *sl)
{
apr_skiplistnode *m = skiplist_qpop(&sl->nodes_q);
if (!m) {
if (sl->pool) {
m = apr_palloc(sl->pool, sizeof *m);
}
else {
m = malloc(sizeof *m);
}
}
return m;
}
static apr_status_t skiplist_free_node(apr_skiplist *sl, apr_skiplistnode *m)
{
return skiplist_qpush(&sl->nodes_q, m);
}
static apr_status_t skiplisti_init(apr_skiplist **s, apr_pool_t *p)
{
apr_skiplist *sl;
if (p) {
sl = apr_pcalloc(p, sizeof(apr_skiplist));
sl->memlist = apr_array_make(p, 20, sizeof(memlist_t));
sl->pool = sl->nodes_q.p = sl->stack_q.p = p;
}
else {
sl = calloc(1, sizeof(apr_skiplist));
if (!sl) {
return APR_ENOMEM;
}
}
#if 0
sl->compare = (apr_skiplist_compare) NULL;
sl->comparek = (apr_skiplist_compare) NULL;
sl->height = 0;
sl->preheight = 0;
sl->size = 0;
sl->top = NULL;
sl->bottom = NULL;
sl->index = NULL;
#endif
sl->pool = p;
*s = sl;
return APR_SUCCESS;
}
@ -248,56 +297,32 @@ APR_DECLARE(void) apr_skiplist_add_index(apr_skiplist *sl,
}
}
APR_DECLARE(apr_skiplistnode *) apr_skiplist_getlist(apr_skiplist *sl)
{
if (!sl->bottom) {
return NULL;
}
return sl->bottom->next;
}
APR_DECLARE(void *) apr_skiplist_find(apr_skiplist *sl, void *data, apr_skiplistnode **iter)
{
void *ret;
apr_skiplistnode *aiter;
if (!sl->compare) {
return 0;
}
if (iter) {
ret = apr_skiplist_find_compare(sl, data, iter, sl->compare);
}
else {
ret = apr_skiplist_find_compare(sl, data, &aiter, sl->compare);
}
return ret;
}
static int skiplisti_find_compare(apr_skiplist *sl, void *data,
apr_skiplistnode **ret,
apr_skiplist_compare comp)
{
apr_skiplistnode *m = NULL;
int count = 0;
apr_skiplistnode *m;
m = sl->top;
while (m) {
int compared;
compared = (m->next) ? comp(data, m->next->data) : -1;
if (compared == 0) {
m = m->next;
while (m->down) {
m = m->down;
if (m->next) {
int compared = comp(data, m->next->data);
if (compared == 0) {
m = m->next;
while (m->down) {
m = m->down;
}
*ret = m;
return count;
}
if (compared > 0) {
m = m->next;
count++;
continue;
}
*ret = m;
return count;
}
if ((m->next == NULL) || (compared < 0)) {
m = m->down;
count++;
}
else {
m = m->next;
count++;
}
m = m->down;
count++;
}
*ret = NULL;
return count;
@ -307,19 +332,47 @@ APR_DECLARE(void *) apr_skiplist_find_compare(apr_skiplist *sli, void *data,
apr_skiplistnode **iter,
apr_skiplist_compare comp)
{
apr_skiplistnode *m = NULL;
apr_skiplistnode *m;
apr_skiplist *sl;
if (!comp) {
if (iter) {
*iter = NULL;
}
return NULL;
}
if (comp == sli->compare || !sli->index) {
sl = sli;
}
else {
apr_skiplist_find(sli->index, (void *)comp, &m);
if (!m) {
if (iter) {
*iter = NULL;
}
return NULL;
}
sl = (apr_skiplist *) m->data;
}
skiplisti_find_compare(sl, data, iter, sl->comparek);
return (iter && *iter) ? ((*iter)->data) : NULL;
skiplisti_find_compare(sl, data, &m, sl->comparek);
if (iter) {
*iter = m;
}
return (m) ? m->data : NULL;
}
APR_DECLARE(void *) apr_skiplist_find(apr_skiplist *sl, void *data, apr_skiplistnode **iter)
{
return apr_skiplist_find_compare(sl, data, iter, sl->compare);
}
APR_DECLARE(apr_skiplistnode *) apr_skiplist_getlist(apr_skiplist *sl)
{
if (!sl->bottom) {
return NULL;
}
return sl->bottom->next;
}
APR_DECLARE(void *) apr_skiplist_next(apr_skiplist *sl, apr_skiplistnode **iter)
{
@ -339,98 +392,74 @@ APR_DECLARE(void *) apr_skiplist_previous(apr_skiplist *sl, apr_skiplistnode **i
return (*iter) ? ((*iter)->data) : NULL;
}
APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert(apr_skiplist *sl, void *data)
static APR_INLINE int skiplist_height(const apr_skiplist *sl)
{
if (!sl->compare) {
return 0;
}
return apr_skiplist_insert_compare(sl, data, sl->compare);
/* Skiplists (even empty) always have a top node, although this
* implementation defers its creation until the first insert, or
* deletes it with the last remove. We want the real height here.
*/
return sl->height ? sl->height : 1;
}
APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl, void *data,
apr_skiplist_compare comp)
{
apr_skiplistnode *m, *p, *tmp, *ret = NULL, **stack;
int nh = 1, ch, stacki;
if (!sl->top) {
sl->height = 1;
sl->topend = sl->bottomend = sl->top = sl->bottom =
(apr_skiplistnode *)apr_skiplist_alloc(sl, sizeof(apr_skiplistnode));
#if 0
sl->top->next = (apr_skiplistnode *)NULL;
sl->top->data = (apr_skiplistnode *)NULL;
sl->top->prev = (apr_skiplistnode *)NULL;
sl->top->up = (apr_skiplistnode *)NULL;
sl->top->down = (apr_skiplistnode *)NULL;
sl->top->nextindex = (apr_skiplistnode *)NULL;
sl->top->previndex = (apr_skiplistnode *)NULL;
#endif
sl->top->sl = sl;
apr_skiplistnode *m, *p, *tmp, *ret = NULL;
int ch, nh = 1;
if (!comp) {
return NULL;
}
ch = skiplist_height(sl);
if (sl->preheight) {
while (nh < sl->preheight && get_b_rand()) {
nh++;
}
}
else {
while (nh <= sl->height && get_b_rand()) {
while (nh <= ch && get_b_rand()) {
nh++;
}
}
/* Now we have the new height at which we wish to insert our new node */
/*
* Let us make sure that our tree is a least that tall (grow if
* necessary)
/* Now we have in nh the height at which we wish to insert our new node,
* and in ch the current height: don't create skip paths to the inserted
* element until the walk down through the tree (which decrements ch)
* reaches nh. From there, any walk down pushes the current node on a
* stack (the node(s) after which we would insert) to pop back through
* for insertion later.
*/
for (; sl->height < nh; sl->height++) {
sl->top->up =
(apr_skiplistnode *)apr_skiplist_alloc(sl, sizeof(apr_skiplistnode));
sl->top->up->down = sl->top;
sl->top = sl->topend = sl->top->up;
#if 0
sl->top->prev = sl->top->next = sl->top->nextindex =
sl->top->previndex = sl->top->up = NULL;
sl->top->data = NULL;
#endif
sl->top->sl = sl;
}
ch = sl->height;
/* Find the node (or node after which we would insert) */
/* Keep a stack to pop back through for insertion */
/* malloc() is OK since we free the temp stack */
m = sl->top;
stack = (apr_skiplistnode **)malloc(sizeof(apr_skiplistnode *) * (nh));
stacki = 0;
while (m) {
int compared = -1;
if (m->next) {
compared = comp(data, m->next->data);
}
if (compared == 0) {
free(stack); /* OK. was malloc'ed */
return 0;
}
if ((m->next == NULL) || (compared < 0)) {
if (ch <= nh) {
/* push on stack */
stack[stacki++] = m;
int compared = comp(data, m->next->data);
if (compared == 0) {
/* Keep the existing element(s) */
skiplist_qclear(&sl->stack_q);
return NULL;
}
if (compared > 0) {
m = m->next;
continue;
}
m = m->down;
ch--;
}
else {
m = m->next;
if (ch <= nh) {
/* push on stack */
skiplist_qpush(&sl->stack_q, m);
}
m = m->down;
ch--;
}
/* Pop the stack and insert nodes */
p = NULL;
for (; stacki > 0; stacki--) {
m = stack[stacki - 1];
tmp = (apr_skiplistnode *)apr_skiplist_alloc(sl, sizeof(apr_skiplistnode));
while ((m = skiplist_qpop(&sl->stack_q))) {
tmp = skiplist_new_node(sl);
tmp->next = m->next;
if (m->next) {
m->next->prev = tmp;
}
m->next = tmp;
tmp->prev = m;
tmp->up = NULL;
tmp->nextindex = tmp->previndex = NULL;
@ -438,17 +467,44 @@ APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl, vo
if (p) {
p->up = tmp;
}
else {
/* This sets ret to the bottom-most node we are inserting */
ret = tmp;
}
tmp->data = data;
tmp->sl = sl;
p = tmp;
}
/* Now we are sure the node is inserted, grow our tree to 'nh' tall */
for (; sl->height < nh; sl->height++) {
m = skiplist_new_node(sl);
tmp = skiplist_new_node(sl);
m->up = m->prev = m->nextindex = m->previndex = NULL;
m->next = tmp;
/* This sets ret to the bottom-most node we are inserting */
if (!p) {
m->down = sl->top;
m->data = NULL;
m->sl = sl;
if (sl->top) {
sl->top->up = m;
}
else {
sl->bottom = sl->bottomend = m;
}
sl->top = sl->topend = tmp->prev = m;
tmp->up = tmp->next = tmp->nextindex = tmp->previndex = NULL;
tmp->down = p;
tmp->data = data;
tmp->sl = sl;
if (p) {
p->up = tmp;
}
else {
/* This sets ret to the bottom-most node we are inserting */
ret = tmp;
sl->size++; /* this seems to go here got each element to be counted */
}
p = tmp;
}
free(stack); /* OK. was malloc'ed */
if (sl->index != NULL) {
/*
* this is a external insertion, we must insert into each index as
@ -457,25 +513,20 @@ APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert_compare(apr_skiplist *sl, vo
apr_skiplistnode *ni, *li;
li = ret;
for (p = apr_skiplist_getlist(sl->index); p; apr_skiplist_next(sl->index, &p)) {
ni = apr_skiplist_insert((apr_skiplist *) p->data, ret->data);
apr_skiplist *sli = (apr_skiplist *)p->data;
ni = apr_skiplist_insert_compare(sli, ret->data, sli->compare);
li->nextindex = ni;
ni->previndex = li;
li = ni;
}
}
else {
/* sl->size++; */
}
sl->size++;
return ret;
}
APR_DECLARE(int) apr_skiplist_remove(apr_skiplist *sl, void *data, apr_skiplist_freefunc myfree)
APR_DECLARE(apr_skiplistnode *) apr_skiplist_insert(apr_skiplist *sl, void *data)
{
if (!sl->compare) {
return 0;
}
return apr_skiplist_remove_compare(sl, data, myfree, sl->comparek);
return apr_skiplist_insert_compare(sl, data, sl->compare);
}
#if 0
@ -520,7 +571,7 @@ static int skiplisti_remove(apr_skiplist *sl, apr_skiplistnode *m, apr_skiplist_
if (!m && myfree && p->data) {
myfree(p->data);
}
apr_skiplist_free(sl, p);
skiplist_free_node(sl, p);
}
sl->size--;
while (sl->top && sl->top->next == NULL) {
@ -530,13 +581,14 @@ static int skiplisti_remove(apr_skiplist *sl, apr_skiplistnode *m, apr_skiplist_
if (sl->top) {
sl->top->up = NULL; /* Make it think its the top */
}
apr_skiplist_free(sl, p);
skiplist_free_node(sl, p);
sl->height--;
}
if (!sl->top) {
sl->bottom = NULL;
sl->bottom = sl->bottomend = NULL;
sl->topend = NULL;
}
return sl->height; /* return 1; ?? */
return skiplist_height(sl);
}
APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sli,
@ -545,11 +597,17 @@ APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sli,
{
apr_skiplistnode *m;
apr_skiplist *sl;
if (!comp) {
return 0;
}
if (comp == sli->comparek || !sli->index) {
sl = sli;
}
else {
apr_skiplist_find(sli->index, (void *)comp, &m);
if (!m) {
return 0;
}
sl = (apr_skiplist *) m->data;
}
skiplisti_find_compare(sl, data, &m, comp);
@ -562,6 +620,11 @@ APR_DECLARE(int) apr_skiplist_remove_compare(apr_skiplist *sli,
return skiplisti_remove(sl, m, myfree);
}
APR_DECLARE(int) apr_skiplist_remove(apr_skiplist *sl, void *data, apr_skiplist_freefunc myfree)
{
return apr_skiplist_remove_compare(sl, data, myfree, sl->comparek);
}
APR_DECLARE(void) apr_skiplist_remove_all(apr_skiplist *sl, apr_skiplist_freefunc myfree)
{
/*
@ -573,16 +636,18 @@ APR_DECLARE(void) apr_skiplist_remove_all(apr_skiplist *sl, apr_skiplist_freefun
m = sl->bottom;
while (m) {
p = m->next;
if (p && myfree && p->data)
if (myfree && p && p->data) {
myfree(p->data);
while (m) {
u = m->up;
apr_skiplist_free(sl, p);
m = u;
}
do {
u = m->up;
skiplist_free_node(sl, m);
m = u;
} while (m);
m = p;
}
sl->top = sl->bottom = NULL;
sl->topend = sl->bottomend = NULL;
sl->height = 0;
sl->size = 0;
}
@ -611,8 +676,7 @@ APR_DECLARE(void *) apr_skiplist_peek(apr_skiplist *a)
static void skiplisti_destroy(void *vsl)
{
apr_skiplist_destroy((apr_skiplist *) vsl, NULL);
apr_skiplist_free((apr_skiplist *) vsl, vsl);
apr_skiplist_destroy(vsl, NULL);
}
APR_DECLARE(void) apr_skiplist_destroy(apr_skiplist *sl, apr_skiplist_freefunc myfree)
@ -620,6 +684,13 @@ APR_DECLARE(void) apr_skiplist_destroy(apr_skiplist *sl, apr_skiplist_freefunc m
while (apr_skiplist_pop(sl->index, skiplisti_destroy) != NULL)
;
apr_skiplist_remove_all(sl, myfree);
if (!sl->pool) {
while (sl->nodes_q.pos)
free(sl->nodes_q.data[--sl->nodes_q.pos]);
free(sl->nodes_q.data);
free(sl->stack_q.data);
free(sl);
}
}
APR_DECLARE(apr_skiplist *) apr_skiplist_merge(apr_skiplist *sl1, apr_skiplist *sl2)

View File

@ -914,8 +914,8 @@ fits_in_signed_long (offsetT num ATTRIBUTE_UNUSED)
#ifndef BFD64
return 1;
#else
return (!(((offsetT) -1 << 31) & num)
|| (((offsetT) -1 << 31) & num) == ((offsetT) -1 << 31));
return (!(-((offsetT) 1 << 31) & num)
|| (-((offsetT) 1 << 31) & num) == -((offsetT) 1 << 31));
#endif
} /* fits_in_signed_long() */

View File

@ -52,7 +52,7 @@
# $SB/obj-i386/bsd/gnu/lib/csu
# $SB/obj-i386/bsd/gnu/lib/libgcc
# $SB/obj-i386/bsd/include
# $SB/obj-i386/bsd/lib/csu/i386-elf
# $SB/obj-i386/bsd/lib/csu/i386
# $SB/obj-i386/bsd/lib/libc
# $SB/src/bsd/include
# $SB/src/bsd/sys/i386/include

View File

@ -151,7 +151,7 @@ int
op_ip(struct snmp_context *ctx, struct snmp_value *value,
u_int sub, u_int idx __unused, enum snmp_op op)
{
int old;
int old = 0;
switch (op) {

View File

@ -0,0 +1,35 @@
# $Id: Makefile 3107 2014-12-20 08:31:58Z kaiwang27 $
TOP= ..
PROG= ar
SRCS= ar.c read.c util.c write.c
LSRC= acplex.l
YSRC= acpyacc.y
WARNS?= 5
DPADD= ${LIBARCHIVE} ${LIBELFTC} ${LIBELF} ${LIBZ}
LDADD= -larchive -lelftc -lelf -lz
CFLAGS+=-I. -I${.CURDIR}
LINKS= ${BINDIR}/ar ${BINDIR}/ranlib
EXTRA_TARGETS= ranlib
CLEANFILES+= ${EXTRA_TARGETS}
MAN= ar.1 ranlib.1 ar.5
all: ${EXTRA_TARGETS}
${EXTRA_TARGETS}: ${PROG}
ln -s ${PROG} ${.TARGET}
.include "${TOP}/mk/elftoolchain.prog.mk"
.if ${OS_HOST} == "OpenBSD"
CFLAGS+= -I/usr/local/include
LDFLAGS+= -L/usr/local/lib
.endif

View File

@ -0,0 +1,83 @@
%{
/*-
* Copyright (c) 2008 Kai Wang
* 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
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) 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 <err.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "_elftc.h"
ELFTC_VCSID("$Id: acplex.l 3174 2015-03-27 17:13:41Z emaste $");
#include "acpyacc.h"
#define YY_NO_UNPUT
#if !defined(ELFTC_BROKEN_YY_NO_INPUT)
#define YY_NO_INPUT
#endif
int lineno = 1;
int yylex(void);
%}
%option nounput
%option noyywrap
%%
ADDLIB|addlib { return (ADDLIB); }
ADDMOD|addmod { return (ADDMOD); }
CLEAR|clear { return (CLEAR); }
CREATE|create { return (CREATE); }
DELETE|delete { return (DELETE); }
DIRECTORY|directory { return (DIRECTORY); }
END|end { return (END); }
EXTRACT|extract { return (EXTRACT); }
LIST|list { return (LIST); }
OPEN|open { return (OPEN); }
REPLACE|replace { return (REPLACE); }
VERBOSE|verbose { return (VERBOSE); }
SAVE|save { return (SAVE); }
"(" { return (LP); }
")" { return (RP); }
"," { return (COMMA); }
[-_A-Za-z0-9/:$.\\]+ {
yylval.str = strdup(yytext);
if (yylval.str == NULL)
err(EXIT_FAILURE, "strdup failed");
return (FNAME);
}
[ \t] /* whitespace */
"*".* /* comment */
";".* /* comment */
"+\n" { lineno++; /* '+' is line continuation char */ }
"\n" { lineno++; return (EOL); }

View File

@ -0,0 +1,658 @@
%{
/*-
* Copyright (c) 2008 Kai Wang
* 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
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <archive.h>
#include <archive_entry.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "libelftc.h"
#include "ar.h"
ELFTC_VCSID("$Id");
#define TEMPLATE "arscp.XXXXXXXX"
struct list {
char *str;
struct list *next;
};
extern int yylex(void);
extern int yyparse(void);
static void yyerror(const char *);
static void arscp_addlib(char *archive, struct list *list);
static void arscp_addmod(struct list *list);
static void arscp_clear(void);
static void arscp_create(char *in, char *out);
static void arscp_delete(struct list *list);
static void arscp_dir(char *archive, struct list *list, char *rlt);
static void arscp_end(int eval);
static void arscp_extract(struct list *list);
static void arscp_free_argv(void);
static void arscp_free_mlist(struct list *list);
static void arscp_list(void);
static struct list *arscp_mlist(struct list *list, char *str);
static void arscp_mlist2argv(struct list *list);
static int arscp_mlist_len(struct list *list);
static void arscp_open(char *fname);
static void arscp_prompt(void);
static void arscp_replace(struct list *list);
static void arscp_save(void);
static int arscp_target_exist(void);
extern int lineno;
static struct bsdar *bsdar;
static char *target;
static char *tmpac;
static int interactive;
static int verbose;
%}
%token ADDLIB
%token ADDMOD
%token CLEAR
%token CREATE
%token DELETE
%token DIRECTORY
%token END
%token EXTRACT
%token LIST
%token OPEN
%token REPLACE
%token VERBOSE
%token SAVE
%token LP
%token RP
%token COMMA
%token EOL
%token <str> FNAME
%type <list> mod_list
%union {
char *str;
struct list *list;
}
%%
begin
: { arscp_prompt(); } ar_script
;
ar_script
: cmd_list
|
;
mod_list
: FNAME { $$ = arscp_mlist(NULL, $1); }
| mod_list separator FNAME { $$ = arscp_mlist($1, $3); }
;
separator
: COMMA
|
;
cmd_list
: rawcmd
| cmd_list rawcmd
;
rawcmd
: cmd EOL { arscp_prompt(); }
;
cmd
: addlib_cmd
| addmod_cmd
| clear_cmd
| create_cmd
| delete_cmd
| directory_cmd
| end_cmd
| extract_cmd
| list_cmd
| open_cmd
| replace_cmd
| verbose_cmd
| save_cmd
| invalid_cmd
| empty_cmd
| error
;
addlib_cmd
: ADDLIB FNAME LP mod_list RP { arscp_addlib($2, $4); }
| ADDLIB FNAME { arscp_addlib($2, NULL); }
;
addmod_cmd
: ADDMOD mod_list { arscp_addmod($2); }
;
clear_cmd
: CLEAR { arscp_clear(); }
;
create_cmd
: CREATE FNAME { arscp_create(NULL, $2); }
;
delete_cmd
: DELETE mod_list { arscp_delete($2); }
;
directory_cmd
: DIRECTORY FNAME { arscp_dir($2, NULL, NULL); }
| DIRECTORY FNAME LP mod_list RP { arscp_dir($2, $4, NULL); }
| DIRECTORY FNAME LP mod_list RP FNAME { arscp_dir($2, $4, $6); }
;
end_cmd
: END { arscp_end(EXIT_SUCCESS); }
;
extract_cmd
: EXTRACT mod_list { arscp_extract($2); }
;
list_cmd
: LIST { arscp_list(); }
;
open_cmd
: OPEN FNAME { arscp_open($2); }
;
replace_cmd
: REPLACE mod_list { arscp_replace($2); }
;
save_cmd
: SAVE { arscp_save(); }
;
verbose_cmd
: VERBOSE { verbose = !verbose; }
;
empty_cmd
:
;
invalid_cmd
: FNAME { yyerror(NULL); }
;
%%
/* ARGSUSED */
static void
yyerror(const char *s)
{
(void) s;
printf("Syntax error in archive script, line %d\n", lineno);
}
/*
* The arscp_open() function will first open an archive and check its
* validity. If the archive format is valid, it will call
* arscp_create() to create a temporary copy of the archive.
*/
static void
arscp_open(char *fname)
{
struct archive *a;
struct archive_entry *entry;
int r;
if ((a = archive_read_new()) == NULL)
bsdar_errc(bsdar, 0, "archive_read_new failed");
archive_read_support_format_ar(a);
AC(archive_read_open_filename(a, fname, DEF_BLKSZ));
if ((r = archive_read_next_header(a, &entry)))
bsdar_warnc(bsdar, 0, "%s", archive_error_string(a));
AC(archive_read_close(a));
ACV(archive_read_free(a));
if (r != ARCHIVE_OK)
return;
arscp_create(fname, fname);
}
/*
* Create an archive.
*
* If the parameter 'in' is NULL (the 'CREATE' command), a new empty
* archive will be created. If the parameter 'in' is not NULL (the
* 'OPEN' command), the resulting archive will be a modified version
* of the existing archive.
*/
static void
arscp_create(char *in, char *out)
{
struct archive *a;
int ifd, ofd;
/* Delete the previously created temporary archive, if any. */
if (tmpac) {
if (unlink(tmpac) < 0)
bsdar_errc(bsdar, errno, "unlink failed");
free(tmpac);
}
tmpac = strdup(TEMPLATE);
if (tmpac == NULL)
bsdar_errc(bsdar, errno, "strdup failed");
if ((ofd = mkstemp(tmpac)) < 0)
bsdar_errc(bsdar, errno, "mkstemp failed");
if (in) {
/*
* The 'OPEN' command creates a temporary copy of the
* input archive.
*/
if ((ifd = open(in, O_RDONLY)) < 0 ||
elftc_copyfile(ifd, ofd) < 0) {
bsdar_warnc(bsdar, errno, "'OPEN' failed");
(void) close(ofd);
if (ifd != -1)
(void) close(ifd);
return;
}
(void) close(ifd);
(void) close(ofd);
} else {
/*
* The 'CREATE' command creates an "empty" archive (an
* archive consisting only of the archive header).
*/
if ((a = archive_write_new()) == NULL)
bsdar_errc(bsdar, 0, "archive_write_new failed");
archive_write_set_format_ar_svr4(a);
AC(archive_write_open_fd(a, ofd));
AC(archive_write_close(a));
ACV(archive_write_free(a));
}
/* Override the previous target, if any. */
if (target)
free(target);
target = out;
bsdar->filename = tmpac;
}
/*
* Add all modules of an archive to the current archive. If the
* parameter 'list' is not NULL, only those modules specified by
* 'list' will be added.
*/
static void
arscp_addlib(char *archive, struct list *list)
{
if (!arscp_target_exist())
return;
arscp_mlist2argv(list);
bsdar->addlib = archive;
ar_write_archive(bsdar, 'A');
arscp_free_argv();
arscp_free_mlist(list);
}
/*
* Add modules to the current archive.
*/
static void
arscp_addmod(struct list *list)
{
if (!arscp_target_exist())
return;
arscp_mlist2argv(list);
ar_write_archive(bsdar, 'q');
arscp_free_argv();
arscp_free_mlist(list);
}
/*
* Delete modules from the current archive.
*/
static void
arscp_delete(struct list *list)
{
if (!arscp_target_exist())
return;
arscp_mlist2argv(list);
ar_write_archive(bsdar, 'd');
arscp_free_argv();
arscp_free_mlist(list);
}
/*
* Extract modules from the current archive.
*/
static void
arscp_extract(struct list *list)
{
if (!arscp_target_exist())
return;
arscp_mlist2argv(list);
ar_read_archive(bsdar, 'x');
arscp_free_argv();
arscp_free_mlist(list);
}
/*
* List the contents of an archive (simple mode).
*/
static void
arscp_list(void)
{
if (!arscp_target_exist())
return;
bsdar->argc = 0;
bsdar->argv = NULL;
/* Always verbose. */
bsdar->options |= AR_V;
ar_read_archive(bsdar, 't');
bsdar->options &= ~AR_V;
}
/*
* List the contents of an archive (advanced mode).
*/
static void
arscp_dir(char *archive, struct list *list, char *rlt)
{
FILE *out;
/* If rlt != NULL, redirect the output to it. */
out = NULL;
if (rlt) {
out = bsdar->output;
if ((bsdar->output = fopen(rlt, "w")) == NULL)
bsdar_errc(bsdar, errno, "fopen %s failed", rlt);
}
bsdar->filename = archive;
if (list)
arscp_mlist2argv(list);
else {
bsdar->argc = 0;
bsdar->argv = NULL;
}
if (verbose)
bsdar->options |= AR_V;
ar_read_archive(bsdar, 't');
bsdar->options &= ~AR_V;
if (rlt) {
if (fclose(bsdar->output) == EOF)
bsdar_errc(bsdar, errno, "fclose %s failed", rlt);
bsdar->output = out;
free(rlt);
}
free(archive);
bsdar->filename = tmpac;
arscp_free_argv();
arscp_free_mlist(list);
}
/*
* Replace modules in the current archive.
*/
static void
arscp_replace(struct list *list)
{
if (!arscp_target_exist())
return;
arscp_mlist2argv(list);
ar_write_archive(bsdar, 'r');
arscp_free_argv();
arscp_free_mlist(list);
}
/*
* Rename the temporary archive to the target archive.
*/
static void
arscp_save(void)
{
mode_t mask;
if (target) {
if (rename(tmpac, target) < 0)
bsdar_errc(bsdar, errno, "rename failed");
/*
* Because mkstemp() creates temporary files with mode
* 0600, we set target archive's mode as per the
* process umask.
*/
mask = umask(0);
umask(mask);
if (chmod(target, 0666 & ~mask) < 0)
bsdar_errc(bsdar, errno, "chmod failed");
free(tmpac);
free(target);
tmpac = NULL;
target= NULL;
bsdar->filename = NULL;
} else
bsdar_warnc(bsdar, 0, "no open output archive");
}
/*
* Discard the contents of the current archive. This is achieved by
* invoking the 'CREATE' cmd on the current archive.
*/
static void
arscp_clear(void)
{
char *new_target;
if (target) {
new_target = strdup(target);
if (new_target == NULL)
bsdar_errc(bsdar, errno, "strdup failed");
arscp_create(NULL, new_target);
}
}
/*
* Quit ar(1). Note that the 'END' cmd will not 'SAVE' the current
* archive before exiting.
*/
static void
arscp_end(int eval)
{
if (target)
free(target);
if (tmpac) {
if (unlink(tmpac) == -1)
bsdar_errc(bsdar, errno, "unlink %s failed", tmpac);
free(tmpac);
}
exit(eval);
}
/*
* Check if a target was specified, i.e, whether an 'OPEN' or 'CREATE'
* had been issued by the user.
*/
static int
arscp_target_exist(void)
{
if (target)
return (1);
bsdar_warnc(bsdar, 0, "no open output archive");
return (0);
}
/*
* Construct the list of modules.
*/
static struct list *
arscp_mlist(struct list *list, char *str)
{
struct list *l;
l = malloc(sizeof(*l));
if (l == NULL)
bsdar_errc(bsdar, errno, "malloc failed");
l->str = str;
l->next = list;
return (l);
}
/*
* Calculate the length of an mlist.
*/
static int
arscp_mlist_len(struct list *list)
{
int len;
for(len = 0; list; list = list->next)
len++;
return (len);
}
/*
* Free the space allocated for a module list.
*/
static void
arscp_free_mlist(struct list *list)
{
struct list *l;
/* Note: list->str was freed in arscp_free_argv(). */
for(; list; list = l) {
l = list->next;
free(list);
}
}
/*
* Convert a module list to an 'argv' array.
*/
static void
arscp_mlist2argv(struct list *list)
{
char **argv;
int i, n;
n = arscp_mlist_len(list);
argv = malloc(n * sizeof(*argv));
if (argv == NULL)
bsdar_errc(bsdar, errno, "malloc failed");
/* Note that module names are stored in reverse order. */
for(i = n - 1; i >= 0; i--, list = list->next) {
if (list == NULL)
bsdar_errc(bsdar, errno, "invalid mlist");
argv[i] = list->str;
}
bsdar->argc = n;
bsdar->argv = argv;
}
/*
* Free the space allocated for an argv array and its elements.
*/
static void
arscp_free_argv(void)
{
int i;
for(i = 0; i < bsdar->argc; i++)
free(bsdar->argv[i]);
free(bsdar->argv);
}
/*
* Show a prompt if we are in interactive mode.
*/
static void
arscp_prompt(void)
{
if (interactive) {
printf("AR >");
fflush(stdout);
}
}
/*
* The main function implementing script mode.
*/
void
ar_mode_script(struct bsdar *ar)
{
bsdar = ar;
interactive = isatty(fileno(stdin));
while(yyparse()) {
if (!interactive)
arscp_end(EXIT_FAILURE);
}
/* Script ends without END */
arscp_end(EXIT_SUCCESS);
}

View File

@ -0,0 +1,603 @@
.\" Copyright (c) 2007,2009-2012 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy 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.
.\"
.\" $Id: ar.1 3195 2015-05-12 17:22:19Z emaste $
.\"
.Dd December 10, 2012
.Os
.Dt AR 1
.Sh NAME
.Nm ar
.Nd manage archives
.Sh SYNOPSIS
.Nm
.Fl d
.Op Fl T
.Op Fl f
.Op Fl j
.Op Fl v
.Op Fl z
.Ar archive
.Ar
.Nm
.Fl m
.Op Fl T
.Op Fl a Ar position-after
.Op Fl b Ar position-before
.Op Fl f
.Op Fl i Ar position-before
.Op Fl j
.Op Fl s | Fl S
.Op Fl z
.Ar archive
.Ar
.Nm
.Fl p
.Op Fl T
.Op Fl f
.Op Fl v
.Ar archive
.Op Ar
.Nm
.Fl q
.Op Fl T
.Op Fl c
.Op Fl D
.Op Fl f
.Op Fl F Ar flavor | Fl -flavor Ar flavor
.Op Fl s | Fl S
.Op Fl v
.Op Fl z
.Ar archive
.Ar
.Nm
.Fl r
.Op Fl T
.Op Fl a Ar position-after
.Op Fl b Ar position-before
.Op Fl c
.Op Fl D
.Op Fl f
.Op Fl F Ar flavor | Fl -flavor Ar flavor
.Op Fl i Ar position-before
.Op Fl j
.Op Fl s | Fl S
.Op Fl u
.Op Fl v
.Op Fl z
.Ar archive
.Ar
.Nm
.Fl s
.Op Fl D
.Op Fl j
.Op Fl z
.Ar archive
.Nm
.Fl t
.Op Fl f
.Op Fl T
.Op Fl v
.Ar archive
.Op Ar
.Nm
.Fl x
.Op Fl C
.Op Fl T
.Op Fl f
.Op Fl o
.Op Fl u
.Op Fl v
.Ar archive
.Op Ar
.Nm
.Fl M
.Nm
.Fl V
.Sh DESCRIPTION
The
.Nm
utility creates and maintains groups of files combined into an
archive.
Once an archive has been created, new files can be added to it, and
existing files can be extracted, deleted or replaced.
.Pp
Files are named in the archive by their last file name component,
so if a file referenced by a path containing a
.Dq /
is archived, it will be named by the last component of the path.
Similarly when matching paths listed on the command line against
file names stored in the archive, only the last component of the
path will be compared.
.Pp
The normal use of
.Nm
is for the creation and maintenance of libraries suitable for use
with the link editor
.Xr ld 1 ,
although it is not restricted to this purpose.
The
.Nm
utility can create and manage an archive symbol table (see
.Xr ar 5 )
used to speed up link editing operations.
If a symbol table is present in an archive, it will be
kept up-to-date by subsequent operations on the archive.
.Sh OPTIONS
The
.Nm
utility supports the following options:
.Bl -tag -width indent
.It Fl a Ar member-after
When used with option
.Fl m
this option specifies that the archive members specified by
arguments
.Ar
are moved to after the archive member named by argument
.Ar member-after .
When used with option
.Fl r
this option specifies that the files specified by arguments
.Ar
are added after the archive member named by argument
.Ar member-after .
.It Fl b Ar member-before
When used with option
.Fl m
this option specifies that the archive members specified by
arguments
.Ar
are moved to before the archive member named by argument
.Ar member-before .
When used with option
.Fl r
this option specifies that the files specified by arguments
.Ar
are added before the archive member named by argument
.Ar member-before .
.It Fl c
Suppress the informational message printed when a new archive is
created using the
.Fl r
and
.Fl q
options.
.It Fl C
Prevent extracted files from replacing like-named files
in the file system.
.It Fl d
Delete the members named by arguments
.Ar
from the archive specified by argument
.Ar archive .
The archive's symbol table, if present, is updated to reflect
the new contents of the archive.
.It Fl D
When used in combination with the
.Fl r
or
.Fl q
option, insert 0's instead of the real mtime, uid and gid values
and 0644 instead of file mode from the members named by arguments
.Ar .
This ensures that checksums on the resulting archives are reproducible
when member contents are identical.
.It Fl f
Synonymous with option
.Fl T .
.It Fl F Ar flavor | Fl -flavor Ar flavor
Create archives with the specified archive format.
Legal values for argument
.Ar flavor
are:
.Bl -tag -width indent -compact
.It Ar bsd
Create BSD format archives.
.It Ar gnu
An alias for
.Ar svr4 .
.It Ar svr4
Create SVR4 format archives.
.El
If this option is not specified,
.Nm
will create archives using the SVR4 format.
.It Fl i Ar member-before
Synonymous with option
.Fl b .
.It Fl j
This option is accepted for compatibility with the
.Tn FreeBSD
version of the
.Nm
utility, but is ignored.
.It Fl l
This option is accepted for compatibility with GNU
.Xr ar 1 ,
but is ignored.
.It Fl m
Move archive members specified by arguments
.Ar
within the archive.
If a position has been specified by one of the
.Fl a ,
.Fl b
or
.Fl i
options, the members are moved to before or after the specified
position.
If no position has been specified, the specified members are moved
to the end of the archive.
If the archive has a symbol table, it is updated to reflect the
new contents of the archive.
.It Fl M
Read and execute MRI librarian commands from standard input.
The commands understood by the
.Nm
utility are described in the section
.Sx "MRI Librarian Commands" .
.It Fl o
Preserve the original modification times of members when extracting
them.
.It Fl p
Write the contents of the specified archive members named by
arguments
.Ar
to standard output.
If no members were specified, the contents of all the files in the
archive are written in the order they appear in the archive.
.It Fl q
Append the files specified by arguments
.Ar
to the archive specified by argument
.Ar archive
without checking if the files already exist in the archive.
The archive symbol table will be updated as needed.
If the file specified by the argument
.Ar archive
does not already exist, a new archive will be created.
.It Fl r
Replace (add) the files specified by arguments
.Ar
in the archive specified by argument
.Ar archive ,
creating the archive if necessary.
Replacing existing members will not change the order of members within
the archive.
If a file named in arguments
.Ar
does not exist, existing members in the archive that match that
name are not changed.
New files are added to the end of the archive unless one of the
positioning options
.Fl a ,
.Fl b
or
.Fl i
is specified.
The archive symbol table, if it exists, is updated to reflect the
new state of the archive.
.It Fl s
Add an archive symbol table (see
.Xr ar 5 )
to the archive specified by argument
.Ar archive .
Invoking
.Nm
with the
.Fl s
option alone is equivalent to invoking
.Xr ranlib 1 .
.It Fl S
Do not generate an archive symbol table.
.It Fl t
For
.Nm ,
list the files specified by arguments
.Ar
in the order in which they appear in the archive, one per line.
If no files are specified, all files in the archive are listed.
.It Fl T
Use only the first fifteen characters of the archive member name or
command line file name argument when naming archive members.
.It Fl u
Conditionally update the archive or extract members.
When used with the
.Fl r
option, files named by arguments
.Ar
will be replaced in the archive if they are newer than their
archived versions.
When used with the
.Fl x
option, the members specified by arguments
.Ar
will be extracted only if they are newer than the corresponding
files in the file system.
.It Fl v
Provide verbose output.
When used with the
.Fl d ,
.Fl m ,
.Fl q
or
.Fl x
options,
.Nm
gives a file-by-file description of the archive modification being
performed, which consists of three white-space separated fields:
the option letter, a dash
.Dq "-" ,
and the file name.
When used with the
.Fl r
option,
.Nm
displays the description as above, but the initial letter is an
.Dq a
if the file is added to the archive, or an
.Dq r
if the file replaces a file already in the archive.
When used with the
.Fl p
option, the name of the file enclosed in
.Dq <
and
.Dq >
characters is written to standard output preceded by a single newline
character and followed by two newline characters.
The contents of the named file follow the file name.
When used with the
.Fl t
option,
.Nm
displays eight whitespace separated fields:
the file permissions as displayed by
.Xr strmode 3 ,
decimal user and group IDs separated by a slash (
.Dq / Ns ) ,
the file size in bytes, the file modification time in
.Xr strftime 3
format
.Dq "%b %e %H:%M %Y" ,
and the name of the file.
.It Fl V
Print a version identifier and exit.
.It Fl x
Extract archive members specified by arguments
.Ar
into the current directory.
If no members have been specified, extract all members of the archive.
If the file corresponding to an extracted member does not exist it
will be created.
If the file corresponding to an extracted member does exist, its owner
and group will not be changed while its contents will be overwritten
and its permissions will set to that entered in the archive.
The file's access and modification time would be that of the time
of extraction unless the
.Fl o
option was specified.
.It Fl z
This option is accepted for compatibility with the
.Tn FreeBSD
version of the
.Nm
utility, but is ignored.
.El
.Ss "MRI Librarian Commands"
If the
.Fl M
option is specified, the
.Nm
utility will read and execute commands from its standard input.
If standard input is a terminal, the
.Nm
utility will display the prompt
.Dq Li "AR >"
before reading a line, and will continue operation even if errors are
encountered.
If standard input is not a terminal, the
.Nm
utility will not display a prompt and will terminate execution on
encountering an error.
.Pp
Each input line contains a single command.
Words in an input line are separated by whitespace characters.
The first word of the line is the command, the remaining words are
the arguments to the command.
The command word may be specified in either case.
Arguments may be separated by commas or blanks.
.Pp
Empty lines are allowed and are ignored.
Long lines are continued by ending them with the
.Dq Li +
character.
.Pp
The
.Dq Li *
and
.Dq Li "\;"
characters start a comment.
Comments extend till the end of the line.
.Pp
When executing an MRI librarian script the
.Nm
utility works on a temporary copy of an archive.
Changes to the copy are made permanent using the
.Ic save
command.
.Pp
Commands understood by the
.Nm
utility are:
.Bl -tag -width indent
.It Ic addlib Ar archive | Ic addlib Ar archive Pq Ar member Oo Li , Ar member Oc Ns ...
Add the contents of the archive named by argument
.Ar archive
to the current archive.
If specific members are named using the arguments
.Ar member ,
then those members are added to the current archive.
If no members are specified, the entire contents of the archive
are added to the current archive.
.It Ic addmod Ar member Oo Li , Ar member Oc Ns ...
Add the files named by arguments
.Ar member
to the current archive.
.It Ic clear
Discard all the contents of the current archive.
.It Ic create Ar archive
Create a new archive named by the argument
.Ar archive ,
and makes it the current archive.
If the named archive already exists, it will be overwritten
when the
.Ic save
command is issued.
.It Ic delete Ar module Oo Li , Ar member Oc Ns ...
Delete the modules named by the arguments
.Ar member
from the current archive.
.It Ic directory Ar archive Po Ar member Oo Li , Ar member Oc Ns ... Pc Op Ar outputfile
List each named module in the archive.
The format of the output depends on the verbosity setting set using
the
.Ic verbose
command.
Output is sent to standard output, or to the file specified by
argument
.Ar outputfile .
.It Ic end
Exit successfully from the
.Nm
utility.
Any unsaved changes to the current archive will be discarded.
.It Ic extract Ar member Oo Li , Ar member Oc Ns ...
Extract the members named by the arguments
.Ar member
from the current archive.
.It Ic list
Display the contents of the current archive in verbose style.
.It Ic open Ar archive
Open the archive named by argument
.Ar archive
and make it the current archive.
.It Ic replace Ar member Oo Li , Ar member Oc Ns ...
Replace named members in the current archive with the files specified
by arguments
.Ar member .
The files must be present in the current directory and the named
modules must already exist in the current archive.
.It Ic save
Commit all changes to the current archive.
.It Ic verbose
Toggle the verbosity of the
.Ic directory
command.
.El
.Sh EXAMPLES
To create a new archive
.Pa ex.a
containing three files
.Pa ex1.o ,
.Pa ex2.o
and
.Pa ex3.o ,
use:
.Dl "ar -rc ex.a ex1.o ex2.o ex3.o"
.Pp
To add an archive symbol table to an existing archive
.Pa ex.a ,
use:
.Dl "ar -s ex.a"
.Pp
To delete file
.Pa ex1.o
from archive
.Pa ex.a ,
use:
.D1 "ar -d ex.a ex1.o"
.Pp
To verbosely list the contents of archive
.Pa ex.a ,
use:
.D1 "ar -tv ex.a"
.Pp
To create a new archive
.Pa ex.a
containing the files
.Pa ex1.o ,
and
.Pa ex2.o ,
using MRI librarian commands, use the following script:
.Bd -literal -offset indent
create ex.a * specify the output archive
addmod ex1.o ex2.o * add modules
save * save pending changes
end * exit the utility
.Ed
.Sh DIAGNOSTICS
.Ex -std
.Sh SEE ALSO
.Xr ld 1 ,
.Xr ranlib 1 ,
.Xr archive 3 ,
.Xr elf 3 ,
.Xr strftime 3 ,
.Xr strmode 3 ,
.Xr ar 5
.Sh STANDARDS COMPLIANCE
The
.Nm
utility's support for the
.Fl a ,
.Fl b ,
.Fl c ,
.Fl i ,
.Fl m ,
.Fl p ,
.Fl q ,
.Fl r ,
.Fl s ,
.Fl t ,
.Fl u ,
.Fl v ,
.Fl C
and
.Fl T
options is believed to be compliant with
.St -p1003.2 .
.Sh HISTORY
An
.Nm
command first appeared in AT&T UNIX Version 1.
In
.Fx 8.0 ,
.An Kai Wang Aq Mt kaiw@FreeBSD.org
reimplemented
.Nm
using the
.Lb libarchive
and the
.Lb libelf .

View File

@ -0,0 +1,327 @@
.\" Copyright (c) 2010 Joseph Koshy. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: ar.5 3182 2015-04-10 16:08:10Z emaste $
.\"
.Dd November 28, 2010
.Os
.Dt AR 5
.Sh NAME
.Nm ar
.Nd archive file format for
.Xr ar 1
and
.Xr ranlib 1
.Sh SYNOPSIS
.In ar.h
.Sh DESCRIPTION
.Xr ar 1
archives are created and managed by the
.Xr ar 1
and
.Xr ranlib 1
utilities.
These archives are typically used during program development to
hold libraries of program objects.
An
.Xr ar 1
archive is contained in a single operating system file.
.Pp
This manual page documents two variants of the
.Xr ar 1
archive format: the BSD archive format, and the SVR4/GNU archive
format.
.Pp
In both variants the archive file starts with an identifying byte
sequence of the seven ASCII characters
.Sq Li "!<arch>"
followed by a ASCII linefeed character
.Po
see the constant
.Dq ARMAG
in the header file
.In ar.h
.Pc .
.Pp
Archive members follow the initial identifying byte sequence.
Each archive member is prefixed by a fixed size header describing the
file attributes associated with the member.
.Ss "Archive Headers"
An archive header describes the file attributes for the archive member that
follows it.
The
.Xr ar 5
format only supports a limited number of attributes: the file name,
the file creation time stamp, the uid and gid of the creator, the file
mode and the file size.
.Pp
Archive headers are placed at an even byte offset in the archive file.
If the data for an archive member ends at an odd byte offset, then a
padding byte with value 0x0A is used to position the next archive
header on an even byte offset.
.Pp
An archive header comprises the following fixed sized fields:
.Bl -tag -width "Li ar_name"
.It Ar ar_name
(16 bytes) The file name of the archive member.
The format of this field varies between the BSD and SVR4/GNU formats and
is described in more detail in the section
.Sx "Representing File Names"
below.
.It Ar ar_date
(12 bytes) The file modification time for the member in seconds since the
epoch, encoded as a decimal number.
.It Ar ar_uid
(6 bytes) The uid associated with the archive member, encoded as a
decimal number.
.It Ar ar_gid
(6 bytes) The gid associated with the archive member, encoded as a
decimal number.
.It Ar ar_mode
(8 bytes) The file mode for the archive member, encoded as an octal
number.
.It Ar ar_size
(10 bytes) In the SVR4/GNU archive format this field holds the size in
bytes of the archive member, encoded as a decimal number.
In the BSD archive format, for short file names, this field
holds the size in bytes of the archive member, encoded as a decimal
number.
For long file names
.Po
see
.Sx "Representing File Names"
below
.Pc ,
the field contains the combined size of the
archive member and its file name, encoded as a decimal number.
.It Ar ar_fmag
(2 bytes) This field holds 2 bytes with values 0x96 and 0x0A
respectively, marking the end of the header.
.El
.Pp
Unused bytes in the fields of an archive header are set to the value
0x20.
.Ss "Representing File Names"
The BSD and SVR4/GNU variants use different schemes for encoding file
names for members.
.Bl -tag -width "SVR4/GNU"
.It "BSD"
File names that are up to 16 bytes long and which do not contain
embedded spaces are stored directly in the
.Ar ar_name
field of the archive header.
File names that are either longer than 16 bytes or which contain
embedded spaces are stored immediately after the archive header
and the
.Ar ar_name
field of the archive header is set to the string
.Dq "#1/"
followed by a decimal representation of the number of bytes needed for
the file name.
In addition, the
.Ar ar_size
field of the archive header is set to the decimal representation of
the combined sizes of the archive member and the file name.
The file contents of the member follows the file name without further
padding.
.Pp
As an example, if the file name for a member was
.Dq "A B"
and its contents was the string
.Dq "C D" ,
then the
.Ar ar_name
field of the header would contain
.Dq Li "#1/3" ,
the
.Ar ar_size
field of the header would contain
.Dq Li 6 ,
and the bytes immediately following the header would be 0x41, 0x20,
0x42, 0x43, 0x20 and 0x44
.Po
ASCII
.Dq "A BC D"
.Pc .
.It "SVR4/GNU"
File names that are up to 15 characters long are stored directly in the
.Ar ar_name
field of the header, terminated by a
.Dq Li /
character.
.Pp
If the file name is larger than would fit in space for the
.Ar ar_name
field, then the actual file name is kept in the archive
string table
.Po
see
.Sx "Archive String Tables"
below
.Pc ,
and the decimal offset of the file name in the string table is stored
in the
.Ar ar_name
field, prefixed by a
.Dq Li /
character.
.Pp
As an example, if the real file name has been stored at offset 768 in
the archive string table, the
.Ar ar_name
field of the header will contain the string
.Dq /768 .
.El
.Ss "Special Archive Members"
The following archive members are special.
.Bl -tag -width indent
.It Dq Li /
In the SVR4/GNU variant of the archive format, the archive member with
name
.Dq Li /
denotes an archive symbol table.
If present, this member will be the very first member in the
archive.
.It Dq Li //
In the SVR4/GNU variant of the archive format, the archive member with
name
.Dq Li //
denotes the archive string table.
This special member is used to hold filenames that do not fit in the
file name field of the header
.Po
see
.Sx "Representing File Names"
above
.Pc .
If present, this member immediately follows the archive symbol table
if an archive symbol table is present, or is the first member otherwise.
.It Dq Li "__.SYMDEF"
This special member contains the archive symbol table in the BSD
variant of the archive format.
If present, this member will be the very first member in the
archive.
.El
.Ss "Archive String Tables"
An archive string table is used in the SVR4/GNU archive format to hold
file names that are too large to fit into the constraints of the
.Ar ar_name
field of the archive header.
An archive string table contains a sequence of file names.
Each file name in the archive string table is terminated by the
byte sequence 0x2F, 0x0A
.Po
the ASCII string
.Dq "/\en"
.Pc .
No padding is used to separate adjacent file names.
.Ss "Archive Symbol Tables"
Archive symbol tables are used to speed up link editing by providing a
mapping between the program symbols defined in the archive
and the corresponding archive members.
Archive symbol tables are managed by the
.Xr ranlib 1
utility.
.Pp
The format of archive symbol tables is as follows:
.Bl -tag -width "SVR4/GNU"
.It BSD
In the BSD archive format, the archive symbol table comprises
of two parts: a part containing an array of
.Vt "struct ranlib"
descriptors, followed by a part containing a symbol string table.
The sizes and layout of the structures that make up a BSD format
archive symbol table are machine dependent.
.Pp
The part containing
.Vt "struct ranlib"
descriptors begins with a field containing the size in bytes of the
array of
.Vt "struct ranlib"
descriptors encoded as a C
.Vt long
value.
.Pp
The array of
.Vt "struct ranlib"
descriptors follows the size field.
Each
.Vt "struct ranlib"
descriptor describes one symbol.
.Pp
A
.Vt "struct ranlib"
descriptor comprises two fields:
.Bl -tag -width "Ar ran_strx" -compact
.It Ar ran_strx
.Pq C Vt long
This field contains the zero-based offset of the symbol name in the
symbol string table.
.It Ar ran_off
.Pq C Vt long
This field is the file offset to the archive header for the archive
member defining the symbol.
.El
.Pp
The part containing the symbol string table begins with a field
containing the size in bytes of the string table, encoded as a C
.Vt long
value.
This string table follows the size field, and contains
NUL-terminated strings for the symbols in the symbol table.
.It SVR4/GNU
In the SVR4/GNU archive format, the archive symbol table starts with a
4-byte binary value containing the number of entries contained in the
archive symbol table.
This count of entries is stored most significant byte first.
.Pp
Next, there are
.Ar count
4-byte numbers, each stored most significant byte first.
Each number is a binary offset to the archive header for the member in
the archive file for the corresponding symbol table entry.
.Pp
After the binary offset values, there are
.Ar count
NUL-terminated strings in sequence, holding the symbol names for
the corresponding symbol table entries.
.El
.Sh STANDARDS COMPLIANCE
The
.Xr ar 1
archive format is not currently specified by a standard.
.Pp
This manual page documents the
.Xr ar 1
archive formats used by the
.Bx 4.4
and
.Ux SVR4
operating system releases.
.Sh SEE ALSO
.Xr ar 1 ,
.Xr ld 1 ,
.Xr ranlib 1 ,
.Xr elf 3 ,
.Xr elf_getarsym 3 ,
.Xr elf_rand 3

View File

@ -0,0 +1,433 @@
/*-
* Copyright (c) 2007 Kai Wang
* Copyright (c) 2007 Tim Kientzle
* Copyright (c) 2007 Joseph Koshy
* 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
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) 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.
*/
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Hugh Smith at The University of Guelph.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/queue.h>
#include <sys/types.h>
#include <archive.h>
#include <errno.h>
#include <getopt.h>
#include <libelftc.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "ar.h"
ELFTC_VCSID("$Id: ar.c 3183 2015-04-10 16:18:42Z emaste $");
enum options
{
OPTION_HELP
};
static struct option longopts[] =
{
{"flavor", required_argument, NULL, 'F'},
{"help", no_argument, NULL, OPTION_HELP},
{"version", no_argument, NULL, 'V'},
{NULL, 0, NULL, 0}
};
static void bsdar_usage(void);
static void ranlib_usage(void);
static void set_mode(struct bsdar *bsdar, char opt);
static void only_mode(struct bsdar *bsdar, const char *opt,
const char *valid_modes);
static void bsdar_version(void);
int
main(int argc, char **argv)
{
struct bsdar *bsdar, bsdar_storage;
char *arcmd, *argv1_saved;
size_t len;
int i, opt;
bsdar = &bsdar_storage;
memset(bsdar, 0, sizeof(*bsdar));
arcmd = argv1_saved = NULL;
bsdar->output = stdout;
if ((bsdar->progname = ELFTC_GETPROGNAME()) == NULL)
bsdar->progname = "ar";
if (elf_version(EV_CURRENT) == EV_NONE)
bsdar_errc(bsdar, 0, "ELF library initialization failed: %s",
elf_errmsg(-1));
/*
* Act like ranlib if our name ends in "ranlib"; this
* accommodates names like "arm-freebsd7.1-ranlib",
* "bsdranlib", etc.
*/
len = strlen(bsdar->progname);
if (len >= strlen("ranlib") &&
strcmp(bsdar->progname + len - strlen("ranlib"), "ranlib") == 0) {
while ((opt = getopt_long(argc, argv, "tDV", longopts,
NULL)) != -1) {
switch(opt) {
case 't':
/* Ignored. */
break;
case 'D':
bsdar->options |= AR_D;
break;
case 'V':
bsdar_version();
break;
case OPTION_HELP:
ranlib_usage();
default:
ranlib_usage();
}
}
argv += optind;
argc -= optind;
if (*argv == NULL)
ranlib_usage();
bsdar->options |= AR_S;
for (;(bsdar->filename = *argv++) != NULL;)
ar_write_archive(bsdar, 's');
exit(EXIT_SUCCESS);
} else {
if (argc < 2)
bsdar_usage();
/*
* Tack on a leading '-', for old-style usage.
*/
if (*argv[1] != '-') {
argv1_saved = argv[1];
len = strlen(argv[1]) + 2;
if ((arcmd = malloc(len)) == NULL)
bsdar_errc(bsdar, errno, "malloc failed");
(void) snprintf(arcmd, len, "-%s", argv[1]);
argv[1] = arcmd;
}
}
while ((opt = getopt_long(argc, argv, "abCcdDfF:ijlMmopqrSsTtuVvxz",
longopts, NULL)) != -1) {
switch(opt) {
case 'a':
bsdar->options |= AR_A;
break;
case 'b':
case 'i':
bsdar->options |= AR_B;
break;
case 'C':
bsdar->options |= AR_CC;
break;
case 'c':
bsdar->options |= AR_C;
break;
case 'd':
set_mode(bsdar, opt);
break;
case 'D':
bsdar->options |= AR_D;
break;
case 'F':
if (!strcasecmp(optarg, "svr4") ||
!strcasecmp(optarg, "gnu"))
bsdar->options &= ~AR_BSD;
else if (!strcasecmp(optarg, "bsd"))
bsdar->options |= AR_BSD;
else
bsdar_usage();
break;
case 'f':
case 'T':
bsdar->options |= AR_TR;
break;
case 'j':
/* ignored */
break;
case 'l':
/* ignored, for GNU ar comptibility */
break;
case 'M':
set_mode(bsdar, opt);
break;
case 'm':
set_mode(bsdar, opt);
break;
case 'o':
bsdar->options |= AR_O;
break;
case 'p':
set_mode(bsdar, opt);
break;
case 'q':
set_mode(bsdar, opt);
break;
case 'r':
set_mode(bsdar, opt);
break;
case 'S':
bsdar->options |= AR_SS;
break;
case 's':
bsdar->options |= AR_S;
break;
case 't':
set_mode(bsdar, opt);
break;
case 'u':
bsdar->options |= AR_U;
break;
case 'V':
bsdar_version();
break;
case 'v':
bsdar->options |= AR_V;
break;
case 'x':
set_mode(bsdar, opt);
break;
case 'z':
/* ignored */
break;
case OPTION_HELP:
bsdar_usage();
default:
bsdar_usage();
}
}
/* Restore argv[1] if we had modified it. */
if (arcmd != NULL) {
argv[1] = argv1_saved;
free(arcmd);
arcmd = argv1_saved = NULL;
}
argv += optind;
argc -= optind;
if (*argv == NULL && bsdar->mode != 'M')
bsdar_usage();
if (bsdar->options & AR_A && bsdar->options & AR_B)
bsdar_errc(bsdar, 0,
"only one of -a and -[bi] options allowed");
if (bsdar->options & AR_J && bsdar->options & AR_Z)
bsdar_errc(bsdar, 0,
"only one of -j and -z options allowed");
if (bsdar->options & AR_S && bsdar->options & AR_SS)
bsdar_errc(bsdar, 0,
"only one of -s and -S options allowed");
if (bsdar->options & (AR_A | AR_B)) {
if (*argv == NULL)
bsdar_errc(bsdar, 0,
"no position operand specified");
if ((bsdar->posarg = basename(*argv)) == NULL)
bsdar_errc(bsdar, errno,
"basename failed");
argc--;
argv++;
}
if (bsdar->options & AR_A)
only_mode(bsdar, "-a", "mqr");
if (bsdar->options & AR_B)
only_mode(bsdar, "-b", "mqr");
if (bsdar->options & AR_C)
only_mode(bsdar, "-c", "qr");
if (bsdar->options & AR_CC)
only_mode(bsdar, "-C", "x");
if (bsdar->options & AR_D)
only_mode(bsdar, "-D", "qr");
if (bsdar->options & AR_O)
only_mode(bsdar, "-o", "x");
if (bsdar->options & AR_SS)
only_mode(bsdar, "-S", "mqr");
if (bsdar->options & AR_U)
only_mode(bsdar, "-u", "qrx");
if (bsdar->mode == 'M') {
ar_mode_script(bsdar);
exit(EXIT_SUCCESS);
}
if ((bsdar->filename = *argv) == NULL)
bsdar_usage();
bsdar->argc = --argc;
bsdar->argv = ++argv;
if ((!bsdar->mode || strchr("ptx", bsdar->mode)) &&
bsdar->options & AR_S) {
ar_write_archive(bsdar, 's');
if (!bsdar->mode)
exit(EXIT_SUCCESS);
}
switch(bsdar->mode) {
case 'd': case 'm': case 'q': case 'r':
ar_write_archive(bsdar, bsdar->mode);
break;
case 'p': case 't': case 'x':
ar_read_archive(bsdar, bsdar->mode);
break;
default:
bsdar_usage();
/* NOTREACHED */
}
for (i = 0; i < bsdar->argc; i++)
if (bsdar->argv[i] != NULL)
bsdar_warnc(bsdar, 0, "%s: not found in archive",
bsdar->argv[i]);
exit(EXIT_SUCCESS);
}
static void
set_mode(struct bsdar *bsdar, char opt)
{
if (bsdar->mode != '\0' && bsdar->mode != opt)
bsdar_errc(bsdar, 0, "Can't specify both -%c and -%c",
opt, bsdar->mode);
bsdar->mode = opt;
}
static void
only_mode(struct bsdar *bsdar, const char *opt, const char *valid_modes)
{
if (strchr(valid_modes, bsdar->mode) == NULL)
bsdar_errc(bsdar, 0, "Option %s is not permitted in mode -%c",
opt, bsdar->mode);
}
#define AR_USAGE_MESSAGE "\
Usage: %s <command> [options] archive file...\n\
Manage archives.\n\n\
Where <command> is one of:\n\
-d Delete members from the archive.\n\
-m Move archive members within the archive.\n\
-p Write the contents of members to standard output.\n\
-q Append files to an archive.\n\
-r Replace (add) files to an archive.\n\
-s Add an archive symbol to an archive.\n\
-t List files in an archive.\n\
-x Extract members from an archive.\n\
-M Execute MRI librarian commands.\n\
-V Print a version identifier and exit.\n\n\
Options:\n\
-a MEMBER Add members after the specified member.\n\
-b MEMBER | -i MEMBER\n\
Add members before the specified member.\n\
-c Do not print a message when creating a new archive.\n\
-f | -T Only use the first fifteen characters of the member name.\n\
-j (This option is accepted, but is ignored).\n\
-l (This option is accepted, but is ignored).\n\
-o Preserve modification times when extracting members.\n\
-u Conditionally update or extract members.\n\
-v Be verbose.\n\
-z (This option is accepted, but is ignored).\n\
-C Do not overwrite existing files in the file system.\n\
-D Use fixed metadata, for consistent archive checksums.\n\
-F FORMAT | --flavor=FORMAT\n\
Create archives with the specified format.\n\
-S Do not generate an archive symbol table.\n"
static void
bsdar_usage(void)
{
(void) fprintf(stderr, AR_USAGE_MESSAGE, ELFTC_GETPROGNAME());
exit(EXIT_FAILURE);
}
#define RANLIB_USAGE_MESSAGE "\
Usage: %s [options] archive...\n\
Update or create archive symbol tables.\n\n\
Options:\n\
-t (This option is accepted, but ignored).\n\
-D Use fixed metadata, for consistent archive checksums.\n\
-V Print a version identifier and exit.\n"
static void
ranlib_usage(void)
{
(void)fprintf(stderr, RANLIB_USAGE_MESSAGE, ELFTC_GETPROGNAME());
exit(EXIT_FAILURE);
}
static void
bsdar_version(void)
{
(void)printf("%s (%s, %s)\n", ELFTC_GETPROGNAME(), archive_version_string(),
elftc_version());
exit(EXIT_SUCCESS);
}

View File

@ -0,0 +1,143 @@
/*-
* Copyright (c) 2007 Kai Wang
* 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
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) 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.
*
* $Id: ar.h 2496 2012-04-24 02:33:40Z jkoshy $
*/
#include <libelf.h>
#include "_elftc.h"
/*
* ar(1) options.
*/
#define AR_A 0x0001 /* position-after */
#define AR_B 0x0002 /* position-before */
#define AR_C 0x0004 /* creating new archive */
#define AR_CC 0x0008 /* do not overwrite when extracting */
#define AR_J 0x0010 /* bzip2 compression */
#define AR_O 0x0020 /* preserve original mtime when extracting */
#define AR_S 0x0040 /* write archive symbol table */
#define AR_SS 0x0080 /* do not write archive symbol table */
#define AR_TR 0x0100 /* only keep first 15 chars for member name */
#define AR_U 0x0200 /* only extract or update newer members.*/
#define AR_V 0x0400 /* verbose mode */
#define AR_Z 0x0800 /* gzip compression */
#define AR_D 0x1000 /* insert dummy mode, mtime, uid and gid */
#define AR_BSD 0x2000 /* use the BSD archive format */
#define DEF_BLKSZ 10240 /* default block size */
/* Special names. */
#define AR_STRINGTAB_NAME_SVR4 "//"
#define AR_SYMTAB_NAME_BSD "__.SYMDEF"
#define AR_SYMTAB_NAME_SVR4 "/"
/*
* Convenient wrapper for general libarchive error handling.
*/
#define AC(CALL) do { \
if ((CALL)) \
bsdar_errc(bsdar, 0, "%s", \
archive_error_string(a)); \
} while (0)
/*
* The 'ACV' wrapper is used for libarchive APIs that changed from
* returning 'void' to returning an 'int' in later versions of libarchive.
*/
#if ARCHIVE_VERSION_NUMBER >= 2000000
#define ACV(CALL) AC(CALL)
#else
#define ACV(CALL) do { \
(CALL); \
} while (0)
#endif
/*
* In-memory representation of archive member(object).
*/
struct ar_obj {
Elf *elf; /* object file descriptor */
char *name; /* member name */
uid_t uid; /* user id */
gid_t gid; /* group id */
mode_t md; /* octal file permissions */
size_t size; /* member size */
time_t mtime; /* modification time */
dev_t dev; /* inode's device */
ino_t ino; /* inode's number */
TAILQ_ENTRY(ar_obj) objs;
};
/*
* Structure encapsulates the "global" data for "ar" program.
*/
struct bsdar {
const char *filename; /* archive name. */
const char *addlib; /* target of ADDLIB. */
const char *posarg; /* position arg for modifiers -a, -b. */
char mode; /* program mode */
int options; /* command line options */
FILE *output; /* default output stream */
const char *progname; /* program name */
int argc;
char **argv;
dev_t ar_dev; /* archive device. */
ino_t ar_ino; /* archive inode. */
/*
* Fields for the archive string table.
*/
char *as; /* buffer for archive string table. */
size_t as_sz; /* current size of as table. */
size_t as_cap; /* capacity of as table buffer. */
/*
* Fields for the archive symbol table.
*/
uint32_t s_cnt; /* current number of symbols. */
uint32_t *s_so; /* symbol offset table. */
size_t s_so_cap; /* capacity of so table buffer. */
char *s_sn; /* symbol name table */
size_t s_sn_cap; /* capacity of sn table buffer. */
size_t s_sn_sz; /* current size of sn table. */
/* Current member's offset (relative to the end of pseudo members.) */
off_t rela_off;
TAILQ_HEAD(, ar_obj) v_obj; /* object(member) list */
};
void ar_mode_script(struct bsdar *ar);
void ar_read_archive(struct bsdar *_ar, int _mode);
void ar_write_archive(struct bsdar *_ar, int _mode);
void bsdar_errc(struct bsdar *, int _code, const char *fmt, ...);
int bsdar_is_pseudomember(struct bsdar *_ar, const char *_name);
const char *bsdar_strmode(mode_t m);
void bsdar_warnc(struct bsdar *, int _code, const char *fmt, ...);

View File

@ -0,0 +1,65 @@
#!/bin/sh
# $Id: acp.sh 2086 2011-10-27 05:18:01Z jkoshy $
# This script is adapted from Jan Psota's Tar Comparison Program(TCP).
n=3 # number of repetitions
AR="bsdar gnuar" # ar archivers to compare
test $# -ge 2 || {
echo "usage: $0 source_dir where_to_place_archive [where_to_extract_it]"
exit 0
}
THISDIR=`/bin/pwd`
src=$1
dst=$2/acp.a
ext=${3:-$2}/acptmp
test -e $dst -o -e /tmp/acp \
&& { echo "$dst or /tmp/acp exists, exiting"; exit 1; }
mkdir -p $ext || exit 1
show_result ()
{
awk -vL="`du -k $dst`" '{printf "%s\t%s\t%s\%10.1d KB/s\n",
$1, $3, $5, ($1>0?L/$1:0)}' /tmp/acp | sort | head -n 1
}
test -d $src || { echo "'$src' is not a directory"; exit 1; }
# ar versions
for ar in $AR; do echo -n "$ar: "; $ar -V | head -n 1;
done
echo
echo "best time of $n repetitions"
echo -n " src=$src, "
echo -n "`du -sh $src | awk '{print $1}'`"
echo -n " in "
echo "`find $src | wc -l` files"
echo " archive=$dst, extract to $ext"
echo "program operation real user system speed"
for op in "cru $dst $src/*" "t $dst" "x `basename $dst`"; do
for ar in $AR; do
echo -n "$ar "
echo $op | grep -q ^cr && echo -n "create "
echo $op | grep -q ^t && echo -n "list "
echo $op | grep -q ^x && echo -n "extract "
num=0
while [ $num -lt $n ]; do
echo $op | grep -q ^cr && rm -f $dst
echo $op | grep -q ^x && { rm -rf $ext; mkdir -p $ext
cp $dst $ext; cd $ext; }
sync
time $ar $op > /dev/null 2>> /tmp/acp
echo $op | grep -q ^x && cd $THISDIR
num=`expr $num + 1`
done
show_result
rm -rf /tmp/acp
done
echo
done
rm -rf $ext $dst
rm -f /tmp/acp

View File

@ -0,0 +1,9 @@
.if ${OS_DISTRIBUTION} == "Ubuntu"
.if ${OS_DISTRIBUTION_VERSION} >= 14
# Ubuntu Trusty Tahr and later.
# Use the --nounput option to flex(1), to prevent unused functions from
# being generated.
LFLAGS += --nounput
.endif
.endif

View File

@ -0,0 +1,86 @@
.\" Copyright (c) 2007,2009-2012 Joseph Koshy. 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 Joseph Koshy ``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 Joseph Koshy 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.
.\"
.\" $Id: ranlib.1 3195 2015-05-12 17:22:19Z emaste $
.\"
.Dd December 9, 2012
.Os
.Dt RANLIB 1
.Sh NAME
.Nm ranlib
.Nd update archive symbol tables
.Sh SYNOPSIS
.Nm
.Op Fl D
.Op Fl t
.Ar archive Ns ...
.Nm
.Fl V
.Sh DESCRIPTION
The
.Nm ranlib
utility is used to update an existing archive symbol table in an
.Xr ar 1
archive, or to add an archive symbol table to an archive lacking one.
.Sh OPTIONS
The
.Nm
utility supports the following options:
.Bl -tag -width indent
.It Fl D
Use zeros for the mtime, uid and gid fields, and use mode 0644 for the
file mode field for all archive member headers.
This ensures that checksums on the resulting archives are reproducible
when member contents are identical.
.It Fl t
This option is accepted, but is ignored.
.It Fl V
Print a version identifier and exit.
.El
.Sh EXAMPLES
To update the archive symbol table for an archive
.Pa lib.a ,
use:
.Dl "ranlib lib.a"
.Sh DIAGNOSTICS
.Ex -std
.Sh SEE ALSO
.Xr ar 1 ,
.Xr ld 1 ,
.Xr archive 3 ,
.Xr elf 3 ,
.Xr ar 5
.Sh HISTORY
The
.Nm
command first appeared in AT&T UNIX Version 7.
.Pp
In
.Fx 8.0 ,
.An Kai Wang Aq Mt kaiw@FreeBSD.org
reimplemented
.Nm
using the
.Lb libarchive
and the
.Lb libelf .

View File

@ -0,0 +1,199 @@
/*-
* Copyright (c) 2007 Kai Wang
* Copyright (c) 2007 Tim Kientzle
* 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
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/queue.h>
#include <sys/stat.h>
#include <archive.h>
#include <archive_entry.h>
#include <assert.h>
#include <errno.h>
#include <libgen.h>
#include <stdio.h>
#include <string.h>
#include "ar.h"
ELFTC_VCSID("$Id: read.c 3180 2015-04-09 15:13:57Z emaste $");
/*
* Handle read modes: 'x', 't' and 'p'.
*/
void
ar_read_archive(struct bsdar *bsdar, int mode)
{
FILE *out;
struct archive *a;
struct archive_entry *entry;
struct stat sb;
struct tm *tp;
const char *bname;
const char *name;
mode_t md;
size_t size;
time_t mtime;
uid_t uid;
gid_t gid;
char **av;
char buf[25];
char find;
int i, flags, r;
assert(mode == 'p' || mode == 't' || mode == 'x');
if ((a = archive_read_new()) == NULL)
bsdar_errc(bsdar, 0, "archive_read_new failed");
archive_read_support_format_ar(a);
AC(archive_read_open_filename(a, bsdar->filename, DEF_BLKSZ));
out = bsdar->output;
for (;;) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY ||
r == ARCHIVE_FATAL)
bsdar_warnc(bsdar, 0, "%s", archive_error_string(a));
if (r == ARCHIVE_EOF || r == ARCHIVE_FATAL)
break;
if (r == ARCHIVE_RETRY) {
bsdar_warnc(bsdar, 0, "Retrying...");
continue;
}
if (archive_format(a) == ARCHIVE_FORMAT_AR_BSD)
bsdar->options |= AR_BSD;
else
bsdar->options &= ~AR_BSD;
if ((name = archive_entry_pathname(entry)) == NULL)
break;
/* Skip pseudo members. */
if (bsdar_is_pseudomember(bsdar, name))
continue;
if (bsdar->argc > 0) {
find = 0;
for(i = 0; i < bsdar->argc; i++) {
av = &bsdar->argv[i];
if (*av == NULL)
continue;
if ((bname = basename(*av)) == NULL)
bsdar_errc(bsdar, errno,
"basename failed");
if (strcmp(bname, name) != 0)
continue;
*av = NULL;
find = 1;
break;
}
if (!find)
continue;
}
if (mode == 't') {
if (bsdar->options & AR_V) {
md = archive_entry_mode(entry);
uid = archive_entry_uid(entry);
gid = archive_entry_gid(entry);
size = archive_entry_size(entry);
mtime = archive_entry_mtime(entry);
(void)fprintf(out, "%s %6d/%-6d %8ju ",
bsdar_strmode(md) + 1, uid, gid,
(uintmax_t)size);
tp = localtime(&mtime);
(void)strftime(buf, sizeof(buf),
"%b %e %H:%M %Y", tp);
(void)fprintf(out, "%s %s", buf, name);
} else
(void)fprintf(out, "%s", name);
r = archive_read_data_skip(a);
if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY ||
r == ARCHIVE_FATAL) {
(void)fprintf(out, "\n");
bsdar_warnc(bsdar, 0, "%s",
archive_error_string(a));
}
if (r == ARCHIVE_FATAL)
break;
(void)fprintf(out, "\n");
} else {
/* mode == 'x' || mode = 'p' */
if (mode == 'p') {
if (bsdar->options & AR_V) {
(void)fprintf(out, "\n<%s>\n\n",
name);
fflush(out);
}
r = archive_read_data_into_fd(a, fileno(out));
} else {
/* mode == 'x' */
if (stat(name, &sb) != 0) {
if (errno != ENOENT) {
bsdar_warnc(bsdar, 0,
"stat %s failed",
bsdar->filename);
continue;
}
} else {
/* stat success, file exist */
if (bsdar->options & AR_CC)
continue;
if (bsdar->options & AR_U &&
archive_entry_mtime(entry) <=
sb.st_mtime)
continue;
}
if (bsdar->options & AR_V)
(void)fprintf(out, "x - %s\n", name);
/* Disallow absolute paths. */
if (name[0] == '/') {
bsdar_warnc(bsdar, 0,
"Absolute path '%s'", name);
continue;
}
/* Basic path security flags. */
flags = ARCHIVE_EXTRACT_SECURE_SYMLINKS |
ARCHIVE_EXTRACT_SECURE_NODOTDOT;
if (bsdar->options & AR_O)
flags |= ARCHIVE_EXTRACT_TIME;
r = archive_read_extract(a, entry, flags);
}
if (r)
bsdar_warnc(bsdar, 0, "%s",
archive_error_string(a));
}
}
AC(archive_read_close(a));
ACV(archive_read_free(a));
}

View File

@ -0,0 +1,184 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* 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
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/queue.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include "ar.h"
ELFTC_VCSID("$Id: util.c 3174 2015-03-27 17:13:41Z emaste $");
static void bsdar_vwarnc(struct bsdar *, int code,
const char *fmt, va_list ap);
static void bsdar_verrc(struct bsdar *bsdar, int code,
const char *fmt, va_list ap);
static void
bsdar_vwarnc(struct bsdar *bsdar, int code, const char *fmt, va_list ap)
{
fprintf(stderr, "%s: warning: ", bsdar->progname);
vfprintf(stderr, fmt, ap);
if (code != 0)
fprintf(stderr, ": %s", strerror(code));
fprintf(stderr, "\n");
}
void
bsdar_warnc(struct bsdar *bsdar, int code, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
bsdar_vwarnc(bsdar, code, fmt, ap);
va_end(ap);
}
static void
bsdar_verrc(struct bsdar *bsdar, int code, const char *fmt, va_list ap)
{
fprintf(stderr, "%s: fatal: ", bsdar->progname);
vfprintf(stderr, fmt, ap);
if (code != 0)
fprintf(stderr, ": %s", strerror(code));
fprintf(stderr, "\n");
}
void
bsdar_errc(struct bsdar *bsdar, int code, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
bsdar_verrc(bsdar, code, fmt, ap);
va_end(ap);
exit(EXIT_FAILURE);
}
#define AR_STRMODE_SIZE 12
const char *
bsdar_strmode(mode_t m)
{
static char buf[AR_STRMODE_SIZE];
#if ELFTC_HAVE_STRMODE
/* Use the system's strmode(3). */
strmode(m, buf);
return buf;
#else
char c;
/*
* The first character of the string denotes the type of the
* entry.
*/
if (S_ISBLK(m))
c = 'b';
else if (S_ISCHR(m))
c = 'c';
else if (S_ISDIR(m))
c = 'd';
#if defined(S_ISFIFO)
else if (S_ISFIFO(m))
c = 'p';
#endif
#if defined(S_ISLNK)
else if (S_ISLNK(m))
c = 'l';
#endif
else if (S_ISREG(m))
c = '-';
#if defined(S_ISSOCK)
else if (S_ISSOCK(m))
c = 's';
#endif
else
c = '?';
buf[0] = c;
/* The next 3 characters show permissions for the owner. */
buf[1] = (m & S_IRUSR) ? 'r' : '-';
buf[2] = m & S_IWUSR ? 'w' : '-';
if (m & S_ISUID)
c = (m & S_IXUSR) ? 's' : 'S';
else
c = (m & S_IXUSR) ? 'x' : '-';
buf[3] = c;
/* The next 3 characters describe permissions for the group. */
buf[4] = (m & S_IRGRP) ? 'r' : '-';
buf[5] = m & S_IWGRP ? 'w' : '-';
if (m & S_ISGID)
c = (m & S_IXGRP) ? 's' : 'S';
else
c = (m & S_IXGRP) ? 'x' : '-';
buf[6] = c;
/* The next 3 characters describe permissions for others. */
buf[7] = (m & S_IROTH) ? 'r' : '-';
buf[8] = m & S_IWOTH ? 'w' : '-';
if (m & S_ISVTX) /* sticky bit */
c = (m & S_IXOTH) ? 't' : 'T';
else
c = (m & S_IXOTH) ? 'x' : '-';
buf[9] = c;
/* End the string with a blank and NUL-termination. */
buf[10] = ' ';
buf[11] = '\0';
return buf;
#endif /* !ELTC_HAVE_STRMODE */
}
int
bsdar_is_pseudomember(struct bsdar *bsdar, const char *name)
{
/*
* The "__.SYMDEF" member is special in the BSD format
* variant.
*/
if (bsdar->options & AR_BSD)
return (strcmp(name, AR_SYMTAB_NAME_BSD) == 0);
else
/*
* The names "/ " and "// " are special in the SVR4
* variant.
*/
return (strcmp(name, AR_STRINGTAB_NAME_SVR4) == 0 ||
strcmp(name, AR_SYMTAB_NAME_SVR4) == 0);
}

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