SYMROOT = .
endif
ARCH = $(shell arch)
-ifndef RC_ppc
-ifndef RC_i386
-RC_ppc = 1
+ifndef RC_ARCHS
+RC_$(ARCH) = 1
+RC_ARCHS = $(ARCH)
endif
-endif
-BSDMAKE = bsdmake -j 2
+# temporary disable multi-threaded builds, which are failing; see 3683272
+#BSDMAKE = bsdmake -j 2
+BSDMAKE = bsdmake
# Remove the arch stuff, since we know better here.
-LOCAL_CFLAGS = $(filter-out -arch ppc -arch i386,$(RC_CFLAGS))
+LOCAL_CFLAGS = $(filter-out -arch ppc -arch ppc64 -arch i386,$(RC_CFLAGS))
all: build
+
# These are the non B&I defaults
ifndef RC_ProjectName
installhdrs: installhdrs-real
# And these are to deal with B&I building libc differently
# based on RC_ProjectName.
ifeq ($(RC_ProjectName),Libc)
+installhdrs:
+build: build-dynamic
+install: BI-install-dynamic
+endif
+ifeq ($(RC_ProjectName),Libc_headers)
installhdrs: installhdrs-real
-build: build-man build-dynamic
-install: installhdrs-real BI-install-dynamic install-man
+build:
+install: installhdrs-real
+endif
+ifeq ($(RC_ProjectName),Libc_man)
+installhdrs:
+build:
+install: install-man
endif
ifeq ($(RC_ProjectName),Libc_static)
installhdrs:
install: BI-install-profile
endif
-build-man:
- MAKEOBJDIR="$(OBJROOT)" MACHINE_ARCH="$(shell arch)" \
- MAKEFLAGS="" $(BSDMAKE) buildman
-build-static: build-ppc-static build-i386-static
- @echo "Checking for libc_static.a"
- @if [ -f "$(OBJROOT)/obj.ppc/libc_static.a" -a -f "$(OBJROOT)/obj.i386/libc_static.a" ]; then\
- lipo -create -arch ppc "$(OBJROOT)/obj.ppc/libc_static.a" \
- -arch i386 "$(OBJROOT)/obj.i386/libc_static.a" \
- -output $(SYMROOT)/libc_static.a;\
- elif [ -f "$(OBJROOT)/obj.ppc/libc_static.a" ]; then \
- cp -p "$(OBJROOT)/obj.ppc/libc_static.a" "$(SYMROOT)"; \
- elif [ -f "$(OBJROOT)/obj.i386/libc_static.a" ]; then \
- cp -p "$(OBJROOT)/obj.i386/libc_static.a" "$(SYMROOT)"; \
- fi
-build-profile: build-ppc-profile build-i386-profile
- @echo "Checking for libc_profile.a"
- @if [ -f "$(OBJROOT)/obj.ppc/libc_profile.a" -a -f "$(OBJROOT)/obj.i386/libc_profile.a" ]; then\
- lipo -create -arch ppc "$(OBJROOT)/obj.ppc/libc_profile.a" \
- -arch i386 "$(OBJROOT)/obj.i386/libc_profile.a" \
- -output $(SYMROOT)/libc_profile.a;\
- elif [ -f "$(OBJROOT)/obj.ppc/libc_profile.a" ]; then \
- cp -p "$(OBJROOT)/obj.ppc/libc_profile.a" "$(SYMROOT)"; \
- elif [ -f "$(OBJROOT)/obj.i386/libc_profile.a" ]; then \
- cp -p "$(OBJROOT)/obj.i386/libc_profile.a" "$(SYMROOT)"; \
- fi
-build-debug: build-ppc-debug build-i386-debug
- @echo "Checking for libc_debug.a"
- @if [ -f "$(OBJROOT)/obj.ppc/libc_debug.a" -a -f "$(OBJROOT)/obj.i386/libc_debug.a" ]; then\
- lipo -create -arch ppc "$(OBJROOT)/obj.ppc/libc_debug.a" \
- -arch i386 "$(OBJROOT)/obj.i386/libc_debug.a" \
- -output $(SYMROOT)/libc_debug.a;\
- elif [ -f "$(OBJROOT)/obj.ppc/libc_debug.a" ]; then \
- cp -p "$(OBJROOT)/obj.ppc/libc_debug.a" "$(SYMROOT)"; \
- elif [ -f "$(OBJROOT)/obj.i386/libc_debug.a" ]; then \
- cp -p "$(OBJROOT)/obj.i386/libc_debug.a" "$(SYMROOT)"; \
- fi
-build-dynamic: build-ppc-dynamic build-i386-dynamic
- @echo "Checking for libc.a"
- @if [ -f "$(OBJROOT)/obj.ppc/libc.a" -a -f "$(OBJROOT)/obj.i386/libc.a" ]; then\
- echo "Creating FAT libc.a"; \
- lipo -create -arch ppc "$(OBJROOT)/obj.ppc/libc.a" -arch i386 \
- "$(OBJROOT)/obj.i386/libc.a" -output $(SYMROOT)/libc.a;\
- elif [ -f "$(OBJROOT)/obj.ppc/libc.a" ]; then \
- echo "Using thin PPC libc.a" ;\
- cp -p "$(OBJROOT)/obj.ppc/libc.a" "$(SYMROOT)"; \
- elif [ -f "$(OBJROOT)/obj.i386/libc.a" ]; then \
- echo "Using thin i386 libc.a" ;\
- cp -p "$(OBJROOT)/obj.i386/libc.a" "$(SYMROOT)"; \
- fi
+build-static: autopatch build-ppc-static build-ppc64-static build-i386-static
+ @echo "Creating final libc_static.a"
+ifeq ($(words $(RC_ARCHS)),1)
+ cp -p "$(OBJROOT)/obj.$(RC_ARCHS)/libc_static.a" "$(SYMROOT)"
+else
+ lipo -create \
+ $(foreach A,$(RC_ARCHS),-arch $(A) "$(OBJROOT)/obj.$(A)/libc_static.a") \
+ -output $(SYMROOT)/libc_static.a
+endif
+build-profile: autopatch build-ppc-profile build-ppc64-profile build-i386-profile
+ @echo "Creating final libc_profile.a"
+ifeq ($(words $(RC_ARCHS)),1)
+ cp -p "$(OBJROOT)/obj.$(RC_ARCHS)/libc_profile.a" "$(SYMROOT)"
+else
+ lipo -create \
+ $(foreach A,$(RC_ARCHS),-arch $(A) "$(OBJROOT)/obj.$(A)/libc_profile.a") \
+ -output $(SYMROOT)/libc_profile.a
+endif
+build-debug: autopatch build-ppc-debug build-ppc64-debug build-i386-debug
+ @echo "Creating final libc_debug.a"
+ifeq ($(words $(RC_ARCHS)),1)
+ cp -p "$(OBJROOT)/obj.$(RC_ARCHS)/libc_debug.a" "$(SYMROOT)"
+else
+ lipo -create \
+ $(foreach A,$(RC_ARCHS),-arch $(A) "$(OBJROOT)/obj.$(A)/libc_debug.a") \
+ -output $(SYMROOT)/libc_debug.a
+endif
+build-dynamic: autopatch build-ppc-dynamic build-ppc64-dynamic build-i386-dynamic
+ @echo "Creating final libc.a"
+ifeq ($(words $(RC_ARCHS)),1)
+ cp -p "$(OBJROOT)/obj.$(RC_ARCHS)/libc.a" "$(SYMROOT)"
+else
+ lipo -create \
+ $(foreach A,$(RC_ARCHS),-arch $(A) "$(OBJROOT)/obj.$(A)/libc.a") \
+ -output $(SYMROOT)/libc.a
+endif
build-ppc-static:
@if [ ! -z "$(RC_ppc)" ]; then \
mkdir -p $(OBJROOT)/obj.ppc ; \
MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \
MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" $(BSDMAKE) libc_static.a;\
fi
+build-ppc64-static:
+ @if [ ! -z "$(RC_ppc64)" ]; then \
+ mkdir -p $(OBJROOT)/obj.ppc64 ; \
+ MAKEOBJDIR="$(OBJROOT)/obj.ppc64" MACHINE_ARCH="ppc64" \
+ MAKEFLAGS="" CFLAGS="-arch ppc64 $(LOCAL_CFLAGS)" $(BSDMAKE) libc_static.a;\
+ fi
build-i386-static:
@if [ ! -z "$(RC_i386)" ]; then \
mkdir -p $(OBJROOT)/obj.i386 ; \
MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \
MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" $(BSDMAKE) libc_profile.a;\
fi
+build-ppc64-profile:
+ @if [ ! -z "$(RC_ppc64)" ]; then \
+ mkdir -p $(OBJROOT)/obj.ppc64 ; \
+ MAKEOBJDIR="$(OBJROOT)/obj.ppc64" MACHINE_ARCH="ppc64" \
+ MAKEFLAGS="" CFLAGS="-arch ppc64 $(LOCAL_CFLAGS)" $(BSDMAKE) libc_profile.a;\
+ fi
build-i386-profile:
@if [ ! -z "$(RC_i386)" ]; then \
mkdir -p $(OBJROOT)/obj.i386 ; \
MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \
MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" $(BSDMAKE) libc_debug.a;\
fi
+build-ppc64-debug:
+ @if [ ! -z "$(RC_ppc64)" ]; then \
+ mkdir -p $(OBJROOT)/obj.ppc64 ; \
+ MAKEOBJDIR="$(OBJROOT)/obj.ppc64" MACHINE_ARCH="ppc64" \
+ MAKEFLAGS="" CFLAGS="-arch ppc64 $(LOCAL_CFLAGS)" $(BSDMAKE) libc_debug.a;\
+ fi
build-i386-debug:
@if [ ! -z "$(RC_i386)" ]; then \
mkdir -p $(OBJROOT)/obj.i386 ; \
MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \
MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" $(BSDMAKE) libc.a;\
fi
+build-ppc64-dynamic:
+ @if [ ! -z "$(RC_ppc64)" ]; then \
+ mkdir -p $(OBJROOT)/obj.ppc64 ; \
+ MAKEOBJDIR="$(OBJROOT)/obj.ppc64" MACHINE_ARCH="ppc64" \
+ MAKEFLAGS="" CFLAGS="-arch ppc64 $(LOCAL_CFLAGS)" $(BSDMAKE) libc.a;\
+ fi
build-i386-dynamic:
@if [ ! -z "$(RC_i386)" ]; then \
mkdir -p $(OBJROOT)/obj.i386 ; \
MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \
MAKEFLAGS="" CFLAGS="-arch ppc $(LOCAL_CFLAGS)" $(BSDMAKE) build;\
fi
+build-ppc64:
+ @if [ ! -z "$(RC_ppc64)" ]; then \
+ mkdir -p $(OBJROOT)/obj.ppc64 ; \
+ MAKEOBJDIR="$(OBJROOT)/obj.ppc64" MACHINE_ARCH="ppc64" \
+ MAKEFLAGS="" CFLAGS="-arch ppc64 $(LOCAL_CFLAGS)" $(BSDMAKE) build;\
+ fi
build-i386:
@if [ ! -z "$(RC_i386)" ]; then \
mkdir -p $(OBJROOT)/obj.i386 ; \
MAKEOBJDIR="$(OBJROOT)/obj.i386" MACHINE_ARCH="i386" \
MAKEFLAGS="" CFLAGS="-arch i386 $(LOCAL_CFLAGS)" $(BSDMAKE) build;\
fi
+
+# We have to separately call bsdmake to patch the FreeBSD files, because of
+# the way its cache works, it would otherwise pick a file in ${SYMROOT}, even
+# over a .s file.
+autopatch:
+ @if [ ! -z "$(RC_i386)" ]; then \
+ MACHINE_ARCH="i386" $(BSDMAKE) autopatch; \
+ fi
+ @if [ ! -z "$(RC_ppc)" ]; then \
+ MACHINE_ARCH="ppc" $(BSDMAKE) autopatch; \
+ fi
+ @if [ ! -z "$(RC_ppc64)" ]; then \
+ MACHINE_ARCH="ppc64" $(BSDMAKE) autopatch; \
+ fi
+
installsrc:
$(_v) pax -rw . "$(SRCROOT)"
MAKEOBJDIR="$(OBJROOT)/obj.ppc" MACHINE_ARCH="ppc" \
MAKEFLAGS="" $(BSDMAKE) installhdrs-md ; \
fi
+ @if [ ! -z "$(RC_ppc64)" ]; then \
+ mkdir -p "$(OBJROOT)/obj.ppc64" ; \
+ MAKEOBJDIR="$(OBJROOT)/obj.ppc64" MACHINE_ARCH="ppc64" \
+ MAKEFLAGS="" $(BSDMAKE) installhdrs-md ; \
+ fi
BI-install-static: build-static
mkdir -p $(DSTROOT)/usr/local/lib/system
mkdir -p $(DSTROOT)/usr/share/man/man5
mkdir -p $(DSTROOT)/usr/share/man/man7
MAKEOBJDIR="$(OBJROOT)" DESTDIR="$(DSTROOT)" NOMANCOMPRESS=1 \
- MACHINE_ARCH="$(shell arch)" MAKEFLAGS="" bsdmake fbsdman maninstall
+ MACHINE_ARCH="$(shell arch)" MAKEFLAGS="" bsdmake autopatchman maninstall
-install-all: build install-man BI-install-dynamic BI-install-static BI-install-profile
+install-all: build install-man BI-install-dynamic BI-install-static BI-install-profile BI-install-debug
clean:
rm -rf $(OBJROOT)/obj.ppc $(OBJROOT)/obj.i386 $(OBJROOT)/libc.a \
.if (${MACHINE_ARCH} == unknown)
MACHINE_ARCH != /usr/bin/arch
.endif
-.if (${MACHINE_ARCH} == ppc)
+.if (${MACHINE_ARCH} == ppc) || (${MACHINE_ARCH} == ppc64)
CFLAGS += -faltivec -DALTIVEC
.endif
-CFLAGS += -DNOID -I${.CURDIR}/include -I${.CURDIR}/include/objc
-PRIVINC = ${NEXT_ROOT}/System/Library/Frameworks/System.framework/PrivateHeaders
-CFLAGS += -I${PRIVINC}
+CFLAGS += -DNOID
+.ifdef ALTLIBCHEADERS
+CFLAGS += -I${ALTLIBCHEADERS}
+.else
+CFLAGS += -I${.CURDIR}/include
+.endif
+.ifdef ALTFRAMEWORKSPATH
+PRIVINC = -F${ALTFRAMEWORKSPATH} -I${ALTFRAMEWORKSPATH}/System.framework/PrivateHeaders
+.else
+PRIVINC = -I${NEXT_ROOT}/System/Library/Frameworks/System.framework/PrivateHeaders
+.endif
+CFLAGS += ${PRIVINC}
CFLAGS += -DLIBC_MAJOR=${SHLIB_MAJOR} -no-cpp-precomp -force_cpusubtype_ALL
CFLAGS += -arch ${MACHINE_ARCH} -fno-common -pipe -Wmost -g
CFLAGS += -finline-limit=5000 -D__FBSDID=__RCSID -Wno-long-double
-CFLAGS += -D__APPLE_PR3275149_HACK__
AINC= -I${.CURDIR}/${MACHINE_ARCH} -no-cpp-precomp -force_cpusubtype_ALL
AINC+=-arch ${MACHINE_ARCH} -g
CLEANFILES+=tags
DSTROOT ?= /
OBJROOT ?= .
SRCROOT ?= ${.CURDIR}
+.ifndef SYMROOT
+SYMROOT = ${.CURDIR}/SYMROOT
+_x_ != test -d ${SYMROOT} || mkdir -p ${SYMROOT}
+.endif
DESTDIR ?= ${DSTROOT}
MAKEOBJDIR ?= ${OBJROOT}
+CFLAGS += -I${SYMROOT}
.include "${.CURDIR}/Makefile.inc"
+.PATH: ${SYMROOT}
.include "Makefile.xbs"
.include <bsd.man.mk>
FBSDMAN9=
FBSDMDSRCS=
FBSDMISRCS=
-FBSDORIGHDRS=
+FBSDHDRS=
FBSDSRCS=
FBSDSECTIONS= 1 2 3 4 5 6 7 8 9
-.if !target(_FBSDPATCH)
-_FBSDPATCH: .USE
- @if [ -f ${.ALLSRC}.patch ]; then \
- echo cp ${.ALLSRC} ${.TARGET}; \
- cp ${.ALLSRC} ${.TARGET}; \
- echo patch ${.TARGET} ${.ALLSRC}.patch; \
- patch ${.TARGET} ${.ALLSRC}.patch; \
- else \
- echo ln -s ${.ALLSRC} ${.TARGET}; \
- ln -s ${.ALLSRC} ${.TARGET}; \
- fi
-.endif
-.if !target(_FBSDPATCH)
-_FBSDPATCH: .USE
- cp ${.ALLSRC} ${.TARGET}; \
- patch ${.TARGET} ${.ALLSRC}.patch
-.endif
-
.for _src in ${FBSDSRCS}
-${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _FBSDPATCH
+${SYMROOT}/${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _AUTOPATCHSYM
SRCS+= ${_src}
+AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-fbsd.${_src:E}
.endfor
.for _src in ${FBSDMDSRCS}
-${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _FBSDPATCH
+${SYMROOT}/${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _AUTOPATCHSYM
MDSRCS+= ${_src}
+AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-fbsd.${_src:E}
.endfor
.for _src in ${FBSDMISRCS}
-${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _FBSDPATCH
+${SYMROOT}/${_src:R}-fbsd.${_src:E}: FreeBSD/${_src} _AUTOPATCHSYM
MISRCS+= ${_src}
+AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-fbsd.${_src:E}
.endfor
-.for _src in ${FBSDORIGHDRS}
-${_src}: FreeBSD/${_src} _FBSDPATCH
-FBSDHDRS+= ${_src}
+.for _src in ${FBSDHDRS}
+${SYMROOT}/${_src}: FreeBSD/${_src} _AUTOPATCHSYM
+AUTOPATCHHDRS+= ${SYMROOT}/${_src}
.endfor
.for _sect in ${FBSDSECTIONS}
.for _src in ${FBSDMAN${_sect}}
-${_src}: FreeBSD/${_src} _FBSDPATCH
+${_src}: FreeBSD/${_src} _AUTOPATCH
MAN${_sect}+= ${_src}
-FBSDPATCHMAN+= ${_src}
+AUTOPATCHMAN+= ${_src}
.endfor
.endfor
# Use MDSRCS to block one file, and SUPPRESSSRCS to block the others.
SUPPRESSSRCS=
-# Variable needed by the FreeBSD auto-patching mechanism
-FBSDHDRS=
-FBSDPATCHMAN=
+# Auto-patching variables
+AUTOPATCHHDRS=
+AUTOPATCHMAN=
+AUTOPATCHSRCS=
+
+# Auto-patch into OBJROOT
+_AUTOPATCH: .USE
+ @if [ -f ${.ALLSRC}.patch ]; then \
+ echo cp ${.ALLSRC} ${.TARGET}; \
+ cp ${.ALLSRC} ${.TARGET}; \
+ echo patch ${.TARGET} ${.ALLSRC}.patch; \
+ patch ${.TARGET} ${.ALLSRC}.patch; \
+ else \
+ echo ln -s ${.ALLSRC} ${.TARGET}; \
+ ln -s ${.ALLSRC} ${.TARGET}; \
+ fi
+# Auto-patch into SYMROOT
+_AUTOPATCHSYM: .USE
+ @echo cp ${.ALLSRC} ${.TARGET}; \
+ cp ${.ALLSRC} ${.TARGET}; \
+ if [ -f ${.ALLSRC}.patch ]; then \
+ echo patch ${.TARGET} ${.ALLSRC}.patch; \
+ patch ${.TARGET} ${.ALLSRC}.patch; \
+ fi
#
# If there is a machine dependent makefile, use it:
.include "${.CURDIR}/db/Makefile.inc"
.include "${.CURDIR}/compat-43/Makefile.inc"
+.include "${.CURDIR}/emulated/Makefile.inc"
.include "${.CURDIR}/gdtoa/Makefile.inc"
.include "${.CURDIR}/gen/Makefile.inc"
.include "${.CURDIR}/gmon/Makefile.inc"
.include "${.CURDIR}/sys/Makefile.inc"
.include "${.CURDIR}/threads/Makefile.inc"
.include "${.CURDIR}/util/Makefile.inc"
+.include "${.CURDIR}/uuid/Makefile.inc"
#.include "${.CURDIR}/rpc/Makefile.inc"
#.include "${.CURDIR}/xdr/Makefile.inc"
-.if !defined(NO_YP_LIBC)
-CFLAGS+= -DYP
+#.if !defined(NO_YP_LIBC)
+#CFLAGS+= -DYP
#.include "${.CURDIR}/yp/Makefile.inc"
-.endif
-.if !defined(NO_HESIOD_LIBC)
-CFLAGS+= -DHESIOD
-.endif
+#.endif
+#.if !defined(NO_HESIOD_LIBC)
+#CFLAGS+= -DHESIOD
+#.endif
# If there are no machine dependent sources, append all the
# machine-independent sources:
.MAIN: all
all: libc.a libc_static.a libc_debug.a libc_profile.a
install: installhdrs install_libc.a install_libc_static.a \
- install_libc_profile.a install_libc_debug.a fbsdman maninstall
+ install_libc_profile.a install_libc_debug.a autopatchman maninstall
.SUFFIXES:
-.SUFFIXES: .o .po .So .do .S .s -fbsd.c .c .cc .cpp .cxx .m .C .f .y .l .defs .h
+.SUFFIXES: .o .po .So .do .S .s .c .cc .cpp .cxx .m .C
+.SUFFIXES: -fbsd.c -uuid.c .3-uuid.in .3
+.SUFFIXES: .f .y .l .defs .h
.SUFFIXES: User.c User.o User.po User.So User.do
.SUFFIXES: Server.c Server.o Server.po Server.So Server.do
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
POBJS+= ${OBJS:.o=.po} ${STATICOBJS:.o=.po}
SOBJS+= ${OBJS:.o=.So}
+
+#### FreeBSD Rules ##################################################
FBSDFLAGS= -I${.CURDIR}/fbsdcompat -include _fbsd_compat_.h
-fbsd.c.o:
- ${CC} -static ${FBSDFLAGS} ${CFLAGS} -Os -c ${.IMPSRC} -o ${.TARGET}
-.c.o User.cUser.o Server.cServer.o:
- ${CC} -static ${CFLAGS} -Os -c ${.IMPSRC} -o ${.TARGET}
+ ${CC} -static ${FBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
-fbsd.c.po:
- ${CC} -pg -DPROFILE ${FBSDFLAGS} ${CFLAGS} -Os -c ${.IMPSRC} \
- -o ${.TARGET}
-.c.po User.cUser.po Server.cServer.po:
- ${CC} -pg -DPROFILE ${CFLAGS} -Os -c ${.IMPSRC} -o ${.TARGET}
+ ${CC} -pg -DPROFILE ${FBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
-fbsd.c.So:
- ${CC} ${FBSDFLAGS} ${CFLAGS} -Os -c ${.IMPSRC} -o ${.TARGET}
-.c.So User.cUser.So Server.cServer.So:
- ${CC} ${CFLAGS} -Os -c ${.IMPSRC} -o ${.TARGET}
+ ${CC} ${FBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
-fbsd.c.do:
- ${CC} -g -DDEBUG ${FBSDFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+ ${CC} -g -DDEBUG ${FBSDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -c ${.IMPSRC} -o ${.TARGET}
+
+#### UUID Rules ######################################################
+UUIDFLAGS= -I${.CURDIR}/uuid -include uuid-config.h
+
+-uuid.c.o:
+ ${CC} -static ${UUIDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
+-uuid.c.po:
+ ${CC} -pg -DPROFILE ${UUIDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
+-uuid.c.So:
+ ${CC} ${UUIDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
+-uuid.c.do:
+ ${CC} -g -DDEBUG ${UUIDFLAGS} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -c ${.IMPSRC} -o ${.TARGET}
+.3-uuid.in.3:
+ sed -f ${.CURDIR}/uuid/uuidman.sed ${.IMPSRC} > ${.TARGET}
+
+#### Standard C Rules #################################################
+.c.o User.cUser.o Server.cServer.o:
+ ${CC} -static ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
+.c.po User.cUser.po Server.cServer.po:
+ ${CC} -pg -DPROFILE ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
+.c.So User.cUser.So Server.cServer.So:
+ ${CC} ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
.c.do User.cUser.do Server.cServer.do:
- ${CC} -g -DDEBUG ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
--fbsd.s.o:
- ${CC} -x assembler-with-cpp ${FBSDFLAGS} ${CFLAGS:M-[BID]*} \
- -static ${AINC} -c ${.IMPSRC} -o ${.TARGET}
+ ${CC} -g -DDEBUG ${CFLAGS} ${CFLAGS-${.IMPSRC:T}} \
+ -c ${.IMPSRC} -o ${.TARGET}
+
+#### Standard Assembler Rules #########################################
.s.o:
- ${CC} -x assembler-with-cpp ${CFLAGS:M-[BID]*} -static ${AINC} -c \
- ${.IMPSRC} -o ${.TARGET}
--fbsd.s.po:
- ${CC} -pg -DPROFILE -x assembler-with-cpp ${FBSDFLAGS} \
- ${CFLAGS:M-[BID]*} -Os ${AINC} -c ${.IMPSRC} -o ${.TARGET}
+ ${CC} -static -x assembler-with-cpp ${CFLAGS:M-[BIDF]*} \
+ ${CFLAGS-${.IMPSRC:T}:M-[BIDF]*} ${AINC} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
.s.po:
- ${CC} -pg -DPROFILE -x assembler-with-cpp ${CFLAGS:M-[BID]*} -Os \
- ${AINC} -c ${.IMPSRC} -o ${.TARGET}
--fbsd.s.So:
- ${CC} -x assembler-with-cpp ${FBSDFLAGS} \
- ${CFLAGS:M-[BID]*} -Os ${AINC} -c ${.IMPSRC} -o ${.TARGET}
+ ${CC} -pg -DPROFILE -x assembler-with-cpp ${CFLAGS:M-[BIDF]*} \
+ ${CFLAGS-${.IMPSRC:T}:M-[BIDF]*} ${AINC} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
.s.So:
- ${CC} -x assembler-with-cpp \
- ${CFLAGS:M-[BID]*} -Os ${AINC} -c ${.IMPSRC} -o ${.TARGET}
--fbsd.s.do:
- ${CC} -DDEBUG -g -x assembler-with-cpp ${FBSDFLAGS} ${CFLAGS:M-[BID]*} \
- ${AINC} -c ${.IMPSRC} -o ${.TARGET}
+ ${CC} -x assembler-with-cpp ${CFLAGS:M-[BIDF]*} \
+ ${CFLAGS-${.IMPSRC:T}:M-[BIDF]*} ${AINC} \
+ -Os -c ${.IMPSRC} -o ${.TARGET}
.s.do:
- ${CC} -DDEBUG -g -x assembler-with-cpp ${CFLAGS:M-[BID]*} ${AINC} -c \
- ${.IMPSRC} -o ${.TARGET}
+ ${CC} -g -DDEBUG -x assembler-with-cpp ${CFLAGS:M-[BIDF]*} \
+ ${CFLAGS-${.IMPSRC:T}:M-[BIDF]*} ${AINC} \
+ -c ${.IMPSRC} -o ${.TARGET}
+
+#### mig Rules ########################################################
.defs.h .defsUser.c .defsServer.c:
mig -arch ${MACHINE_ARCH} -user ${.PREFIX}User.c -server ${.PREFIX}Server.c -header ${.PREFIX}.h ${.IMPSRC}
gen_mig_defs: ${SRVMIGHDRS} ${MIGHDRS}
gen_md_mig_defs: ${MD_MIGHDRS}
-lib${LIB}_static.a:: ${FBSDHDRS} ${OBJS} ${STATICOBJS}
+lib${LIB}_static.a:: ${OBJS} ${STATICOBJS}
@${ECHO} building static ${LIB} library
@rm -f lib${LIB}_static.a
@${AR} cq lib${LIB}_static.a `lorder ${OBJS} ${STATICOBJS} | tsort -q` ${ARADD}
${RANLIB} lib${LIB}_static.a
-lib${LIB}_profile.a:: ${FBSDHDRS} ${POBJS}
+lib${LIB}_profile.a:: ${POBJS}
@${ECHO} building profiled ${LIB} library
@rm -f lib${LIB}_profile.a
@${AR} cq lib${LIB}_profile.a `lorder ${POBJS} | tsort -q` ${ARADD}
${RANLIB} lib${LIB}_profile.a
DOBJS+= ${OBJS:.o=.do}
-lib${LIB}_debug.a:: ${FBSDHDRS} ${DOBJS}
+lib${LIB}_debug.a:: ${DOBJS}
@${ECHO} building debug ${LIB} library
@rm -f lib${LIB}_debug.a
@${AR} cq lib${LIB}_debug.a `lorder ${DOBJS} | tsort -q` ${ARADD}
${RANLIB} lib${LIB}_debug.a
-lib${LIB}.a:: ${FBSDHDRS} ${SOBJS}
+lib${LIB}.a:: ${SOBJS}
@${ECHO} building standard ${LIB} library
@rm -f lib${LIB}.a
@${AR} cq lib${LIB}.a `lorder ${SOBJS} | tsort -q` ${ARADD}
mkdir -p ${INCDIR}/mach/${MACHINE_ARCH}
${INSTALL} -c -m 444 ${MD_MIGHDRS} ${INCDIR}/mach/${MACHINE_ARCH}
-installhdrs: ${FBSDHDRS} gen_mig_defs
+installhdrs: autopatchhdrs gen_mig_defs
mkdir -p ${INCDIR}/arpa
+ mkdir -p ${INCDIR}/libkern
mkdir -p ${INCDIR}/mach
mkdir -p ${INCDIR}/malloc
mkdir -p ${INCDIR}/objc
mkdir -p ${INCDIR}/protocols
mkdir -p ${INCDIR}/servers
+ mkdir -p ${INCDIR}/sys
${INSTALL} -c -m 444 ${INSTHDRS} ${INCDIR}
${INSTALL} -c -m 444 ${ARPA_INSTHDRS} ${INCDIR}/arpa
+ ${INSTALL} -c -m 444 ${LIBKERN_INSTHDRS} ${INCDIR}/libkern
${INSTALL} -c -m 444 ${MACH_INSTHDRS} ${INCDIR}/mach
${INSTALL} -c -m 444 ${MALLOC_INSTHDRS} ${INCDIR}/malloc
${INSTALL} -c -m 444 ${OBJC_INSTHDRS} ${INCDIR}/objc
${INSTALL} -c -m 444 ${PROTO_INSTHDRS} ${INCDIR}/protocols
${INSTALL} -c -m 444 ${SRVHDRS} ${INCDIR}/servers
+ ${INSTALL} -c -m 444 ${SYS_INSTHDRS} ${INCDIR}/sys
mkdir -p ${LOCINCDIR}
${INSTALL} -c -m 444 ${LOCALHDRS} ${LOCINCDIR}
mkdir -p ${PRIVHDRS}/architecture/ppc
mkdir -p ${PRIVHDRS}/btree
mkdir -p ${PRIVHDRS}/machine
mkdir -p ${PRIVHDRS}/objc
+ mkdir -p ${PRIVHDRS}/sys
${INSTALL} -c -m 444 ${SRCROOT}/ppc/sys/processor_facilities.h ${PRIVHDRS}/architecture/ppc
- ${INSTALL} -c -m 444 ${SRCROOT}/db/btree/btree.h ${PRIVHDRS}/btree
- ${INSTALL} -c -m 444 ${SRCROOT}/db/btree/bt_extern.h ${PRIVHDRS}/btree
+ ${INSTALL} -c -m 444 ${SYMROOT}/btree.h ${PRIVHDRS}/btree
+ ${INSTALL} -c -m 444 ${SYMROOT}/bt_extern.h ${PRIVHDRS}/btree
${INSTALL} -c -m 444 ${SRCROOT}/internat/NXCType.h ${PRIVHDRS}/objc
${INSTALL} -c -m 444 ${SRCROOT}/gen/stack_logging.h ${PRIVHDRS}
mv ${DESTDIR}/usr/include/asm.h ${PRIVHDRS}/machine
mv ${INCDIR}/servers/srvbootstrap.h ${INCDIR}/servers/bootstrap.h
+ @for i in `find ${DESTDIR}/usr/include/mach ${DESTDIR}/usr/include/servers -name \*.h`; do \
+ x=`fgrep '<mach/mig.h>' $$i | uniq -d`; \
+ if [ -n "$$x" ]; then \
+ echo patching $$i; \
+ ed - $$i < ${SRCROOT}/fixdups.ed; \
+ fi; \
+ done
+ ${INSTALL} -c -m 444 ${SYS_INSTHDRS} ${PRIVHDRS}/sys
+ mkdir -p ${INCDIR}/uuid
+ ${INSTALL} -c -m 444 ${SYMROOT}/uuid.h ${INCDIR}/uuid
install_lib${LIB}_static.a:
${INSTALL} -c -m 444 lib${LIB}_static.a ${DESTDIR}/usr/local/lib/system/
install_lib${LIB}.a:
${INSTALL} -c -m 444 lib${LIB}.a ${DESTDIR}/usr/local/lib/system/
-fbsdman: ${FBSDPATCHMAN}
+autopatch: autopatchhdrs ${AUTOPATCHSRCS}
+autopatchhdrs: ${AUTOPATCHHDRS}
+autopatchman: ${AUTOPATCHMAN}
clean:
rm -f ${OBJS} ${POBJS} ${DOBJS} ${SOBJS} ${CLEANFILES}
fchmod
chown
fchown
+lchown
chroot
close
connect
# compat-43 sources
.PATH: ${.CURDIR}/${MACHINE_ARCH}/compat-43 ${.CURDIR}/compat-43
-SRCS+= creat.c gethostid.c getwd.c killpg.c sethostid.c setpgrp.c \
+MISRCS+= creat.c gethostid.c getwd.c killpg.c sethostid.c setpgrp.c \
setrgid.c setruid.c sigcompat.c
MAN+= creat.2 killpg.2 sigpause.2 sigsetmask.2 sigvec.2
# compat-43 sources
.PATH: ${.CURDIR}/${MACHINE_ARCH}/compat-43 ${.CURDIR}/compat-43
-SRCS+= setregid.c setreuid.c sigcompat.c
+MISRCS+= setregid.c setreuid.c sigcompat.c
.include "Makefile.fbsd_begin"
-FBSDSRCS= creat.c gethostid.c getwd.c killpg.c sethostid.c setpgrp.c \
+FBSDMISRCS= creat.c gethostid.c getwd.c killpg.c sethostid.c setpgrp.c \
setrgid.c setruid.c
.include "Makefile.fbsd_end"
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
extern int _sigaction_nobind (int sig, const struct sigaction *nsv, struct sigaction *osv);
#endif
-static int sigvec__(signo, sv, osv, bind)
+static int
+sigvec__(signo, sv, osv, bind)
int signo;
struct sigvec *sv, *osv;
int bind;
return (ret);
}
-int sigvec(signo, sv, osv)
+int
+sigvec(signo, sv, osv)
int signo;
struct sigvec *sv, *osv;
{
}
#if defined(__DYNAMIC__)
-int _sigvec_nobind(signo, sv, osv)
+int
+_sigvec_nobind(signo, sv, osv)
int signo;
struct sigvec *sv, *osv;
{
}
#endif
-int sigsetmask(mask)
+int
+sigsetmask(mask)
int mask;
{
int omask, n;
return (omask);
}
-int sigblock(mask)
+int
+sigblock(mask)
int mask;
{
int omask, n;
return (omask);
}
-int sigpause(mask)
+int
+sigpause(mask)
int mask;
{
return (sigsuspend((sigset_t *)&mask));
}
-int sighold(sig)
+int
+sighold(sig)
int sig;
{
sigset_t mask;
sigaddset(&mask, sig);
return(sigprocmask(SIG_BLOCK, &mask,(sigset_t *)0));
}
-int sigrelse(sig)
+
+int
+sigrelse(sig)
int sig;
{
sigset_t mask;
return(sigprocmask(SIG_UNBLOCK, &mask,(sigset_t *)0));
}
+
+int
+sigignore(sig)
+ int sig;
+{
+ return (signal(sig, SIG_IGN) == SIG_ERR ? -1 : 0);
+}
+
# from @(#)Makefile.inc 8.2 (Berkeley) 2/21/94
-# $FreeBSD: src/ldb/Makefile.inc,v 1.3 1999/08/27 23:58:15 peter Exp $
+# $FreeBSD: src/lib/libc/db/Makefile.inc,v 1.4 2002/11/18 09:50:54 ru Exp $
#
-CFLAGS+=-D__DBINTERFACE_PRIVATE
.include "${.CURDIR}/db/btree/Makefile.inc"
.include "${.CURDIR}/db/db/Makefile.inc"
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_close.c 8.7 (Berkeley) 8/17/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_close.c,v 1.8 2002/03/22 21:52:00 obrien Exp $");
+
+#include "namespace.h"
+#include <sys/param.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "un-namespace.h"
+
+#include <db.h>
+#include "btree.h"
+
+static int bt_meta(BTREE *);
+
+/*
+ * BT_CLOSE -- Close a btree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__bt_close(dbp)
+ DB *dbp;
+{
+ BTREE *t;
+ int fd;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Sync the tree. */
+ if (__bt_sync(dbp, 0) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Close the memory pool. */
+ if (mpool_close(t->bt_mp) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Free random memory. */
+ if (t->bt_cursor.key.data != NULL) {
+ free(t->bt_cursor.key.data);
+ t->bt_cursor.key.size = 0;
+ t->bt_cursor.key.data = NULL;
+ }
+ if (t->bt_rkey.data) {
+ free(t->bt_rkey.data);
+ t->bt_rkey.size = 0;
+ t->bt_rkey.data = NULL;
+ }
+ if (t->bt_rdata.data) {
+ free(t->bt_rdata.data);
+ t->bt_rdata.size = 0;
+ t->bt_rdata.data = NULL;
+ }
+
+ fd = t->bt_fd;
+ free(t);
+ free(dbp);
+ return (_close(fd) ? RET_ERROR : RET_SUCCESS);
+}
+
+/*
+ * BT_SYNC -- sync the btree to disk.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__bt_sync(dbp, flags)
+ const DB *dbp;
+ u_int flags;
+{
+ BTREE *t;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Sync doesn't currently take any flags. */
+ if (flags != 0) {
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED))
+ return (RET_SUCCESS);
+
+ if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
+ return (RET_ERROR);
+
+ if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS)
+ F_CLR(t, B_MODIFIED);
+
+ return (status);
+}
+
+/*
+ * BT_META -- write the tree meta data to disk.
+ *
+ * Parameters:
+ * t: tree
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+static int
+bt_meta(t)
+ BTREE *t;
+{
+ BTMETA m;
+ void *p;
+
+ if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL)
+ return (RET_ERROR);
+
+ /* Fill in metadata. */
+ m.magic = BTREEMAGIC;
+ m.version = BTREEVERSION;
+ m.psize = t->bt_psize;
+ m.free = t->bt_free;
+ m.nrecs = t->bt_nrecs;
+ m.flags = F_ISSET(t, SAVEMETA);
+
+ memmove(p, &m, sizeof(BTMETA));
+ mpool_put(t->bt_mp, p, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_conv.c 8.5 (Berkeley) 8/17/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_conv.c,v 1.2 2002/03/21 22:46:25 obrien Exp $");
+
+#include <sys/param.h>
+
+#include <stdio.h>
+
+#include <db.h>
+#include "btree.h"
+
+static void mswap(PAGE *);
+
+/*
+ * __BT_BPGIN, __BT_BPGOUT --
+ * Convert host-specific number layout to/from the host-independent
+ * format stored on disk.
+ *
+ * Parameters:
+ * t: tree
+ * pg: page number
+ * h: page to convert
+ */
+void
+__bt_pgin(t, pg, pp)
+ void *t;
+ pgno_t pg;
+ void *pp;
+{
+ PAGE *h;
+ indx_t i, top;
+ u_char flags;
+ char *p;
+
+ if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
+ return;
+ if (pg == P_META) {
+ mswap(pp);
+ return;
+ }
+
+ h = pp;
+ M_32_SWAP(h->pgno);
+ M_32_SWAP(h->prevpg);
+ M_32_SWAP(h->nextpg);
+ M_32_SWAP(h->flags);
+ M_16_SWAP(h->lower);
+ M_16_SWAP(h->upper);
+
+ top = NEXTINDEX(h);
+ if ((h->flags & P_TYPE) == P_BINTERNAL)
+ for (i = 0; i < top; i++) {
+ M_16_SWAP(h->linp[i]);
+ p = (char *)GETBINTERNAL(h, i);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ if (*(u_char *)p & P_BIGKEY) {
+ p += sizeof(u_char);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ }
+ else if ((h->flags & P_TYPE) == P_BLEAF)
+ for (i = 0; i < top; i++) {
+ M_16_SWAP(h->linp[i]);
+ p = (char *)GETBLEAF(h, i);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ flags = *(u_char *)p;
+ if (flags & (P_BIGKEY | P_BIGDATA)) {
+ p += sizeof(u_char);
+ if (flags & P_BIGKEY) {
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ if (flags & P_BIGDATA) {
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ }
+ }
+}
+
+void
+__bt_pgout(t, pg, pp)
+ void *t;
+ pgno_t pg;
+ void *pp;
+{
+ PAGE *h;
+ indx_t i, top;
+ u_char flags;
+ char *p;
+
+ if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
+ return;
+ if (pg == P_META) {
+ mswap(pp);
+ return;
+ }
+
+ h = pp;
+ top = NEXTINDEX(h);
+ if ((h->flags & P_TYPE) == P_BINTERNAL)
+ for (i = 0; i < top; i++) {
+ p = (char *)GETBINTERNAL(h, i);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ if (*(u_char *)p & P_BIGKEY) {
+ p += sizeof(u_char);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ M_16_SWAP(h->linp[i]);
+ }
+ else if ((h->flags & P_TYPE) == P_BLEAF)
+ for (i = 0; i < top; i++) {
+ p = (char *)GETBLEAF(h, i);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(u_int32_t);
+ flags = *(u_char *)p;
+ if (flags & (P_BIGKEY | P_BIGDATA)) {
+ p += sizeof(u_char);
+ if (flags & P_BIGKEY) {
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ if (flags & P_BIGDATA) {
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p);
+ p += sizeof(pgno_t);
+ P_32_SWAP(p);
+ }
+ }
+ M_16_SWAP(h->linp[i]);
+ }
+
+ M_32_SWAP(h->pgno);
+ M_32_SWAP(h->prevpg);
+ M_32_SWAP(h->nextpg);
+ M_32_SWAP(h->flags);
+ M_16_SWAP(h->lower);
+ M_16_SWAP(h->upper);
+}
+
+/*
+ * MSWAP -- Actually swap the bytes on the meta page.
+ *
+ * Parameters:
+ * p: page to convert
+ */
+static void
+mswap(pg)
+ PAGE *pg;
+{
+ char *p;
+
+ p = (char *)pg;
+ P_32_SWAP(p); /* magic */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* version */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* psize */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* free */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* nrecs */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* flags */
+ p += sizeof(u_int32_t);
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_debug.c 8.5 (Berkeley) 8/17/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_debug.c,v 1.2 2002/03/22 21:52:01 obrien Exp $");
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+#ifdef DEBUG
+/*
+ * BT_DUMP -- Dump the tree
+ *
+ * Parameters:
+ * dbp: pointer to the DB
+ */
+void
+__bt_dump(dbp)
+ DB *dbp;
+{
+ BTREE *t;
+ PAGE *h;
+ pgno_t i;
+ char *sep;
+
+ t = dbp->internal;
+ (void)fprintf(stderr, "%s: pgsz %d",
+ F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize);
+ if (F_ISSET(t, R_RECNO))
+ (void)fprintf(stderr, " keys %lu", t->bt_nrecs);
+#undef X
+#define X(flag, name) \
+ if (F_ISSET(t, flag)) { \
+ (void)fprintf(stderr, "%s%s", sep, name); \
+ sep = ", "; \
+ }
+ if (t->flags != 0) {
+ sep = " flags (";
+ X(R_FIXLEN, "FIXLEN");
+ X(B_INMEM, "INMEM");
+ X(B_NODUPS, "NODUPS");
+ X(B_RDONLY, "RDONLY");
+ X(R_RECNO, "RECNO");
+ X(B_METADIRTY,"METADIRTY");
+ (void)fprintf(stderr, ")\n");
+ }
+#undef X
+
+ for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
+ __bt_dpage(h);
+ (void)mpool_put(t->bt_mp, h, 0);
+ }
+}
+
+/*
+ * BT_DMPAGE -- Dump the meta page
+ *
+ * Parameters:
+ * h: pointer to the PAGE
+ */
+void
+__bt_dmpage(h)
+ PAGE *h;
+{
+ BTMETA *m;
+ char *sep;
+
+ m = (BTMETA *)h;
+ (void)fprintf(stderr, "magic %lx\n", m->magic);
+ (void)fprintf(stderr, "version %lu\n", m->version);
+ (void)fprintf(stderr, "psize %lu\n", m->psize);
+ (void)fprintf(stderr, "free %lu\n", m->free);
+ (void)fprintf(stderr, "nrecs %lu\n", m->nrecs);
+ (void)fprintf(stderr, "flags %lu", m->flags);
+#undef X
+#define X(flag, name) \
+ if (m->flags & flag) { \
+ (void)fprintf(stderr, "%s%s", sep, name); \
+ sep = ", "; \
+ }
+ if (m->flags) {
+ sep = " (";
+ X(B_NODUPS, "NODUPS");
+ X(R_RECNO, "RECNO");
+ (void)fprintf(stderr, ")");
+ }
+}
+
+/*
+ * BT_DNPAGE -- Dump the page
+ *
+ * Parameters:
+ * n: page number to dump.
+ */
+void
+__bt_dnpage(dbp, pgno)
+ DB *dbp;
+ pgno_t pgno;
+{
+ BTREE *t;
+ PAGE *h;
+
+ t = dbp->internal;
+ if ((h = mpool_get(t->bt_mp, pgno, 0)) != NULL) {
+ __bt_dpage(h);
+ (void)mpool_put(t->bt_mp, h, 0);
+ }
+}
+
+/*
+ * BT_DPAGE -- Dump the page
+ *
+ * Parameters:
+ * h: pointer to the PAGE
+ */
+void
+__bt_dpage(h)
+ PAGE *h;
+{
+ BINTERNAL *bi;
+ BLEAF *bl;
+ RINTERNAL *ri;
+ RLEAF *rl;
+ indx_t cur, top;
+ char *sep;
+
+ (void)fprintf(stderr, " page %d: (", h->pgno);
+#undef X
+#define X(flag, name) \
+ if (h->flags & flag) { \
+ (void)fprintf(stderr, "%s%s", sep, name); \
+ sep = ", "; \
+ }
+ sep = "";
+ X(P_BINTERNAL, "BINTERNAL") /* types */
+ X(P_BLEAF, "BLEAF")
+ X(P_RINTERNAL, "RINTERNAL") /* types */
+ X(P_RLEAF, "RLEAF")
+ X(P_OVERFLOW, "OVERFLOW")
+ X(P_PRESERVE, "PRESERVE");
+ (void)fprintf(stderr, ")\n");
+#undef X
+
+ (void)fprintf(stderr, "\tprev %2d next %2d", h->prevpg, h->nextpg);
+ if (h->flags & P_OVERFLOW)
+ return;
+
+ top = NEXTINDEX(h);
+ (void)fprintf(stderr, " lower %3d upper %3d nextind %d\n",
+ h->lower, h->upper, top);
+ for (cur = 0; cur < top; cur++) {
+ (void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]);
+ switch (h->flags & P_TYPE) {
+ case P_BINTERNAL:
+ bi = GETBINTERNAL(h, cur);
+ (void)fprintf(stderr,
+ "size %03d pgno %03d", bi->ksize, bi->pgno);
+ if (bi->flags & P_BIGKEY)
+ (void)fprintf(stderr, " (indirect)");
+ else if (bi->ksize)
+ (void)fprintf(stderr,
+ " {%.*s}", (int)bi->ksize, bi->bytes);
+ break;
+ case P_RINTERNAL:
+ ri = GETRINTERNAL(h, cur);
+ (void)fprintf(stderr, "entries %03d pgno %03d",
+ ri->nrecs, ri->pgno);
+ break;
+ case P_BLEAF:
+ bl = GETBLEAF(h, cur);
+ if (bl->flags & P_BIGKEY)
+ (void)fprintf(stderr,
+ "big key page %lu size %u/",
+ *(pgno_t *)bl->bytes,
+ *(u_int32_t *)(bl->bytes + sizeof(pgno_t)));
+ else if (bl->ksize)
+ (void)fprintf(stderr, "%s/", bl->bytes);
+ if (bl->flags & P_BIGDATA)
+ (void)fprintf(stderr,
+ "big data page %lu size %u",
+ *(pgno_t *)(bl->bytes + bl->ksize),
+ *(u_int32_t *)(bl->bytes + bl->ksize +
+ sizeof(pgno_t)));
+ else if (bl->dsize)
+ (void)fprintf(stderr, "%.*s",
+ (int)bl->dsize, bl->bytes + bl->ksize);
+ break;
+ case P_RLEAF:
+ rl = GETRLEAF(h, cur);
+ if (rl->flags & P_BIGDATA)
+ (void)fprintf(stderr,
+ "big data page %lu size %u",
+ *(pgno_t *)rl->bytes,
+ *(u_int32_t *)(rl->bytes + sizeof(pgno_t)));
+ else if (rl->dsize)
+ (void)fprintf(stderr,
+ "%.*s", (int)rl->dsize, rl->bytes);
+ break;
+ }
+ (void)fprintf(stderr, "\n");
+ }
+}
+#endif
+
+#ifdef STATISTICS
+/*
+ * BT_STAT -- Gather/print the tree statistics
+ *
+ * Parameters:
+ * dbp: pointer to the DB
+ */
+void
+__bt_stat(dbp)
+ DB *dbp;
+{
+ extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit;
+ extern u_long bt_sortsplit, bt_split;
+ BTREE *t;
+ PAGE *h;
+ pgno_t i, pcont, pinternal, pleaf;
+ u_long ifree, lfree, nkeys;
+ int levels;
+
+ t = dbp->internal;
+ pcont = pinternal = pleaf = 0;
+ nkeys = ifree = lfree = 0;
+ for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
+ switch (h->flags & P_TYPE) {
+ case P_BINTERNAL:
+ case P_RINTERNAL:
+ ++pinternal;
+ ifree += h->upper - h->lower;
+ break;
+ case P_BLEAF:
+ case P_RLEAF:
+ ++pleaf;
+ lfree += h->upper - h->lower;
+ nkeys += NEXTINDEX(h);
+ break;
+ case P_OVERFLOW:
+ ++pcont;
+ break;
+ }
+ (void)mpool_put(t->bt_mp, h, 0);
+ }
+
+ /* Count the levels of the tree. */
+ for (i = P_ROOT, levels = 0 ;; ++levels) {
+ h = mpool_get(t->bt_mp, i, 0);
+ if (h->flags & (P_BLEAF|P_RLEAF)) {
+ if (levels == 0)
+ levels = 1;
+ (void)mpool_put(t->bt_mp, h, 0);
+ break;
+ }
+ i = F_ISSET(t, R_RECNO) ?
+ GETRINTERNAL(h, 0)->pgno :
+ GETBINTERNAL(h, 0)->pgno;
+ (void)mpool_put(t->bt_mp, h, 0);
+ }
+
+ (void)fprintf(stderr, "%d level%s with %ld keys",
+ levels, levels == 1 ? "" : "s", nkeys);
+ if (F_ISSET(t, R_RECNO))
+ (void)fprintf(stderr, " (%ld header count)", t->bt_nrecs);
+ (void)fprintf(stderr,
+ "\n%lu pages (leaf %ld, internal %ld, overflow %ld)\n",
+ pinternal + pleaf + pcont, pleaf, pinternal, pcont);
+ (void)fprintf(stderr, "%ld cache hits, %ld cache misses\n",
+ bt_cache_hit, bt_cache_miss);
+ (void)fprintf(stderr, "%ld splits (%ld root splits, %ld sort splits)\n",
+ bt_split, bt_rootsplit, bt_sortsplit);
+ pleaf *= t->bt_psize - BTDATAOFF;
+ if (pleaf)
+ (void)fprintf(stderr,
+ "%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n",
+ ((double)(pleaf - lfree) / pleaf) * 100,
+ pleaf - lfree, lfree);
+ pinternal *= t->bt_psize - BTDATAOFF;
+ if (pinternal)
+ (void)fprintf(stderr,
+ "%.0f%% internal fill (%ld bytes used, %ld bytes free\n",
+ ((double)(pinternal - ifree) / pinternal) * 100,
+ pinternal - ifree, ifree);
+ if (bt_pfxsaved)
+ (void)fprintf(stderr, "prefix checking removed %lu bytes.\n",
+ bt_pfxsaved);
+}
+#endif
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_delete.c 8.13 (Berkeley) 7/28/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_delete.c,v 1.2 2002/03/21 22:46:25 obrien Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+static int __bt_bdelete(BTREE *, const DBT *);
+static int __bt_curdel(BTREE *, const DBT *, PAGE *, u_int);
+static int __bt_pdelete(BTREE *, PAGE *);
+static int __bt_relink(BTREE *, PAGE *);
+static int __bt_stkacq(BTREE *, PAGE **, CURSOR *);
+
+/*
+ * __bt_delete
+ * Delete the item(s) referenced by a key.
+ *
+ * Return RET_SPECIAL if the key is not found.
+ */
+int
+__bt_delete(dbp, key, flags)
+ const DB *dbp;
+ const DBT *key;
+ u_int flags;
+{
+ BTREE *t;
+ CURSOR *c;
+ PAGE *h;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Check for change to a read-only tree. */
+ if (F_ISSET(t, B_RDONLY)) {
+ errno = EPERM;
+ return (RET_ERROR);
+ }
+
+ switch (flags) {
+ case 0:
+ status = __bt_bdelete(t, key);
+ break;
+ case R_CURSOR:
+ /*
+ * If flags is R_CURSOR, delete the cursor. Must already
+ * have started a scan and not have already deleted it.
+ */
+ c = &t->bt_cursor;
+ if (F_ISSET(c, CURS_INIT)) {
+ if (F_ISSET(c, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
+ return (RET_SPECIAL);
+ if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
+ return (RET_ERROR);
+
+ /*
+ * If the page is about to be emptied, we'll need to
+ * delete it, which means we have to acquire a stack.
+ */
+ if (NEXTINDEX(h) == 1)
+ if (__bt_stkacq(t, &h, &t->bt_cursor))
+ return (RET_ERROR);
+
+ status = __bt_dleaf(t, NULL, h, c->pg.index);
+
+ if (NEXTINDEX(h) == 0 && status == RET_SUCCESS) {
+ if (__bt_pdelete(t, h))
+ return (RET_ERROR);
+ } else
+ mpool_put(t->bt_mp,
+ h, status == RET_SUCCESS ? MPOOL_DIRTY : 0);
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+ if (status == RET_SUCCESS)
+ F_SET(t, B_MODIFIED);
+ return (status);
+}
+
+/*
+ * __bt_stkacq --
+ * Acquire a stack so we can delete a cursor entry.
+ *
+ * Parameters:
+ * t: tree
+ * hp: pointer to current, pinned PAGE pointer
+ * c: pointer to the cursor
+ *
+ * Returns:
+ * 0 on success, 1 on failure
+ */
+static int
+__bt_stkacq(t, hp, c)
+ BTREE *t;
+ PAGE **hp;
+ CURSOR *c;
+{
+ BINTERNAL *bi;
+ EPG *e;
+ EPGNO *parent;
+ PAGE *h;
+ indx_t index;
+ pgno_t pgno;
+ recno_t nextpg, prevpg;
+ int exact, level;
+
+ /*
+ * Find the first occurrence of the key in the tree. Toss the
+ * currently locked page so we don't hit an already-locked page.
+ */
+ h = *hp;
+ mpool_put(t->bt_mp, h, 0);
+ if ((e = __bt_search(t, &c->key, &exact)) == NULL)
+ return (1);
+ h = e->page;
+
+ /* See if we got it in one shot. */
+ if (h->pgno == c->pg.pgno)
+ goto ret;
+
+ /*
+ * Move right, looking for the page. At each move we have to move
+ * up the stack until we don't have to move to the next page. If
+ * we have to change pages at an internal level, we have to fix the
+ * stack back up.
+ */
+ while (h->pgno != c->pg.pgno) {
+ if ((nextpg = h->nextpg) == P_INVALID)
+ break;
+ mpool_put(t->bt_mp, h, 0);
+
+ /* Move up the stack. */
+ for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
+ /* Get the parent page. */
+ if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
+ return (1);
+
+ /* Move to the next index. */
+ if (parent->index != NEXTINDEX(h) - 1) {
+ index = parent->index + 1;
+ BT_PUSH(t, h->pgno, index);
+ break;
+ }
+ mpool_put(t->bt_mp, h, 0);
+ }
+
+ /* Restore the stack. */
+ while (level--) {
+ /* Push the next level down onto the stack. */
+ bi = GETBINTERNAL(h, index);
+ pgno = bi->pgno;
+ BT_PUSH(t, pgno, 0);
+
+ /* Lose the currently pinned page. */
+ mpool_put(t->bt_mp, h, 0);
+
+ /* Get the next level down. */
+ if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
+ return (1);
+ index = 0;
+ }
+ mpool_put(t->bt_mp, h, 0);
+ if ((h = mpool_get(t->bt_mp, nextpg, 0)) == NULL)
+ return (1);
+ }
+
+ if (h->pgno == c->pg.pgno)
+ goto ret;
+
+ /* Reacquire the original stack. */
+ mpool_put(t->bt_mp, h, 0);
+ if ((e = __bt_search(t, &c->key, &exact)) == NULL)
+ return (1);
+ h = e->page;
+
+ /*
+ * Move left, looking for the page. At each move we have to move
+ * up the stack until we don't have to change pages to move to the
+ * next page. If we have to change pages at an internal level, we
+ * have to fix the stack back up.
+ */
+ while (h->pgno != c->pg.pgno) {
+ if ((prevpg = h->prevpg) == P_INVALID)
+ break;
+ mpool_put(t->bt_mp, h, 0);
+
+ /* Move up the stack. */
+ for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
+ /* Get the parent page. */
+ if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
+ return (1);
+
+ /* Move to the next index. */
+ if (parent->index != 0) {
+ index = parent->index - 1;
+ BT_PUSH(t, h->pgno, index);
+ break;
+ }
+ mpool_put(t->bt_mp, h, 0);
+ }
+
+ /* Restore the stack. */
+ while (level--) {
+ /* Push the next level down onto the stack. */
+ bi = GETBINTERNAL(h, index);
+ pgno = bi->pgno;
+
+ /* Lose the currently pinned page. */
+ mpool_put(t->bt_mp, h, 0);
+
+ /* Get the next level down. */
+ if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
+ return (1);
+
+ index = NEXTINDEX(h) - 1;
+ BT_PUSH(t, pgno, index);
+ }
+ mpool_put(t->bt_mp, h, 0);
+ if ((h = mpool_get(t->bt_mp, prevpg, 0)) == NULL)
+ return (1);
+ }
+
+
+ret: mpool_put(t->bt_mp, h, 0);
+ return ((*hp = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL);
+}
+
+/*
+ * __bt_bdelete --
+ * Delete all key/data pairs matching the specified key.
+ *
+ * Parameters:
+ * t: tree
+ * key: key to delete
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
+ */
+static int
+__bt_bdelete(t, key)
+ BTREE *t;
+ const DBT *key;
+{
+ EPG *e;
+ PAGE *h;
+ int deleted, exact, redo;
+
+ deleted = 0;
+
+ /* Find any matching record; __bt_search pins the page. */
+loop: if ((e = __bt_search(t, key, &exact)) == NULL)
+ return (deleted ? RET_SUCCESS : RET_ERROR);
+ if (!exact) {
+ mpool_put(t->bt_mp, e->page, 0);
+ return (deleted ? RET_SUCCESS : RET_SPECIAL);
+ }
+
+ /*
+ * Delete forward, then delete backward, from the found key. If
+ * there are duplicates and we reach either side of the page, do
+ * the key search again, so that we get them all.
+ */
+ redo = 0;
+ h = e->page;
+ do {
+ if (__bt_dleaf(t, key, h, e->index)) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_ERROR);
+ }
+ if (F_ISSET(t, B_NODUPS)) {
+ if (NEXTINDEX(h) == 0) {
+ if (__bt_pdelete(t, h))
+ return (RET_ERROR);
+ } else
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+ }
+ deleted = 1;
+ } while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0);
+
+ /* Check for right-hand edge of the page. */
+ if (e->index == NEXTINDEX(h))
+ redo = 1;
+
+ /* Delete from the key to the beginning of the page. */
+ while (e->index-- > 0) {
+ if (__bt_cmp(t, key, e) != 0)
+ break;
+ if (__bt_dleaf(t, key, h, e->index) == RET_ERROR) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_ERROR);
+ }
+ if (e->index == 0)
+ redo = 1;
+ }
+
+ /* Check for an empty page. */
+ if (NEXTINDEX(h) == 0) {
+ if (__bt_pdelete(t, h))
+ return (RET_ERROR);
+ goto loop;
+ }
+
+ /* Put the page. */
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+
+ if (redo)
+ goto loop;
+ return (RET_SUCCESS);
+}
+
+/*
+ * __bt_pdelete --
+ * Delete a single page from the tree.
+ *
+ * Parameters:
+ * t: tree
+ * h: leaf page
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ *
+ * Side-effects:
+ * mpool_put's the page
+ */
+static int
+__bt_pdelete(t, h)
+ BTREE *t;
+ PAGE *h;
+{
+ BINTERNAL *bi;
+ PAGE *pg;
+ EPGNO *parent;
+ indx_t cnt, index, *ip, offset;
+ u_int32_t nksize;
+ char *from;
+
+ /*
+ * Walk the parent page stack -- a LIFO stack of the pages that were
+ * traversed when we searched for the page where the delete occurred.
+ * Each stack entry is a page number and a page index offset. The
+ * offset is for the page traversed on the search. We've just deleted
+ * a page, so we have to delete the key from the parent page.
+ *
+ * If the delete from the parent page makes it empty, this process may
+ * continue all the way up the tree. We stop if we reach the root page
+ * (which is never deleted, it's just not worth the effort) or if the
+ * delete does not empty the page.
+ */
+ while ((parent = BT_POP(t)) != NULL) {
+ /* Get the parent page. */
+ if ((pg = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
+ return (RET_ERROR);
+
+ index = parent->index;
+ bi = GETBINTERNAL(pg, index);
+
+ /* Free any overflow pages. */
+ if (bi->flags & P_BIGKEY &&
+ __ovfl_delete(t, bi->bytes) == RET_ERROR) {
+ mpool_put(t->bt_mp, pg, 0);
+ return (RET_ERROR);
+ }
+
+ /*
+ * Free the parent if it has only the one key and it's not the
+ * root page. If it's the rootpage, turn it back into an empty
+ * leaf page.
+ */
+ if (NEXTINDEX(pg) == 1)
+ if (pg->pgno == P_ROOT) {
+ pg->lower = BTDATAOFF;
+ pg->upper = t->bt_psize;
+ pg->flags = P_BLEAF;
+ } else {
+ if (__bt_relink(t, pg) || __bt_free(t, pg))
+ return (RET_ERROR);
+ continue;
+ }
+ else {
+ /* Pack remaining key items at the end of the page. */
+ nksize = NBINTERNAL(bi->ksize);
+ from = (char *)pg + pg->upper;
+ memmove(from + nksize, from, (char *)bi - from);
+ pg->upper += nksize;
+
+ /* Adjust indices' offsets, shift the indices down. */
+ offset = pg->linp[index];
+ for (cnt = index, ip = &pg->linp[0]; cnt--; ++ip)
+ if (ip[0] < offset)
+ ip[0] += nksize;
+ for (cnt = NEXTINDEX(pg) - index; --cnt; ++ip)
+ ip[0] = ip[1] < offset ? ip[1] + nksize : ip[1];
+ pg->lower -= sizeof(indx_t);
+ }
+
+ mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
+ break;
+ }
+
+ /* Free the leaf page, as long as it wasn't the root. */
+ if (h->pgno == P_ROOT) {
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+ }
+ return (__bt_relink(t, h) || __bt_free(t, h));
+}
+
+/*
+ * __bt_dleaf --
+ * Delete a single record from a leaf page.
+ *
+ * Parameters:
+ * t: tree
+ * key: referenced key
+ * h: page
+ * index: index on page to delete
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__bt_dleaf(t, key, h, index)
+ BTREE *t;
+ const DBT *key;
+ PAGE *h;
+ u_int index;
+{
+ BLEAF *bl;
+ indx_t cnt, *ip, offset;
+ u_int32_t nbytes;
+ void *to;
+ char *from;
+
+ /* If this record is referenced by the cursor, delete the cursor. */
+ if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
+ !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
+ t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index == index &&
+ __bt_curdel(t, key, h, index))
+ return (RET_ERROR);
+
+ /* If the entry uses overflow pages, make them available for reuse. */
+ to = bl = GETBLEAF(h, index);
+ if (bl->flags & P_BIGKEY && __ovfl_delete(t, bl->bytes) == RET_ERROR)
+ return (RET_ERROR);
+ if (bl->flags & P_BIGDATA &&
+ __ovfl_delete(t, bl->bytes + bl->ksize) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Pack the remaining key/data items at the end of the page. */
+ nbytes = NBLEAF(bl);
+ from = (char *)h + h->upper;
+ memmove(from + nbytes, from, (char *)to - from);
+ h->upper += nbytes;
+
+ /* Adjust the indices' offsets, shift the indices down. */
+ offset = h->linp[index];
+ for (cnt = index, ip = &h->linp[0]; cnt--; ++ip)
+ if (ip[0] < offset)
+ ip[0] += nbytes;
+ for (cnt = NEXTINDEX(h) - index; --cnt; ++ip)
+ ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
+ h->lower -= sizeof(indx_t);
+
+ /* If the cursor is on this page, adjust it as necessary. */
+ if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
+ !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
+ t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index > index)
+ --t->bt_cursor.pg.index;
+
+ return (RET_SUCCESS);
+}
+
+/*
+ * __bt_curdel --
+ * Delete the cursor.
+ *
+ * Parameters:
+ * t: tree
+ * key: referenced key (or NULL)
+ * h: page
+ * index: index on page to delete
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+static int
+__bt_curdel(t, key, h, index)
+ BTREE *t;
+ const DBT *key;
+ PAGE *h;
+ u_int index;
+{
+ CURSOR *c;
+ EPG e;
+ PAGE *pg;
+ int curcopy, status;
+
+ /*
+ * If there are duplicates, move forward or backward to one.
+ * Otherwise, copy the key into the cursor area.
+ */
+ c = &t->bt_cursor;
+ F_CLR(c, CURS_AFTER | CURS_BEFORE | CURS_ACQUIRE);
+
+ curcopy = 0;
+ if (!F_ISSET(t, B_NODUPS)) {
+ /*
+ * We're going to have to do comparisons. If we weren't
+ * provided a copy of the key, i.e. the user is deleting
+ * the current cursor position, get one.
+ */
+ if (key == NULL) {
+ e.page = h;
+ e.index = index;
+ if ((status = __bt_ret(t, &e,
+ &c->key, &c->key, NULL, NULL, 1)) != RET_SUCCESS)
+ return (status);
+ curcopy = 1;
+ key = &c->key;
+ }
+ /* Check previous key, if not at the beginning of the page. */
+ if (index > 0) {
+ e.page = h;
+ e.index = index - 1;
+ if (__bt_cmp(t, key, &e) == 0) {
+ F_SET(c, CURS_BEFORE);
+ goto dup2;
+ }
+ }
+ /* Check next key, if not at the end of the page. */
+ if (index < NEXTINDEX(h) - 1) {
+ e.page = h;
+ e.index = index + 1;
+ if (__bt_cmp(t, key, &e) == 0) {
+ F_SET(c, CURS_AFTER);
+ goto dup2;
+ }
+ }
+ /* Check previous key if at the beginning of the page. */
+ if (index == 0 && h->prevpg != P_INVALID) {
+ if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
+ return (RET_ERROR);
+ e.page = pg;
+ e.index = NEXTINDEX(pg) - 1;
+ if (__bt_cmp(t, key, &e) == 0) {
+ F_SET(c, CURS_BEFORE);
+ goto dup1;
+ }
+ mpool_put(t->bt_mp, pg, 0);
+ }
+ /* Check next key if at the end of the page. */
+ if (index == NEXTINDEX(h) - 1 && h->nextpg != P_INVALID) {
+ if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
+ return (RET_ERROR);
+ e.page = pg;
+ e.index = 0;
+ if (__bt_cmp(t, key, &e) == 0) {
+ F_SET(c, CURS_AFTER);
+dup1: mpool_put(t->bt_mp, pg, 0);
+dup2: c->pg.pgno = e.page->pgno;
+ c->pg.index = e.index;
+ return (RET_SUCCESS);
+ }
+ mpool_put(t->bt_mp, pg, 0);
+ }
+ }
+ e.page = h;
+ e.index = index;
+ if (curcopy || (status =
+ __bt_ret(t, &e, &c->key, &c->key, NULL, NULL, 1)) == RET_SUCCESS) {
+ F_SET(c, CURS_ACQUIRE);
+ return (RET_SUCCESS);
+ }
+ return (status);
+}
+
+/*
+ * __bt_relink --
+ * Link around a deleted page.
+ *
+ * Parameters:
+ * t: tree
+ * h: page to be deleted
+ */
+static int
+__bt_relink(t, h)
+ BTREE *t;
+ PAGE *h;
+{
+ PAGE *pg;
+
+ if (h->nextpg != P_INVALID) {
+ if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
+ return (RET_ERROR);
+ pg->prevpg = h->prevpg;
+ mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
+ }
+ if (h->prevpg != P_INVALID) {
+ if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
+ return (RET_ERROR);
+ pg->nextpg = h->nextpg;
+ mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
+ }
+ return (0);
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_get.c 8.6 (Berkeley) 7/20/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_get.c,v 1.2 2002/03/22 21:52:01 obrien Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include <db.h>
+#include "btree.h"
+
+/*
+ * __BT_GET -- Get a record from the btree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key to find
+ * data: data to return
+ * flag: currently unused
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
+ */
+int
+__bt_get(dbp, key, data, flags)
+ const DB *dbp;
+ const DBT *key;
+ DBT *data;
+ u_int flags;
+{
+ BTREE *t;
+ EPG *e;
+ int exact, status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Get currently doesn't take any flags. */
+ if (flags) {
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if ((e = __bt_search(t, key, &exact)) == NULL)
+ return (RET_ERROR);
+ if (!exact) {
+ mpool_put(t->bt_mp, e->page, 0);
+ return (RET_SPECIAL);
+ }
+
+ status = __bt_ret(t, e, NULL, NULL, data, &t->bt_rdata, 0);
+
+ /*
+ * If the user is doing concurrent access, we copied the
+ * key/data, toss the page.
+ */
+ if (F_ISSET(t, B_DB_LOCK))
+ mpool_put(t->bt_mp, e->page, 0);
+ else
+ t->bt_pinned = e->page;
+ return (status);
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_open.c 8.10 (Berkeley) 8/17/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_open.c,v 1.11 2002/03/22 21:52:01 obrien Exp $");
+
+/*
+ * Implementation of btree access method for 4.4BSD.
+ *
+ * The design here was originally based on that of the btree access method
+ * used in the Postgres database system at UC Berkeley. This implementation
+ * is wholly independent of the Postgres code.
+ */
+
+#include "namespace.h"
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "un-namespace.h"
+
+#include <db.h>
+#include "btree.h"
+
+#ifdef DEBUG
+#undef MINPSIZE
+#define MINPSIZE 128
+#endif
+
+static int byteorder(void);
+static int nroot(BTREE *);
+static int tmp(void);
+
+/*
+ * __BT_OPEN -- Open a btree.
+ *
+ * Creates and fills a DB struct, and calls the routine that actually
+ * opens the btree.
+ *
+ * Parameters:
+ * fname: filename (NULL for in-memory trees)
+ * flags: open flag bits
+ * mode: open permission bits
+ * b: BTREEINFO pointer
+ *
+ * Returns:
+ * NULL on failure, pointer to DB on success.
+ *
+ */
+DB *
+__bt_open(fname, flags, mode, openinfo, dflags)
+ const char *fname;
+ int flags, mode, dflags;
+ const BTREEINFO *openinfo;
+{
+ struct stat sb;
+ BTMETA m;
+ BTREE *t;
+ BTREEINFO b;
+ DB *dbp;
+ pgno_t ncache;
+ ssize_t nr;
+ int machine_lorder;
+
+ t = NULL;
+
+ /*
+ * Intention is to make sure all of the user's selections are okay
+ * here and then use them without checking. Can't be complete, since
+ * we don't know the right page size, lorder or flags until the backing
+ * file is opened. Also, the file's page size can cause the cachesize
+ * to change.
+ */
+ machine_lorder = byteorder();
+ if (openinfo) {
+ b = *openinfo;
+
+ /* Flags: R_DUP. */
+ if (b.flags & ~(R_DUP))
+ goto einval;
+
+ /*
+ * Page size must be indx_t aligned and >= MINPSIZE. Default
+ * page size is set farther on, based on the underlying file
+ * transfer size.
+ */
+ if (b.psize &&
+ (b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 ||
+ b.psize & (sizeof(indx_t) - 1) ))
+ goto einval;
+
+ /* Minimum number of keys per page; absolute minimum is 2. */
+ if (b.minkeypage) {
+ if (b.minkeypage < 2)
+ goto einval;
+ } else
+ b.minkeypage = DEFMINKEYPAGE;
+
+ /* If no comparison, use default comparison and prefix. */
+ if (b.compare == NULL) {
+ b.compare = __bt_defcmp;
+ if (b.prefix == NULL)
+ b.prefix = __bt_defpfx;
+ }
+
+ if (b.lorder == 0)
+ b.lorder = machine_lorder;
+ } else {
+ b.compare = __bt_defcmp;
+ b.cachesize = 0;
+ b.flags = 0;
+ b.lorder = machine_lorder;
+ b.minkeypage = DEFMINKEYPAGE;
+ b.prefix = __bt_defpfx;
+ b.psize = 0;
+ }
+
+ /* Check for the ubiquitous PDP-11. */
+ if (b.lorder != BIG_ENDIAN && b.lorder != LITTLE_ENDIAN)
+ goto einval;
+
+ /* Allocate and initialize DB and BTREE structures. */
+ if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL)
+ goto err;
+ memset(t, 0, sizeof(BTREE));
+ t->bt_fd = -1; /* Don't close unopened fd on error. */
+ t->bt_lorder = b.lorder;
+ t->bt_order = NOT;
+ t->bt_cmp = b.compare;
+ t->bt_pfx = b.prefix;
+ t->bt_rfd = -1;
+
+ if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL)
+ goto err;
+ memset(t->bt_dbp, 0, sizeof(DB));
+ if (t->bt_lorder != machine_lorder)
+ F_SET(t, B_NEEDSWAP);
+
+ dbp->type = DB_BTREE;
+ dbp->internal = t;
+ dbp->close = __bt_close;
+ dbp->del = __bt_delete;
+ dbp->fd = __bt_fd;
+ dbp->get = __bt_get;
+ dbp->put = __bt_put;
+ dbp->seq = __bt_seq;
+ dbp->sync = __bt_sync;
+
+ /*
+ * If no file name was supplied, this is an in-memory btree and we
+ * open a backing temporary file. Otherwise, it's a disk-based tree.
+ */
+ if (fname) {
+ switch (flags & O_ACCMODE) {
+ case O_RDONLY:
+ F_SET(t, B_RDONLY);
+ break;
+ case O_RDWR:
+ break;
+ case O_WRONLY:
+ default:
+ goto einval;
+ }
+
+ if ((t->bt_fd = _open(fname, flags, mode)) < 0)
+ goto err;
+
+ } else {
+ if ((flags & O_ACCMODE) != O_RDWR)
+ goto einval;
+ if ((t->bt_fd = tmp()) == -1)
+ goto err;
+ F_SET(t, B_INMEM);
+ }
+
+ if (_fcntl(t->bt_fd, F_SETFD, 1) == -1)
+ goto err;
+
+ if (_fstat(t->bt_fd, &sb))
+ goto err;
+ if (sb.st_size) {
+ if ((nr = _read(t->bt_fd, &m, sizeof(BTMETA))) < 0)
+ goto err;
+ if (nr != sizeof(BTMETA))
+ goto eftype;
+
+ /*
+ * Read in the meta-data. This can change the notion of what
+ * the lorder, page size and flags are, and, when the page size
+ * changes, the cachesize value can change too. If the user
+ * specified the wrong byte order for an existing database, we
+ * don't bother to return an error, we just clear the NEEDSWAP
+ * bit.
+ */
+ if (m.magic == BTREEMAGIC)
+ F_CLR(t, B_NEEDSWAP);
+ else {
+ F_SET(t, B_NEEDSWAP);
+ M_32_SWAP(m.magic);
+ M_32_SWAP(m.version);
+ M_32_SWAP(m.psize);
+ M_32_SWAP(m.free);
+ M_32_SWAP(m.nrecs);
+ M_32_SWAP(m.flags);
+ }
+ if (m.magic != BTREEMAGIC || m.version != BTREEVERSION)
+ goto eftype;
+ if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 ||
+ m.psize & (sizeof(indx_t) - 1) )
+ goto eftype;
+ if (m.flags & ~SAVEMETA)
+ goto eftype;
+ b.psize = m.psize;
+ F_SET(t, m.flags);
+ t->bt_free = m.free;
+ t->bt_nrecs = m.nrecs;
+ } else {
+ /*
+ * Set the page size to the best value for I/O to this file.
+ * Don't overflow the page offset type.
+ */
+ if (b.psize == 0) {
+ b.psize = sb.st_blksize;
+ if (b.psize < MINPSIZE)
+ b.psize = MINPSIZE;
+ if (b.psize > MAX_PAGE_OFFSET + 1)
+ b.psize = MAX_PAGE_OFFSET + 1;
+ }
+
+ /* Set flag if duplicates permitted. */
+ if (!(b.flags & R_DUP))
+ F_SET(t, B_NODUPS);
+
+ t->bt_free = P_INVALID;
+ t->bt_nrecs = 0;
+ F_SET(t, B_METADIRTY);
+ }
+
+ t->bt_psize = b.psize;
+
+ /* Set the cache size; must be a multiple of the page size. */
+ if (b.cachesize && b.cachesize & (b.psize - 1) )
+ b.cachesize += (~b.cachesize & (b.psize - 1) ) + 1;
+ if (b.cachesize < b.psize * MINCACHE)
+ b.cachesize = b.psize * MINCACHE;
+
+ /* Calculate number of pages to cache. */
+ ncache = (b.cachesize + t->bt_psize - 1) / t->bt_psize;
+
+ /*
+ * The btree data structure requires that at least two keys can fit on
+ * a page, but other than that there's no fixed requirement. The user
+ * specified a minimum number per page, and we translated that into the
+ * number of bytes a key/data pair can use before being placed on an
+ * overflow page. This calculation includes the page header, the size
+ * of the index referencing the leaf item and the size of the leaf item
+ * structure. Also, don't let the user specify a minkeypage such that
+ * a key/data pair won't fit even if both key and data are on overflow
+ * pages.
+ */
+ t->bt_ovflsize = (t->bt_psize - BTDATAOFF) / b.minkeypage -
+ (sizeof(indx_t) + NBLEAFDBT(0, 0));
+ if (t->bt_ovflsize < NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t))
+ t->bt_ovflsize =
+ NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t);
+
+ /* Initialize the buffer pool. */
+ if ((t->bt_mp =
+ mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL)
+ goto err;
+ if (!F_ISSET(t, B_INMEM))
+ mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t);
+
+ /* Create a root page if new tree. */
+ if (nroot(t) == RET_ERROR)
+ goto err;
+
+ /* Global flags. */
+ if (dflags & DB_LOCK)
+ F_SET(t, B_DB_LOCK);
+ if (dflags & DB_SHMEM)
+ F_SET(t, B_DB_SHMEM);
+ if (dflags & DB_TXN)
+ F_SET(t, B_DB_TXN);
+
+ return (dbp);
+
+einval: errno = EINVAL;
+ goto err;
+
+eftype: errno = EFTYPE;
+ goto err;
+
+err: if (t) {
+ if (t->bt_dbp)
+ free(t->bt_dbp);
+ if (t->bt_fd != -1)
+ (void)_close(t->bt_fd);
+ free(t);
+ }
+ return (NULL);
+}
+
+/*
+ * NROOT -- Create the root of a new tree.
+ *
+ * Parameters:
+ * t: tree
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+static int
+nroot(t)
+ BTREE *t;
+{
+ PAGE *meta, *root;
+ pgno_t npg;
+
+ if ((meta = mpool_get(t->bt_mp, 0, 0)) != NULL) {
+ mpool_put(t->bt_mp, meta, 0);
+ return (RET_SUCCESS);
+ }
+ if (errno != EINVAL) /* It's OK to not exist. */
+ return (RET_ERROR);
+ errno = 0;
+
+ if ((meta = mpool_new(t->bt_mp, &npg)) == NULL)
+ return (RET_ERROR);
+
+ if ((root = mpool_new(t->bt_mp, &npg)) == NULL)
+ return (RET_ERROR);
+
+ if (npg != P_ROOT)
+ return (RET_ERROR);
+ root->pgno = npg;
+ root->prevpg = root->nextpg = P_INVALID;
+ root->lower = BTDATAOFF;
+ root->upper = t->bt_psize;
+ root->flags = P_BLEAF;
+ memset(meta, 0, t->bt_psize);
+ mpool_put(t->bt_mp, meta, MPOOL_DIRTY);
+ mpool_put(t->bt_mp, root, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+}
+
+static int
+tmp()
+{
+ sigset_t set, oset;
+ int fd;
+ char *envtmp = NULL;
+ char path[MAXPATHLEN];
+
+ if (issetugid() == 0)
+ envtmp = getenv("TMPDIR");
+ (void)snprintf(path,
+ sizeof(path), "%s/bt.XXXXXXXXXX", envtmp ? envtmp : "/tmp");
+
+ (void)sigfillset(&set);
+ (void)_sigprocmask(SIG_BLOCK, &set, &oset);
+ if ((fd = mkstemp(path)) != -1)
+ (void)unlink(path);
+ (void)_sigprocmask(SIG_SETMASK, &oset, NULL);
+ return(fd);
+}
+
+static int
+byteorder()
+{
+ u_int32_t x;
+ u_char *p;
+
+ x = 0x01020304;
+ p = (u_char *)&x;
+ switch (*p) {
+ case 1:
+ return (BIG_ENDIAN);
+ case 4:
+ return (LITTLE_ENDIAN);
+ default:
+ return (0);
+ }
+}
+
+int
+__bt_fd(dbp)
+ const DB *dbp;
+{
+ BTREE *t;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* In-memory database can't have a file descriptor. */
+ if (F_ISSET(t, B_INMEM)) {
+ errno = ENOENT;
+ return (-1);
+ }
+ return (t->bt_fd);
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_overflow.c 8.5 (Berkeley) 7/16/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_overflow.c,v 1.3 2002/03/22 21:52:01 obrien Exp $");
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+/*
+ * Big key/data code.
+ *
+ * Big key and data entries are stored on linked lists of pages. The initial
+ * reference is byte string stored with the key or data and is the page number
+ * and size. The actual record is stored in a chain of pages linked by the
+ * nextpg field of the PAGE header.
+ *
+ * The first page of the chain has a special property. If the record is used
+ * by an internal page, it cannot be deleted and the P_PRESERVE bit will be set
+ * in the header.
+ *
+ * XXX
+ * A single DBT is written to each chain, so a lot of space on the last page
+ * is wasted. This is a fairly major bug for some data sets.
+ */
+
+/*
+ * __OVFL_GET -- Get an overflow key/data item.
+ *
+ * Parameters:
+ * t: tree
+ * p: pointer to { pgno_t, u_int32_t }
+ * buf: storage address
+ * bufsz: storage size
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__ovfl_get(t, p, ssz, buf, bufsz)
+ BTREE *t;
+ void *p;
+ size_t *ssz;
+ void **buf;
+ size_t *bufsz;
+{
+ PAGE *h;
+ pgno_t pg;
+ size_t nb, plen;
+ u_int32_t sz;
+
+ memmove(&pg, p, sizeof(pgno_t));
+ memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
+ *ssz = sz;
+
+#ifdef DEBUG
+ if (pg == P_INVALID || sz == 0)
+ abort();
+#endif
+ /* Make the buffer bigger as necessary. */
+ if (*bufsz < sz) {
+ *buf = (char *)(*buf == NULL ? malloc(sz) : reallocf(*buf, sz));
+ if (*buf == NULL)
+ return (RET_ERROR);
+ *bufsz = sz;
+ }
+
+ /*
+ * Step through the linked list of pages, copying the data on each one
+ * into the buffer. Never copy more than the data's length.
+ */
+ plen = t->bt_psize - BTDATAOFF;
+ for (p = *buf;; p = (char *)p + nb, pg = h->nextpg) {
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+
+ nb = MIN(sz, plen);
+ memmove(p, (char *)h + BTDATAOFF, nb);
+ mpool_put(t->bt_mp, h, 0);
+
+ if ((sz -= nb) == 0)
+ break;
+ }
+ return (RET_SUCCESS);
+}
+
+/*
+ * __OVFL_PUT -- Store an overflow key/data item.
+ *
+ * Parameters:
+ * t: tree
+ * data: DBT to store
+ * pgno: storage page number
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__ovfl_put(t, dbt, pg)
+ BTREE *t;
+ const DBT *dbt;
+ pgno_t *pg;
+{
+ PAGE *h, *last;
+ void *p;
+ pgno_t npg;
+ size_t nb, plen;
+ u_int32_t sz;
+
+ /*
+ * Allocate pages and copy the key/data record into them. Store the
+ * number of the first page in the chain.
+ */
+ plen = t->bt_psize - BTDATAOFF;
+ for (last = NULL, p = dbt->data, sz = dbt->size;;
+ p = (char *)p + plen, last = h) {
+ if ((h = __bt_new(t, &npg)) == NULL)
+ return (RET_ERROR);
+
+ h->pgno = npg;
+ h->nextpg = h->prevpg = P_INVALID;
+ h->flags = P_OVERFLOW;
+ h->lower = h->upper = 0;
+
+ nb = MIN(sz, plen);
+ memmove((char *)h + BTDATAOFF, p, nb);
+
+ if (last) {
+ last->nextpg = h->pgno;
+ mpool_put(t->bt_mp, last, MPOOL_DIRTY);
+ } else
+ *pg = h->pgno;
+
+ if ((sz -= nb) == 0) {
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ break;
+ }
+ }
+ return (RET_SUCCESS);
+}
+
+/*
+ * __OVFL_DELETE -- Delete an overflow chain.
+ *
+ * Parameters:
+ * t: tree
+ * p: pointer to { pgno_t, u_int32_t }
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__ovfl_delete(t, p)
+ BTREE *t;
+ void *p;
+{
+ PAGE *h;
+ pgno_t pg;
+ size_t plen;
+ u_int32_t sz;
+
+ memmove(&pg, p, sizeof(pgno_t));
+ memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
+
+#ifdef DEBUG
+ if (pg == P_INVALID || sz == 0)
+ abort();
+#endif
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+
+ /* Don't delete chains used by internal pages. */
+ if (h->flags & P_PRESERVE) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_SUCCESS);
+ }
+
+ /* Step through the chain, calling the free routine for each page. */
+ for (plen = t->bt_psize - BTDATAOFF;; sz -= plen) {
+ pg = h->nextpg;
+ __bt_free(t, h);
+ if (sz <= plen)
+ break;
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ }
+ return (RET_SUCCESS);
+}
--- /dev/null
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_page.c 8.3 (Berkeley) 7/14/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_page.c,v 1.3 2002/03/22 21:52:01 obrien Exp $");
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#include <db.h>
+#include "btree.h"
+
+/*
+ * __bt_free --
+ * Put a page on the freelist.
+ *
+ * Parameters:
+ * t: tree
+ * h: page to free
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ *
+ * Side-effect:
+ * mpool_put's the page.
+ */
+int
+__bt_free(t, h)
+ BTREE *t;
+ PAGE *h;
+{
+ /* Insert the page at the head of the free list. */
+ h->prevpg = P_INVALID;
+ h->nextpg = t->bt_free;
+ t->bt_free = h->pgno;
+ F_SET(t, B_METADIRTY);
+
+ /* Make sure the page gets written back. */
+ return (mpool_put(t->bt_mp, h, MPOOL_DIRTY));
+}
+
+/*
+ * __bt_new --
+ * Get a new page, preferably from the freelist.
+ *
+ * Parameters:
+ * t: tree
+ * npg: storage for page number.
+ *
+ * Returns:
+ * Pointer to a page, NULL on error.
+ */
+PAGE *
+__bt_new(t, npg)
+ BTREE *t;
+ pgno_t *npg;
+{
+ PAGE *h;
+
+ if (t->bt_free != P_INVALID &&
+ (h = mpool_get(t->bt_mp, t->bt_free, 0)) != NULL) {
+ *npg = t->bt_free;
+ t->bt_free = h->nextpg;
+ F_SET(t, B_METADIRTY);
+ return (h);
+ }
+ return (mpool_new(t->bt_mp, npg));
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_put.c 8.8 (Berkeley) 7/26/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_put.c,v 1.4 2003/05/30 11:05:08 tmm Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+static EPG *bt_fast(BTREE *, const DBT *, const DBT *, int *);
+
+/*
+ * __BT_PUT -- Add a btree item to the tree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key
+ * data: data
+ * flag: R_NOOVERWRITE
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is already in the
+ * tree and R_NOOVERWRITE specified.
+ */
+int
+__bt_put(dbp, key, data, flags)
+ const DB *dbp;
+ DBT *key;
+ const DBT *data;
+ u_int flags;
+{
+ BTREE *t;
+ DBT tkey, tdata;
+ EPG *e;
+ PAGE *h;
+ indx_t index, nxtindex;
+ pgno_t pg;
+ u_int32_t nbytes, tmp;
+ int dflags, exact, status;
+ char *dest, db[NOVFLSIZE], kb[NOVFLSIZE];
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Check for change to a read-only tree. */
+ if (F_ISSET(t, B_RDONLY)) {
+ errno = EPERM;
+ return (RET_ERROR);
+ }
+
+ switch (flags) {
+ case 0:
+ case R_NOOVERWRITE:
+ break;
+ case R_CURSOR:
+ /*
+ * If flags is R_CURSOR, put the cursor. Must already
+ * have started a scan and not have already deleted it.
+ */
+ if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
+ !F_ISSET(&t->bt_cursor,
+ CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
+ break;
+ /* FALLTHROUGH */
+ default:
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ /*
+ * If the key/data pair won't fit on a page, store it on overflow
+ * pages. Only put the key on the overflow page if the pair are
+ * still too big after moving the data to an overflow page.
+ *
+ * XXX
+ * If the insert fails later on, the overflow pages aren't recovered.
+ */
+ dflags = 0;
+ if (key->size + data->size > t->bt_ovflsize) {
+ if (key->size > t->bt_ovflsize) {
+storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR)
+ return (RET_ERROR);
+ tkey.data = kb;
+ tkey.size = NOVFLSIZE;
+ memmove(kb, &pg, sizeof(pgno_t));
+ tmp = key->size;
+ memmove(kb + sizeof(pgno_t),
+ &tmp, sizeof(u_int32_t));
+ dflags |= P_BIGKEY;
+ key = &tkey;
+ }
+ if (key->size + data->size > t->bt_ovflsize) {
+ if (__ovfl_put(t, data, &pg) == RET_ERROR)
+ return (RET_ERROR);
+ tdata.data = db;
+ tdata.size = NOVFLSIZE;
+ memmove(db, &pg, sizeof(pgno_t));
+ tmp = data->size;
+ memmove(db + sizeof(pgno_t),
+ &tmp, sizeof(u_int32_t));
+ dflags |= P_BIGDATA;
+ data = &tdata;
+ }
+ if (key->size + data->size > t->bt_ovflsize)
+ goto storekey;
+ }
+
+ /* Replace the cursor. */
+ if (flags == R_CURSOR) {
+ if ((h = mpool_get(t->bt_mp, t->bt_cursor.pg.pgno, 0)) == NULL)
+ return (RET_ERROR);
+ index = t->bt_cursor.pg.index;
+ goto delete;
+ }
+
+ /*
+ * Find the key to delete, or, the location at which to insert.
+ * Bt_fast and __bt_search both pin the returned page.
+ */
+ if (t->bt_order == NOT || (e = bt_fast(t, key, data, &exact)) == NULL)
+ if ((e = __bt_search(t, key, &exact)) == NULL)
+ return (RET_ERROR);
+ h = e->page;
+ index = e->index;
+
+ /*
+ * Add the key/data pair to the tree. If an identical key is already
+ * in the tree, and R_NOOVERWRITE is set, an error is returned. If
+ * R_NOOVERWRITE is not set, the key is either added (if duplicates are
+ * permitted) or an error is returned.
+ */
+ switch (flags) {
+ case R_NOOVERWRITE:
+ if (!exact)
+ break;
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_SPECIAL);
+ default:
+ if (!exact || !F_ISSET(t, B_NODUPS))
+ break;
+ /*
+ * !!!
+ * Note, the delete may empty the page, so we need to put a
+ * new entry into the page immediately.
+ */
+delete: if (__bt_dleaf(t, key, h, index) == RET_ERROR) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_ERROR);
+ }
+ break;
+ }
+
+ /*
+ * If not enough room, or the user has put a ceiling on the number of
+ * keys permitted in the page, split the page. The split code will
+ * insert the key and data and unpin the current page. If inserting
+ * into the offset array, shift the pointers up.
+ */
+ nbytes = NBLEAFDBT(key->size, data->size);
+ if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
+ if ((status = __bt_split(t, h, key,
+ data, dflags, nbytes, index)) != RET_SUCCESS)
+ return (status);
+ goto success;
+ }
+
+ if (index < (nxtindex = NEXTINDEX(h)))
+ memmove(h->linp + index + 1, h->linp + index,
+ (nxtindex - index) * sizeof(indx_t));
+ h->lower += sizeof(indx_t);
+
+ h->linp[index] = h->upper -= nbytes;
+ dest = (char *)h + h->upper;
+ WR_BLEAF(dest, key, data, dflags);
+
+ /* If the cursor is on this page, adjust it as necessary. */
+ if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
+ !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
+ t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index >= index)
+ ++t->bt_cursor.pg.index;
+
+ if (t->bt_order == NOT) {
+ if (h->nextpg == P_INVALID) {
+ if (index == NEXTINDEX(h) - 1) {
+ t->bt_order = FORWARD;
+ t->bt_last.index = index;
+ t->bt_last.pgno = h->pgno;
+ }
+ } else if (h->prevpg == P_INVALID) {
+ if (index == 0) {
+ t->bt_order = BACK;
+ t->bt_last.index = 0;
+ t->bt_last.pgno = h->pgno;
+ }
+ }
+ }
+
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+
+success:
+ if (flags == R_SETCURSOR)
+ __bt_setcur(t, e->page->pgno, e->index);
+
+ F_SET(t, B_MODIFIED);
+ return (RET_SUCCESS);
+}
+
+#ifdef STATISTICS
+u_long bt_cache_hit, bt_cache_miss;
+#endif
+
+/*
+ * BT_FAST -- Do a quick check for sorted data.
+ *
+ * Parameters:
+ * t: tree
+ * key: key to insert
+ *
+ * Returns:
+ * EPG for new record or NULL if not found.
+ */
+static EPG *
+bt_fast(t, key, data, exactp)
+ BTREE *t;
+ const DBT *key, *data;
+ int *exactp;
+{
+ PAGE *h;
+ u_int32_t nbytes;
+ int cmp;
+
+ if ((h = mpool_get(t->bt_mp, t->bt_last.pgno, 0)) == NULL) {
+ t->bt_order = NOT;
+ return (NULL);
+ }
+ t->bt_cur.page = h;
+ t->bt_cur.index = t->bt_last.index;
+
+ /*
+ * If won't fit in this page or have too many keys in this page,
+ * have to search to get split stack.
+ */
+ nbytes = NBLEAFDBT(key->size, data->size);
+ if (h->upper - h->lower < nbytes + sizeof(indx_t))
+ goto miss;
+
+ if (t->bt_order == FORWARD) {
+ if (t->bt_cur.page->nextpg != P_INVALID)
+ goto miss;
+ if (t->bt_cur.index != NEXTINDEX(h) - 1)
+ goto miss;
+ if ((cmp = __bt_cmp(t, key, &t->bt_cur)) < 0)
+ goto miss;
+ t->bt_last.index = cmp ? ++t->bt_cur.index : t->bt_cur.index;
+ } else {
+ if (t->bt_cur.page->prevpg != P_INVALID)
+ goto miss;
+ if (t->bt_cur.index != 0)
+ goto miss;
+ if ((cmp = __bt_cmp(t, key, &t->bt_cur)) > 0)
+ goto miss;
+ t->bt_last.index = 0;
+ }
+ *exactp = cmp == 0;
+#ifdef STATISTICS
+ ++bt_cache_hit;
+#endif
+ return (&t->bt_cur);
+
+miss:
+#ifdef STATISTICS
+ ++bt_cache_miss;
+#endif
+ t->bt_order = NOT;
+ mpool_put(t->bt_mp, h, 0);
+ return (NULL);
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_search.c 8.8 (Berkeley) 7/31/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_search.c,v 1.2 2002/03/21 22:46:25 obrien Exp $");
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#include <db.h>
+#include "btree.h"
+
+static int __bt_snext(BTREE *, PAGE *, const DBT *, int *);
+static int __bt_sprev(BTREE *, PAGE *, const DBT *, int *);
+
+/*
+ * __bt_search --
+ * Search a btree for a key.
+ *
+ * Parameters:
+ * t: tree to search
+ * key: key to find
+ * exactp: pointer to exact match flag
+ *
+ * Returns:
+ * The EPG for matching record, if any, or the EPG for the location
+ * of the key, if it were inserted into the tree, is entered into
+ * the bt_cur field of the tree. A pointer to the field is returned.
+ */
+EPG *
+__bt_search(t, key, exactp)
+ BTREE *t;
+ const DBT *key;
+ int *exactp;
+{
+ PAGE *h;
+ indx_t base, index, lim;
+ pgno_t pg;
+ int cmp;
+
+ BT_CLR(t);
+ for (pg = P_ROOT;;) {
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (NULL);
+
+ /* Do a binary search on the current page. */
+ t->bt_cur.page = h;
+ for (base = 0, lim = NEXTINDEX(h); lim; lim >>= 1) {
+ t->bt_cur.index = index = base + (lim >> 1);
+ if ((cmp = __bt_cmp(t, key, &t->bt_cur)) == 0) {
+ if (h->flags & P_BLEAF) {
+ *exactp = 1;
+ return (&t->bt_cur);
+ }
+ goto next;
+ }
+ if (cmp > 0) {
+ base = index + 1;
+ --lim;
+ }
+ }
+
+ /*
+ * If it's a leaf page, we're almost done. If no duplicates
+ * are allowed, or we have an exact match, we're done. Else,
+ * it's possible that there were matching keys on this page,
+ * which later deleted, and we're on a page with no matches
+ * while there are matches on other pages. If at the start or
+ * end of a page, check the adjacent page.
+ */
+ if (h->flags & P_BLEAF) {
+ if (!F_ISSET(t, B_NODUPS)) {
+ if (base == 0 &&
+ h->prevpg != P_INVALID &&
+ __bt_sprev(t, h, key, exactp))
+ return (&t->bt_cur);
+ if (base == NEXTINDEX(h) &&
+ h->nextpg != P_INVALID &&
+ __bt_snext(t, h, key, exactp))
+ return (&t->bt_cur);
+ }
+ *exactp = 0;
+ t->bt_cur.index = base;
+ return (&t->bt_cur);
+ }
+
+ /*
+ * No match found. Base is the smallest index greater than
+ * key and may be zero or a last + 1 index. If it's non-zero,
+ * decrement by one, and record the internal page which should
+ * be a parent page for the key. If a split later occurs, the
+ * inserted page will be to the right of the saved page.
+ */
+ index = base ? base - 1 : base;
+
+next: BT_PUSH(t, h->pgno, index);
+ pg = GETBINTERNAL(h, index)->pgno;
+ mpool_put(t->bt_mp, h, 0);
+ }
+}
+
+/*
+ * __bt_snext --
+ * Check for an exact match after the key.
+ *
+ * Parameters:
+ * t: tree
+ * h: current page
+ * key: key
+ * exactp: pointer to exact match flag
+ *
+ * Returns:
+ * If an exact match found.
+ */
+static int
+__bt_snext(t, h, key, exactp)
+ BTREE *t;
+ PAGE *h;
+ const DBT *key;
+ int *exactp;
+{
+ EPG e;
+
+ /*
+ * Get the next page. The key is either an exact
+ * match, or not as good as the one we already have.
+ */
+ if ((e.page = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
+ return (0);
+ e.index = 0;
+ if (__bt_cmp(t, key, &e) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ t->bt_cur = e;
+ *exactp = 1;
+ return (1);
+ }
+ mpool_put(t->bt_mp, e.page, 0);
+ return (0);
+}
+
+/*
+ * __bt_sprev --
+ * Check for an exact match before the key.
+ *
+ * Parameters:
+ * t: tree
+ * h: current page
+ * key: key
+ * exactp: pointer to exact match flag
+ *
+ * Returns:
+ * If an exact match found.
+ */
+static int
+__bt_sprev(t, h, key, exactp)
+ BTREE *t;
+ PAGE *h;
+ const DBT *key;
+ int *exactp;
+{
+ EPG e;
+
+ /*
+ * Get the previous page. The key is either an exact
+ * match, or not as good as the one we already have.
+ */
+ if ((e.page = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
+ return (0);
+ e.index = NEXTINDEX(e.page) - 1;
+ if (__bt_cmp(t, key, &e) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ t->bt_cur = e;
+ *exactp = 1;
+ return (1);
+ }
+ mpool_put(t->bt_mp, e.page, 0);
+ return (0);
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_seq.c 8.7 (Berkeley) 7/20/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_seq.c,v 1.3 2002/03/21 22:46:25 obrien Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <db.h>
+#include "btree.h"
+
+static int __bt_first(BTREE *, const DBT *, EPG *, int *);
+static int __bt_seqadv(BTREE *, EPG *, int);
+static int __bt_seqset(BTREE *, EPG *, DBT *, int);
+
+/*
+ * Sequential scan support.
+ *
+ * The tree can be scanned sequentially, starting from either end of the
+ * tree or from any specific key. A scan request before any scanning is
+ * done is initialized as starting from the least node.
+ */
+
+/*
+ * __bt_seq --
+ * Btree sequential scan interface.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key for positioning and return value
+ * data: data return value
+ * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
+ */
+int
+__bt_seq(dbp, key, data, flags)
+ const DB *dbp;
+ DBT *key, *data;
+ u_int flags;
+{
+ BTREE *t;
+ EPG e;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /*
+ * If scan unitialized as yet, or starting at a specific record, set
+ * the scan to a specific key. Both __bt_seqset and __bt_seqadv pin
+ * the page the cursor references if they're successful.
+ */
+ switch (flags) {
+ case R_NEXT:
+ case R_PREV:
+ if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
+ status = __bt_seqadv(t, &e, flags);
+ break;
+ }
+ /* FALLTHROUGH */
+ case R_FIRST:
+ case R_LAST:
+ case R_CURSOR:
+ status = __bt_seqset(t, &e, key, flags);
+ break;
+ default:
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if (status == RET_SUCCESS) {
+ __bt_setcur(t, e.page->pgno, e.index);
+
+ status =
+ __bt_ret(t, &e, key, &t->bt_rkey, data, &t->bt_rdata, 0);
+
+ /*
+ * If the user is doing concurrent access, we copied the
+ * key/data, toss the page.
+ */
+ if (F_ISSET(t, B_DB_LOCK))
+ mpool_put(t->bt_mp, e.page, 0);
+ else
+ t->bt_pinned = e.page;
+ }
+ return (status);
+}
+
+/*
+ * __bt_seqset --
+ * Set the sequential scan to a specific key.
+ *
+ * Parameters:
+ * t: tree
+ * ep: storage for returned key
+ * key: key for initial scan position
+ * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV
+ *
+ * Side effects:
+ * Pins the page the cursor references.
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
+ */
+static int
+__bt_seqset(t, ep, key, flags)
+ BTREE *t;
+ EPG *ep;
+ DBT *key;
+ int flags;
+{
+ PAGE *h;
+ pgno_t pg;
+ int exact;
+
+ /*
+ * Find the first, last or specific key in the tree and point the
+ * cursor at it. The cursor may not be moved until a new key has
+ * been found.
+ */
+ switch (flags) {
+ case R_CURSOR: /* Keyed scan. */
+ /*
+ * Find the first instance of the key or the smallest key
+ * which is greater than or equal to the specified key.
+ */
+ if (key->data == NULL || key->size == 0) {
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+ return (__bt_first(t, key, ep, &exact));
+ case R_FIRST: /* First record. */
+ case R_NEXT:
+ /* Walk down the left-hand side of the tree. */
+ for (pg = P_ROOT;;) {
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+
+ /* Check for an empty tree. */
+ if (NEXTINDEX(h) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_SPECIAL);
+ }
+
+ if (h->flags & (P_BLEAF | P_RLEAF))
+ break;
+ pg = GETBINTERNAL(h, 0)->pgno;
+ mpool_put(t->bt_mp, h, 0);
+ }
+ ep->page = h;
+ ep->index = 0;
+ break;
+ case R_LAST: /* Last record. */
+ case R_PREV:
+ /* Walk down the right-hand side of the tree. */
+ for (pg = P_ROOT;;) {
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+
+ /* Check for an empty tree. */
+ if (NEXTINDEX(h) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_SPECIAL);
+ }
+
+ if (h->flags & (P_BLEAF | P_RLEAF))
+ break;
+ pg = GETBINTERNAL(h, NEXTINDEX(h) - 1)->pgno;
+ mpool_put(t->bt_mp, h, 0);
+ }
+
+ ep->page = h;
+ ep->index = NEXTINDEX(h) - 1;
+ break;
+ }
+ return (RET_SUCCESS);
+}
+
+/*
+ * __bt_seqadvance --
+ * Advance the sequential scan.
+ *
+ * Parameters:
+ * t: tree
+ * flags: R_NEXT, R_PREV
+ *
+ * Side effects:
+ * Pins the page the new key/data record is on.
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
+ */
+static int
+__bt_seqadv(t, ep, flags)
+ BTREE *t;
+ EPG *ep;
+ int flags;
+{
+ CURSOR *c;
+ PAGE *h;
+ indx_t index;
+ pgno_t pg;
+ int exact;
+
+ /*
+ * There are a couple of states that we can be in. The cursor has
+ * been initialized by the time we get here, but that's all we know.
+ */
+ c = &t->bt_cursor;
+
+ /*
+ * The cursor was deleted where there weren't any duplicate records,
+ * so the key was saved. Find out where that key would go in the
+ * current tree. It doesn't matter if the returned key is an exact
+ * match or not -- if it's an exact match, the record was added after
+ * the delete so we can just return it. If not, as long as there's
+ * a record there, return it.
+ */
+ if (F_ISSET(c, CURS_ACQUIRE))
+ return (__bt_first(t, &c->key, ep, &exact));
+
+ /* Get the page referenced by the cursor. */
+ if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
+ return (RET_ERROR);
+
+ /*
+ * Find the next/previous record in the tree and point the cursor at
+ * it. The cursor may not be moved until a new key has been found.
+ */
+ switch (flags) {
+ case R_NEXT: /* Next record. */
+ /*
+ * The cursor was deleted in duplicate records, and moved
+ * forward to a record that has yet to be returned. Clear
+ * that flag, and return the record.
+ */
+ if (F_ISSET(c, CURS_AFTER))
+ goto usecurrent;
+ index = c->pg.index;
+ if (++index == NEXTINDEX(h)) {
+ pg = h->nextpg;
+ mpool_put(t->bt_mp, h, 0);
+ if (pg == P_INVALID)
+ return (RET_SPECIAL);
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ index = 0;
+ }
+ break;
+ case R_PREV: /* Previous record. */
+ /*
+ * The cursor was deleted in duplicate records, and moved
+ * backward to a record that has yet to be returned. Clear
+ * that flag, and return the record.
+ */
+ if (F_ISSET(c, CURS_BEFORE)) {
+usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE);
+ ep->page = h;
+ ep->index = c->pg.index;
+ return (RET_SUCCESS);
+ }
+ index = c->pg.index;
+ if (index == 0) {
+ pg = h->prevpg;
+ mpool_put(t->bt_mp, h, 0);
+ if (pg == P_INVALID)
+ return (RET_SPECIAL);
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ index = NEXTINDEX(h) - 1;
+ } else
+ --index;
+ break;
+ }
+
+ ep->page = h;
+ ep->index = index;
+ return (RET_SUCCESS);
+}
+
+/*
+ * __bt_first --
+ * Find the first entry.
+ *
+ * Parameters:
+ * t: the tree
+ * key: the key
+ * erval: return EPG
+ * exactp: pointer to exact match flag
+ *
+ * Returns:
+ * The first entry in the tree greater than or equal to key,
+ * or RET_SPECIAL if no such key exists.
+ */
+static int
+__bt_first(t, key, erval, exactp)
+ BTREE *t;
+ const DBT *key;
+ EPG *erval;
+ int *exactp;
+{
+ PAGE *h;
+ EPG *ep, save;
+ pgno_t pg;
+
+ /*
+ * Find any matching record; __bt_search pins the page.
+ *
+ * If it's an exact match and duplicates are possible, walk backwards
+ * in the tree until we find the first one. Otherwise, make sure it's
+ * a valid key (__bt_search may return an index just past the end of a
+ * page) and return it.
+ */
+ if ((ep = __bt_search(t, key, exactp)) == NULL)
+ return (0);
+ if (*exactp) {
+ if (F_ISSET(t, B_NODUPS)) {
+ *erval = *ep;
+ return (RET_SUCCESS);
+ }
+
+ /*
+ * Walk backwards, as long as the entry matches and there are
+ * keys left in the tree. Save a copy of each match in case
+ * we go too far.
+ */
+ save = *ep;
+ h = ep->page;
+ do {
+ if (save.page->pgno != ep->page->pgno) {
+ mpool_put(t->bt_mp, save.page, 0);
+ save = *ep;
+ } else
+ save.index = ep->index;
+
+ /*
+ * Don't unpin the page the last (or original) match
+ * was on, but make sure it's unpinned if an error
+ * occurs.
+ */
+ if (ep->index == 0) {
+ if (h->prevpg == P_INVALID)
+ break;
+ if (h->pgno != save.page->pgno)
+ mpool_put(t->bt_mp, h, 0);
+ if ((h = mpool_get(t->bt_mp,
+ h->prevpg, 0)) == NULL) {
+ if (h->pgno == save.page->pgno)
+ mpool_put(t->bt_mp,
+ save.page, 0);
+ return (RET_ERROR);
+ }
+ ep->page = h;
+ ep->index = NEXTINDEX(h);
+ }
+ --ep->index;
+ } while (__bt_cmp(t, key, ep) == 0);
+
+ /*
+ * Reach here with the last page that was looked at pinned,
+ * which may or may not be the same as the last (or original)
+ * match page. If it's not useful, release it.
+ */
+ if (h->pgno != save.page->pgno)
+ mpool_put(t->bt_mp, h, 0);
+
+ *erval = save;
+ return (RET_SUCCESS);
+ }
+
+ /* If at the end of a page, find the next entry. */
+ if (ep->index == NEXTINDEX(ep->page)) {
+ h = ep->page;
+ pg = h->nextpg;
+ mpool_put(t->bt_mp, h, 0);
+ if (pg == P_INVALID)
+ return (RET_SPECIAL);
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ ep->index = 0;
+ ep->page = h;
+ }
+ *erval = *ep;
+ return (RET_SUCCESS);
+}
+
+/*
+ * __bt_setcur --
+ * Set the cursor to an entry in the tree.
+ *
+ * Parameters:
+ * t: the tree
+ * pgno: page number
+ * index: page index
+ */
+void
+__bt_setcur(t, pgno, index)
+ BTREE *t;
+ pgno_t pgno;
+ u_int index;
+{
+ /* Lose any already deleted key. */
+ if (t->bt_cursor.key.data != NULL) {
+ free(t->bt_cursor.key.data);
+ t->bt_cursor.key.size = 0;
+ t->bt_cursor.key.data = NULL;
+ }
+ F_CLR(&t->bt_cursor, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE);
+
+ /* Update the cursor. */
+ t->bt_cursor.pg.pgno = pgno;
+ t->bt_cursor.pg.index = index;
+ F_SET(&t->bt_cursor, CURS_INIT);
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_split.c 8.9 (Berkeley) 7/26/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_split.c,v 1.5 2003/02/16 17:29:09 nectar Exp $");
+
+#include <sys/types.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+static int bt_broot(BTREE *, PAGE *, PAGE *, PAGE *);
+static PAGE *bt_page (BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t);
+static int bt_preserve(BTREE *, pgno_t);
+static PAGE *bt_psplit (BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t);
+static PAGE *bt_root (BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t);
+static int bt_rroot(BTREE *, PAGE *, PAGE *, PAGE *);
+static recno_t rec_total(PAGE *);
+
+#ifdef STATISTICS
+u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved;
+#endif
+
+/*
+ * __BT_SPLIT -- Split the tree.
+ *
+ * Parameters:
+ * t: tree
+ * sp: page to split
+ * key: key to insert
+ * data: data to insert
+ * flags: BIGKEY/BIGDATA flags
+ * ilen: insert length
+ * skip: index to leave open
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__bt_split(t, sp, key, data, flags, ilen, argskip)
+ BTREE *t;
+ PAGE *sp;
+ const DBT *key, *data;
+ int flags;
+ size_t ilen;
+ u_int32_t argskip;
+{
+ BINTERNAL *bi;
+ BLEAF *bl, *tbl;
+ DBT a, b;
+ EPGNO *parent;
+ PAGE *h, *l, *r, *lchild, *rchild;
+ indx_t nxtindex;
+ u_int16_t skip;
+ u_int32_t n, nbytes, nksize;
+ int parentsplit;
+ char *dest;
+
+ /*
+ * Split the page into two pages, l and r. The split routines return
+ * a pointer to the page into which the key should be inserted and with
+ * skip set to the offset which should be used. Additionally, l and r
+ * are pinned.
+ */
+ skip = argskip;
+ h = sp->pgno == P_ROOT ?
+ bt_root(t, sp, &l, &r, &skip, ilen) :
+ bt_page(t, sp, &l, &r, &skip, ilen);
+ if (h == NULL)
+ return (RET_ERROR);
+
+ /*
+ * Insert the new key/data pair into the leaf page. (Key inserts
+ * always cause a leaf page to split first.)
+ */
+ h->linp[skip] = h->upper -= ilen;
+ dest = (char *)h + h->upper;
+ if (F_ISSET(t, R_RECNO))
+ WR_RLEAF(dest, data, flags)
+ else
+ WR_BLEAF(dest, key, data, flags)
+
+ /* If the root page was split, make it look right. */
+ if (sp->pgno == P_ROOT &&
+ (F_ISSET(t, R_RECNO) ?
+ bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
+ goto err2;
+
+ /*
+ * Now we walk the parent page stack -- a LIFO stack of the pages that
+ * were traversed when we searched for the page that split. Each stack
+ * entry is a page number and a page index offset. The offset is for
+ * the page traversed on the search. We've just split a page, so we
+ * have to insert a new key into the parent page.
+ *
+ * If the insert into the parent page causes it to split, may have to
+ * continue splitting all the way up the tree. We stop if the root
+ * splits or the page inserted into didn't have to split to hold the
+ * new key. Some algorithms replace the key for the old page as well
+ * as the new page. We don't, as there's no reason to believe that the
+ * first key on the old page is any better than the key we have, and,
+ * in the case of a key being placed at index 0 causing the split, the
+ * key is unavailable.
+ *
+ * There are a maximum of 5 pages pinned at any time. We keep the left
+ * and right pages pinned while working on the parent. The 5 are the
+ * two children, left parent and right parent (when the parent splits)
+ * and the root page or the overflow key page when calling bt_preserve.
+ * This code must make sure that all pins are released other than the
+ * root page or overflow page which is unlocked elsewhere.
+ */
+ while ((parent = BT_POP(t)) != NULL) {
+ lchild = l;
+ rchild = r;
+
+ /* Get the parent page. */
+ if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
+ goto err2;
+
+ /*
+ * The new key goes ONE AFTER the index, because the split
+ * was to the right.
+ */
+ skip = parent->index + 1;
+
+ /*
+ * Calculate the space needed on the parent page.
+ *
+ * Prefix trees: space hack when inserting into BINTERNAL
+ * pages. Retain only what's needed to distinguish between
+ * the new entry and the LAST entry on the page to its left.
+ * If the keys compare equal, retain the entire key. Note,
+ * we don't touch overflow keys, and the entire key must be
+ * retained for the next-to-left most key on the leftmost
+ * page of each level, or the search will fail. Applicable
+ * ONLY to internal pages that have leaf pages as children.
+ * Further reduction of the key between pairs of internal
+ * pages loses too much information.
+ */
+ switch (rchild->flags & P_TYPE) {
+ case P_BINTERNAL:
+ bi = GETBINTERNAL(rchild, 0);
+ nbytes = NBINTERNAL(bi->ksize);
+ break;
+ case P_BLEAF:
+ bl = GETBLEAF(rchild, 0);
+ nbytes = NBINTERNAL(bl->ksize);
+ if (t->bt_pfx && !(bl->flags & P_BIGKEY) &&
+ (h->prevpg != P_INVALID || skip > 1)) {
+ tbl = GETBLEAF(lchild, NEXTINDEX(lchild) - 1);
+ a.size = tbl->ksize;
+ a.data = tbl->bytes;
+ b.size = bl->ksize;
+ b.data = bl->bytes;
+ nksize = t->bt_pfx(&a, &b);
+ n = NBINTERNAL(nksize);
+ if (n < nbytes) {
+#ifdef STATISTICS
+ bt_pfxsaved += nbytes - n;
+#endif
+ nbytes = n;
+ } else
+ nksize = 0;
+ } else
+ nksize = 0;
+ break;
+ case P_RINTERNAL:
+ case P_RLEAF:
+ nbytes = NRINTERNAL;
+ break;
+ default:
+ abort();
+ }
+
+ /* Split the parent page if necessary or shift the indices. */
+ if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
+ sp = h;
+ h = h->pgno == P_ROOT ?
+ bt_root(t, h, &l, &r, &skip, nbytes) :
+ bt_page(t, h, &l, &r, &skip, nbytes);
+ if (h == NULL)
+ goto err1;
+ parentsplit = 1;
+ } else {
+ if (skip < (nxtindex = NEXTINDEX(h)))
+ memmove(h->linp + skip + 1, h->linp + skip,
+ (nxtindex - skip) * sizeof(indx_t));
+ h->lower += sizeof(indx_t);
+ parentsplit = 0;
+ }
+
+ /* Insert the key into the parent page. */
+ switch (rchild->flags & P_TYPE) {
+ case P_BINTERNAL:
+ h->linp[skip] = h->upper -= nbytes;
+ dest = (char *)h + h->linp[skip];
+ memmove(dest, bi, nbytes);
+ ((BINTERNAL *)dest)->pgno = rchild->pgno;
+ break;
+ case P_BLEAF:
+ h->linp[skip] = h->upper -= nbytes;
+ dest = (char *)h + h->linp[skip];
+ WR_BINTERNAL(dest, nksize ? nksize : bl->ksize,
+ rchild->pgno, bl->flags & P_BIGKEY);
+ memmove(dest, bl->bytes, nksize ? nksize : bl->ksize);
+ if (bl->flags & P_BIGKEY &&
+ bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
+ goto err1;
+ break;
+ case P_RINTERNAL:
+ /*
+ * Update the left page count. If split
+ * added at index 0, fix the correct page.
+ */
+ if (skip > 0)
+ dest = (char *)h + h->linp[skip - 1];
+ else
+ dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
+ ((RINTERNAL *)dest)->nrecs = rec_total(lchild);
+ ((RINTERNAL *)dest)->pgno = lchild->pgno;
+
+ /* Update the right page count. */
+ h->linp[skip] = h->upper -= nbytes;
+ dest = (char *)h + h->linp[skip];
+ ((RINTERNAL *)dest)->nrecs = rec_total(rchild);
+ ((RINTERNAL *)dest)->pgno = rchild->pgno;
+ break;
+ case P_RLEAF:
+ /*
+ * Update the left page count. If split
+ * added at index 0, fix the correct page.
+ */
+ if (skip > 0)
+ dest = (char *)h + h->linp[skip - 1];
+ else
+ dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
+ ((RINTERNAL *)dest)->nrecs = NEXTINDEX(lchild);
+ ((RINTERNAL *)dest)->pgno = lchild->pgno;
+
+ /* Update the right page count. */
+ h->linp[skip] = h->upper -= nbytes;
+ dest = (char *)h + h->linp[skip];
+ ((RINTERNAL *)dest)->nrecs = NEXTINDEX(rchild);
+ ((RINTERNAL *)dest)->pgno = rchild->pgno;
+ break;
+ default:
+ abort();
+ }
+
+ /* Unpin the held pages. */
+ if (!parentsplit) {
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ break;
+ }
+
+ /* If the root page was split, make it look right. */
+ if (sp->pgno == P_ROOT &&
+ (F_ISSET(t, R_RECNO) ?
+ bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
+ goto err1;
+
+ mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
+ mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
+ }
+
+ /* Unpin the held pages. */
+ mpool_put(t->bt_mp, l, MPOOL_DIRTY);
+ mpool_put(t->bt_mp, r, MPOOL_DIRTY);
+
+ /* Clear any pages left on the stack. */
+ return (RET_SUCCESS);
+
+ /*
+ * If something fails in the above loop we were already walking back
+ * up the tree and the tree is now inconsistent. Nothing much we can
+ * do about it but release any memory we're holding.
+ */
+err1: mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
+ mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
+
+err2: mpool_put(t->bt_mp, l, 0);
+ mpool_put(t->bt_mp, r, 0);
+ __dbpanic(t->bt_dbp);
+ return (RET_ERROR);
+}
+
+/*
+ * BT_PAGE -- Split a non-root page of a btree.
+ *
+ * Parameters:
+ * t: tree
+ * h: root page
+ * lp: pointer to left page pointer
+ * rp: pointer to right page pointer
+ * skip: pointer to index to leave open
+ * ilen: insert length
+ *
+ * Returns:
+ * Pointer to page in which to insert or NULL on error.
+ */
+static PAGE *
+bt_page(t, h, lp, rp, skip, ilen)
+ BTREE *t;
+ PAGE *h, **lp, **rp;
+ indx_t *skip;
+ size_t ilen;
+{
+ PAGE *l, *r, *tp;
+ pgno_t npg;
+
+#ifdef STATISTICS
+ ++bt_split;
+#endif
+ /* Put the new right page for the split into place. */
+ if ((r = __bt_new(t, &npg)) == NULL)
+ return (NULL);
+ r->pgno = npg;
+ r->lower = BTDATAOFF;
+ r->upper = t->bt_psize;
+ r->nextpg = h->nextpg;
+ r->prevpg = h->pgno;
+ r->flags = h->flags & P_TYPE;
+
+ /*
+ * If we're splitting the last page on a level because we're appending
+ * a key to it (skip is NEXTINDEX()), it's likely that the data is
+ * sorted. Adding an empty page on the side of the level is less work
+ * and can push the fill factor much higher than normal. If we're
+ * wrong it's no big deal, we'll just do the split the right way next
+ * time. It may look like it's equally easy to do a similar hack for
+ * reverse sorted data, that is, split the tree left, but it's not.
+ * Don't even try.
+ */
+ if (h->nextpg == P_INVALID && *skip == NEXTINDEX(h)) {
+#ifdef STATISTICS
+ ++bt_sortsplit;
+#endif
+ h->nextpg = r->pgno;
+ r->lower = BTDATAOFF + sizeof(indx_t);
+ *skip = 0;
+ *lp = h;
+ *rp = r;
+ return (r);
+ }
+
+ /* Put the new left page for the split into place. */
+ if ((l = (PAGE *)malloc(t->bt_psize)) == NULL) {
+ mpool_put(t->bt_mp, r, 0);
+ return (NULL);
+ }
+#ifdef PURIFY
+ memset(l, 0xff, t->bt_psize);
+#endif
+ l->pgno = h->pgno;
+ l->nextpg = r->pgno;
+ l->prevpg = h->prevpg;
+ l->lower = BTDATAOFF;
+ l->upper = t->bt_psize;
+ l->flags = h->flags & P_TYPE;
+
+ /* Fix up the previous pointer of the page after the split page. */
+ if (h->nextpg != P_INVALID) {
+ if ((tp = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) {
+ free(l);
+ /* XXX mpool_free(t->bt_mp, r->pgno); */
+ return (NULL);
+ }
+ tp->prevpg = r->pgno;
+ mpool_put(t->bt_mp, tp, MPOOL_DIRTY);
+ }
+
+ /*
+ * Split right. The key/data pairs aren't sorted in the btree page so
+ * it's simpler to copy the data from the split page onto two new pages
+ * instead of copying half the data to the right page and compacting
+ * the left page in place. Since the left page can't change, we have
+ * to swap the original and the allocated left page after the split.
+ */
+ tp = bt_psplit(t, h, l, r, skip, ilen);
+
+ /* Move the new left page onto the old left page. */
+ memmove(h, l, t->bt_psize);
+ if (tp == l)
+ tp = h;
+ free(l);
+
+ *lp = h;
+ *rp = r;
+ return (tp);
+}
+
+/*
+ * BT_ROOT -- Split the root page of a btree.
+ *
+ * Parameters:
+ * t: tree
+ * h: root page
+ * lp: pointer to left page pointer
+ * rp: pointer to right page pointer
+ * skip: pointer to index to leave open
+ * ilen: insert length
+ *
+ * Returns:
+ * Pointer to page in which to insert or NULL on error.
+ */
+static PAGE *
+bt_root(t, h, lp, rp, skip, ilen)
+ BTREE *t;
+ PAGE *h, **lp, **rp;
+ indx_t *skip;
+ size_t ilen;
+{
+ PAGE *l, *r, *tp;
+ pgno_t lnpg, rnpg;
+
+#ifdef STATISTICS
+ ++bt_split;
+ ++bt_rootsplit;
+#endif
+ /* Put the new left and right pages for the split into place. */
+ if ((l = __bt_new(t, &lnpg)) == NULL ||
+ (r = __bt_new(t, &rnpg)) == NULL)
+ return (NULL);
+ l->pgno = lnpg;
+ r->pgno = rnpg;
+ l->nextpg = r->pgno;
+ r->prevpg = l->pgno;
+ l->prevpg = r->nextpg = P_INVALID;
+ l->lower = r->lower = BTDATAOFF;
+ l->upper = r->upper = t->bt_psize;
+ l->flags = r->flags = h->flags & P_TYPE;
+
+ /* Split the root page. */
+ tp = bt_psplit(t, h, l, r, skip, ilen);
+
+ *lp = l;
+ *rp = r;
+ return (tp);
+}
+
+/*
+ * BT_RROOT -- Fix up the recno root page after it has been split.
+ *
+ * Parameters:
+ * t: tree
+ * h: root page
+ * l: left page
+ * r: right page
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+static int
+bt_rroot(t, h, l, r)
+ BTREE *t;
+ PAGE *h, *l, *r;
+{
+ char *dest;
+
+ /* Insert the left and right keys, set the header information. */
+ h->linp[0] = h->upper = t->bt_psize - NRINTERNAL;
+ dest = (char *)h + h->upper;
+ WR_RINTERNAL(dest,
+ l->flags & P_RLEAF ? NEXTINDEX(l) : rec_total(l), l->pgno);
+
+ h->linp[1] = h->upper -= NRINTERNAL;
+ dest = (char *)h + h->upper;
+ WR_RINTERNAL(dest,
+ r->flags & P_RLEAF ? NEXTINDEX(r) : rec_total(r), r->pgno);
+
+ h->lower = BTDATAOFF + 2 * sizeof(indx_t);
+
+ /* Unpin the root page, set to recno internal page. */
+ h->flags &= ~P_TYPE;
+ h->flags |= P_RINTERNAL;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+
+ return (RET_SUCCESS);
+}
+
+/*
+ * BT_BROOT -- Fix up the btree root page after it has been split.
+ *
+ * Parameters:
+ * t: tree
+ * h: root page
+ * l: left page
+ * r: right page
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+static int
+bt_broot(t, h, l, r)
+ BTREE *t;
+ PAGE *h, *l, *r;
+{
+ BINTERNAL *bi;
+ BLEAF *bl;
+ u_int32_t nbytes;
+ char *dest;
+
+ /*
+ * If the root page was a leaf page, change it into an internal page.
+ * We copy the key we split on (but not the key's data, in the case of
+ * a leaf page) to the new root page.
+ *
+ * The btree comparison code guarantees that the left-most key on any
+ * level of the tree is never used, so it doesn't need to be filled in.
+ */
+ nbytes = NBINTERNAL(0);
+ h->linp[0] = h->upper = t->bt_psize - nbytes;
+ dest = (char *)h + h->upper;
+ WR_BINTERNAL(dest, 0, l->pgno, 0);
+
+ switch (h->flags & P_TYPE) {
+ case P_BLEAF:
+ bl = GETBLEAF(r, 0);
+ nbytes = NBINTERNAL(bl->ksize);
+ h->linp[1] = h->upper -= nbytes;
+ dest = (char *)h + h->upper;
+ WR_BINTERNAL(dest, bl->ksize, r->pgno, 0);
+ memmove(dest, bl->bytes, bl->ksize);
+
+ /*
+ * If the key is on an overflow page, mark the overflow chain
+ * so it isn't deleted when the leaf copy of the key is deleted.
+ */
+ if (bl->flags & P_BIGKEY &&
+ bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
+ return (RET_ERROR);
+ break;
+ case P_BINTERNAL:
+ bi = GETBINTERNAL(r, 0);
+ nbytes = NBINTERNAL(bi->ksize);
+ h->linp[1] = h->upper -= nbytes;
+ dest = (char *)h + h->upper;
+ memmove(dest, bi, nbytes);
+ ((BINTERNAL *)dest)->pgno = r->pgno;
+ break;
+ default:
+ abort();
+ }
+
+ /* There are two keys on the page. */
+ h->lower = BTDATAOFF + 2 * sizeof(indx_t);
+
+ /* Unpin the root page, set to btree internal page. */
+ h->flags &= ~P_TYPE;
+ h->flags |= P_BINTERNAL;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+
+ return (RET_SUCCESS);
+}
+
+/*
+ * BT_PSPLIT -- Do the real work of splitting the page.
+ *
+ * Parameters:
+ * t: tree
+ * h: page to be split
+ * l: page to put lower half of data
+ * r: page to put upper half of data
+ * pskip: pointer to index to leave open
+ * ilen: insert length
+ *
+ * Returns:
+ * Pointer to page in which to insert.
+ */
+static PAGE *
+bt_psplit(t, h, l, r, pskip, ilen)
+ BTREE *t;
+ PAGE *h, *l, *r;
+ indx_t *pskip;
+ size_t ilen;
+{
+ BINTERNAL *bi;
+ BLEAF *bl;
+ CURSOR *c;
+ RLEAF *rl;
+ PAGE *rval;
+ void *src;
+ indx_t full, half, nxt, off, skip, top, used;
+ u_int32_t nbytes;
+ int bigkeycnt, isbigkey;
+
+ /*
+ * Split the data to the left and right pages. Leave the skip index
+ * open. Additionally, make some effort not to split on an overflow
+ * key. This makes internal page processing faster and can save
+ * space as overflow keys used by internal pages are never deleted.
+ */
+ bigkeycnt = 0;
+ skip = *pskip;
+ full = t->bt_psize - BTDATAOFF;
+ half = full / 2;
+ used = 0;
+ for (nxt = off = 0, top = NEXTINDEX(h); nxt < top; ++off) {
+ if (skip == off) {
+ nbytes = ilen;
+ isbigkey = 0; /* XXX: not really known. */
+ } else
+ switch (h->flags & P_TYPE) {
+ case P_BINTERNAL:
+ src = bi = GETBINTERNAL(h, nxt);
+ nbytes = NBINTERNAL(bi->ksize);
+ isbigkey = bi->flags & P_BIGKEY;
+ break;
+ case P_BLEAF:
+ src = bl = GETBLEAF(h, nxt);
+ nbytes = NBLEAF(bl);
+ isbigkey = bl->flags & P_BIGKEY;
+ break;
+ case P_RINTERNAL:
+ src = GETRINTERNAL(h, nxt);
+ nbytes = NRINTERNAL;
+ isbigkey = 0;
+ break;
+ case P_RLEAF:
+ src = rl = GETRLEAF(h, nxt);
+ nbytes = NRLEAF(rl);
+ isbigkey = 0;
+ break;
+ default:
+ abort();
+ }
+
+ /*
+ * If the key/data pairs are substantial fractions of the max
+ * possible size for the page, it's possible to get situations
+ * where we decide to try and copy too much onto the left page.
+ * Make sure that doesn't happen.
+ */
+ if ((skip <= off && used + nbytes + sizeof(indx_t) >= full)
+ || nxt == top - 1) {
+ --off;
+ break;
+ }
+
+ /* Copy the key/data pair, if not the skipped index. */
+ if (skip != off) {
+ ++nxt;
+
+ l->linp[off] = l->upper -= nbytes;
+ memmove((char *)l + l->upper, src, nbytes);
+ }
+
+ used += nbytes + sizeof(indx_t);
+ if (used >= half) {
+ if (!isbigkey || bigkeycnt == 3)
+ break;
+ else
+ ++bigkeycnt;
+ }
+ }
+
+ /*
+ * Off is the last offset that's valid for the left page.
+ * Nxt is the first offset to be placed on the right page.
+ */
+ l->lower += (off + 1) * sizeof(indx_t);
+
+ /*
+ * If splitting the page that the cursor was on, the cursor has to be
+ * adjusted to point to the same record as before the split. If the
+ * cursor is at or past the skipped slot, the cursor is incremented by
+ * one. If the cursor is on the right page, it is decremented by the
+ * number of records split to the left page.
+ */
+ c = &t->bt_cursor;
+ if (F_ISSET(c, CURS_INIT) && c->pg.pgno == h->pgno) {
+ if (c->pg.index >= skip)
+ ++c->pg.index;
+ if (c->pg.index < nxt) /* Left page. */
+ c->pg.pgno = l->pgno;
+ else { /* Right page. */
+ c->pg.pgno = r->pgno;
+ c->pg.index -= nxt;
+ }
+ }
+
+ /*
+ * If the skipped index was on the left page, just return that page.
+ * Otherwise, adjust the skip index to reflect the new position on
+ * the right page.
+ */
+ if (skip <= off) {
+ skip = 0;
+ rval = l;
+ } else {
+ rval = r;
+ *pskip -= nxt;
+ }
+
+ for (off = 0; nxt < top; ++off) {
+ if (skip == nxt) {
+ ++off;
+ skip = 0;
+ }
+ switch (h->flags & P_TYPE) {
+ case P_BINTERNAL:
+ src = bi = GETBINTERNAL(h, nxt);
+ nbytes = NBINTERNAL(bi->ksize);
+ break;
+ case P_BLEAF:
+ src = bl = GETBLEAF(h, nxt);
+ nbytes = NBLEAF(bl);
+ break;
+ case P_RINTERNAL:
+ src = GETRINTERNAL(h, nxt);
+ nbytes = NRINTERNAL;
+ break;
+ case P_RLEAF:
+ src = rl = GETRLEAF(h, nxt);
+ nbytes = NRLEAF(rl);
+ break;
+ default:
+ abort();
+ }
+ ++nxt;
+ r->linp[off] = r->upper -= nbytes;
+ memmove((char *)r + r->upper, src, nbytes);
+ }
+ r->lower += off * sizeof(indx_t);
+
+ /* If the key is being appended to the page, adjust the index. */
+ if (skip == top)
+ r->lower += sizeof(indx_t);
+
+ return (rval);
+}
+
+/*
+ * BT_PRESERVE -- Mark a chain of pages as used by an internal node.
+ *
+ * Chains of indirect blocks pointed to by leaf nodes get reclaimed when the
+ * record that references them gets deleted. Chains pointed to by internal
+ * pages never get deleted. This routine marks a chain as pointed to by an
+ * internal page.
+ *
+ * Parameters:
+ * t: tree
+ * pg: page number of first page in the chain.
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+static int
+bt_preserve(t, pg)
+ BTREE *t;
+ pgno_t pg;
+{
+ PAGE *h;
+
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ h->flags |= P_PRESERVE;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+}
+
+/*
+ * REC_TOTAL -- Return the number of recno entries below a page.
+ *
+ * Parameters:
+ * h: page
+ *
+ * Returns:
+ * The number of recno entries below a page.
+ *
+ * XXX
+ * These values could be set by the bt_psplit routine. The problem is that the
+ * entry has to be popped off of the stack etc. or the values have to be passed
+ * all the way back to bt_split/bt_rroot and it's not very clean.
+ */
+static recno_t
+rec_total(h)
+ PAGE *h;
+{
+ recno_t recs;
+ indx_t nxt, top;
+
+ for (recs = 0, nxt = 0, top = NEXTINDEX(h); nxt < top; ++nxt)
+ recs += GETRINTERNAL(h, nxt)->nrecs;
+ return (recs);
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bt_utils.c 8.8 (Berkeley) 7/20/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_utils.c,v 1.3 2003/01/01 18:48:42 schweikh Exp $");
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "btree.h"
+
+/*
+ * __bt_ret --
+ * Build return key/data pair.
+ *
+ * Parameters:
+ * t: tree
+ * e: key/data pair to be returned
+ * key: user's key structure (NULL if not to be filled in)
+ * rkey: memory area to hold key
+ * data: user's data structure (NULL if not to be filled in)
+ * rdata: memory area to hold data
+ * copy: always copy the key/data item
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__bt_ret(t, e, key, rkey, data, rdata, copy)
+ BTREE *t;
+ EPG *e;
+ DBT *key, *rkey, *data, *rdata;
+ int copy;
+{
+ BLEAF *bl;
+ void *p;
+
+ bl = GETBLEAF(e->page, e->index);
+
+ /*
+ * We must copy big keys/data to make them contigous. Otherwise,
+ * leave the page pinned and don't copy unless the user specified
+ * concurrent access.
+ */
+ if (key == NULL)
+ goto dataonly;
+
+ if (bl->flags & P_BIGKEY) {
+ if (__ovfl_get(t, bl->bytes,
+ &key->size, &rkey->data, &rkey->size))
+ return (RET_ERROR);
+ key->data = rkey->data;
+ } else if (copy || F_ISSET(t, B_DB_LOCK)) {
+ if (bl->ksize > rkey->size) {
+ p = (void *)(rkey->data == NULL ?
+ malloc(bl->ksize) : realloc(rkey->data, bl->ksize));
+ if (p == NULL)
+ return (RET_ERROR);
+ rkey->data = p;
+ rkey->size = bl->ksize;
+ }
+ memmove(rkey->data, bl->bytes, bl->ksize);
+ key->size = bl->ksize;
+ key->data = rkey->data;
+ } else {
+ key->size = bl->ksize;
+ key->data = bl->bytes;
+ }
+
+dataonly:
+ if (data == NULL)
+ return (RET_SUCCESS);
+
+ if (bl->flags & P_BIGDATA) {
+ if (__ovfl_get(t, bl->bytes + bl->ksize,
+ &data->size, &rdata->data, &rdata->size))
+ return (RET_ERROR);
+ data->data = rdata->data;
+ } else if (copy || F_ISSET(t, B_DB_LOCK)) {
+ /* Use +1 in case the first record retrieved is 0 length. */
+ if (bl->dsize + 1 > rdata->size) {
+ p = (void *)(rdata->data == NULL ?
+ malloc(bl->dsize + 1) :
+ realloc(rdata->data, bl->dsize + 1));
+ if (p == NULL)
+ return (RET_ERROR);
+ rdata->data = p;
+ rdata->size = bl->dsize + 1;
+ }
+ memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize);
+ data->size = bl->dsize;
+ data->data = rdata->data;
+ } else {
+ data->size = bl->dsize;
+ data->data = bl->bytes + bl->ksize;
+ }
+
+ return (RET_SUCCESS);
+}
+
+/*
+ * __BT_CMP -- Compare a key to a given record.
+ *
+ * Parameters:
+ * t: tree
+ * k1: DBT pointer of first arg to comparison
+ * e: pointer to EPG for comparison
+ *
+ * Returns:
+ * < 0 if k1 is < record
+ * = 0 if k1 is = record
+ * > 0 if k1 is > record
+ */
+int
+__bt_cmp(t, k1, e)
+ BTREE *t;
+ const DBT *k1;
+ EPG *e;
+{
+ BINTERNAL *bi;
+ BLEAF *bl;
+ DBT k2;
+ PAGE *h;
+ void *bigkey;
+
+ /*
+ * The left-most key on internal pages, at any level of the tree, is
+ * guaranteed by the following code to be less than any user key.
+ * This saves us from having to update the leftmost key on an internal
+ * page when the user inserts a new key in the tree smaller than
+ * anything we've yet seen.
+ */
+ h = e->page;
+ if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF))
+ return (1);
+
+ bigkey = NULL;
+ if (h->flags & P_BLEAF) {
+ bl = GETBLEAF(h, e->index);
+ if (bl->flags & P_BIGKEY)
+ bigkey = bl->bytes;
+ else {
+ k2.data = bl->bytes;
+ k2.size = bl->ksize;
+ }
+ } else {
+ bi = GETBINTERNAL(h, e->index);
+ if (bi->flags & P_BIGKEY)
+ bigkey = bi->bytes;
+ else {
+ k2.data = bi->bytes;
+ k2.size = bi->ksize;
+ }
+ }
+
+ if (bigkey) {
+ if (__ovfl_get(t, bigkey,
+ &k2.size, &t->bt_rdata.data, &t->bt_rdata.size))
+ return (RET_ERROR);
+ k2.data = t->bt_rdata.data;
+ }
+ return ((*t->bt_cmp)(k1, &k2));
+}
+
+/*
+ * __BT_DEFCMP -- Default comparison routine.
+ *
+ * Parameters:
+ * a: DBT #1
+ * b: DBT #2
+ *
+ * Returns:
+ * < 0 if a is < b
+ * = 0 if a is = b
+ * > 0 if a is > b
+ */
+int
+__bt_defcmp(a, b)
+ const DBT *a, *b;
+{
+ size_t len;
+ u_char *p1, *p2;
+
+ /*
+ * XXX
+ * If a size_t doesn't fit in an int, this routine can lose.
+ * What we need is an integral type which is guaranteed to be
+ * larger than a size_t, and there is no such thing.
+ */
+ len = MIN(a->size, b->size);
+ for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
+ if (*p1 != *p2)
+ return ((int)*p1 - (int)*p2);
+ return ((int)a->size - (int)b->size);
+}
+
+/*
+ * __BT_DEFPFX -- Default prefix routine.
+ *
+ * Parameters:
+ * a: DBT #1
+ * b: DBT #2
+ *
+ * Returns:
+ * Number of bytes needed to distinguish b from a.
+ */
+size_t
+__bt_defpfx(a, b)
+ const DBT *a, *b;
+{
+ u_char *p1, *p2;
+ size_t cnt, len;
+
+ cnt = 1;
+ len = MIN(a->size, b->size);
+ for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
+ if (*p1 != *p2)
+ return (cnt);
+
+ /* a->size must be <= b->size, or they wouldn't be in this order. */
+ return (a->size < b->size ? a->size + 1 : a->size);
+}
--- /dev/null
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)btree.h 8.11 (Berkeley) 8/17/94
+ * $FreeBSD: src/lib/libc/db/btree/btree.h,v 1.3 2002/03/22 23:41:40 obrien Exp $
+ */
+
+/* Macros to set/clear/test flags. */
+#define F_SET(p, f) (p)->flags |= (f)
+#define F_CLR(p, f) (p)->flags &= ~(f)
+#define F_ISSET(p, f) ((p)->flags & (f))
+
+#include <mpool.h>
+
+#define DEFMINKEYPAGE (2) /* Minimum keys per page */
+#define MINCACHE (5) /* Minimum cached pages */
+#define MINPSIZE (512) /* Minimum page size */
+
+/*
+ * Page 0 of a btree file contains a copy of the meta-data. This page is also
+ * used as an out-of-band page, i.e. page pointers that point to nowhere point
+ * to page 0. Page 1 is the root of the btree.
+ */
+#define P_INVALID 0 /* Invalid tree page number. */
+#define P_META 0 /* Tree metadata page number. */
+#define P_ROOT 1 /* Tree root page number. */
+
+/*
+ * There are five page layouts in the btree: btree internal pages (BINTERNAL),
+ * btree leaf pages (BLEAF), recno internal pages (RINTERNAL), recno leaf pages
+ * (RLEAF) and overflow pages. All five page types have a page header (PAGE).
+ * This implementation requires that values within structures NOT be padded.
+ * (ANSI C permits random padding.) If your compiler pads randomly you'll have
+ * to do some work to get this package to run.
+ */
+typedef struct _page {
+ pgno_t pgno; /* this page's page number */
+ pgno_t prevpg; /* left sibling */
+ pgno_t nextpg; /* right sibling */
+
+#define P_BINTERNAL 0x01 /* btree internal page */
+#define P_BLEAF 0x02 /* leaf page */
+#define P_OVERFLOW 0x04 /* overflow page */
+#define P_RINTERNAL 0x08 /* recno internal page */
+#define P_RLEAF 0x10 /* leaf page */
+#define P_TYPE 0x1f /* type mask */
+#define P_PRESERVE 0x20 /* never delete this chain of pages */
+ u_int32_t flags;
+
+ indx_t lower; /* lower bound of free space on page */
+ indx_t upper; /* upper bound of free space on page */
+ indx_t linp[1]; /* indx_t-aligned VAR. LENGTH DATA */
+} PAGE;
+
+/* First and next index. */
+#define BTDATAOFF \
+ (sizeof(pgno_t) + sizeof(pgno_t) + sizeof(pgno_t) + \
+ sizeof(u_int32_t) + sizeof(indx_t) + sizeof(indx_t))
+#define NEXTINDEX(p) (((p)->lower - BTDATAOFF) / sizeof(indx_t))
+
+/*
+ * For pages other than overflow pages, there is an array of offsets into the
+ * rest of the page immediately following the page header. Each offset is to
+ * an item which is unique to the type of page. The h_lower offset is just
+ * past the last filled-in index. The h_upper offset is the first item on the
+ * page. Offsets are from the beginning of the page.
+ *
+ * If an item is too big to store on a single page, a flag is set and the item
+ * is a { page, size } pair such that the page is the first page of an overflow
+ * chain with size bytes of item. Overflow pages are simply bytes without any
+ * external structure.
+ *
+ * The page number and size fields in the items are pgno_t-aligned so they can
+ * be manipulated without copying. (This presumes that 32 bit items can be
+ * manipulated on this system.)
+ */
+#define LALIGN(n) (((n) + sizeof(pgno_t) - 1) & ~(sizeof(pgno_t) - 1))
+#define NOVFLSIZE (sizeof(pgno_t) + sizeof(u_int32_t))
+
+/*
+ * For the btree internal pages, the item is a key. BINTERNALs are {key, pgno}
+ * pairs, such that the key compares less than or equal to all of the records
+ * on that page. For a tree without duplicate keys, an internal page with two
+ * consecutive keys, a and b, will have all records greater than or equal to a
+ * and less than b stored on the page associated with a. Duplicate keys are
+ * somewhat special and can cause duplicate internal and leaf page records and
+ * some minor modifications of the above rule.
+ */
+typedef struct _binternal {
+ u_int32_t ksize; /* key size */
+ pgno_t pgno; /* page number stored on */
+#define P_BIGDATA 0x01 /* overflow data */
+#define P_BIGKEY 0x02 /* overflow key */
+ u_char flags;
+ char bytes[1]; /* data */
+} BINTERNAL;
+
+/* Get the page's BINTERNAL structure at index indx. */
+#define GETBINTERNAL(pg, indx) \
+ ((BINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
+
+/* Get the number of bytes in the entry. */
+#define NBINTERNAL(len) \
+ LALIGN(sizeof(u_int32_t) + sizeof(pgno_t) + sizeof(u_char) + (len))
+
+/* Copy a BINTERNAL entry to the page. */
+#define WR_BINTERNAL(p, size, pgno, flags) { \
+ *(u_int32_t *)p = size; \
+ p += sizeof(u_int32_t); \
+ *(pgno_t *)p = pgno; \
+ p += sizeof(pgno_t); \
+ *(u_char *)p = flags; \
+ p += sizeof(u_char); \
+}
+
+/*
+ * For the recno internal pages, the item is a page number with the number of
+ * keys found on that page and below.
+ */
+typedef struct _rinternal {
+ recno_t nrecs; /* number of records */
+ pgno_t pgno; /* page number stored below */
+} RINTERNAL;
+
+/* Get the page's RINTERNAL structure at index indx. */
+#define GETRINTERNAL(pg, indx) \
+ ((RINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
+
+/* Get the number of bytes in the entry. */
+#define NRINTERNAL \
+ LALIGN(sizeof(recno_t) + sizeof(pgno_t))
+
+/* Copy a RINTERAL entry to the page. */
+#define WR_RINTERNAL(p, nrecs, pgno) { \
+ *(recno_t *)p = nrecs; \
+ p += sizeof(recno_t); \
+ *(pgno_t *)p = pgno; \
+}
+
+/* For the btree leaf pages, the item is a key and data pair. */
+typedef struct _bleaf {
+ u_int32_t ksize; /* size of key */
+ u_int32_t dsize; /* size of data */
+ u_char flags; /* P_BIGDATA, P_BIGKEY */
+ char bytes[1]; /* data */
+} BLEAF;
+
+/* Get the page's BLEAF structure at index indx. */
+#define GETBLEAF(pg, indx) \
+ ((BLEAF *)((char *)(pg) + (pg)->linp[indx]))
+
+/* Get the number of bytes in the entry. */
+#define NBLEAF(p) NBLEAFDBT((p)->ksize, (p)->dsize)
+
+/* Get the number of bytes in the user's key/data pair. */
+#define NBLEAFDBT(ksize, dsize) \
+ LALIGN(sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_char) + \
+ (ksize) + (dsize))
+
+/* Copy a BLEAF entry to the page. */
+#define WR_BLEAF(p, key, data, flags) { \
+ *(u_int32_t *)p = key->size; \
+ p += sizeof(u_int32_t); \
+ *(u_int32_t *)p = data->size; \
+ p += sizeof(u_int32_t); \
+ *(u_char *)p = flags; \
+ p += sizeof(u_char); \
+ memmove(p, key->data, key->size); \
+ p += key->size; \
+ memmove(p, data->data, data->size); \
+}
+
+/* For the recno leaf pages, the item is a data entry. */
+typedef struct _rleaf {
+ u_int32_t dsize; /* size of data */
+ u_char flags; /* P_BIGDATA */
+ char bytes[1];
+} RLEAF;
+
+/* Get the page's RLEAF structure at index indx. */
+#define GETRLEAF(pg, indx) \
+ ((RLEAF *)((char *)(pg) + (pg)->linp[indx]))
+
+/* Get the number of bytes in the entry. */
+#define NRLEAF(p) NRLEAFDBT((p)->dsize)
+
+/* Get the number of bytes from the user's data. */
+#define NRLEAFDBT(dsize) \
+ LALIGN(sizeof(u_int32_t) + sizeof(u_char) + (dsize))
+
+/* Copy a RLEAF entry to the page. */
+#define WR_RLEAF(p, data, flags) { \
+ *(u_int32_t *)p = data->size; \
+ p += sizeof(u_int32_t); \
+ *(u_char *)p = flags; \
+ p += sizeof(u_char); \
+ memmove(p, data->data, data->size); \
+}
+
+/*
+ * A record in the tree is either a pointer to a page and an index in the page
+ * or a page number and an index. These structures are used as a cursor, stack
+ * entry and search returns as well as to pass records to other routines.
+ *
+ * One comment about searches. Internal page searches must find the largest
+ * record less than key in the tree so that descents work. Leaf page searches
+ * must find the smallest record greater than key so that the returned index
+ * is the record's correct position for insertion.
+ */
+typedef struct _epgno {
+ pgno_t pgno; /* the page number */
+ indx_t index; /* the index on the page */
+} EPGNO;
+
+typedef struct _epg {
+ PAGE *page; /* the (pinned) page */
+ indx_t index; /* the index on the page */
+} EPG;
+
+/*
+ * About cursors. The cursor (and the page that contained the key/data pair
+ * that it referenced) can be deleted, which makes things a bit tricky. If
+ * there are no duplicates of the cursor key in the tree (i.e. B_NODUPS is set
+ * or there simply aren't any duplicates of the key) we copy the key that it
+ * referenced when it's deleted, and reacquire a new cursor key if the cursor
+ * is used again. If there are duplicates keys, we move to the next/previous
+ * key, and set a flag so that we know what happened. NOTE: if duplicate (to
+ * the cursor) keys are added to the tree during this process, it is undefined
+ * if they will be returned or not in a cursor scan.
+ *
+ * The flags determine the possible states of the cursor:
+ *
+ * CURS_INIT The cursor references *something*.
+ * CURS_ACQUIRE The cursor was deleted, and a key has been saved so that
+ * we can reacquire the right position in the tree.
+ * CURS_AFTER, CURS_BEFORE
+ * The cursor was deleted, and now references a key/data pair
+ * that has not yet been returned, either before or after the
+ * deleted key/data pair.
+ * XXX
+ * This structure is broken out so that we can eventually offer multiple
+ * cursors as part of the DB interface.
+ */
+typedef struct _cursor {
+ EPGNO pg; /* B: Saved tree reference. */
+ DBT key; /* B: Saved key, or key.data == NULL. */
+ recno_t rcursor; /* R: recno cursor (1-based) */
+
+#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */
+#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */
+#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */
+#define CURS_INIT 0x08 /* RB: Cursor initialized. */
+ u_int8_t flags;
+} CURSOR;
+
+/*
+ * The metadata of the tree. The nrecs field is used only by the RECNO code.
+ * This is because the btree doesn't really need it and it requires that every
+ * put or delete call modify the metadata.
+ */
+typedef struct _btmeta {
+ u_int32_t magic; /* magic number */
+ u_int32_t version; /* version */
+ u_int32_t psize; /* page size */
+ u_int32_t free; /* page number of first free page */
+ u_int32_t nrecs; /* R: number of records */
+
+#define SAVEMETA (B_NODUPS | R_RECNO)
+ u_int32_t flags; /* bt_flags & SAVEMETA */
+} BTMETA;
+
+/* The in-memory btree/recno data structure. */
+typedef struct _btree {
+ MPOOL *bt_mp; /* memory pool cookie */
+
+ DB *bt_dbp; /* pointer to enclosing DB */
+
+ EPG bt_cur; /* current (pinned) page */
+ PAGE *bt_pinned; /* page pinned across calls */
+
+ CURSOR bt_cursor; /* cursor */
+
+#define BT_PUSH(t, p, i) { \
+ t->bt_sp->pgno = p; \
+ t->bt_sp->index = i; \
+ ++t->bt_sp; \
+}
+#define BT_POP(t) (t->bt_sp == t->bt_stack ? NULL : --t->bt_sp)
+#define BT_CLR(t) (t->bt_sp = t->bt_stack)
+ EPGNO bt_stack[50]; /* stack of parent pages */
+ EPGNO *bt_sp; /* current stack pointer */
+
+ DBT bt_rkey; /* returned key */
+ DBT bt_rdata; /* returned data */
+
+ int bt_fd; /* tree file descriptor */
+
+ pgno_t bt_free; /* next free page */
+ u_int32_t bt_psize; /* page size */
+ indx_t bt_ovflsize; /* cut-off for key/data overflow */
+ int bt_lorder; /* byte order */
+ /* sorted order */
+ enum { NOT, BACK, FORWARD } bt_order;
+ EPGNO bt_last; /* last insert */
+
+ /* B: key comparison function */
+ int (*bt_cmp)(const DBT *, const DBT *);
+ /* B: prefix comparison function */
+ size_t (*bt_pfx)(const DBT *, const DBT *);
+ /* R: recno input function */
+ int (*bt_irec)(struct _btree *, recno_t);
+
+ FILE *bt_rfp; /* R: record FILE pointer */
+ int bt_rfd; /* R: record file descriptor */
+
+ caddr_t bt_cmap; /* R: current point in mapped space */
+ caddr_t bt_smap; /* R: start of mapped space */
+ caddr_t bt_emap; /* R: end of mapped space */
+ size_t bt_msize; /* R: size of mapped region. */
+
+ recno_t bt_nrecs; /* R: number of records */
+ size_t bt_reclen; /* R: fixed record length */
+ u_char bt_bval; /* R: delimiting byte/pad character */
+
+/*
+ * NB:
+ * B_NODUPS and R_RECNO are stored on disk, and may not be changed.
+ */
+#define B_INMEM 0x00001 /* in-memory tree */
+#define B_METADIRTY 0x00002 /* need to write metadata */
+#define B_MODIFIED 0x00004 /* tree modified */
+#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */
+#define B_RDONLY 0x00010 /* read-only tree */
+
+#define B_NODUPS 0x00020 /* no duplicate keys permitted */
+#define R_RECNO 0x00080 /* record oriented tree */
+
+#define R_CLOSEFP 0x00040 /* opened a file pointer */
+#define R_EOF 0x00100 /* end of input file reached. */
+#define R_FIXLEN 0x00200 /* fixed length records */
+#define R_MEMMAPPED 0x00400 /* memory mapped file. */
+#define R_INMEM 0x00800 /* in-memory file */
+#define R_MODIFIED 0x01000 /* modified file */
+#define R_RDONLY 0x02000 /* read-only file */
+
+#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */
+#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */
+#define B_DB_TXN 0x10000 /* DB_TXN specified. */
+ u_int32_t flags;
+} BTREE;
+
+#include "extern.h"
--- /dev/null
+--- btree.h.orig Fri Mar 22 15:41:40 2002
++++ btree.h Sat Oct 18 18:14:05 2003
+@@ -381,4 +381,4 @@
+ u_int32_t flags;
+ } BTREE;
+
+-#include "extern.h"
++#include "bt_extern.h"
--- /dev/null
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)extern.h 8.10 (Berkeley) 7/20/94
+ * $FreeBSD: src/lib/libc/db/btree/extern.h,v 1.3 2002/03/22 09:18:22 obrien Exp $
+ */
+
+int __bt_close(DB *);
+int __bt_cmp(BTREE *, const DBT *, EPG *);
+int __bt_crsrdel(BTREE *, EPGNO *);
+int __bt_defcmp(const DBT *, const DBT *);
+size_t __bt_defpfx(const DBT *, const DBT *);
+int __bt_delete(const DB *, const DBT *, u_int);
+int __bt_dleaf(BTREE *, const DBT *, PAGE *, u_int);
+int __bt_fd(const DB *);
+int __bt_free(BTREE *, PAGE *);
+int __bt_get(const DB *, const DBT *, DBT *, u_int);
+PAGE *__bt_new(BTREE *, pgno_t *);
+void __bt_pgin(void *, pgno_t, void *);
+void __bt_pgout(void *, pgno_t, void *);
+int __bt_push(BTREE *, pgno_t, int);
+int __bt_put(const DB *dbp, DBT *, const DBT *, u_int);
+int __bt_ret(BTREE *, EPG *, DBT *, DBT *, DBT *, DBT *, int);
+EPG *__bt_search(BTREE *, const DBT *, int *);
+int __bt_seq(const DB *, DBT *, DBT *, u_int);
+void __bt_setcur(BTREE *, pgno_t, u_int);
+int __bt_split(BTREE *, PAGE *,
+ const DBT *, const DBT *, int, size_t, u_int32_t);
+int __bt_sync(const DB *, u_int);
+
+int __ovfl_delete(BTREE *, void *);
+int __ovfl_get(BTREE *, void *, size_t *, void **, size_t *);
+int __ovfl_put(BTREE *, const DBT *, pgno_t *);
+
+#ifdef DEBUG
+void __bt_dnpage(DB *, pgno_t);
+void __bt_dpage(PAGE *);
+void __bt_dump(DB *);
+#endif
+#ifdef STATISTICS
+void __bt_stat(DB *);
+#endif
# from @(#)Makefile.inc 8.2 (Berkeley) 7/14/94
-# $FreeBSD: src/lib/libc/db/btree/Makefile.inc,v 1.3 1999/08/27 23:58:16 peter Exp $
+# $FreeBSD: src/lib/libc/db/btree/Makefile.inc,v 1.4 2002/11/18 09:50:54 ru Exp $
.PATH: ${.CURDIR}/db/btree
-SRCS+= bt_close.c bt_conv.c bt_debug.c bt_delete.c bt_get.c bt_open.c \
+.include "Makefile.fbsd_begin"
+FBSDMISRCS= bt_close.c bt_conv.c bt_debug.c bt_delete.c bt_get.c bt_open.c \
bt_overflow.c bt_page.c bt_put.c bt_search.c bt_seq.c bt_split.c \
bt_utils.c
+.for _src in ${FBSDMISRCS}
+CFLAGS-${_src:R}-fbsd.${_src:E} += -D__DBINTERFACE_PRIVATE
+.endfor
+FBSDHDRS= btree.h
+.include "Makefile.fbsd_end"
+
+# need to rename extern.h to make it unique
+${SYMROOT}/bt_extern.h: ${.CURDIR}/db/btree/FreeBSD/extern.h _AUTOPATCHSYM
+AUTOPATCHHDRS+= ${SYMROOT}/bt_extern.h
+++ /dev/null
-{
- DYNAMIC_CODE_GEN = YES;
- FILESTABLE = {
- H_FILES = (bt_extern.h, btree.h);
- OTHER_LINKED = (
- bt_close.c,
- bt_conv.c,
- bt_debug.c,
- bt_delete.c,
- bt_get.c,
- bt_open.c,
- bt_overflow.c,
- bt_page.c,
- bt_put.c,
- bt_search.c,
- bt_seq.c,
- bt_split.c,
- bt_stack.c,
- bt_utils.c
- );
- OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble);
- PROJECT_HEADERS = (btree.h, bt_extern.h);
- SUBPROJECTS = ();
- };
- LANGUAGE = English;
- MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles";
- NEXTSTEP_BUILDDIR = "/Local/Public/Sandbox/$(USER)/BUILD/$(NAME)";
- NEXTSTEP_BUILDTOOL = /bin/gnumake;
- NEXTSTEP_INSTALLDIR = /Local/Developer/System;
- NEXTSTEP_JAVA_COMPILER = /usr/bin/javac;
- NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc;
- NEXTSTEP_PUBLICHEADERSDIR = /usr/include;
- PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make;
- PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac";
- PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc";
- PROJECTNAME = btree;
- PROJECTTYPE = Component;
- PROJECTVERSION = 2.8;
- WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make;
- WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe";
- WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc";
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_close.c 8.7 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-#ifndef __APPLE_
-#endif
-
-#include <sys/param.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <db.h>
-#include "btree.h"
-
-static int bt_meta(BTREE *);
-
-/*
- * BT_CLOSE -- Close a btree.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__bt_close(dbp)
- DB *dbp;
-{
- BTREE *t;
- int fd;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Sync the tree. */
- if (__bt_sync(dbp, 0) == RET_ERROR)
- return (RET_ERROR);
-
- /* Close the memory pool. */
- if (mpool_close(t->bt_mp) == RET_ERROR)
- return (RET_ERROR);
-
- /* Free random memory. */
- if (t->bt_cursor.key.data != NULL) {
- free(t->bt_cursor.key.data);
- t->bt_cursor.key.size = 0;
- t->bt_cursor.key.data = NULL;
- }
- if (t->bt_rkey.data) {
- free(t->bt_rkey.data);
- t->bt_rkey.size = 0;
- t->bt_rkey.data = NULL;
- }
- if (t->bt_rdata.data) {
- free(t->bt_rdata.data);
- t->bt_rdata.size = 0;
- t->bt_rdata.data = NULL;
- }
-
- fd = t->bt_fd;
- free(t);
- free(dbp);
- return (close(fd) ? RET_ERROR : RET_SUCCESS);
-}
-
-/*
- * BT_SYNC -- sync the btree to disk.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__bt_sync(dbp, flags)
- const DB *dbp;
- u_int flags;
-{
- BTREE *t;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Sync doesn't currently take any flags. */
- if (flags != 0) {
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED))
- return (RET_SUCCESS);
-
- if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
- return (RET_ERROR);
-
- if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS)
- F_CLR(t, B_MODIFIED);
-
- return (status);
-}
-
-/*
- * BT_META -- write the tree meta data to disk.
- *
- * Parameters:
- * t: tree
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-bt_meta(t)
- BTREE *t;
-{
- BTMETA m;
- void *p;
-
- if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL)
- return (RET_ERROR);
-
- /* Fill in metadata. */
- m.magic = BTREEMAGIC;
- m.version = BTREEVERSION;
- m.psize = t->bt_psize;
- m.free = t->bt_free;
- m.nrecs = t->bt_nrecs;
- m.flags = F_ISSET(t, SAVEMETA);
-
- memmove(p, &m, sizeof(BTMETA));
- mpool_put(t->bt_mp, p, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_conv.c 8.5 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-
-#include <stdio.h>
-
-#include <db.h>
-#include "btree.h"
-
-static void mswap(PAGE *);
-
-/*
- * __BT_BPGIN, __BT_BPGOUT --
- * Convert host-specific number layout to/from the host-independent
- * format stored on disk.
- *
- * Parameters:
- * t: tree
- * pg: page number
- * h: page to convert
- */
-void
-__bt_pgin(t, pg, pp)
- void *t;
- pgno_t pg;
- void *pp;
-{
- PAGE *h;
- indx_t i, top;
- u_char flags;
- char *p;
-
- if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
- return;
- if (pg == P_META) {
- mswap(pp);
- return;
- }
-
- h = pp;
- M_32_SWAP(h->pgno);
- M_32_SWAP(h->prevpg);
- M_32_SWAP(h->nextpg);
- M_32_SWAP(h->flags);
- M_16_SWAP(h->lower);
- M_16_SWAP(h->upper);
-
- top = NEXTINDEX(h);
- if ((h->flags & P_TYPE) == P_BINTERNAL)
- for (i = 0; i < top; i++) {
- M_16_SWAP(h->linp[i]);
- p = (char *)GETBINTERNAL(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- if (*(u_char *)p & P_BIGKEY) {
- p += sizeof(u_char);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- }
- else if ((h->flags & P_TYPE) == P_BLEAF)
- for (i = 0; i < top; i++) {
- M_16_SWAP(h->linp[i]);
- p = (char *)GETBLEAF(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- flags = *(u_char *)p;
- if (flags & (P_BIGKEY | P_BIGDATA)) {
- p += sizeof(u_char);
- if (flags & P_BIGKEY) {
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- if (flags & P_BIGDATA) {
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- }
- }
-}
-
-void
-__bt_pgout(t, pg, pp)
- void *t;
- pgno_t pg;
- void *pp;
-{
- PAGE *h;
- indx_t i, top;
- u_char flags;
- char *p;
-
- if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
- return;
- if (pg == P_META) {
- mswap(pp);
- return;
- }
-
- h = pp;
- top = NEXTINDEX(h);
- if ((h->flags & P_TYPE) == P_BINTERNAL)
- for (i = 0; i < top; i++) {
- p = (char *)GETBINTERNAL(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- if (*(u_char *)p & P_BIGKEY) {
- p += sizeof(u_char);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- M_16_SWAP(h->linp[i]);
- }
- else if ((h->flags & P_TYPE) == P_BLEAF)
- for (i = 0; i < top; i++) {
- p = (char *)GETBLEAF(h, i);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(u_int32_t);
- flags = *(u_char *)p;
- if (flags & (P_BIGKEY | P_BIGDATA)) {
- p += sizeof(u_char);
- if (flags & P_BIGKEY) {
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- if (flags & P_BIGDATA) {
- p += sizeof(u_int32_t);
- P_32_SWAP(p);
- p += sizeof(pgno_t);
- P_32_SWAP(p);
- }
- }
- M_16_SWAP(h->linp[i]);
- }
-
- M_32_SWAP(h->pgno);
- M_32_SWAP(h->prevpg);
- M_32_SWAP(h->nextpg);
- M_32_SWAP(h->flags);
- M_16_SWAP(h->lower);
- M_16_SWAP(h->upper);
-}
-
-/*
- * MSWAP -- Actually swap the bytes on the meta page.
- *
- * Parameters:
- * p: page to convert
- */
-static void
-mswap(pg)
- PAGE *pg;
-{
- char *p;
-
- p = (char *)pg;
- P_32_SWAP(p); /* magic */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* version */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* psize */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* free */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* nrecs */
- p += sizeof(u_int32_t);
- P_32_SWAP(p); /* flags */
- p += sizeof(u_int32_t);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_debug.c 8.5 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-#ifdef DEBUG
-/*
- * BT_DUMP -- Dump the tree
- *
- * Parameters:
- * dbp: pointer to the DB
- */
-void
-__bt_dump(dbp)
- DB *dbp;
-{
- BTREE *t;
- PAGE *h;
- pgno_t i;
- char *sep;
-
- t = dbp->internal;
- (void)fprintf(stderr, "%s: pgsz %d",
- F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize);
- if (F_ISSET(t, R_RECNO))
- (void)fprintf(stderr, " keys %lu", t->bt_nrecs);
-#undef X
-#define X(flag, name) \
- if (F_ISSET(t, flag)) { \
- (void)fprintf(stderr, "%s%s", sep, name); \
- sep = ", "; \
- }
- if (t->flags != 0) {
- sep = " flags (";
- X(R_FIXLEN, "FIXLEN");
- X(B_INMEM, "INMEM");
- X(B_NODUPS, "NODUPS");
- X(B_RDONLY, "RDONLY");
- X(R_RECNO, "RECNO");
- X(B_METADIRTY,"METADIRTY");
- (void)fprintf(stderr, ")\n");
- }
-#undef X
-
- for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
- __bt_dpage(h);
- (void)mpool_put(t->bt_mp, h, 0);
- }
-}
-
-/*
- * BT_DMPAGE -- Dump the meta page
- *
- * Parameters:
- * h: pointer to the PAGE
- */
-void
-__bt_dmpage(h)
- PAGE *h;
-{
- BTMETA *m;
- char *sep;
-
- m = (BTMETA *)h;
- (void)fprintf(stderr, "magic %lx\n", m->magic);
- (void)fprintf(stderr, "version %lu\n", m->version);
- (void)fprintf(stderr, "psize %lu\n", m->psize);
- (void)fprintf(stderr, "free %lu\n", m->free);
- (void)fprintf(stderr, "nrecs %lu\n", m->nrecs);
- (void)fprintf(stderr, "flags %lu", m->flags);
-#undef X
-#define X(flag, name) \
- if (m->flags & flag) { \
- (void)fprintf(stderr, "%s%s", sep, name); \
- sep = ", "; \
- }
- if (m->flags) {
- sep = " (";
- X(B_NODUPS, "NODUPS");
- X(R_RECNO, "RECNO");
- (void)fprintf(stderr, ")");
- }
-}
-
-/*
- * BT_DNPAGE -- Dump the page
- *
- * Parameters:
- * n: page number to dump.
- */
-void
-__bt_dnpage(dbp, pgno)
- DB *dbp;
- pgno_t pgno;
-{
- BTREE *t;
- PAGE *h;
-
- t = dbp->internal;
- if ((h = mpool_get(t->bt_mp, pgno, 0)) != NULL) {
- __bt_dpage(h);
- (void)mpool_put(t->bt_mp, h, 0);
- }
-}
-
-/*
- * BT_DPAGE -- Dump the page
- *
- * Parameters:
- * h: pointer to the PAGE
- */
-void
-__bt_dpage(h)
- PAGE *h;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- RINTERNAL *ri;
- RLEAF *rl;
- indx_t cur, top;
- char *sep;
-
- (void)fprintf(stderr, " page %d: (", h->pgno);
-#undef X
-#define X(flag, name) \
- if (h->flags & flag) { \
- (void)fprintf(stderr, "%s%s", sep, name); \
- sep = ", "; \
- }
- sep = "";
- X(P_BINTERNAL, "BINTERNAL") /* types */
- X(P_BLEAF, "BLEAF")
- X(P_RINTERNAL, "RINTERNAL") /* types */
- X(P_RLEAF, "RLEAF")
- X(P_OVERFLOW, "OVERFLOW")
- X(P_PRESERVE, "PRESERVE");
- (void)fprintf(stderr, ")\n");
-#undef X
-
- (void)fprintf(stderr, "\tprev %2d next %2d", h->prevpg, h->nextpg);
- if (h->flags & P_OVERFLOW)
- return;
-
- top = NEXTINDEX(h);
- (void)fprintf(stderr, " lower %3d upper %3d nextind %d\n",
- h->lower, h->upper, top);
- for (cur = 0; cur < top; cur++) {
- (void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]);
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- bi = GETBINTERNAL(h, cur);
- (void)fprintf(stderr,
- "size %03d pgno %03d", bi->ksize, bi->pgno);
- if (bi->flags & P_BIGKEY)
- (void)fprintf(stderr, " (indirect)");
- else if (bi->ksize)
- (void)fprintf(stderr,
- " {%.*s}", (int)bi->ksize, bi->bytes);
- break;
- case P_RINTERNAL:
- ri = GETRINTERNAL(h, cur);
- (void)fprintf(stderr, "entries %03d pgno %03d",
- ri->nrecs, ri->pgno);
- break;
- case P_BLEAF:
- bl = GETBLEAF(h, cur);
- if (bl->flags & P_BIGKEY)
- (void)fprintf(stderr,
- "big key page %lu size %u/",
- *(pgno_t *)bl->bytes,
- *(u_int32_t *)(bl->bytes + sizeof(pgno_t)));
- else if (bl->ksize)
- (void)fprintf(stderr, "%s/", bl->bytes);
- if (bl->flags & P_BIGDATA)
- (void)fprintf(stderr,
- "big data page %lu size %u",
- *(pgno_t *)(bl->bytes + bl->ksize),
- *(u_int32_t *)(bl->bytes + bl->ksize +
- sizeof(pgno_t)));
- else if (bl->dsize)
- (void)fprintf(stderr, "%.*s",
- (int)bl->dsize, bl->bytes + bl->ksize);
- break;
- case P_RLEAF:
- rl = GETRLEAF(h, cur);
- if (rl->flags & P_BIGDATA)
- (void)fprintf(stderr,
- "big data page %lu size %u",
- *(pgno_t *)rl->bytes,
- *(u_int32_t *)(rl->bytes + sizeof(pgno_t)));
- else if (rl->dsize)
- (void)fprintf(stderr,
- "%.*s", (int)rl->dsize, rl->bytes);
- break;
- }
- (void)fprintf(stderr, "\n");
- }
-}
-#endif
-
-#ifdef STATISTICS
-/*
- * BT_STAT -- Gather/print the tree statistics
- *
- * Parameters:
- * dbp: pointer to the DB
- */
-void
-__bt_stat(dbp)
- DB *dbp;
-{
- extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit;
- extern u_long bt_sortsplit, bt_split;
- BTREE *t;
- PAGE *h;
- pgno_t i, pcont, pinternal, pleaf;
- u_long ifree, lfree, nkeys;
- int levels;
-
- t = dbp->internal;
- pcont = pinternal = pleaf = 0;
- nkeys = ifree = lfree = 0;
- for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- case P_RINTERNAL:
- ++pinternal;
- ifree += h->upper - h->lower;
- break;
- case P_BLEAF:
- case P_RLEAF:
- ++pleaf;
- lfree += h->upper - h->lower;
- nkeys += NEXTINDEX(h);
- break;
- case P_OVERFLOW:
- ++pcont;
- break;
- }
- (void)mpool_put(t->bt_mp, h, 0);
- }
-
- /* Count the levels of the tree. */
- for (i = P_ROOT, levels = 0 ;; ++levels) {
- h = mpool_get(t->bt_mp, i, 0);
- if (h->flags & (P_BLEAF|P_RLEAF)) {
- if (levels == 0)
- levels = 1;
- (void)mpool_put(t->bt_mp, h, 0);
- break;
- }
- i = F_ISSET(t, R_RECNO) ?
- GETRINTERNAL(h, 0)->pgno :
- GETBINTERNAL(h, 0)->pgno;
- (void)mpool_put(t->bt_mp, h, 0);
- }
-
- (void)fprintf(stderr, "%d level%s with %ld keys",
- levels, levels == 1 ? "" : "s", nkeys);
- if (F_ISSET(t, R_RECNO))
- (void)fprintf(stderr, " (%ld header count)", t->bt_nrecs);
- (void)fprintf(stderr,
- "\n%lu pages (leaf %ld, internal %ld, overflow %ld)\n",
- pinternal + pleaf + pcont, pleaf, pinternal, pcont);
- (void)fprintf(stderr, "%ld cache hits, %ld cache misses\n",
- bt_cache_hit, bt_cache_miss);
- (void)fprintf(stderr, "%ld splits (%ld root splits, %ld sort splits)\n",
- bt_split, bt_rootsplit, bt_sortsplit);
- pleaf *= t->bt_psize - BTDATAOFF;
- if (pleaf)
- (void)fprintf(stderr,
- "%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n",
- ((double)(pleaf - lfree) / pleaf) * 100,
- pleaf - lfree, lfree);
- pinternal *= t->bt_psize - BTDATAOFF;
- if (pinternal)
- (void)fprintf(stderr,
- "%.0f%% internal fill (%ld bytes used, %ld bytes free\n",
- ((double)(pinternal - ifree) / pinternal) * 100,
- pinternal - ifree, ifree);
- if (bt_pfxsaved)
- (void)fprintf(stderr, "prefix checking removed %lu bytes.\n",
- bt_pfxsaved);
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_delete.c 8.13 (Berkeley) 7/28/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-static int __bt_bdelete(BTREE *, const DBT *);
-static int __bt_curdel(BTREE *, const DBT *, PAGE *, u_int);
-static int __bt_pdelete(BTREE *, PAGE *);
-static int __bt_relink(BTREE *, PAGE *);
-static int __bt_stkacq(BTREE *, PAGE **, CURSOR *);
-
-/*
- * __bt_delete
- * Delete the item(s) referenced by a key.
- *
- * Return RET_SPECIAL if the key is not found.
- */
-int
-__bt_delete(dbp, key, flags)
- const DB *dbp;
- const DBT *key;
- u_int flags;
-{
- BTREE *t;
- CURSOR *c;
- PAGE *h;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Check for change to a read-only tree. */
- if (F_ISSET(t, B_RDONLY)) {
- errno = EPERM;
- return (RET_ERROR);
- }
-
- switch (flags) {
- case 0:
- status = __bt_bdelete(t, key);
- break;
- case R_CURSOR:
- /*
- * If flags is R_CURSOR, delete the cursor. Must already
- * have started a scan and not have already deleted it.
- */
- c = &t->bt_cursor;
- if (F_ISSET(c, CURS_INIT)) {
- if (F_ISSET(c, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
- return (RET_ERROR);
-
- /*
- * If the page is about to be emptied, we'll need to
- * delete it, which means we have to acquire a stack.
- */
- if (NEXTINDEX(h) == 1)
- if (__bt_stkacq(t, &h, &t->bt_cursor))
- return (RET_ERROR);
-
- status = __bt_dleaf(t, NULL, h, c->pg.index);
-
- if (NEXTINDEX(h) == 0 && status == RET_SUCCESS) {
- if (__bt_pdelete(t, h))
- return (RET_ERROR);
- } else
- mpool_put(t->bt_mp,
- h, status == RET_SUCCESS ? MPOOL_DIRTY : 0);
- break;
- }
- /* FALLTHROUGH */
- default:
- errno = EINVAL;
- return (RET_ERROR);
- }
- if (status == RET_SUCCESS)
- F_SET(t, B_MODIFIED);
- return (status);
-}
-
-/*
- * __bt_stkacq --
- * Acquire a stack so we can delete a cursor entry.
- *
- * Parameters:
- * t: tree
- * hp: pointer to current, pinned PAGE pointer
- * c: pointer to the cursor
- *
- * Returns:
- * 0 on success, 1 on failure
- */
-static int
-__bt_stkacq(t, hp, c)
- BTREE *t;
- PAGE **hp;
- CURSOR *c;
-{
- BINTERNAL *bi;
- EPG *e;
- EPGNO *parent;
- PAGE *h;
- indx_t index;
- pgno_t pgno;
- recno_t nextpg, prevpg;
- int exact, level;
-
- /*
- * Find the first occurrence of the key in the tree. Toss the
- * currently locked page so we don't hit an already-locked page.
- */
- h = *hp;
- mpool_put(t->bt_mp, h, 0);
- if ((e = __bt_search(t, &c->key, &exact)) == NULL)
- return (1);
- h = e->page;
-
- /* See if we got it in one shot. */
- if (h->pgno == c->pg.pgno)
- goto ret;
-
- /*
- * Move right, looking for the page. At each move we have to move
- * up the stack until we don't have to move to the next page. If
- * we have to change pages at an internal level, we have to fix the
- * stack back up.
- */
- while (h->pgno != c->pg.pgno) {
- if ((nextpg = h->nextpg) == P_INVALID)
- break;
- mpool_put(t->bt_mp, h, 0);
-
- /* Move up the stack. */
- for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
- /* Get the parent page. */
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- return (1);
-
- /* Move to the next index. */
- if (parent->index != NEXTINDEX(h) - 1) {
- index = parent->index + 1;
- BT_PUSH(t, h->pgno, index);
- break;
- }
- mpool_put(t->bt_mp, h, 0);
- }
-
- /* Restore the stack. */
- while (level--) {
- /* Push the next level down onto the stack. */
- bi = GETBINTERNAL(h, index);
- pgno = bi->pgno;
- BT_PUSH(t, pgno, 0);
-
- /* Lose the currently pinned page. */
- mpool_put(t->bt_mp, h, 0);
-
- /* Get the next level down. */
- if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
- return (1);
- index = 0;
- }
- mpool_put(t->bt_mp, h, 0);
- if ((h = mpool_get(t->bt_mp, nextpg, 0)) == NULL)
- return (1);
- }
-
- if (h->pgno == c->pg.pgno)
- goto ret;
-
- /* Reacquire the original stack. */
- mpool_put(t->bt_mp, h, 0);
- if ((e = __bt_search(t, &c->key, &exact)) == NULL)
- return (1);
- h = e->page;
-
- /*
- * Move left, looking for the page. At each move we have to move
- * up the stack until we don't have to change pages to move to the
- * next page. If we have to change pages at an internal level, we
- * have to fix the stack back up.
- */
- while (h->pgno != c->pg.pgno) {
- if ((prevpg = h->prevpg) == P_INVALID)
- break;
- mpool_put(t->bt_mp, h, 0);
-
- /* Move up the stack. */
- for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
- /* Get the parent page. */
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- return (1);
-
- /* Move to the next index. */
- if (parent->index != 0) {
- index = parent->index - 1;
- BT_PUSH(t, h->pgno, index);
- break;
- }
- mpool_put(t->bt_mp, h, 0);
- }
-
- /* Restore the stack. */
- while (level--) {
- /* Push the next level down onto the stack. */
- bi = GETBINTERNAL(h, index);
- pgno = bi->pgno;
-
- /* Lose the currently pinned page. */
- mpool_put(t->bt_mp, h, 0);
-
- /* Get the next level down. */
- if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
- return (1);
-
- index = NEXTINDEX(h) - 1;
- BT_PUSH(t, pgno, index);
- }
- mpool_put(t->bt_mp, h, 0);
- if ((h = mpool_get(t->bt_mp, prevpg, 0)) == NULL)
- return (1);
- }
-
-
-ret: mpool_put(t->bt_mp, h, 0);
- return ((*hp = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL);
-}
-
-/*
- * __bt_bdelete --
- * Delete all key/data pairs matching the specified key.
- *
- * Parameters:
- * t: tree
- * key: key to delete
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-static int
-__bt_bdelete(t, key)
- BTREE *t;
- const DBT *key;
-{
- EPG *e;
- PAGE *h;
- int deleted, exact, redo;
-
- deleted = 0;
-
- /* Find any matching record; __bt_search pins the page. */
-loop: if ((e = __bt_search(t, key, &exact)) == NULL)
- return (deleted ? RET_SUCCESS : RET_ERROR);
- if (!exact) {
- mpool_put(t->bt_mp, e->page, 0);
- return (deleted ? RET_SUCCESS : RET_SPECIAL);
- }
-
- /*
- * Delete forward, then delete backward, from the found key. If
- * there are duplicates and we reach either side of the page, do
- * the key search again, so that we get them all.
- */
- redo = 0;
- h = e->page;
- do {
- if (__bt_dleaf(t, key, h, e->index)) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- if (F_ISSET(t, B_NODUPS)) {
- if (NEXTINDEX(h) == 0) {
- if (__bt_pdelete(t, h))
- return (RET_ERROR);
- } else
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
- }
- deleted = 1;
- } while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0);
-
- /* Check for right-hand edge of the page. */
- if (e->index == NEXTINDEX(h))
- redo = 1;
-
- /* Delete from the key to the beginning of the page. */
- while (e->index-- > 0) {
- if (__bt_cmp(t, key, e) != 0)
- break;
- if (__bt_dleaf(t, key, h, e->index) == RET_ERROR) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- if (e->index == 0)
- redo = 1;
- }
-
- /* Check for an empty page. */
- if (NEXTINDEX(h) == 0) {
- if (__bt_pdelete(t, h))
- return (RET_ERROR);
- goto loop;
- }
-
- /* Put the page. */
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- if (redo)
- goto loop;
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_pdelete --
- * Delete a single page from the tree.
- *
- * Parameters:
- * t: tree
- * h: leaf page
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- *
- * Side-effects:
- * mpool_put's the page
- */
-static int
-__bt_pdelete(t, h)
- BTREE *t;
- PAGE *h;
-{
- BINTERNAL *bi;
- PAGE *pg;
- EPGNO *parent;
- indx_t cnt, index, *ip, offset;
- u_int32_t nksize;
- char *from;
-
- /*
- * Walk the parent page stack -- a LIFO stack of the pages that were
- * traversed when we searched for the page where the delete occurred.
- * Each stack entry is a page number and a page index offset. The
- * offset is for the page traversed on the search. We've just deleted
- * a page, so we have to delete the key from the parent page.
- *
- * If the delete from the parent page makes it empty, this process may
- * continue all the way up the tree. We stop if we reach the root page
- * (which is never deleted, it's just not worth the effort) or if the
- * delete does not empty the page.
- */
- while ((parent = BT_POP(t)) != NULL) {
- /* Get the parent page. */
- if ((pg = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- return (RET_ERROR);
-
- index = parent->index;
- bi = GETBINTERNAL(pg, index);
-
- /* Free any overflow pages. */
- if (bi->flags & P_BIGKEY &&
- __ovfl_delete(t, bi->bytes) == RET_ERROR) {
- mpool_put(t->bt_mp, pg, 0);
- return (RET_ERROR);
- }
-
- /*
- * Free the parent if it has only the one key and it's not the
- * root page. If it's the rootpage, turn it back into an empty
- * leaf page.
- */
- if (NEXTINDEX(pg) == 1)
- if (pg->pgno == P_ROOT) {
- pg->lower = BTDATAOFF;
- pg->upper = t->bt_psize;
- pg->flags = P_BLEAF;
- } else {
- if (__bt_relink(t, pg) || __bt_free(t, pg))
- return (RET_ERROR);
- continue;
- }
- else {
- /* Pack remaining key items at the end of the page. */
- nksize = NBINTERNAL(bi->ksize);
- from = (char *)pg + pg->upper;
- memmove(from + nksize, from, (char *)bi - from);
- pg->upper += nksize;
-
- /* Adjust indices' offsets, shift the indices down. */
- offset = pg->linp[index];
- for (cnt = index, ip = &pg->linp[0]; cnt--; ++ip)
- if (ip[0] < offset)
- ip[0] += nksize;
- for (cnt = NEXTINDEX(pg) - index; --cnt; ++ip)
- ip[0] = ip[1] < offset ? ip[1] + nksize : ip[1];
- pg->lower -= sizeof(indx_t);
- }
-
- mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
- break;
- }
-
- /* Free the leaf page, as long as it wasn't the root. */
- if (h->pgno == P_ROOT) {
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
- }
- return (__bt_relink(t, h) || __bt_free(t, h));
-}
-
-/*
- * __bt_dleaf --
- * Delete a single record from a leaf page.
- *
- * Parameters:
- * t: tree
- * key: referenced key
- * h: page
- * index: index on page to delete
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__bt_dleaf(t, key, h, index)
- BTREE *t;
- const DBT *key;
- PAGE *h;
- u_int index;
-{
- BLEAF *bl;
- indx_t cnt, *ip, offset;
- u_int32_t nbytes;
- void *to;
- char *from;
-
- /* If this record is referenced by the cursor, delete the cursor. */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
- t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index == index &&
- __bt_curdel(t, key, h, index))
- return (RET_ERROR);
-
- /* If the entry uses overflow pages, make them available for reuse. */
- to = bl = GETBLEAF(h, index);
- if (bl->flags & P_BIGKEY && __ovfl_delete(t, bl->bytes) == RET_ERROR)
- return (RET_ERROR);
- if (bl->flags & P_BIGDATA &&
- __ovfl_delete(t, bl->bytes + bl->ksize) == RET_ERROR)
- return (RET_ERROR);
-
- /* Pack the remaining key/data items at the end of the page. */
- nbytes = NBLEAF(bl);
- from = (char *)h + h->upper;
- memmove(from + nbytes, from, (char *)to - from);
- h->upper += nbytes;
-
- /* Adjust the indices' offsets, shift the indices down. */
- offset = h->linp[index];
- for (cnt = index, ip = &h->linp[0]; cnt--; ++ip)
- if (ip[0] < offset)
- ip[0] += nbytes;
- for (cnt = NEXTINDEX(h) - index; --cnt; ++ip)
- ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
- h->lower -= sizeof(indx_t);
-
- /* If the cursor is on this page, adjust it as necessary. */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
- t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index > index)
- --t->bt_cursor.pg.index;
-
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_curdel --
- * Delete the cursor.
- *
- * Parameters:
- * t: tree
- * key: referenced key (or NULL)
- * h: page
- * index: index on page to delete
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-static int
-__bt_curdel(t, key, h, index)
- BTREE *t;
- const DBT *key;
- PAGE *h;
- u_int index;
-{
- CURSOR *c;
- EPG e;
- PAGE *pg;
- int curcopy, status;
-
- /*
- * If there are duplicates, move forward or backward to one.
- * Otherwise, copy the key into the cursor area.
- */
- c = &t->bt_cursor;
- F_CLR(c, CURS_AFTER | CURS_BEFORE | CURS_ACQUIRE);
-
- curcopy = 0;
- if (!F_ISSET(t, B_NODUPS)) {
- /*
- * We're going to have to do comparisons. If we weren't
- * provided a copy of the key, i.e. the user is deleting
- * the current cursor position, get one.
- */
- if (key == NULL) {
- e.page = h;
- e.index = index;
- if ((status = __bt_ret(t, &e,
- &c->key, &c->key, NULL, NULL, 1)) != RET_SUCCESS)
- return (status);
- curcopy = 1;
- key = &c->key;
- }
- /* Check previous key, if not at the beginning of the page. */
- if (index > 0) {
- e.page = h;
- e.index = index - 1;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_BEFORE);
- goto dup2;
- }
- }
- /* Check next key, if not at the end of the page. */
- if (index < NEXTINDEX(h) - 1) {
- e.page = h;
- e.index = index + 1;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_AFTER);
- goto dup2;
- }
- }
- /* Check previous key if at the beginning of the page. */
- if (index == 0 && h->prevpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
- return (RET_ERROR);
- e.page = pg;
- e.index = NEXTINDEX(pg) - 1;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_BEFORE);
- goto dup1;
- }
- mpool_put(t->bt_mp, pg, 0);
- }
- /* Check next key if at the end of the page. */
- if (index == NEXTINDEX(h) - 1 && h->nextpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
- return (RET_ERROR);
- e.page = pg;
- e.index = 0;
- if (__bt_cmp(t, key, &e) == 0) {
- F_SET(c, CURS_AFTER);
-dup1: mpool_put(t->bt_mp, pg, 0);
-dup2: c->pg.pgno = e.page->pgno;
- c->pg.index = e.index;
- return (RET_SUCCESS);
- }
- mpool_put(t->bt_mp, pg, 0);
- }
- }
- e.page = h;
- e.index = index;
- if (curcopy || (status =
- __bt_ret(t, &e, &c->key, &c->key, NULL, NULL, 1)) == RET_SUCCESS) {
- F_SET(c, CURS_ACQUIRE);
- return (RET_SUCCESS);
- }
- return (status);
-}
-
-/*
- * __bt_relink --
- * Link around a deleted page.
- *
- * Parameters:
- * t: tree
- * h: page to be deleted
- */
-static int
-__bt_relink(t, h)
- BTREE *t;
- PAGE *h;
-{
- PAGE *pg;
-
- if (h->nextpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
- return (RET_ERROR);
- pg->prevpg = h->prevpg;
- mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
- }
- if (h->prevpg != P_INVALID) {
- if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
- return (RET_ERROR);
- pg->nextpg = h->nextpg;
- mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
- }
- return (0);
-}
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-int __bt_close __P((DB *));
-int __bt_cmp __P((BTREE *, const DBT *, EPG *));
-int __bt_crsrdel __P((BTREE *, EPGNO *));
-int __bt_defcmp __P((const DBT *, const DBT *));
-size_t __bt_defpfx __P((const DBT *, const DBT *));
-int __bt_delete __P((const DB *, const DBT *, u_int));
-int __bt_dleaf __P((BTREE *, PAGE *, int));
-int __bt_fd __P((const DB *));
-EPG *__bt_first __P((BTREE *, const DBT *, int *));
-int __bt_free __P((BTREE *, PAGE *));
-int __bt_get __P((const DB *, const DBT *, DBT *, u_int));
-PAGE *__bt_new __P((BTREE *, pgno_t *));
-void __bt_pgin __P((void *, pgno_t, void *));
-void __bt_pgout __P((void *, pgno_t, void *));
-int __bt_push __P((BTREE *, pgno_t, int));
-int __bt_put __P((const DB *dbp, DBT *, const DBT *, u_int));
-int __bt_ret __P((BTREE *, EPG *, DBT *, DBT *));
-EPG *__bt_search __P((BTREE *, const DBT *, int *));
-int __bt_seq __P((const DB *, DBT *, DBT *, u_int));
-int __bt_split __P((BTREE *, PAGE *,
- const DBT *, const DBT *, int, size_t, indx_t));
-int __bt_sync __P((const DB *, u_int));
-
-int __ovfl_delete __P((BTREE *, void *));
-int __ovfl_get __P((BTREE *, void *, size_t *, char **, size_t *));
-int __ovfl_put __P((BTREE *, const DBT *, pgno_t *));
-
-#ifdef DEBUG
-void __bt_dnpage __P((DB *, pgno_t));
-void __bt_dpage __P((PAGE *));
-void __bt_dump __P((DB *));
-#endif
-#ifdef STATISTICS
-void __bt_stat __P((DB *));
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_get.c 8.6 (Berkeley) 7/20/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-
-#include <db.h>
-#include "btree.h"
-
-/*
- * __BT_GET -- Get a record from the btree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key to find
- * data: data to return
- * flag: currently unused
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-int
-__bt_get(dbp, key, data, flags)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int flags;
-{
- BTREE *t;
- EPG *e;
- int exact, status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Get currently doesn't take any flags. */
- if (flags) {
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- if ((e = __bt_search(t, key, &exact)) == NULL)
- return (RET_ERROR);
- if (!exact) {
- mpool_put(t->bt_mp, e->page, 0);
- return (RET_SPECIAL);
- }
-
- status = __bt_ret(t, e, NULL, NULL, data, &t->bt_rdata, 0);
-
- /*
- * If the user is doing concurrent access, we copied the
- * key/data, toss the page.
- */
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e->page, 0);
- else
- t->bt_pinned = e->page;
- return (status);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_open.c 8.10 (Berkeley) 8/17/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-/*
- * Implementation of btree access method for 4.4BSD.
- *
- * The design here was originally based on that of the btree access method
- * used in the Postgres database system at UC Berkeley. This implementation
- * is wholly independent of the Postgres code.
- */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <db.h>
-#include "btree.h"
-
-#ifdef DEBUG
-#undef MINPSIZE
-#define MINPSIZE 128
-#endif
-
-static int byteorder(void);
-static int nroot(BTREE *);
-static int tmp(void);
-
-/*
- * __BT_OPEN -- Open a btree.
- *
- * Creates and fills a DB struct, and calls the routine that actually
- * opens the btree.
- *
- * Parameters:
- * fname: filename (NULL for in-memory trees)
- * flags: open flag bits
- * mode: open permission bits
- * b: BTREEINFO pointer
- *
- * Returns:
- * NULL on failure, pointer to DB on success.
- *
- */
-DB *
-__bt_open(fname, flags, mode, openinfo, dflags)
- const char *fname;
- int flags, mode, dflags;
- const BTREEINFO *openinfo;
-{
- struct stat sb;
- BTMETA m;
- BTREE *t;
- BTREEINFO b;
- DB *dbp;
- pgno_t ncache;
- ssize_t nr;
- int machine_lorder;
-
- t = NULL;
-
- /*
- * Intention is to make sure all of the user's selections are okay
- * here and then use them without checking. Can't be complete, since
- * we don't know the right page size, lorder or flags until the backing
- * file is opened. Also, the file's page size can cause the cachesize
- * to change.
- */
- machine_lorder = byteorder();
- if (openinfo) {
- b = *openinfo;
-
- /* Flags: R_DUP. */
- if (b.flags & ~(R_DUP))
- goto einval;
-
- /*
- * Page size must be indx_t aligned and >= MINPSIZE. Default
- * page size is set farther on, based on the underlying file
- * transfer size.
- */
- if (b.psize &&
- (b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 ||
- b.psize & (sizeof(indx_t) - 1) ))
- goto einval;
-
- /* Minimum number of keys per page; absolute minimum is 2. */
- if (b.minkeypage) {
- if (b.minkeypage < 2)
- goto einval;
- } else
- b.minkeypage = DEFMINKEYPAGE;
-
- /* If no comparison, use default comparison and prefix. */
- if (b.compare == NULL) {
- b.compare = __bt_defcmp;
- if (b.prefix == NULL)
- b.prefix = __bt_defpfx;
- }
-
- if (b.lorder == 0)
- b.lorder = machine_lorder;
- } else {
- b.compare = __bt_defcmp;
- b.cachesize = 0;
- b.flags = 0;
- b.lorder = machine_lorder;
- b.minkeypage = DEFMINKEYPAGE;
- b.prefix = __bt_defpfx;
- b.psize = 0;
- }
-
- /* Check for the ubiquitous PDP-11. */
- if (b.lorder != BIG_ENDIAN && b.lorder != LITTLE_ENDIAN)
- goto einval;
-
- /* Allocate and initialize DB and BTREE structures. */
- if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL)
- goto err;
- memset(t, 0, sizeof(BTREE));
- t->bt_fd = -1; /* Don't close unopened fd on error. */
- t->bt_lorder = b.lorder;
- t->bt_order = NOT;
- t->bt_cmp = b.compare;
- t->bt_pfx = b.prefix;
- t->bt_rfd = -1;
-
- if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL)
- goto err;
- memset(t->bt_dbp, 0, sizeof(DB));
- if (t->bt_lorder != machine_lorder)
- F_SET(t, B_NEEDSWAP);
-
- dbp->type = DB_BTREE;
- dbp->internal = t;
- dbp->close = __bt_close;
- dbp->del = __bt_delete;
- dbp->fd = __bt_fd;
- dbp->get = __bt_get;
- dbp->put = __bt_put;
- dbp->seq = __bt_seq;
- dbp->sync = __bt_sync;
-
- /*
- * If no file name was supplied, this is an in-memory btree and we
- * open a backing temporary file. Otherwise, it's a disk-based tree.
- */
- if (fname) {
- switch (flags & O_ACCMODE) {
- case O_RDONLY:
- F_SET(t, B_RDONLY);
- break;
- case O_RDWR:
- break;
- case O_WRONLY:
- default:
- goto einval;
- }
-
- if ((t->bt_fd = open(fname, flags, mode)) < 0)
- goto err;
-
- } else {
- if ((flags & O_ACCMODE) != O_RDWR)
- goto einval;
- if ((t->bt_fd = tmp()) == -1)
- goto err;
- F_SET(t, B_INMEM);
- }
-
- if (fcntl(t->bt_fd, F_SETFD, 1) == -1)
- goto err;
-
- if (fstat(t->bt_fd, &sb))
- goto err;
- if (sb.st_size) {
- if ((nr = read(t->bt_fd, &m, sizeof(BTMETA))) < 0)
- goto err;
- if (nr != sizeof(BTMETA))
- goto eftype;
-
- /*
- * Read in the meta-data. This can change the notion of what
- * the lorder, page size and flags are, and, when the page size
- * changes, the cachesize value can change too. If the user
- * specified the wrong byte order for an existing database, we
- * don't bother to return an error, we just clear the NEEDSWAP
- * bit.
- */
- if (m.magic == BTREEMAGIC)
- F_CLR(t, B_NEEDSWAP);
- else {
- F_SET(t, B_NEEDSWAP);
- M_32_SWAP(m.magic);
- M_32_SWAP(m.version);
- M_32_SWAP(m.psize);
- M_32_SWAP(m.free);
- M_32_SWAP(m.nrecs);
- M_32_SWAP(m.flags);
- }
- if (m.magic != BTREEMAGIC || m.version != BTREEVERSION)
- goto eftype;
- if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 ||
- m.psize & (sizeof(indx_t) - 1) )
- goto eftype;
- if (m.flags & ~SAVEMETA)
- goto eftype;
- b.psize = m.psize;
- F_SET(t, m.flags);
- t->bt_free = m.free;
- t->bt_nrecs = m.nrecs;
- } else {
- /*
- * Set the page size to the best value for I/O to this file.
- * Don't overflow the page offset type.
- */
- if (b.psize == 0) {
- b.psize = sb.st_blksize;
- if (b.psize < MINPSIZE)
- b.psize = MINPSIZE;
- if (b.psize > MAX_PAGE_OFFSET + 1)
- b.psize = MAX_PAGE_OFFSET + 1;
- }
-
- /* Set flag if duplicates permitted. */
- if (!(b.flags & R_DUP))
- F_SET(t, B_NODUPS);
-
- t->bt_free = P_INVALID;
- t->bt_nrecs = 0;
- F_SET(t, B_METADIRTY);
- }
-
- t->bt_psize = b.psize;
-
- /* Set the cache size; must be a multiple of the page size. */
- if (b.cachesize && b.cachesize & (b.psize - 1) )
- b.cachesize += (~b.cachesize & (b.psize - 1) ) + 1;
- if (b.cachesize < b.psize * MINCACHE)
- b.cachesize = b.psize * MINCACHE;
-
- /* Calculate number of pages to cache. */
- ncache = (b.cachesize + t->bt_psize - 1) / t->bt_psize;
-
- /*
- * The btree data structure requires that at least two keys can fit on
- * a page, but other than that there's no fixed requirement. The user
- * specified a minimum number per page, and we translated that into the
- * number of bytes a key/data pair can use before being placed on an
- * overflow page. This calculation includes the page header, the size
- * of the index referencing the leaf item and the size of the leaf item
- * structure. Also, don't let the user specify a minkeypage such that
- * a key/data pair won't fit even if both key and data are on overflow
- * pages.
- */
- t->bt_ovflsize = (t->bt_psize - BTDATAOFF) / b.minkeypage -
- (sizeof(indx_t) + NBLEAFDBT(0, 0));
- if (t->bt_ovflsize < NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t))
- t->bt_ovflsize =
- NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t);
-
- /* Initialize the buffer pool. */
- if ((t->bt_mp =
- mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL)
- goto err;
- if (!F_ISSET(t, B_INMEM))
- mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t);
-
- /* Create a root page if new tree. */
- if (nroot(t) == RET_ERROR)
- goto err;
-
- /* Global flags. */
- if (dflags & DB_LOCK)
- F_SET(t, B_DB_LOCK);
- if (dflags & DB_SHMEM)
- F_SET(t, B_DB_SHMEM);
- if (dflags & DB_TXN)
- F_SET(t, B_DB_TXN);
-
- return (dbp);
-
-einval: errno = EINVAL;
- goto err;
-
-eftype: errno = EFTYPE;
- goto err;
-
-err: if (t) {
- if (t->bt_dbp)
- free(t->bt_dbp);
- if (t->bt_fd != -1)
- (void)close(t->bt_fd);
- free(t);
- }
- return (NULL);
-}
-
-/*
- * NROOT -- Create the root of a new tree.
- *
- * Parameters:
- * t: tree
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-nroot(t)
- BTREE *t;
-{
- PAGE *meta, *root;
- pgno_t npg;
-
- if ((meta = mpool_get(t->bt_mp, 0, 0)) != NULL) {
- mpool_put(t->bt_mp, meta, 0);
- return (RET_SUCCESS);
- }
- if (errno != EINVAL) /* It's OK to not exist. */
- return (RET_ERROR);
- errno = 0;
-
- if ((meta = mpool_new(t->bt_mp, &npg)) == NULL)
- return (RET_ERROR);
-
- if ((root = mpool_new(t->bt_mp, &npg)) == NULL)
- return (RET_ERROR);
-
- if (npg != P_ROOT)
- return (RET_ERROR);
- root->pgno = npg;
- root->prevpg = root->nextpg = P_INVALID;
- root->lower = BTDATAOFF;
- root->upper = t->bt_psize;
- root->flags = P_BLEAF;
- memset(meta, 0, t->bt_psize);
- mpool_put(t->bt_mp, meta, MPOOL_DIRTY);
- mpool_put(t->bt_mp, root, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
-
-static int
-tmp()
-{
- sigset_t set, oset;
- int fd;
- char *envtmp = NULL;
- char path[MAXPATHLEN];
-
- if (issetugid() == 0)
- envtmp = getenv("TMPDIR");
- (void)snprintf(path,
- sizeof(path), "%s/bt.XXXXXXXXXX", envtmp ? envtmp : "/tmp");
-
- (void)sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
- if ((fd = mkstemp(path)) != -1)
- (void)unlink(path);
- (void)sigprocmask(SIG_SETMASK, &oset, NULL);
- return(fd);
-}
-
-static int
-byteorder()
-{
- u_int32_t x;
- u_char *p;
-
- x = 0x01020304;
- p = (u_char *)&x;
- switch (*p) {
- case 1:
- return (BIG_ENDIAN);
- case 4:
- return (LITTLE_ENDIAN);
- default:
- return (0);
- }
-}
-
-int
-__bt_fd(dbp)
- const DB *dbp;
-{
- BTREE *t;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* In-memory database can't have a file descriptor. */
- if (F_ISSET(t, B_INMEM)) {
- errno = ENOENT;
- return (-1);
- }
- return (t->bt_fd);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_overflow.c 8.5 (Berkeley) 7/16/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-/*
- * Big key/data code.
- *
- * Big key and data entries are stored on linked lists of pages. The initial
- * reference is byte string stored with the key or data and is the page number
- * and size. The actual record is stored in a chain of pages linked by the
- * nextpg field of the PAGE header.
- *
- * The first page of the chain has a special property. If the record is used
- * by an internal page, it cannot be deleted and the P_PRESERVE bit will be set
- * in the header.
- *
- * XXX
- * A single DBT is written to each chain, so a lot of space on the last page
- * is wasted. This is a fairly major bug for some data sets.
- */
-
-/*
- * __OVFL_GET -- Get an overflow key/data item.
- *
- * Parameters:
- * t: tree
- * p: pointer to { pgno_t, u_int32_t }
- * buf: storage address
- * bufsz: storage size
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__ovfl_get(t, p, ssz, buf, bufsz)
- BTREE *t;
- void *p;
- size_t *ssz;
- void **buf;
- size_t *bufsz;
-{
- PAGE *h;
- pgno_t pg;
- size_t nb, plen;
- u_int32_t sz;
-
- memmove(&pg, p, sizeof(pgno_t));
- memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
- *ssz = sz;
-
-#ifdef DEBUG
- if (pg == P_INVALID || sz == 0)
- abort();
-#endif
- /* Make the buffer bigger as necessary. */
- if (*bufsz < sz) {
- *buf = (char *)(*buf == NULL ? malloc(sz) : reallocf(*buf, sz));
- if (*buf == NULL)
- return (RET_ERROR);
- *bufsz = sz;
- }
-
- /*
- * Step through the linked list of pages, copying the data on each one
- * into the buffer. Never copy more than the data's length.
- */
- plen = t->bt_psize - BTDATAOFF;
- for (p = *buf;; p = (char *)p + nb, pg = h->nextpg) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- nb = MIN(sz, plen);
- memmove(p, (char *)h + BTDATAOFF, nb);
- mpool_put(t->bt_mp, h, 0);
-
- if ((sz -= nb) == 0)
- break;
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __OVFL_PUT -- Store an overflow key/data item.
- *
- * Parameters:
- * t: tree
- * data: DBT to store
- * pgno: storage page number
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__ovfl_put(t, dbt, pg)
- BTREE *t;
- const DBT *dbt;
- pgno_t *pg;
-{
- PAGE *h, *last;
- void *p;
- pgno_t npg;
- size_t nb, plen;
- u_int32_t sz;
-
- /*
- * Allocate pages and copy the key/data record into them. Store the
- * number of the first page in the chain.
- */
- plen = t->bt_psize - BTDATAOFF;
- for (last = NULL, p = dbt->data, sz = dbt->size;;
- p = (char *)p + plen, last = h) {
- if ((h = __bt_new(t, &npg)) == NULL)
- return (RET_ERROR);
-
- h->pgno = npg;
- h->nextpg = h->prevpg = P_INVALID;
- h->flags = P_OVERFLOW;
- h->lower = h->upper = 0;
-
- nb = MIN(sz, plen);
- memmove((char *)h + BTDATAOFF, p, nb);
-
- if (last) {
- last->nextpg = h->pgno;
- mpool_put(t->bt_mp, last, MPOOL_DIRTY);
- } else
- *pg = h->pgno;
-
- if ((sz -= nb) == 0) {
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- }
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __OVFL_DELETE -- Delete an overflow chain.
- *
- * Parameters:
- * t: tree
- * p: pointer to { pgno_t, u_int32_t }
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__ovfl_delete(t, p)
- BTREE *t;
- void *p;
-{
- PAGE *h;
- pgno_t pg;
- size_t plen;
- u_int32_t sz;
-
- memmove(&pg, p, sizeof(pgno_t));
- memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
-
-#ifdef DEBUG
- if (pg == P_INVALID || sz == 0)
- abort();
-#endif
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- /* Don't delete chains used by internal pages. */
- if (h->flags & P_PRESERVE) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_SUCCESS);
- }
-
- /* Step through the chain, calling the free routine for each page. */
- for (plen = t->bt_psize - BTDATAOFF;; sz -= plen) {
- pg = h->nextpg;
- __bt_free(t, h);
- if (sz <= plen)
- break;
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- }
- return (RET_SUCCESS);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_page.c 8.3 (Berkeley) 7/14/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <stdio.h>
-
-#include <db.h>
-#include "btree.h"
-
-/*
- * __bt_free --
- * Put a page on the freelist.
- *
- * Parameters:
- * t: tree
- * h: page to free
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- *
- * Side-effect:
- * mpool_put's the page.
- */
-int
-__bt_free(t, h)
- BTREE *t;
- PAGE *h;
-{
- /* Insert the page at the head of the free list. */
- h->prevpg = P_INVALID;
- h->nextpg = t->bt_free;
- t->bt_free = h->pgno;
- F_SET(t, B_METADIRTY);
-
- /* Make sure the page gets written back. */
- return (mpool_put(t->bt_mp, h, MPOOL_DIRTY));
-}
-
-/*
- * __bt_new --
- * Get a new page, preferably from the freelist.
- *
- * Parameters:
- * t: tree
- * npg: storage for page number.
- *
- * Returns:
- * Pointer to a page, NULL on error.
- */
-PAGE *
-__bt_new(t, npg)
- BTREE *t;
- pgno_t *npg;
-{
- PAGE *h;
-
- if (t->bt_free != P_INVALID &&
- (h = mpool_get(t->bt_mp, t->bt_free, 0)) != NULL) {
- *npg = t->bt_free;
- t->bt_free = h->nextpg;
- F_SET(t, B_METADIRTY);
- return (h);
- }
- return (mpool_new(t->bt_mp, npg));
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_put.c 8.8 (Berkeley) 7/26/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-static EPG *bt_fast(BTREE *, const DBT *, const DBT *, int *);
-
-/*
- * __BT_PUT -- Add a btree item to the tree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key
- * data: data
- * flag: R_NOOVERWRITE
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is already in the
- * tree and R_NOOVERWRITE specified.
- */
-int
-__bt_put(dbp, key, data, flags)
- const DB *dbp;
- DBT *key;
- const DBT *data;
- u_int flags;
-{
- BTREE *t;
- DBT tkey, tdata;
- EPG *e;
- PAGE *h;
- indx_t index, nxtindex;
- pgno_t pg;
- u_int32_t nbytes;
- int dflags, exact, status;
- char *dest, db[NOVFLSIZE], kb[NOVFLSIZE];
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Check for change to a read-only tree. */
- if (F_ISSET(t, B_RDONLY)) {
- errno = EPERM;
- return (RET_ERROR);
- }
-
- switch (flags) {
- case 0:
- case R_NOOVERWRITE:
- break;
- case R_CURSOR:
- /*
- * If flags is R_CURSOR, put the cursor. Must already
- * have started a scan and not have already deleted it.
- */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor,
- CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
- break;
- /* FALLTHROUGH */
- default:
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- /*
- * If the key/data pair won't fit on a page, store it on overflow
- * pages. Only put the key on the overflow page if the pair are
- * still too big after moving the data to an overflow page.
- *
- * XXX
- * If the insert fails later on, the overflow pages aren't recovered.
- */
- dflags = 0;
- if (key->size + data->size > t->bt_ovflsize) {
- if (key->size > t->bt_ovflsize) {
-storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR)
- return (RET_ERROR);
- tkey.data = kb;
- tkey.size = NOVFLSIZE;
- memmove(kb, &pg, sizeof(pgno_t));
- memmove(kb + sizeof(pgno_t),
- &key->size, sizeof(u_int32_t));
- dflags |= P_BIGKEY;
- key = &tkey;
- }
- if (key->size + data->size > t->bt_ovflsize) {
- if (__ovfl_put(t, data, &pg) == RET_ERROR)
- return (RET_ERROR);
- tdata.data = db;
- tdata.size = NOVFLSIZE;
- memmove(db, &pg, sizeof(pgno_t));
- memmove(db + sizeof(pgno_t),
- &data->size, sizeof(u_int32_t));
- dflags |= P_BIGDATA;
- data = &tdata;
- }
- if (key->size + data->size > t->bt_ovflsize)
- goto storekey;
- }
-
- /* Replace the cursor. */
- if (flags == R_CURSOR) {
- if ((h = mpool_get(t->bt_mp, t->bt_cursor.pg.pgno, 0)) == NULL)
- return (RET_ERROR);
- index = t->bt_cursor.pg.index;
- goto delete;
- }
-
- /*
- * Find the key to delete, or, the location at which to insert.
- * Bt_fast and __bt_search both pin the returned page.
- */
- if (t->bt_order == NOT || (e = bt_fast(t, key, data, &exact)) == NULL)
- if ((e = __bt_search(t, key, &exact)) == NULL)
- return (RET_ERROR);
- h = e->page;
- index = e->index;
-
- /*
- * Add the key/data pair to the tree. If an identical key is already
- * in the tree, and R_NOOVERWRITE is set, an error is returned. If
- * R_NOOVERWRITE is not set, the key is either added (if duplicates are
- * permitted) or an error is returned.
- */
- switch (flags) {
- case R_NOOVERWRITE:
- if (!exact)
- break;
- mpool_put(t->bt_mp, h, 0);
- return (RET_SPECIAL);
- default:
- if (!exact || !F_ISSET(t, B_NODUPS))
- break;
- /*
- * !!!
- * Note, the delete may empty the page, so we need to put a
- * new entry into the page immediately.
- */
-delete: if (__bt_dleaf(t, key, h, index) == RET_ERROR) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- break;
- }
-
- /*
- * If not enough room, or the user has put a ceiling on the number of
- * keys permitted in the page, split the page. The split code will
- * insert the key and data and unpin the current page. If inserting
- * into the offset array, shift the pointers up.
- */
- nbytes = NBLEAFDBT(key->size, data->size);
- if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
- if ((status = __bt_split(t, h, key,
- data, dflags, nbytes, index)) != RET_SUCCESS)
- return (status);
- goto success;
- }
-
- if (index < (nxtindex = NEXTINDEX(h)))
- memmove(h->linp + index + 1, h->linp + index,
- (nxtindex - index) * sizeof(indx_t));
- h->lower += sizeof(indx_t);
-
- h->linp[index] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- WR_BLEAF(dest, key, data, dflags);
-
- /* If the cursor is on this page, adjust it as necessary. */
- if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
- !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
- t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index >= index)
- ++t->bt_cursor.pg.index;
-
- if (t->bt_order == NOT) {
- if (h->nextpg == P_INVALID) {
- if (index == NEXTINDEX(h) - 1) {
- t->bt_order = FORWARD;
- t->bt_last.index = index;
- t->bt_last.pgno = h->pgno;
- }
- } else if (h->prevpg == P_INVALID) {
- if (index == 0) {
- t->bt_order = BACK;
- t->bt_last.index = 0;
- t->bt_last.pgno = h->pgno;
- }
- }
- }
-
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
-success:
- if (flags == R_SETCURSOR)
- __bt_setcur(t, e->page->pgno, e->index);
-
- F_SET(t, B_MODIFIED);
- return (RET_SUCCESS);
-}
-
-#ifdef STATISTICS
-u_long bt_cache_hit, bt_cache_miss;
-#endif
-
-/*
- * BT_FAST -- Do a quick check for sorted data.
- *
- * Parameters:
- * t: tree
- * key: key to insert
- *
- * Returns:
- * EPG for new record or NULL if not found.
- */
-static EPG *
-bt_fast(t, key, data, exactp)
- BTREE *t;
- const DBT *key, *data;
- int *exactp;
-{
- PAGE *h;
- u_int32_t nbytes;
- int cmp;
-
- if ((h = mpool_get(t->bt_mp, t->bt_last.pgno, 0)) == NULL) {
- t->bt_order = NOT;
- return (NULL);
- }
- t->bt_cur.page = h;
- t->bt_cur.index = t->bt_last.index;
-
- /*
- * If won't fit in this page or have too many keys in this page,
- * have to search to get split stack.
- */
- nbytes = NBLEAFDBT(key->size, data->size);
- if (h->upper - h->lower < nbytes + sizeof(indx_t))
- goto miss;
-
- if (t->bt_order == FORWARD) {
- if (t->bt_cur.page->nextpg != P_INVALID)
- goto miss;
- if (t->bt_cur.index != NEXTINDEX(h) - 1)
- goto miss;
- if ((cmp = __bt_cmp(t, key, &t->bt_cur)) < 0)
- goto miss;
- t->bt_last.index = cmp ? ++t->bt_cur.index : t->bt_cur.index;
- } else {
- if (t->bt_cur.page->prevpg != P_INVALID)
- goto miss;
- if (t->bt_cur.index != 0)
- goto miss;
- if ((cmp = __bt_cmp(t, key, &t->bt_cur)) > 0)
- goto miss;
- t->bt_last.index = 0;
- }
- *exactp = cmp == 0;
-#ifdef STATISTICS
- ++bt_cache_hit;
-#endif
- return (&t->bt_cur);
-
-miss:
-#ifdef STATISTICS
- ++bt_cache_miss;
-#endif
- t->bt_order = NOT;
- mpool_put(t->bt_mp, h, 0);
- return (NULL);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_search.c 8.8 (Berkeley) 7/31/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <stdio.h>
-
-#include <db.h>
-#include "btree.h"
-
-static int __bt_snext(BTREE *, PAGE *, const DBT *, int *);
-static int __bt_sprev(BTREE *, PAGE *, const DBT *, int *);
-
-/*
- * __bt_search --
- * Search a btree for a key.
- *
- * Parameters:
- * t: tree to search
- * key: key to find
- * exactp: pointer to exact match flag
- *
- * Returns:
- * The EPG for matching record, if any, or the EPG for the location
- * of the key, if it were inserted into the tree, is entered into
- * the bt_cur field of the tree. A pointer to the field is returned.
- */
-EPG *
-__bt_search(t, key, exactp)
- BTREE *t;
- const DBT *key;
- int *exactp;
-{
- PAGE *h;
- indx_t base, index, lim;
- pgno_t pg;
- int cmp;
-
- BT_CLR(t);
- for (pg = P_ROOT;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (NULL);
-
- /* Do a binary search on the current page. */
- t->bt_cur.page = h;
- for (base = 0, lim = NEXTINDEX(h); lim; lim >>= 1) {
- t->bt_cur.index = index = base + (lim >> 1);
- if ((cmp = __bt_cmp(t, key, &t->bt_cur)) == 0) {
- if (h->flags & P_BLEAF) {
- *exactp = 1;
- return (&t->bt_cur);
- }
- goto next;
- }
- if (cmp > 0) {
- base = index + 1;
- --lim;
- }
- }
-
- /*
- * If it's a leaf page, we're almost done. If no duplicates
- * are allowed, or we have an exact match, we're done. Else,
- * it's possible that there were matching keys on this page,
- * which later deleted, and we're on a page with no matches
- * while there are matches on other pages. If at the start or
- * end of a page, check the adjacent page.
- */
- if (h->flags & P_BLEAF) {
- if (!F_ISSET(t, B_NODUPS)) {
- if (base == 0 &&
- h->prevpg != P_INVALID &&
- __bt_sprev(t, h, key, exactp))
- return (&t->bt_cur);
- if (base == NEXTINDEX(h) &&
- h->nextpg != P_INVALID &&
- __bt_snext(t, h, key, exactp))
- return (&t->bt_cur);
- }
- *exactp = 0;
- t->bt_cur.index = base;
- return (&t->bt_cur);
- }
-
- /*
- * No match found. Base is the smallest index greater than
- * key and may be zero or a last + 1 index. If it's non-zero,
- * decrement by one, and record the internal page which should
- * be a parent page for the key. If a split later occurs, the
- * inserted page will be to the right of the saved page.
- */
- index = base ? base - 1 : base;
-
-next: BT_PUSH(t, h->pgno, index);
- pg = GETBINTERNAL(h, index)->pgno;
- mpool_put(t->bt_mp, h, 0);
- }
-}
-
-/*
- * __bt_snext --
- * Check for an exact match after the key.
- *
- * Parameters:
- * t: tree
- * h: current page
- * key: key
- * exactp: pointer to exact match flag
- *
- * Returns:
- * If an exact match found.
- */
-static int
-__bt_snext(t, h, key, exactp)
- BTREE *t;
- PAGE *h;
- const DBT *key;
- int *exactp;
-{
- EPG e;
-
- /*
- * Get the next page. The key is either an exact
- * match, or not as good as the one we already have.
- */
- if ((e.page = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
- return (0);
- e.index = 0;
- if (__bt_cmp(t, key, &e) == 0) {
- mpool_put(t->bt_mp, h, 0);
- t->bt_cur = e;
- *exactp = 1;
- return (1);
- }
- mpool_put(t->bt_mp, e.page, 0);
- return (0);
-}
-
-/*
- * __bt_sprev --
- * Check for an exact match before the key.
- *
- * Parameters:
- * t: tree
- * h: current page
- * key: key
- * exactp: pointer to exact match flag
- *
- * Returns:
- * If an exact match found.
- */
-static int
-__bt_sprev(t, h, key, exactp)
- BTREE *t;
- PAGE *h;
- const DBT *key;
- int *exactp;
-{
- EPG e;
-
- /*
- * Get the previous page. The key is either an exact
- * match, or not as good as the one we already have.
- */
- if ((e.page = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
- return (0);
- e.index = NEXTINDEX(e.page) - 1;
- if (__bt_cmp(t, key, &e) == 0) {
- mpool_put(t->bt_mp, h, 0);
- t->bt_cur = e;
- *exactp = 1;
- return (1);
- }
- mpool_put(t->bt_mp, e.page, 0);
- return (0);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_seq.c 8.7 (Berkeley) 7/20/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <db.h>
-#include "btree.h"
-
-static int __bt_first(BTREE *, const DBT *, EPG *, int *);
-static int __bt_seqadv(BTREE *, EPG *, int);
-static int __bt_seqset(BTREE *, EPG *, DBT *, int);
-
-/*
- * Sequential scan support.
- *
- * The tree can be scanned sequentially, starting from either end of the
- * tree or from any specific key. A scan request before any scanning is
- * done is initialized as starting from the least node.
- */
-
-/*
- * __bt_seq --
- * Btree sequential scan interface.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key for positioning and return value
- * data: data return value
- * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-int
-__bt_seq(dbp, key, data, flags)
- const DB *dbp;
- DBT *key, *data;
- u_int flags;
-{
- BTREE *t;
- EPG e;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /*
- * If scan unitialized as yet, or starting at a specific record, set
- * the scan to a specific key. Both __bt_seqset and __bt_seqadv pin
- * the page the cursor references if they're successful.
- */
- switch (flags) {
- case R_NEXT:
- case R_PREV:
- if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
- status = __bt_seqadv(t, &e, flags);
- break;
- }
- /* FALLTHROUGH */
- case R_FIRST:
- case R_LAST:
- case R_CURSOR:
- status = __bt_seqset(t, &e, key, flags);
- break;
- default:
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (status == RET_SUCCESS) {
- __bt_setcur(t, e.page->pgno, e.index);
-
- status =
- __bt_ret(t, &e, key, &t->bt_rkey, data, &t->bt_rdata, 0);
-
- /*
- * If the user is doing concurrent access, we copied the
- * key/data, toss the page.
- */
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e.page, 0);
- else
- t->bt_pinned = e.page;
- }
- return (status);
-}
-
-/*
- * __bt_seqset --
- * Set the sequential scan to a specific key.
- *
- * Parameters:
- * t: tree
- * ep: storage for returned key
- * key: key for initial scan position
- * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV
- *
- * Side effects:
- * Pins the page the cursor references.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-static int
-__bt_seqset(t, ep, key, flags)
- BTREE *t;
- EPG *ep;
- DBT *key;
- int flags;
-{
- PAGE *h;
- pgno_t pg;
- int exact;
-
- /*
- * Find the first, last or specific key in the tree and point the
- * cursor at it. The cursor may not be moved until a new key has
- * been found.
- */
- switch (flags) {
- case R_CURSOR: /* Keyed scan. */
- /*
- * Find the first instance of the key or the smallest key
- * which is greater than or equal to the specified key.
- */
- if (key->data == NULL || key->size == 0) {
- errno = EINVAL;
- return (RET_ERROR);
- }
- return (__bt_first(t, key, ep, &exact));
- case R_FIRST: /* First record. */
- case R_NEXT:
- /* Walk down the left-hand side of the tree. */
- for (pg = P_ROOT;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- /* Check for an empty tree. */
- if (NEXTINDEX(h) == 0) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_SPECIAL);
- }
-
- if (h->flags & (P_BLEAF | P_RLEAF))
- break;
- pg = GETBINTERNAL(h, 0)->pgno;
- mpool_put(t->bt_mp, h, 0);
- }
- ep->page = h;
- ep->index = 0;
- break;
- case R_LAST: /* Last record. */
- case R_PREV:
- /* Walk down the right-hand side of the tree. */
- for (pg = P_ROOT;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
-
- /* Check for an empty tree. */
- if (NEXTINDEX(h) == 0) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_SPECIAL);
- }
-
- if (h->flags & (P_BLEAF | P_RLEAF))
- break;
- pg = GETBINTERNAL(h, NEXTINDEX(h) - 1)->pgno;
- mpool_put(t->bt_mp, h, 0);
- }
-
- ep->page = h;
- ep->index = NEXTINDEX(h) - 1;
- break;
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_seqadvance --
- * Advance the sequential scan.
- *
- * Parameters:
- * t: tree
- * flags: R_NEXT, R_PREV
- *
- * Side effects:
- * Pins the page the new key/data record is on.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-static int
-__bt_seqadv(t, ep, flags)
- BTREE *t;
- EPG *ep;
- int flags;
-{
- CURSOR *c;
- PAGE *h;
- indx_t index;
- pgno_t pg;
- int exact;
-
- /*
- * There are a couple of states that we can be in. The cursor has
- * been initialized by the time we get here, but that's all we know.
- */
- c = &t->bt_cursor;
-
- /*
- * The cursor was deleted where there weren't any duplicate records,
- * so the key was saved. Find out where that key would go in the
- * current tree. It doesn't matter if the returned key is an exact
- * match or not -- if it's an exact match, the record was added after
- * the delete so we can just return it. If not, as long as there's
- * a record there, return it.
- */
- if (F_ISSET(c, CURS_ACQUIRE))
- return (__bt_first(t, &c->key, ep, &exact));
-
- /* Get the page referenced by the cursor. */
- if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
- return (RET_ERROR);
-
- /*
- * Find the next/previous record in the tree and point the cursor at
- * it. The cursor may not be moved until a new key has been found.
- */
- switch (flags) {
- case R_NEXT: /* Next record. */
- /*
- * The cursor was deleted in duplicate records, and moved
- * forward to a record that has yet to be returned. Clear
- * that flag, and return the record.
- */
- if (F_ISSET(c, CURS_AFTER))
- goto usecurrent;
- index = c->pg.index;
- if (++index == NEXTINDEX(h)) {
- pg = h->nextpg;
- mpool_put(t->bt_mp, h, 0);
- if (pg == P_INVALID)
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- index = 0;
- }
- break;
- case R_PREV: /* Previous record. */
- /*
- * The cursor was deleted in duplicate records, and moved
- * backward to a record that has yet to be returned. Clear
- * that flag, and return the record.
- */
- if (F_ISSET(c, CURS_BEFORE)) {
-usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE);
- ep->page = h;
- ep->index = c->pg.index;
- return (RET_SUCCESS);
- }
- index = c->pg.index;
- if (index == 0) {
- pg = h->prevpg;
- mpool_put(t->bt_mp, h, 0);
- if (pg == P_INVALID)
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- index = NEXTINDEX(h) - 1;
- } else
- --index;
- break;
- }
-
- ep->page = h;
- ep->index = index;
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_first --
- * Find the first entry.
- *
- * Parameters:
- * t: the tree
- * key: the key
- * erval: return EPG
- * exactp: pointer to exact match flag
- *
- * Returns:
- * The first entry in the tree greater than or equal to key,
- * or RET_SPECIAL if no such key exists.
- */
-static int
-__bt_first(t, key, erval, exactp)
- BTREE *t;
- const DBT *key;
- EPG *erval;
- int *exactp;
-{
- PAGE *h;
- EPG *ep, save;
- pgno_t pg;
-
- /*
- * Find any matching record; __bt_search pins the page.
- *
- * If it's an exact match and duplicates are possible, walk backwards
- * in the tree until we find the first one. Otherwise, make sure it's
- * a valid key (__bt_search may return an index just past the end of a
- * page) and return it.
- */
- if ((ep = __bt_search(t, key, exactp)) == NULL)
- return (0);
- if (*exactp) {
- if (F_ISSET(t, B_NODUPS)) {
- *erval = *ep;
- return (RET_SUCCESS);
- }
-
- /*
- * Walk backwards, as long as the entry matches and there are
- * keys left in the tree. Save a copy of each match in case
- * we go too far.
- */
- save = *ep;
- h = ep->page;
- do {
- if (save.page->pgno != ep->page->pgno) {
- mpool_put(t->bt_mp, save.page, 0);
- save = *ep;
- } else
- save.index = ep->index;
-
- /*
- * Don't unpin the page the last (or original) match
- * was on, but make sure it's unpinned if an error
- * occurs.
- */
- if (ep->index == 0) {
- if (h->prevpg == P_INVALID)
- break;
- if (h->pgno != save.page->pgno)
- mpool_put(t->bt_mp, h, 0);
- if ((h = mpool_get(t->bt_mp,
- h->prevpg, 0)) == NULL) {
- if (h->pgno == save.page->pgno)
- mpool_put(t->bt_mp,
- save.page, 0);
- return (RET_ERROR);
- }
- ep->page = h;
- ep->index = NEXTINDEX(h);
- }
- --ep->index;
- } while (__bt_cmp(t, key, ep) == 0);
-
- /*
- * Reach here with the last page that was looked at pinned,
- * which may or may not be the same as the last (or original)
- * match page. If it's not useful, release it.
- */
- if (h->pgno != save.page->pgno)
- mpool_put(t->bt_mp, h, 0);
-
- *erval = save;
- return (RET_SUCCESS);
- }
-
- /* If at the end of a page, find the next entry. */
- if (ep->index == NEXTINDEX(ep->page)) {
- h = ep->page;
- pg = h->nextpg;
- mpool_put(t->bt_mp, h, 0);
- if (pg == P_INVALID)
- return (RET_SPECIAL);
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- ep->index = 0;
- ep->page = h;
- }
- *erval = *ep;
- return (RET_SUCCESS);
-}
-
-/*
- * __bt_setcur --
- * Set the cursor to an entry in the tree.
- *
- * Parameters:
- * t: the tree
- * pgno: page number
- * index: page index
- */
-void
-__bt_setcur(t, pgno, index)
- BTREE *t;
- pgno_t pgno;
- u_int index;
-{
- /* Lose any already deleted key. */
- if (t->bt_cursor.key.data != NULL) {
- free(t->bt_cursor.key.data);
- t->bt_cursor.key.size = 0;
- t->bt_cursor.key.data = NULL;
- }
- F_CLR(&t->bt_cursor, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE);
-
- /* Update the cursor. */
- t->bt_cursor.pg.pgno = pgno;
- t->bt_cursor.pg.index = index;
- F_SET(&t->bt_cursor, CURS_INIT);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_split.c 8.9 (Berkeley) 7/26/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-static int bt_broot(BTREE *, PAGE *, PAGE *, PAGE *);
-static PAGE *bt_page (BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t);
-static int bt_preserve(BTREE *, pgno_t);
-static PAGE *bt_psplit (BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t);
-static PAGE *bt_root (BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t);
-static int bt_rroot(BTREE *, PAGE *, PAGE *, PAGE *);
-static recno_t rec_total(PAGE *);
-
-#ifdef STATISTICS
-u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved;
-#endif
-
-/*
- * __BT_SPLIT -- Split the tree.
- *
- * Parameters:
- * t: tree
- * sp: page to split
- * key: key to insert
- * data: data to insert
- * flags: BIGKEY/BIGDATA flags
- * ilen: insert length
- * skip: index to leave open
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__bt_split(t, sp, key, data, flags, ilen, argskip)
- BTREE *t;
- PAGE *sp;
- const DBT *key, *data;
- int flags;
- size_t ilen;
- u_int32_t argskip;
-{
- BINTERNAL *bi;
- BLEAF *bl, *tbl;
- DBT a, b;
- EPGNO *parent;
- PAGE *h, *l, *r, *lchild, *rchild;
- indx_t nxtindex;
- u_int16_t skip;
- u_int32_t n, nbytes, nksize;
- int parentsplit;
- char *dest;
-
- /*
- * Split the page into two pages, l and r. The split routines return
- * a pointer to the page into which the key should be inserted and with
- * skip set to the offset which should be used. Additionally, l and r
- * are pinned.
- */
- skip = argskip;
- h = sp->pgno == P_ROOT ?
- bt_root(t, sp, &l, &r, &skip, ilen) :
- bt_page(t, sp, &l, &r, &skip, ilen);
- if (h == NULL)
- return (RET_ERROR);
-
- /*
- * Insert the new key/data pair into the leaf page. (Key inserts
- * always cause a leaf page to split first.)
- */
- h->linp[skip] = h->upper -= ilen;
- dest = (char *)h + h->upper;
- if (F_ISSET(t, R_RECNO))
- WR_RLEAF(dest, data, flags)
- else
- WR_BLEAF(dest, key, data, flags)
-
- /* If the root page was split, make it look right. */
- if (sp->pgno == P_ROOT &&
- (F_ISSET(t, R_RECNO) ?
- bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
- goto err2;
-
- /*
- * Now we walk the parent page stack -- a LIFO stack of the pages that
- * were traversed when we searched for the page that split. Each stack
- * entry is a page number and a page index offset. The offset is for
- * the page traversed on the search. We've just split a page, so we
- * have to insert a new key into the parent page.
- *
- * If the insert into the parent page causes it to split, may have to
- * continue splitting all the way up the tree. We stop if the root
- * splits or the page inserted into didn't have to split to hold the
- * new key. Some algorithms replace the key for the old page as well
- * as the new page. We don't, as there's no reason to believe that the
- * first key on the old page is any better than the key we have, and,
- * in the case of a key being placed at index 0 causing the split, the
- * key is unavailable.
- *
- * There are a maximum of 5 pages pinned at any time. We keep the left
- * and right pages pinned while working on the parent. The 5 are the
- * two children, left parent and right parent (when the parent splits)
- * and the root page or the overflow key page when calling bt_preserve.
- * This code must make sure that all pins are released other than the
- * root page or overflow page which is unlocked elsewhere.
- */
- while ((parent = BT_POP(t)) != NULL) {
- lchild = l;
- rchild = r;
-
- /* Get the parent page. */
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- goto err2;
-
- /*
- * The new key goes ONE AFTER the index, because the split
- * was to the right.
- */
- skip = parent->index + 1;
-
- /*
- * Calculate the space needed on the parent page.
- *
- * Prefix trees: space hack when inserting into BINTERNAL
- * pages. Retain only what's needed to distinguish between
- * the new entry and the LAST entry on the page to its left.
- * If the keys compare equal, retain the entire key. Note,
- * we don't touch overflow keys, and the entire key must be
- * retained for the next-to-left most key on the leftmost
- * page of each level, or the search will fail. Applicable
- * ONLY to internal pages that have leaf pages as children.
- * Further reduction of the key between pairs of internal
- * pages loses too much information.
- */
- switch (rchild->flags & P_TYPE) {
- case P_BINTERNAL:
- bi = GETBINTERNAL(rchild, 0);
- nbytes = NBINTERNAL(bi->ksize);
- break;
- case P_BLEAF:
- bl = GETBLEAF(rchild, 0);
- nbytes = NBINTERNAL(bl->ksize);
- if (t->bt_pfx && !(bl->flags & P_BIGKEY) &&
- (h->prevpg != P_INVALID || skip > 1)) {
- tbl = GETBLEAF(lchild, NEXTINDEX(lchild) - 1);
- a.size = tbl->ksize;
- a.data = tbl->bytes;
- b.size = bl->ksize;
- b.data = bl->bytes;
- nksize = t->bt_pfx(&a, &b);
- n = NBINTERNAL(nksize);
- if (n < nbytes) {
-#ifdef STATISTICS
- bt_pfxsaved += nbytes - n;
-#endif
- nbytes = n;
- } else
- nksize = 0;
- } else
- nksize = 0;
- break;
- case P_RINTERNAL:
- case P_RLEAF:
- nbytes = NRINTERNAL;
- break;
- default:
- abort();
- }
-
- /* Split the parent page if necessary or shift the indices. */
- if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
- sp = h;
- h = h->pgno == P_ROOT ?
- bt_root(t, h, &l, &r, &skip, nbytes) :
- bt_page(t, h, &l, &r, &skip, nbytes);
- if (h == NULL)
- goto err1;
- parentsplit = 1;
- } else {
- if (skip < (nxtindex = NEXTINDEX(h)))
- memmove(h->linp + skip + 1, h->linp + skip,
- (nxtindex - skip) * sizeof(indx_t));
- h->lower += sizeof(indx_t);
- parentsplit = 0;
- }
-
- /* Insert the key into the parent page. */
- switch (rchild->flags & P_TYPE) {
- case P_BINTERNAL:
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- memmove(dest, bi, nbytes);
- ((BINTERNAL *)dest)->pgno = rchild->pgno;
- break;
- case P_BLEAF:
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- WR_BINTERNAL(dest, nksize ? nksize : bl->ksize,
- rchild->pgno, bl->flags & P_BIGKEY);
- memmove(dest, bl->bytes, nksize ? nksize : bl->ksize);
- if (bl->flags & P_BIGKEY &&
- bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
- goto err1;
- break;
- case P_RINTERNAL:
- /*
- * Update the left page count. If split
- * added at index 0, fix the correct page.
- */
- if (skip > 0)
- dest = (char *)h + h->linp[skip - 1];
- else
- dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
- ((RINTERNAL *)dest)->nrecs = rec_total(lchild);
- ((RINTERNAL *)dest)->pgno = lchild->pgno;
-
- /* Update the right page count. */
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- ((RINTERNAL *)dest)->nrecs = rec_total(rchild);
- ((RINTERNAL *)dest)->pgno = rchild->pgno;
- break;
- case P_RLEAF:
- /*
- * Update the left page count. If split
- * added at index 0, fix the correct page.
- */
- if (skip > 0)
- dest = (char *)h + h->linp[skip - 1];
- else
- dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
- ((RINTERNAL *)dest)->nrecs = NEXTINDEX(lchild);
- ((RINTERNAL *)dest)->pgno = lchild->pgno;
-
- /* Update the right page count. */
- h->linp[skip] = h->upper -= nbytes;
- dest = (char *)h + h->linp[skip];
- ((RINTERNAL *)dest)->nrecs = NEXTINDEX(rchild);
- ((RINTERNAL *)dest)->pgno = rchild->pgno;
- break;
- default:
- abort();
- }
-
- /* Unpin the held pages. */
- if (!parentsplit) {
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- }
-
- /* If the root page was split, make it look right. */
- if (sp->pgno == P_ROOT &&
- (F_ISSET(t, R_RECNO) ?
- bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
- goto err1;
-
- mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
- mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
- }
-
- /* Unpin the held pages. */
- mpool_put(t->bt_mp, l, MPOOL_DIRTY);
- mpool_put(t->bt_mp, r, MPOOL_DIRTY);
-
- /* Clear any pages left on the stack. */
- return (RET_SUCCESS);
-
- /*
- * If something fails in the above loop we were already walking back
- * up the tree and the tree is now inconsistent. Nothing much we can
- * do about it but release any memory we're holding.
- */
-err1: mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
- mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
-
-err2: mpool_put(t->bt_mp, l, 0);
- mpool_put(t->bt_mp, r, 0);
- __dbpanic(t->bt_dbp);
- return (RET_ERROR);
-}
-
-/*
- * BT_PAGE -- Split a non-root page of a btree.
- *
- * Parameters:
- * t: tree
- * h: root page
- * lp: pointer to left page pointer
- * rp: pointer to right page pointer
- * skip: pointer to index to leave open
- * ilen: insert length
- *
- * Returns:
- * Pointer to page in which to insert or NULL on error.
- */
-static PAGE *
-bt_page(t, h, lp, rp, skip, ilen)
- BTREE *t;
- PAGE *h, **lp, **rp;
- indx_t *skip;
- size_t ilen;
-{
- PAGE *l, *r, *tp;
- pgno_t npg;
-
-#ifdef STATISTICS
- ++bt_split;
-#endif
- /* Put the new right page for the split into place. */
- if ((r = __bt_new(t, &npg)) == NULL)
- return (NULL);
- r->pgno = npg;
- r->lower = BTDATAOFF;
- r->upper = t->bt_psize;
- r->nextpg = h->nextpg;
- r->prevpg = h->pgno;
- r->flags = h->flags & P_TYPE;
-
- /*
- * If we're splitting the last page on a level because we're appending
- * a key to it (skip is NEXTINDEX()), it's likely that the data is
- * sorted. Adding an empty page on the side of the level is less work
- * and can push the fill factor much higher than normal. If we're
- * wrong it's no big deal, we'll just do the split the right way next
- * time. It may look like it's equally easy to do a similar hack for
- * reverse sorted data, that is, split the tree left, but it's not.
- * Don't even try.
- */
- if (h->nextpg == P_INVALID && *skip == NEXTINDEX(h)) {
-#ifdef STATISTICS
- ++bt_sortsplit;
-#endif
- h->nextpg = r->pgno;
- r->lower = BTDATAOFF + sizeof(indx_t);
- *skip = 0;
- *lp = h;
- *rp = r;
- return (r);
- }
-
- /* Put the new left page for the split into place. */
- if ((l = (PAGE *)malloc(t->bt_psize)) == NULL) {
- mpool_put(t->bt_mp, r, 0);
- return (NULL);
- }
-#ifdef PURIFY
- memset(l, 0xff, t->bt_psize);
-#endif
- l->pgno = h->pgno;
- l->nextpg = r->pgno;
- l->prevpg = h->prevpg;
- l->lower = BTDATAOFF;
- l->upper = t->bt_psize;
- l->flags = h->flags & P_TYPE;
-
- /* Fix up the previous pointer of the page after the split page. */
- if (h->nextpg != P_INVALID) {
- if ((tp = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) {
- free(l);
- /* XXX mpool_free(t->bt_mp, r->pgno); */
- return (NULL);
- }
- tp->prevpg = r->pgno;
- mpool_put(t->bt_mp, tp, MPOOL_DIRTY);
- }
-
- /*
- * Split right. The key/data pairs aren't sorted in the btree page so
- * it's simpler to copy the data from the split page onto two new pages
- * instead of copying half the data to the right page and compacting
- * the left page in place. Since the left page can't change, we have
- * to swap the original and the allocated left page after the split.
- */
- tp = bt_psplit(t, h, l, r, skip, ilen);
-
- /* Move the new left page onto the old left page. */
- memmove(h, l, t->bt_psize);
- if (tp == l)
- tp = h;
- free(l);
-
- *lp = h;
- *rp = r;
- return (tp);
-}
-
-/*
- * BT_ROOT -- Split the root page of a btree.
- *
- * Parameters:
- * t: tree
- * h: root page
- * lp: pointer to left page pointer
- * rp: pointer to right page pointer
- * skip: pointer to index to leave open
- * ilen: insert length
- *
- * Returns:
- * Pointer to page in which to insert or NULL on error.
- */
-static PAGE *
-bt_root(t, h, lp, rp, skip, ilen)
- BTREE *t;
- PAGE *h, **lp, **rp;
- indx_t *skip;
- size_t ilen;
-{
- PAGE *l, *r, *tp;
- pgno_t lnpg, rnpg;
-
-#ifdef STATISTICS
- ++bt_split;
- ++bt_rootsplit;
-#endif
- /* Put the new left and right pages for the split into place. */
- if ((l = __bt_new(t, &lnpg)) == NULL ||
- (r = __bt_new(t, &rnpg)) == NULL)
- return (NULL);
- l->pgno = lnpg;
- r->pgno = rnpg;
- l->nextpg = r->pgno;
- r->prevpg = l->pgno;
- l->prevpg = r->nextpg = P_INVALID;
- l->lower = r->lower = BTDATAOFF;
- l->upper = r->upper = t->bt_psize;
- l->flags = r->flags = h->flags & P_TYPE;
-
- /* Split the root page. */
- tp = bt_psplit(t, h, l, r, skip, ilen);
-
- *lp = l;
- *rp = r;
- return (tp);
-}
-
-/*
- * BT_RROOT -- Fix up the recno root page after it has been split.
- *
- * Parameters:
- * t: tree
- * h: root page
- * l: left page
- * r: right page
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-bt_rroot(t, h, l, r)
- BTREE *t;
- PAGE *h, *l, *r;
-{
- char *dest;
-
- /* Insert the left and right keys, set the header information. */
- h->linp[0] = h->upper = t->bt_psize - NRINTERNAL;
- dest = (char *)h + h->upper;
- WR_RINTERNAL(dest,
- l->flags & P_RLEAF ? NEXTINDEX(l) : rec_total(l), l->pgno);
-
- h->linp[1] = h->upper -= NRINTERNAL;
- dest = (char *)h + h->upper;
- WR_RINTERNAL(dest,
- r->flags & P_RLEAF ? NEXTINDEX(r) : rec_total(r), r->pgno);
-
- h->lower = BTDATAOFF + 2 * sizeof(indx_t);
-
- /* Unpin the root page, set to recno internal page. */
- h->flags &= ~P_TYPE;
- h->flags |= P_RINTERNAL;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- return (RET_SUCCESS);
-}
-
-/*
- * BT_BROOT -- Fix up the btree root page after it has been split.
- *
- * Parameters:
- * t: tree
- * h: root page
- * l: left page
- * r: right page
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-static int
-bt_broot(t, h, l, r)
- BTREE *t;
- PAGE *h, *l, *r;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- u_int32_t nbytes;
- char *dest;
-
- /*
- * If the root page was a leaf page, change it into an internal page.
- * We copy the key we split on (but not the key's data, in the case of
- * a leaf page) to the new root page.
- *
- * The btree comparison code guarantees that the left-most key on any
- * level of the tree is never used, so it doesn't need to be filled in.
- */
- nbytes = NBINTERNAL(0);
- h->linp[0] = h->upper = t->bt_psize - nbytes;
- dest = (char *)h + h->upper;
- WR_BINTERNAL(dest, 0, l->pgno, 0);
-
- switch (h->flags & P_TYPE) {
- case P_BLEAF:
- bl = GETBLEAF(r, 0);
- nbytes = NBINTERNAL(bl->ksize);
- h->linp[1] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- WR_BINTERNAL(dest, bl->ksize, r->pgno, 0);
- memmove(dest, bl->bytes, bl->ksize);
-
- /*
- * If the key is on an overflow page, mark the overflow chain
- * so it isn't deleted when the leaf copy of the key is deleted.
- */
- if (bl->flags & P_BIGKEY &&
- bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
- return (RET_ERROR);
- break;
- case P_BINTERNAL:
- bi = GETBINTERNAL(r, 0);
- nbytes = NBINTERNAL(bi->ksize);
- h->linp[1] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- memmove(dest, bi, nbytes);
- ((BINTERNAL *)dest)->pgno = r->pgno;
- break;
- default:
- abort();
- }
-
- /* There are two keys on the page. */
- h->lower = BTDATAOFF + 2 * sizeof(indx_t);
-
- /* Unpin the root page, set to btree internal page. */
- h->flags &= ~P_TYPE;
- h->flags |= P_BINTERNAL;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- return (RET_SUCCESS);
-}
-
-/*
- * BT_PSPLIT -- Do the real work of splitting the page.
- *
- * Parameters:
- * t: tree
- * h: page to be split
- * l: page to put lower half of data
- * r: page to put upper half of data
- * pskip: pointer to index to leave open
- * ilen: insert length
- *
- * Returns:
- * Pointer to page in which to insert.
- */
-static PAGE *
-bt_psplit(t, h, l, r, pskip, ilen)
- BTREE *t;
- PAGE *h, *l, *r;
- indx_t *pskip;
- size_t ilen;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- CURSOR *c;
- RLEAF *rl;
- PAGE *rval;
- void *src;
- indx_t full, half, nxt, off, skip, top, used;
- u_int32_t nbytes;
- int bigkeycnt, isbigkey;
-
- /*
- * Split the data to the left and right pages. Leave the skip index
- * open. Additionally, make some effort not to split on an overflow
- * key. This makes internal page processing faster and can save
- * space as overflow keys used by internal pages are never deleted.
- */
- bigkeycnt = 0;
- skip = *pskip;
- full = t->bt_psize - BTDATAOFF;
- half = full / 2;
- used = 0;
- for (nxt = off = 0, top = NEXTINDEX(h); nxt < top; ++off) {
- if (skip == off) {
- nbytes = ilen;
- isbigkey = 0; /* XXX: not really known. */
- } else
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- src = bi = GETBINTERNAL(h, nxt);
- nbytes = NBINTERNAL(bi->ksize);
- isbigkey = bi->flags & P_BIGKEY;
- break;
- case P_BLEAF:
- src = bl = GETBLEAF(h, nxt);
- nbytes = NBLEAF(bl);
- isbigkey = bl->flags & P_BIGKEY;
- break;
- case P_RINTERNAL:
- src = GETRINTERNAL(h, nxt);
- nbytes = NRINTERNAL;
- isbigkey = 0;
- break;
- case P_RLEAF:
- src = rl = GETRLEAF(h, nxt);
- nbytes = NRLEAF(rl);
- isbigkey = 0;
- break;
- default:
- abort();
- }
-
- /*
- * If the key/data pairs are substantial fractions of the max
- * possible size for the page, it's possible to get situations
- * where we decide to try and copy too much onto the left page.
- * Make sure that doesn't happen.
- */
- if ((skip <= off && used + nbytes + sizeof(indx_t) >= full)
- || nxt == top - 1) {
- --off;
- break;
- }
-
- /* Copy the key/data pair, if not the skipped index. */
- if (skip != off) {
- ++nxt;
-
- l->linp[off] = l->upper -= nbytes;
- memmove((char *)l + l->upper, src, nbytes);
- }
-
- used += nbytes + sizeof(indx_t);
- if (used >= half) {
- if (!isbigkey || bigkeycnt == 3)
- break;
- else
- ++bigkeycnt;
- }
- }
-
- /*
- * Off is the last offset that's valid for the left page.
- * Nxt is the first offset to be placed on the right page.
- */
- l->lower += (off + 1) * sizeof(indx_t);
-
- /*
- * If splitting the page that the cursor was on, the cursor has to be
- * adjusted to point to the same record as before the split. If the
- * cursor is at or past the skipped slot, the cursor is incremented by
- * one. If the cursor is on the right page, it is decremented by the
- * number of records split to the left page.
- */
- c = &t->bt_cursor;
- if (F_ISSET(c, CURS_INIT) && c->pg.pgno == h->pgno) {
- if (c->pg.index >= skip)
- ++c->pg.index;
- if (c->pg.index < nxt) /* Left page. */
- c->pg.pgno = l->pgno;
- else { /* Right page. */
- c->pg.pgno = r->pgno;
- c->pg.index -= nxt;
- }
- }
-
- /*
- * If the skipped index was on the left page, just return that page.
- * Otherwise, adjust the skip index to reflect the new position on
- * the right page.
- */
- if (skip <= off) {
- skip = 0;
- rval = l;
- } else {
- rval = r;
- *pskip -= nxt;
- }
-
- for (off = 0; nxt < top; ++off) {
- if (skip == nxt) {
- ++off;
- skip = 0;
- }
- switch (h->flags & P_TYPE) {
- case P_BINTERNAL:
- src = bi = GETBINTERNAL(h, nxt);
- nbytes = NBINTERNAL(bi->ksize);
- break;
- case P_BLEAF:
- src = bl = GETBLEAF(h, nxt);
- nbytes = NBLEAF(bl);
- break;
- case P_RINTERNAL:
- src = GETRINTERNAL(h, nxt);
- nbytes = NRINTERNAL;
- break;
- case P_RLEAF:
- src = rl = GETRLEAF(h, nxt);
- nbytes = NRLEAF(rl);
- break;
- default:
- abort();
- }
- ++nxt;
- r->linp[off] = r->upper -= nbytes;
- memmove((char *)r + r->upper, src, nbytes);
- }
- r->lower += off * sizeof(indx_t);
-
- /* If the key is being appended to the page, adjust the index. */
- if (skip == top)
- r->lower += sizeof(indx_t);
-
- return (rval);
-}
-
-/*
- * BT_PRESERVE -- Mark a chain of pages as used by an internal node.
- *
- * Chains of indirect blocks pointed to by leaf nodes get reclaimed when the
- * record that references them gets deleted. Chains pointed to by internal
- * pages never get deleted. This routine marks a chain as pointed to by an
- * internal page.
- *
- * Parameters:
- * t: tree
- * pg: page number of first page in the chain.
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-static int
-bt_preserve(t, pg)
- BTREE *t;
- pgno_t pg;
-{
- PAGE *h;
-
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- return (RET_ERROR);
- h->flags |= P_PRESERVE;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
-
-/*
- * REC_TOTAL -- Return the number of recno entries below a page.
- *
- * Parameters:
- * h: page
- *
- * Returns:
- * The number of recno entries below a page.
- *
- * XXX
- * These values could be set by the bt_psplit routine. The problem is that the
- * entry has to be popped off of the stack etc. or the values have to be passed
- * all the way back to bt_split/bt_rroot and it's not very clean.
- */
-static recno_t
-rec_total(h)
- PAGE *h;
-{
- recno_t recs;
- indx_t nxt, top;
-
- for (recs = 0, nxt = 0, top = NEXTINDEX(h); nxt < top; ++nxt)
- recs += GETRINTERNAL(h, nxt)->nrecs;
- return (recs);
-}
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <db.h>
-#include "btree.h"
-
-/*
- * When a page splits, a new record has to be inserted into its parent page.
- * This page may have to split as well, all the way up to the root. Since
- * parent pointers in each page would be expensive, we maintain a stack of
- * parent pages as we descend the tree.
- *
- * XXX
- * This is a concurrency problem -- if user a builds a stack, then user b
- * splits the tree, then user a tries to split the tree, there's a new level
- * in the tree that user a doesn't know about.
- */
-
-/*
- * __BT_PUSH -- Push parent page info onto the stack (LIFO).
- *
- * Parameters:
- * t: tree
- * pgno: page
- * index: page index
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__bt_push(t, pgno, index)
- BTREE *t;
- pgno_t pgno;
- indx_t index;
-{
- if (t->bt_sp == t->bt_maxstack) {
- t->bt_maxstack += 50;
- if ((t->bt_stack = (EPGNO *)realloc(t->bt_stack,
- t->bt_maxstack * sizeof(EPGNO))) == NULL) {
- t->bt_maxstack -= 50;
- return (RET_ERROR);
- }
- }
-
- t->bt_stack[t->bt_sp].pgno = pgno;
- t->bt_stack[t->bt_sp].index = index;
- ++t->bt_sp;
- return (RET_SUCCESS);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_utils.c 8.8 (Berkeley) 7/20/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "btree.h"
-
-/*
- * __bt_ret --
- * Build return key/data pair.
- *
- * Parameters:
- * t: tree
- * e: key/data pair to be returned
- * key: user's key structure (NULL if not to be filled in)
- * rkey: memory area to hold key
- * data: user's data structure (NULL if not to be filled in)
- * rdata: memory area to hold data
- * copy: always copy the key/data item
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__bt_ret(t, e, key, rkey, data, rdata, copy)
- BTREE *t;
- EPG *e;
- DBT *key, *rkey, *data, *rdata;
- int copy;
-{
- BLEAF *bl;
- void *p;
-
- bl = GETBLEAF(e->page, e->index);
-
- /*
- * We must copy big keys/data to make them contigous. Otherwise,
- * leave the page pinned and don't copy unless the user specified
- * concurrent access.
- */
- if (key == NULL)
- goto dataonly;
-
- if (bl->flags & P_BIGKEY) {
- if (__ovfl_get(t, bl->bytes,
- &key->size, &rkey->data, &rkey->size))
- return (RET_ERROR);
- key->data = rkey->data;
- } else if (copy || F_ISSET(t, B_DB_LOCK)) {
- if (bl->ksize > rkey->size) {
- p = (void *)(rkey->data == NULL ?
- malloc(bl->ksize) : realloc(rkey->data, bl->ksize));
- if (p == NULL)
- return (RET_ERROR);
- rkey->data = p;
- rkey->size = bl->ksize;
- }
- memmove(rkey->data, bl->bytes, bl->ksize);
- key->size = bl->ksize;
- key->data = rkey->data;
- } else {
- key->size = bl->ksize;
- key->data = bl->bytes;
- }
-
-dataonly:
- if (data == NULL)
- return (RET_SUCCESS);
-
- if (bl->flags & P_BIGDATA) {
- if (__ovfl_get(t, bl->bytes + bl->ksize,
- &data->size, &rdata->data, &rdata->size))
- return (RET_ERROR);
- data->data = rdata->data;
- } else if (copy || F_ISSET(t, B_DB_LOCK)) {
- /* Use +1 in case the first record retrieved is 0 length. */
- if (bl->dsize + 1 > rdata->size) {
- p = (void *)(rdata->data == NULL ?
- malloc(bl->dsize + 1) :
- realloc(rdata->data, bl->dsize + 1));
- if (p == NULL)
- return (RET_ERROR);
- rdata->data = p;
- rdata->size = bl->dsize + 1;
- }
- memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize);
- data->size = bl->dsize;
- data->data = rdata->data;
- } else {
- data->size = bl->dsize;
- data->data = bl->bytes + bl->ksize;
- }
-
- return (RET_SUCCESS);
-}
-
-/*
- * __BT_CMP -- Compare a key to a given record.
- *
- * Parameters:
- * t: tree
- * k1: DBT pointer of first arg to comparison
- * e: pointer to EPG for comparison
- *
- * Returns:
- * < 0 if k1 is < record
- * = 0 if k1 is = record
- * > 0 if k1 is > record
- */
-int
-__bt_cmp(t, k1, e)
- BTREE *t;
- const DBT *k1;
- EPG *e;
-{
- BINTERNAL *bi;
- BLEAF *bl;
- DBT k2;
- PAGE *h;
- void *bigkey;
-
- /*
- * The left-most key on internal pages, at any level of the tree, is
- * guaranteed by the following code to be less than any user key.
- * This saves us from having to update the leftmost key on an internal
- * page when the user inserts a new key in the tree smaller than
- * anything we've yet seen.
- */
- h = e->page;
- if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF))
- return (1);
-
- bigkey = NULL;
- if (h->flags & P_BLEAF) {
- bl = GETBLEAF(h, e->index);
- if (bl->flags & P_BIGKEY)
- bigkey = bl->bytes;
- else {
- k2.data = bl->bytes;
- k2.size = bl->ksize;
- }
- } else {
- bi = GETBINTERNAL(h, e->index);
- if (bi->flags & P_BIGKEY)
- bigkey = bi->bytes;
- else {
- k2.data = bi->bytes;
- k2.size = bi->ksize;
- }
- }
-
- if (bigkey) {
- if (__ovfl_get(t, bigkey,
- &k2.size, &t->bt_rdata.data, &t->bt_rdata.size))
- return (RET_ERROR);
- k2.data = t->bt_rdata.data;
- }
- return ((*t->bt_cmp)(k1, &k2));
-}
-
-/*
- * __BT_DEFCMP -- Default comparison routine.
- *
- * Parameters:
- * a: DBT #1
- * b: DBT #2
- *
- * Returns:
- * < 0 if a is < b
- * = 0 if a is = b
- * > 0 if a is > b
- */
-int
-__bt_defcmp(a, b)
- const DBT *a, *b;
-{
- size_t len;
- u_char *p1, *p2;
-
- /*
- * XXX
- * If a size_t doesn't fit in an int, this routine can lose.
- * What we need is an integral type which is guaranteed to be
- * larger than a size_t, and there is no such thing.
- */
- len = MIN(a->size, b->size);
- for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
- if (*p1 != *p2)
- return ((int)*p1 - (int)*p2);
- return ((int)a->size - (int)b->size);
-}
-
-/*
- * __BT_DEFPFX -- Default prefix routine.
- *
- * Parameters:
- * a: DBT #1
- * b: DBT #2
- *
- * Returns:
- * Number of bytes needed to distinguish b from a.
- */
-size_t
-__bt_defpfx(a, b)
- const DBT *a, *b;
-{
- u_char *p1, *p2;
- size_t cnt, len;
-
- cnt = 1;
- len = MIN(a->size, b->size);
- for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
- if (*p1 != *p2)
- return (cnt);
-
- /* a->size must be <= b->size, or they wouldn't be in this order. */
- return (a->size < b->size ? a->size + 1 : a->size);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)btree.h 8.11 (Berkeley) 8/17/94
- * $FreeBSD: src/lib/libc/db/btree/btree.h,v 1.3 2002/03/22 23:41:40 obrien Exp $
- */
-
-/* Macros to set/clear/test flags. */
-#define F_SET(p, f) (p)->flags |= (f)
-#define F_CLR(p, f) (p)->flags &= ~(f)
-#define F_ISSET(p, f) ((p)->flags & (f))
-
-#include <mpool.h>
-
-#define DEFMINKEYPAGE (2) /* Minimum keys per page */
-#define MINCACHE (5) /* Minimum cached pages */
-#define MINPSIZE (512) /* Minimum page size */
-
-/*
- * Page 0 of a btree file contains a copy of the meta-data. This page is also
- * used as an out-of-band page, i.e. page pointers that point to nowhere point
- * to page 0. Page 1 is the root of the btree.
- */
-#define P_INVALID 0 /* Invalid tree page number. */
-#define P_META 0 /* Tree metadata page number. */
-#define P_ROOT 1 /* Tree root page number. */
-
-/*
- * There are five page layouts in the btree: btree internal pages (BINTERNAL),
- * btree leaf pages (BLEAF), recno internal pages (RINTERNAL), recno leaf pages
- * (RLEAF) and overflow pages. All five page types have a page header (PAGE).
- * This implementation requires that values within structures NOT be padded.
- * (ANSI C permits random padding.) If your compiler pads randomly you'll have
- * to do some work to get this package to run.
- */
-typedef struct _page {
- pgno_t pgno; /* this page's page number */
- pgno_t prevpg; /* left sibling */
- pgno_t nextpg; /* right sibling */
-
-#define P_BINTERNAL 0x01 /* btree internal page */
-#define P_BLEAF 0x02 /* leaf page */
-#define P_OVERFLOW 0x04 /* overflow page */
-#define P_RINTERNAL 0x08 /* recno internal page */
-#define P_RLEAF 0x10 /* leaf page */
-#define P_TYPE 0x1f /* type mask */
-#define P_PRESERVE 0x20 /* never delete this chain of pages */
- u_int32_t flags;
-
- indx_t lower; /* lower bound of free space on page */
- indx_t upper; /* upper bound of free space on page */
- indx_t linp[1]; /* indx_t-aligned VAR. LENGTH DATA */
-} PAGE;
-
-/* First and next index. */
-#define BTDATAOFF \
- (sizeof(pgno_t) + sizeof(pgno_t) + sizeof(pgno_t) + \
- sizeof(u_int32_t) + sizeof(indx_t) + sizeof(indx_t))
-#define NEXTINDEX(p) (((p)->lower - BTDATAOFF) / sizeof(indx_t))
-
-/*
- * For pages other than overflow pages, there is an array of offsets into the
- * rest of the page immediately following the page header. Each offset is to
- * an item which is unique to the type of page. The h_lower offset is just
- * past the last filled-in index. The h_upper offset is the first item on the
- * page. Offsets are from the beginning of the page.
- *
- * If an item is too big to store on a single page, a flag is set and the item
- * is a { page, size } pair such that the page is the first page of an overflow
- * chain with size bytes of item. Overflow pages are simply bytes without any
- * external structure.
- *
- * The page number and size fields in the items are pgno_t-aligned so they can
- * be manipulated without copying. (This presumes that 32 bit items can be
- * manipulated on this system.)
- */
-#define LALIGN(n) (((n) + sizeof(pgno_t) - 1) & ~(sizeof(pgno_t) - 1))
-#define NOVFLSIZE (sizeof(pgno_t) + sizeof(u_int32_t))
-
-/*
- * For the btree internal pages, the item is a key. BINTERNALs are {key, pgno}
- * pairs, such that the key compares less than or equal to all of the records
- * on that page. For a tree without duplicate keys, an internal page with two
- * consecutive keys, a and b, will have all records greater than or equal to a
- * and less than b stored on the page associated with a. Duplicate keys are
- * somewhat special and can cause duplicate internal and leaf page records and
- * some minor modifications of the above rule.
- */
-typedef struct _binternal {
- u_int32_t ksize; /* key size */
- pgno_t pgno; /* page number stored on */
-#define P_BIGDATA 0x01 /* overflow data */
-#define P_BIGKEY 0x02 /* overflow key */
- u_char flags;
- char bytes[1]; /* data */
-} BINTERNAL;
-
-/* Get the page's BINTERNAL structure at index indx. */
-#define GETBINTERNAL(pg, indx) \
- ((BINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NBINTERNAL(len) \
- LALIGN(sizeof(u_int32_t) + sizeof(pgno_t) + sizeof(u_char) + (len))
-
-/* Copy a BINTERNAL entry to the page. */
-#define WR_BINTERNAL(p, size, pgno, flags) { \
- *(u_int32_t *)p = size; \
- p += sizeof(u_int32_t); \
- *(pgno_t *)p = pgno; \
- p += sizeof(pgno_t); \
- *(u_char *)p = flags; \
- p += sizeof(u_char); \
-}
-
-/*
- * For the recno internal pages, the item is a page number with the number of
- * keys found on that page and below.
- */
-typedef struct _rinternal {
- recno_t nrecs; /* number of records */
- pgno_t pgno; /* page number stored below */
-} RINTERNAL;
-
-/* Get the page's RINTERNAL structure at index indx. */
-#define GETRINTERNAL(pg, indx) \
- ((RINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NRINTERNAL \
- LALIGN(sizeof(recno_t) + sizeof(pgno_t))
-
-/* Copy a RINTERAL entry to the page. */
-#define WR_RINTERNAL(p, nrecs, pgno) { \
- *(recno_t *)p = nrecs; \
- p += sizeof(recno_t); \
- *(pgno_t *)p = pgno; \
-}
-
-/* For the btree leaf pages, the item is a key and data pair. */
-typedef struct _bleaf {
- u_int32_t ksize; /* size of key */
- u_int32_t dsize; /* size of data */
- u_char flags; /* P_BIGDATA, P_BIGKEY */
- char bytes[1]; /* data */
-} BLEAF;
-
-/* Get the page's BLEAF structure at index indx. */
-#define GETBLEAF(pg, indx) \
- ((BLEAF *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NBLEAF(p) NBLEAFDBT((p)->ksize, (p)->dsize)
-
-/* Get the number of bytes in the user's key/data pair. */
-#define NBLEAFDBT(ksize, dsize) \
- LALIGN(sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_char) + \
- (ksize) + (dsize))
-
-/* Copy a BLEAF entry to the page. */
-#define WR_BLEAF(p, key, data, flags) { \
- *(u_int32_t *)p = key->size; \
- p += sizeof(u_int32_t); \
- *(u_int32_t *)p = data->size; \
- p += sizeof(u_int32_t); \
- *(u_char *)p = flags; \
- p += sizeof(u_char); \
- memmove(p, key->data, key->size); \
- p += key->size; \
- memmove(p, data->data, data->size); \
-}
-
-/* For the recno leaf pages, the item is a data entry. */
-typedef struct _rleaf {
- u_int32_t dsize; /* size of data */
- u_char flags; /* P_BIGDATA */
- char bytes[1];
-} RLEAF;
-
-/* Get the page's RLEAF structure at index indx. */
-#define GETRLEAF(pg, indx) \
- ((RLEAF *)((char *)(pg) + (pg)->linp[indx]))
-
-/* Get the number of bytes in the entry. */
-#define NRLEAF(p) NRLEAFDBT((p)->dsize)
-
-/* Get the number of bytes from the user's data. */
-#define NRLEAFDBT(dsize) \
- LALIGN(sizeof(u_int32_t) + sizeof(u_char) + (dsize))
-
-/* Copy a RLEAF entry to the page. */
-#define WR_RLEAF(p, data, flags) { \
- *(u_int32_t *)p = data->size; \
- p += sizeof(u_int32_t); \
- *(u_char *)p = flags; \
- p += sizeof(u_char); \
- memmove(p, data->data, data->size); \
-}
-
-/*
- * A record in the tree is either a pointer to a page and an index in the page
- * or a page number and an index. These structures are used as a cursor, stack
- * entry and search returns as well as to pass records to other routines.
- *
- * One comment about searches. Internal page searches must find the largest
- * record less than key in the tree so that descents work. Leaf page searches
- * must find the smallest record greater than key so that the returned index
- * is the record's correct position for insertion.
- */
-typedef struct _epgno {
- pgno_t pgno; /* the page number */
- indx_t index; /* the index on the page */
-} EPGNO;
-
-typedef struct _epg {
- PAGE *page; /* the (pinned) page */
- indx_t index; /* the index on the page */
-} EPG;
-
-/*
- * About cursors. The cursor (and the page that contained the key/data pair
- * that it referenced) can be deleted, which makes things a bit tricky. If
- * there are no duplicates of the cursor key in the tree (i.e. B_NODUPS is set
- * or there simply aren't any duplicates of the key) we copy the key that it
- * referenced when it's deleted, and reacquire a new cursor key if the cursor
- * is used again. If there are duplicates keys, we move to the next/previous
- * key, and set a flag so that we know what happened. NOTE: if duplicate (to
- * the cursor) keys are added to the tree during this process, it is undefined
- * if they will be returned or not in a cursor scan.
- *
- * The flags determine the possible states of the cursor:
- *
- * CURS_INIT The cursor references *something*.
- * CURS_ACQUIRE The cursor was deleted, and a key has been saved so that
- * we can reacquire the right position in the tree.
- * CURS_AFTER, CURS_BEFORE
- * The cursor was deleted, and now references a key/data pair
- * that has not yet been returned, either before or after the
- * deleted key/data pair.
- * XXX
- * This structure is broken out so that we can eventually offer multiple
- * cursors as part of the DB interface.
- */
-typedef struct _cursor {
- EPGNO pg; /* B: Saved tree reference. */
- DBT key; /* B: Saved key, or key.data == NULL. */
- recno_t rcursor; /* R: recno cursor (1-based) */
-
-#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */
-#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */
-#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */
-#define CURS_INIT 0x08 /* RB: Cursor initialized. */
- u_int8_t flags;
-} CURSOR;
-
-/*
- * The metadata of the tree. The nrecs field is used only by the RECNO code.
- * This is because the btree doesn't really need it and it requires that every
- * put or delete call modify the metadata.
- */
-typedef struct _btmeta {
- u_int32_t magic; /* magic number */
- u_int32_t version; /* version */
- u_int32_t psize; /* page size */
- u_int32_t free; /* page number of first free page */
- u_int32_t nrecs; /* R: number of records */
-
-#define SAVEMETA (B_NODUPS | R_RECNO)
- u_int32_t flags; /* bt_flags & SAVEMETA */
-} BTMETA;
-
-/* The in-memory btree/recno data structure. */
-typedef struct _btree {
- MPOOL *bt_mp; /* memory pool cookie */
-
- DB *bt_dbp; /* pointer to enclosing DB */
-
- EPG bt_cur; /* current (pinned) page */
- PAGE *bt_pinned; /* page pinned across calls */
-
- CURSOR bt_cursor; /* cursor */
-
-#define BT_PUSH(t, p, i) { \
- t->bt_sp->pgno = p; \
- t->bt_sp->index = i; \
- ++t->bt_sp; \
-}
-#define BT_POP(t) (t->bt_sp == t->bt_stack ? NULL : --t->bt_sp)
-#define BT_CLR(t) (t->bt_sp = t->bt_stack)
- EPGNO bt_stack[50]; /* stack of parent pages */
- EPGNO *bt_sp; /* current stack pointer */
-
- DBT bt_rkey; /* returned key */
- DBT bt_rdata; /* returned data */
-
- int bt_fd; /* tree file descriptor */
-
- pgno_t bt_free; /* next free page */
- u_int32_t bt_psize; /* page size */
- indx_t bt_ovflsize; /* cut-off for key/data overflow */
- int bt_lorder; /* byte order */
- /* sorted order */
- enum { NOT, BACK, FORWARD } bt_order;
- EPGNO bt_last; /* last insert */
-
- /* B: key comparison function */
- int (*bt_cmp)(const DBT *, const DBT *);
- /* B: prefix comparison function */
- size_t (*bt_pfx)(const DBT *, const DBT *);
- /* R: recno input function */
- int (*bt_irec)(struct _btree *, recno_t);
-
- FILE *bt_rfp; /* R: record FILE pointer */
- int bt_rfd; /* R: record file descriptor */
-
- caddr_t bt_cmap; /* R: current point in mapped space */
- caddr_t bt_smap; /* R: start of mapped space */
- caddr_t bt_emap; /* R: end of mapped space */
- size_t bt_msize; /* R: size of mapped region. */
-
- recno_t bt_nrecs; /* R: number of records */
- size_t bt_reclen; /* R: fixed record length */
- u_char bt_bval; /* R: delimiting byte/pad character */
-
-/*
- * NB:
- * B_NODUPS and R_RECNO are stored on disk, and may not be changed.
- */
-#define B_INMEM 0x00001 /* in-memory tree */
-#define B_METADIRTY 0x00002 /* need to write metadata */
-#define B_MODIFIED 0x00004 /* tree modified */
-#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */
-#define B_RDONLY 0x00010 /* read-only tree */
-
-#define B_NODUPS 0x00020 /* no duplicate keys permitted */
-#define R_RECNO 0x00080 /* record oriented tree */
-
-#define R_CLOSEFP 0x00040 /* opened a file pointer */
-#define R_EOF 0x00100 /* end of input file reached. */
-#define R_FIXLEN 0x00200 /* fixed length records */
-#define R_MEMMAPPED 0x00400 /* memory mapped file. */
-#define R_INMEM 0x00800 /* in-memory file */
-#define R_MODIFIED 0x01000 /* modified file */
-#define R_RDONLY 0x02000 /* read-only file */
-
-#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */
-#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */
-#define B_DB_TXN 0x10000 /* DB_TXN specified. */
- u_int32_t flags;
-} BTREE;
-
-#include "extern.h"
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)extern.h 8.10 (Berkeley) 7/20/94
- * $FreeBSD: src/lib/libc/db/btree/extern.h,v 1.3 2002/03/22 09:18:22 obrien Exp $
- */
-
-int __bt_close(DB *);
-int __bt_cmp(BTREE *, const DBT *, EPG *);
-int __bt_crsrdel(BTREE *, EPGNO *);
-int __bt_defcmp(const DBT *, const DBT *);
-size_t __bt_defpfx(const DBT *, const DBT *);
-int __bt_delete(const DB *, const DBT *, u_int);
-int __bt_dleaf(BTREE *, const DBT *, PAGE *, u_int);
-int __bt_fd(const DB *);
-int __bt_free(BTREE *, PAGE *);
-int __bt_get(const DB *, const DBT *, DBT *, u_int);
-PAGE *__bt_new(BTREE *, pgno_t *);
-void __bt_pgin(void *, pgno_t, void *);
-void __bt_pgout(void *, pgno_t, void *);
-int __bt_push(BTREE *, pgno_t, int);
-int __bt_put(const DB *dbp, DBT *, const DBT *, u_int);
-int __bt_ret(BTREE *, EPG *, DBT *, DBT *, DBT *, DBT *, int);
-EPG *__bt_search(BTREE *, const DBT *, int *);
-int __bt_seq(const DB *, DBT *, DBT *, u_int);
-void __bt_setcur(BTREE *, pgno_t, u_int);
-int __bt_split(BTREE *, PAGE *,
- const DBT *, const DBT *, int, size_t, u_int32_t);
-int __bt_sync(const DB *, u_int);
-
-int __ovfl_delete(BTREE *, void *);
-int __ovfl_get(BTREE *, void *, size_t *, void **, size_t *);
-int __ovfl_put(BTREE *, const DBT *, pgno_t *);
-
-#ifdef DEBUG
-void __bt_dnpage(DB *, pgno_t);
-void __bt_dpage(PAGE *);
-void __bt_dump(DB *);
-#endif
-#ifdef STATISTICS
-void __bt_stat(DB *);
-#endif
--- /dev/null
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)db.c 8.4 (Berkeley) 2/21/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/db/db.c,v 1.2 2002/03/22 21:52:01 obrien Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include <db.h>
+
+DB *
+dbopen(fname, flags, mode, type, openinfo)
+ const char *fname;
+ int flags, mode;
+ DBTYPE type;
+ const void *openinfo;
+{
+
+#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN)
+#define USE_OPEN_FLAGS \
+ (O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \
+ O_RDWR | O_SHLOCK | O_TRUNC)
+
+ if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0)
+ switch (type) {
+ case DB_BTREE:
+ return (__bt_open(fname, flags & USE_OPEN_FLAGS,
+ mode, openinfo, flags & DB_FLAGS));
+ case DB_HASH:
+ return (__hash_open(fname, flags & USE_OPEN_FLAGS,
+ mode, openinfo, flags & DB_FLAGS));
+ case DB_RECNO:
+ return (__rec_open(fname, flags & USE_OPEN_FLAGS,
+ mode, openinfo, flags & DB_FLAGS));
+ }
+ errno = EINVAL;
+ return (NULL);
+}
+
+static int
+__dberr()
+{
+ return (RET_ERROR);
+}
+
+/*
+ * __DBPANIC -- Stop.
+ *
+ * Parameters:
+ * dbp: pointer to the DB structure.
+ */
+void
+__dbpanic(dbp)
+ DB *dbp;
+{
+ /* The only thing that can succeed is a close. */
+ dbp->del = (int (*)())__dberr;
+ dbp->fd = (int (*)())__dberr;
+ dbp->get = (int (*)())__dberr;
+ dbp->put = (int (*)())__dberr;
+ dbp->seq = (int (*)())__dberr;
+ dbp->sync = (int (*)())__dberr;
+}
# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
-# $FreeBSD: src/lib/libc/db/db/Makefile.inc,v 1.3 1999/08/27 23:58:17 peter Exp $
+# $FreeBSD: src/lib/libc/db/db/Makefile.inc,v 1.4 2002/11/18 09:50:54 ru Exp $
.PATH: ${.CURDIR}/db/db
-SRCS+= db.c
+.include "Makefile.fbsd_begin"
+FBSDMISRCS= db.c
+.for _src in ${FBSDMISRCS}
+CFLAGS-${_src:R}-fbsd.${_src:E} += -D__DBINTERFACE_PRIVATE
+.endfor
+.include "Makefile.fbsd_end"
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)db.c 8.4 (Berkeley) 2/21/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdio.h>
-
-#include <db.h>
-
-DB *
-dbopen(fname, flags, mode, type, openinfo)
- const char *fname;
- int flags, mode;
- DBTYPE type;
- const void *openinfo;
-{
-
-#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN)
-#define USE_OPEN_FLAGS \
- (O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \
- O_RDWR | O_SHLOCK | O_TRUNC)
-
- if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0)
- switch (type) {
- case DB_BTREE:
- return (__bt_open(fname, flags & USE_OPEN_FLAGS,
- mode, openinfo, flags & DB_FLAGS));
- case DB_HASH:
- return (__hash_open(fname, flags & USE_OPEN_FLAGS,
- mode, openinfo, flags & DB_FLAGS));
- case DB_RECNO:
- return (__rec_open(fname, flags & USE_OPEN_FLAGS,
- mode, openinfo, flags & DB_FLAGS));
- }
- errno = EINVAL;
- return (NULL);
-}
-
-static int
-__dberr()
-{
- return (RET_ERROR);
-}
-
-/*
- * __DBPANIC -- Stop.
- *
- * Parameters:
- * dbp: pointer to the DB structure.
- */
-void
-__dbpanic(dbp)
- DB *dbp;
-{
- /* The only thing that can succeed is a close. */
- dbp->del = (int (*)())__dberr;
- dbp->fd = (int (*)())__dberr;
- dbp->get = (int (*)())__dberr;
- dbp->put = (int (*)())__dberr;
- dbp->seq = (int (*)())__dberr;
- dbp->sync = (int (*)())__dberr;
-}
--- /dev/null
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)extern.h 8.4 (Berkeley) 6/16/94
+ * $FreeBSD: src/lib/libc/db/hash/extern.h,v 1.3 2002/03/22 09:18:22 obrien Exp $
+ */
+
+BUFHEAD *__add_ovflpage(HTAB *, BUFHEAD *);
+int __addel(HTAB *, BUFHEAD *, const DBT *, const DBT *);
+int __big_delete(HTAB *, BUFHEAD *);
+int __big_insert(HTAB *, BUFHEAD *, const DBT *, const DBT *);
+int __big_keydata(HTAB *, BUFHEAD *, DBT *, DBT *, int);
+int __big_return(HTAB *, BUFHEAD *, int, DBT *, int);
+int __big_split(HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *,
+ int, u_int32_t, SPLIT_RETURN *);
+int __buf_free(HTAB *, int, int);
+void __buf_init(HTAB *, int);
+u_int32_t __call_hash(HTAB *, char *, int);
+int __delpair(HTAB *, BUFHEAD *, int);
+int __expand_table(HTAB *);
+int __find_bigpair(HTAB *, BUFHEAD *, int, char *, int);
+u_int16_t __find_last_page(HTAB *, BUFHEAD **);
+void __free_ovflpage(HTAB *, BUFHEAD *);
+BUFHEAD *__get_buf(HTAB *, u_int32_t, BUFHEAD *, int);
+int __get_page(HTAB *, char *, u_int32_t, int, int, int);
+int __ibitmap(HTAB *, int, int, int);
+u_int32_t __log2(u_int32_t);
+int __put_page(HTAB *, char *, u_int32_t, int, int);
+void __reclaim_buf(HTAB *, BUFHEAD *);
+int __split_page(HTAB *, u_int32_t, u_int32_t);
+
+/* Default hash routine. */
+extern u_int32_t (*__default_hash)(const void *, size_t);
+
+#ifdef HASH_STATISTICS
+extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
+#endif
--- /dev/null
+/*-
+ * 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
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash.c,v 1.11 2002/03/21 22:46:26 obrien Exp $");
+
+#include "namespace.h"
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef DEBUG
+#include <assert.h>
+#endif
+#include "un-namespace.h"
+
+#include <db.h>
+#include "hash.h"
+#include "page.h"
+#include "extern.h"
+
+static int alloc_segs(HTAB *, int);
+static int flush_meta(HTAB *);
+static int hash_access(HTAB *, ACTION, DBT *, DBT *);
+static int hash_close(DB *);
+static int hash_delete(const DB *, const DBT *, u_int32_t);
+static int hash_fd(const DB *);
+static int hash_get(const DB *, const DBT *, DBT *, u_int32_t);
+static int hash_put(const DB *, DBT *, const DBT *, u_int32_t);
+static void *hash_realloc(SEGMENT **, int, int);
+static int hash_seq(const DB *, DBT *, DBT *, u_int32_t);
+static int hash_sync(const DB *, u_int32_t);
+static int hdestroy(HTAB *);
+static HTAB *init_hash(HTAB *, const char *, HASHINFO *);
+static int init_htab(HTAB *, int);
+#if BYTE_ORDER == LITTLE_ENDIAN
+static void swap_header(HTAB *);
+static void swap_header_copy(HASHHDR *, HASHHDR *);
+#endif
+
+/* Fast arithmetic, relying on powers of 2, */
+#define MOD(x, y) ((x) & ((y) - 1))
+
+#define RETURN_ERROR(ERR, LOC) { save_errno = ERR; goto LOC; }
+
+/* Return values */
+#define SUCCESS (0)
+#define ERROR (-1)
+#define ABNORMAL (1)
+
+#ifdef HASH_STATISTICS
+int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
+#endif
+
+/************************** INTERFACE ROUTINES ***************************/
+/* OPEN/CLOSE */
+
+extern DB *
+__hash_open(file, flags, mode, info, dflags)
+ const char *file;
+ int flags, mode, dflags;
+ const HASHINFO *info; /* Special directives for create */
+{
+ HTAB *hashp;
+ struct stat statbuf;
+ DB *dbp;
+ int bpages, hdrsize, new_table, nsegs, save_errno;
+
+ if ((flags & O_ACCMODE) == O_WRONLY) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB))))
+ return (NULL);
+ hashp->fp = -1;
+
+ /*
+ * Even if user wants write only, we need to be able to read
+ * the actual file, so we need to open it read/write. But, the
+ * field in the hashp structure needs to be accurate so that
+ * we can check accesses.
+ */
+ hashp->flags = flags;
+
+ new_table = 0;
+ if (!file || (flags & O_TRUNC) ||
+ (stat(file, &statbuf) && (errno == ENOENT))) {
+ if (errno == ENOENT)
+ errno = 0; /* Just in case someone looks at errno */
+ new_table = 1;
+ }
+ if (file) {
+ if ((hashp->fp = _open(file, flags, mode)) == -1)
+ RETURN_ERROR(errno, error0);
+
+ /* if the .db file is empty, and we had permission to create
+ a new .db file, then reinitialize the database */
+ if ((flags & O_CREAT) &&
+ _fstat(hashp->fp, &statbuf) == 0 && statbuf.st_size == 0)
+ new_table = 1;
+
+ (void)_fcntl(hashp->fp, F_SETFD, 1);
+ }
+ if (new_table) {
+ if (!(hashp = init_hash(hashp, file, (HASHINFO *)info)))
+ RETURN_ERROR(errno, error1);
+ } else {
+ /* Table already exists */
+ if (info && info->hash)
+ hashp->hash = info->hash;
+ else
+ hashp->hash = __default_hash;
+
+ hdrsize = _read(hashp->fp, &hashp->hdr, sizeof(HASHHDR));
+#if BYTE_ORDER == LITTLE_ENDIAN
+ swap_header(hashp);
+#endif
+ if (hdrsize == -1)
+ RETURN_ERROR(errno, error1);
+ if (hdrsize != sizeof(HASHHDR))
+ RETURN_ERROR(EFTYPE, error1);
+ /* Verify file type, versions and hash function */
+ if (hashp->MAGIC != HASHMAGIC)
+ RETURN_ERROR(EFTYPE, error1);
+#define OLDHASHVERSION 1
+ if (hashp->VERSION != HASHVERSION &&
+ hashp->VERSION != OLDHASHVERSION)
+ RETURN_ERROR(EFTYPE, error1);
+ if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY)
+ RETURN_ERROR(EFTYPE, error1);
+ /*
+ * Figure out how many segments we need. Max_Bucket is the
+ * maximum bucket number, so the number of buckets is
+ * max_bucket + 1.
+ */
+ nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) /
+ hashp->SGSIZE;
+ hashp->nsegs = 0;
+ if (alloc_segs(hashp, nsegs))
+ /*
+ * If alloc_segs fails, table will have been destroyed
+ * and errno will have been set.
+ */
+ return (NULL);
+ /* Read in bitmaps */
+ bpages = (hashp->SPARES[hashp->OVFL_POINT] +
+ (hashp->BSIZE << BYTE_SHIFT) - 1) >>
+ (hashp->BSHIFT + BYTE_SHIFT);
+
+ hashp->nmaps = bpages;
+ (void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_int32_t *));
+ }
+
+ /* Initialize Buffer Manager */
+ if (info && info->cachesize)
+ __buf_init(hashp, info->cachesize);
+ else
+ __buf_init(hashp, DEF_BUFSIZE);
+
+ hashp->new_file = new_table;
+ hashp->save_file = file && (hashp->flags & O_RDWR);
+ hashp->cbucket = -1;
+ if (!(dbp = (DB *)malloc(sizeof(DB)))) {
+ save_errno = errno;
+ hdestroy(hashp);
+ errno = save_errno;
+ return (NULL);
+ }
+ dbp->internal = hashp;
+ dbp->close = hash_close;
+ dbp->del = hash_delete;
+ dbp->fd = hash_fd;
+ dbp->get = hash_get;
+ dbp->put = hash_put;
+ dbp->seq = hash_seq;
+ dbp->sync = hash_sync;
+ dbp->type = DB_HASH;
+
+#ifdef DEBUG
+ (void)fprintf(stderr,
+"%s\n%s%x\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
+ "init_htab:",
+ "TABLE POINTER ", hashp,
+ "BUCKET SIZE ", hashp->BSIZE,
+ "BUCKET SHIFT ", hashp->BSHIFT,
+ "DIRECTORY SIZE ", hashp->DSIZE,
+ "SEGMENT SIZE ", hashp->SGSIZE,
+ "SEGMENT SHIFT ", hashp->SSHIFT,
+ "FILL FACTOR ", hashp->FFACTOR,
+ "MAX BUCKET ", hashp->MAX_BUCKET,
+ "OVFL POINT ", hashp->OVFL_POINT,
+ "LAST FREED ", hashp->LAST_FREED,
+ "HIGH MASK ", hashp->HIGH_MASK,
+ "LOW MASK ", hashp->LOW_MASK,
+ "NSEGS ", hashp->nsegs,
+ "NKEYS ", hashp->NKEYS);
+#endif
+#ifdef HASH_STATISTICS
+ hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0;
+#endif
+ return (dbp);
+
+error1:
+ if (hashp != NULL)
+ (void)_close(hashp->fp);
+
+error0:
+ free(hashp);
+ errno = save_errno;
+ return (NULL);
+}
+
+static int
+hash_close(dbp)
+ DB *dbp;
+{
+ HTAB *hashp;
+ int retval;
+
+ if (!dbp)
+ return (ERROR);
+
+ hashp = (HTAB *)dbp->internal;
+ retval = hdestroy(hashp);
+ free(dbp);
+ return (retval);
+}
+
+static int
+hash_fd(dbp)
+ const DB *dbp;
+{
+ HTAB *hashp;
+
+ if (!dbp)
+ return (ERROR);
+
+ hashp = (HTAB *)dbp->internal;
+ if (hashp->fp == -1) {
+ errno = ENOENT;
+ return (-1);
+ }
+ return (hashp->fp);
+}
+
+/************************** LOCAL CREATION ROUTINES **********************/
+static HTAB *
+init_hash(hashp, file, info)
+ HTAB *hashp;
+ const char *file;
+ HASHINFO *info;
+{
+ struct stat statbuf;
+ int nelem;
+
+ nelem = 1;
+ hashp->NKEYS = 0;
+ hashp->LORDER = BYTE_ORDER;
+ hashp->BSIZE = DEF_BUCKET_SIZE;
+ hashp->BSHIFT = DEF_BUCKET_SHIFT;
+ hashp->SGSIZE = DEF_SEGSIZE;
+ hashp->SSHIFT = DEF_SEGSIZE_SHIFT;
+ hashp->DSIZE = DEF_DIRSIZE;
+ hashp->FFACTOR = DEF_FFACTOR;
+ hashp->hash = __default_hash;
+ memset(hashp->SPARES, 0, sizeof(hashp->SPARES));
+ memset(hashp->BITMAPS, 0, sizeof (hashp->BITMAPS));
+
+ /* Fix bucket size to be optimal for file system */
+ if (file != NULL) {
+ if (stat(file, &statbuf))
+ return (NULL);
+ hashp->BSIZE = statbuf.st_blksize;
+ hashp->BSHIFT = __log2(hashp->BSIZE);
+ }
+
+ if (info) {
+ if (info->bsize) {
+ /* Round pagesize up to power of 2 */
+ hashp->BSHIFT = __log2(info->bsize);
+ hashp->BSIZE = 1 << hashp->BSHIFT;
+ if (hashp->BSIZE > MAX_BSIZE) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ }
+ if (info->ffactor)
+ hashp->FFACTOR = info->ffactor;
+ if (info->hash)
+ hashp->hash = info->hash;
+ if (info->nelem)
+ nelem = info->nelem;
+ if (info->lorder) {
+ if (info->lorder != BIG_ENDIAN &&
+ info->lorder != LITTLE_ENDIAN) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ hashp->LORDER = info->lorder;
+ }
+ }
+ /* init_htab should destroy the table and set errno if it fails */
+ if (init_htab(hashp, nelem))
+ return (NULL);
+ else
+ return (hashp);
+}
+/*
+ * This calls alloc_segs which may run out of memory. Alloc_segs will destroy
+ * the table and set errno, so we just pass the error information along.
+ *
+ * Returns 0 on No Error
+ */
+static int
+init_htab(hashp, nelem)
+ HTAB *hashp;
+ int nelem;
+{
+ int nbuckets, nsegs;
+ int l2;
+
+ /*
+ * Divide number of elements by the fill factor and determine a
+ * desired number of buckets. Allocate space for the next greater
+ * power of two number of buckets.
+ */
+ nelem = (nelem - 1) / hashp->FFACTOR + 1;
+
+ l2 = __log2(MAX(nelem, 2));
+ nbuckets = 1 << l2;
+
+ hashp->SPARES[l2] = l2 + 1;
+ hashp->SPARES[l2 + 1] = l2 + 1;
+ hashp->OVFL_POINT = l2;
+ hashp->LAST_FREED = 2;
+
+ /* First bitmap page is at: splitpoint l2 page offset 1 */
+ if (__ibitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0))
+ return (-1);
+
+ hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1;
+ hashp->HIGH_MASK = (nbuckets << 1) - 1;
+ hashp->HDRPAGES = ((MAX(sizeof(HASHHDR), MINHDRSIZE) - 1) >>
+ hashp->BSHIFT) + 1;
+
+ nsegs = (nbuckets - 1) / hashp->SGSIZE + 1;
+ nsegs = 1 << __log2(nsegs);
+
+ if (nsegs > hashp->DSIZE)
+ hashp->DSIZE = nsegs;
+ return (alloc_segs(hashp, nsegs));
+}
+
+/********************** DESTROY/CLOSE ROUTINES ************************/
+
+/*
+ * Flushes any changes to the file if necessary and destroys the hashp
+ * structure, freeing all allocated space.
+ */
+static int
+hdestroy(hashp)
+ HTAB *hashp;
+{
+ int i, save_errno;
+
+ save_errno = 0;
+
+#ifdef HASH_STATISTICS
+ (void)fprintf(stderr, "hdestroy: accesses %ld collisions %ld\n",
+ hash_accesses, hash_collisions);
+ (void)fprintf(stderr, "hdestroy: expansions %ld\n",
+ hash_expansions);
+ (void)fprintf(stderr, "hdestroy: overflows %ld\n",
+ hash_overflows);
+ (void)fprintf(stderr, "keys %ld maxp %d segmentcount %d\n",
+ hashp->NKEYS, hashp->MAX_BUCKET, hashp->nsegs);
+
+ for (i = 0; i < NCACHED; i++)
+ (void)fprintf(stderr,
+ "spares[%d] = %d\n", i, hashp->SPARES[i]);
+#endif
+ /*
+ * Call on buffer manager to free buffers, and if required,
+ * write them to disk.
+ */
+ if (__buf_free(hashp, 1, hashp->save_file))
+ save_errno = errno;
+ if (hashp->dir) {
+ free(*hashp->dir); /* Free initial segments */
+ /* Free extra segments */
+ while (hashp->exsegs--)
+ free(hashp->dir[--hashp->nsegs]);
+ free(hashp->dir);
+ }
+ if (flush_meta(hashp) && !save_errno)
+ save_errno = errno;
+ /* Free Bigmaps */
+ for (i = 0; i < hashp->nmaps; i++)
+ if (hashp->mapp[i])
+ free(hashp->mapp[i]);
+
+ if (hashp->fp != -1)
+ (void)_close(hashp->fp);
+
+ free(hashp);
+
+ if (save_errno) {
+ errno = save_errno;
+ return (ERROR);
+ }
+ return (SUCCESS);
+}
+/*
+ * Write modified pages to disk
+ *
+ * Returns:
+ * 0 == OK
+ * -1 ERROR
+ */
+static int
+hash_sync(dbp, flags)
+ const DB *dbp;
+ u_int32_t flags;
+{
+ HTAB *hashp;
+
+ if (flags != 0) {
+ errno = EINVAL;
+ return (ERROR);
+ }
+
+ if (!dbp)
+ return (ERROR);
+
+ hashp = (HTAB *)dbp->internal;
+ if (!hashp->save_file)
+ return (0);
+ if (__buf_free(hashp, 0, 1) || flush_meta(hashp))
+ return (ERROR);
+ hashp->new_file = 0;
+ return (0);
+}
+
+/*
+ * Returns:
+ * 0 == OK
+ * -1 indicates that errno should be set
+ */
+static int
+flush_meta(hashp)
+ HTAB *hashp;
+{
+ HASHHDR *whdrp;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ HASHHDR whdr;
+#endif
+ int fp, i, wsize;
+
+ if (!hashp->save_file)
+ return (0);
+ hashp->MAGIC = HASHMAGIC;
+ hashp->VERSION = HASHVERSION;
+ hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY));
+
+ fp = hashp->fp;
+ whdrp = &hashp->hdr;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ whdrp = &whdr;
+ swap_header_copy(&hashp->hdr, whdrp);
+#endif
+ if ((lseek(fp, (off_t)0, SEEK_SET) == -1) ||
+ ((wsize = _write(fp, whdrp, sizeof(HASHHDR))) == -1))
+ return (-1);
+ else
+ if (wsize != sizeof(HASHHDR)) {
+ errno = EFTYPE;
+ hashp->error = errno;
+ return (-1);
+ }
+ for (i = 0; i < NCACHED; i++)
+ if (hashp->mapp[i])
+ if (__put_page(hashp, (char *)hashp->mapp[i],
+ hashp->BITMAPS[i], 0, 1))
+ return (-1);
+ return (0);
+}
+
+/*******************************SEARCH ROUTINES *****************************/
+/*
+ * All the access routines return
+ *
+ * Returns:
+ * 0 on SUCCESS
+ * 1 to indicate an external ERROR (i.e. key not found, etc)
+ * -1 to indicate an internal ERROR (i.e. out of memory, etc)
+ */
+static int
+hash_get(dbp, key, data, flag)
+ const DB *dbp;
+ const DBT *key;
+ DBT *data;
+ u_int32_t flag;
+{
+ HTAB *hashp;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag) {
+ hashp->error = errno = EINVAL;
+ return (ERROR);
+ }
+ return (hash_access(hashp, HASH_GET, (DBT *)key, data));
+}
+
+static int
+hash_put(dbp, key, data, flag)
+ const DB *dbp;
+ DBT *key;
+ const DBT *data;
+ u_int32_t flag;
+{
+ HTAB *hashp;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag && flag != R_NOOVERWRITE) {
+ hashp->error = EINVAL;
+ errno = EINVAL;
+ return (ERROR);
+ }
+ if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
+ hashp->error = errno = EPERM;
+ return (ERROR);
+ }
+ return (hash_access(hashp, flag == R_NOOVERWRITE ?
+ HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data));
+}
+
+static int
+hash_delete(dbp, key, flag)
+ const DB *dbp;
+ const DBT *key;
+ u_int32_t flag; /* Ignored */
+{
+ HTAB *hashp;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag && flag != R_CURSOR) {
+ hashp->error = errno = EINVAL;
+ return (ERROR);
+ }
+ if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
+ hashp->error = errno = EPERM;
+ return (ERROR);
+ }
+ return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL));
+}
+
+/*
+ * Assume that hashp has been set in wrapper routine.
+ */
+static int
+hash_access(hashp, action, key, val)
+ HTAB *hashp;
+ ACTION action;
+ DBT *key, *val;
+{
+ BUFHEAD *rbufp;
+ BUFHEAD *bufp, *save_bufp;
+ u_int16_t *bp;
+ int n, ndx, off, size;
+ char *kp;
+ u_int16_t pageno;
+
+#ifdef HASH_STATISTICS
+ hash_accesses++;
+#endif
+
+ off = hashp->BSIZE;
+ size = key->size;
+ kp = (char *)key->data;
+ rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0);
+ if (!rbufp)
+ return (ERROR);
+ save_bufp = rbufp;
+
+ /* Pin the bucket chain */
+ rbufp->flags |= BUF_PIN;
+ for (bp = (u_int16_t *)rbufp->page, n = *bp++, ndx = 1; ndx < n;)
+ if (bp[1] >= REAL_KEY) {
+ /* Real key/data pair */
+ if (size == off - *bp &&
+ memcmp(kp, rbufp->page + *bp, size) == 0)
+ goto found;
+ off = bp[1];
+#ifdef HASH_STATISTICS
+ hash_collisions++;
+#endif
+ bp += 2;
+ ndx += 2;
+ } else if (bp[1] == OVFLPAGE) {
+ rbufp = __get_buf(hashp, *bp, rbufp, 0);
+ if (!rbufp) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (ERROR);
+ }
+ /* FOR LOOP INIT */
+ bp = (u_int16_t *)rbufp->page;
+ n = *bp++;
+ ndx = 1;
+ off = hashp->BSIZE;
+ } else if (bp[1] < REAL_KEY) {
+ if ((ndx =
+ __find_bigpair(hashp, rbufp, ndx, kp, size)) > 0)
+ goto found;
+ if (ndx == -2) {
+ bufp = rbufp;
+ if (!(pageno =
+ __find_last_page(hashp, &bufp))) {
+ ndx = 0;
+ rbufp = bufp;
+ break; /* FOR */
+ }
+ rbufp = __get_buf(hashp, pageno, bufp, 0);
+ if (!rbufp) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (ERROR);
+ }
+ /* FOR LOOP INIT */
+ bp = (u_int16_t *)rbufp->page;
+ n = *bp++;
+ ndx = 1;
+ off = hashp->BSIZE;
+ } else {
+ save_bufp->flags &= ~BUF_PIN;
+ return (ERROR);
+ }
+ }
+
+ /* Not found */
+ switch (action) {
+ case HASH_PUT:
+ case HASH_PUTNEW:
+ if (__addel(hashp, rbufp, key, val)) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (ERROR);
+ } else {
+ save_bufp->flags &= ~BUF_PIN;
+ return (SUCCESS);
+ }
+ case HASH_GET:
+ case HASH_DELETE:
+ default:
+ save_bufp->flags &= ~BUF_PIN;
+ return (ABNORMAL);
+ }
+
+found:
+ switch (action) {
+ case HASH_PUTNEW:
+ save_bufp->flags &= ~BUF_PIN;
+ return (ABNORMAL);
+ case HASH_GET:
+ bp = (u_int16_t *)rbufp->page;
+ if (bp[ndx + 1] < REAL_KEY) {
+ if (__big_return(hashp, rbufp, ndx, val, 0))
+ return (ERROR);
+ } else {
+ val->data = (u_char *)rbufp->page + (int)bp[ndx + 1];
+ val->size = bp[ndx] - bp[ndx + 1];
+ }
+ break;
+ case HASH_PUT:
+ if ((__delpair(hashp, rbufp, ndx)) ||
+ (__addel(hashp, rbufp, key, val))) {
+ save_bufp->flags &= ~BUF_PIN;
+ return (ERROR);
+ }
+ break;
+ case HASH_DELETE:
+ if (__delpair(hashp, rbufp, ndx))
+ return (ERROR);
+ break;
+ default:
+ abort();
+ }
+ save_bufp->flags &= ~BUF_PIN;
+ return (SUCCESS);
+}
+
+static int
+hash_seq(dbp, key, data, flag)
+ const DB *dbp;
+ DBT *key, *data;
+ u_int32_t flag;
+{
+ u_int32_t bucket;
+ BUFHEAD *bufp;
+ HTAB *hashp;
+ u_int16_t *bp, ndx;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag && flag != R_FIRST && flag != R_NEXT) {
+ hashp->error = errno = EINVAL;
+ return (ERROR);
+ }
+#ifdef HASH_STATISTICS
+ hash_accesses++;
+#endif
+ if ((hashp->cbucket < 0) || (flag == R_FIRST)) {
+ hashp->cbucket = 0;
+ hashp->cndx = 1;
+ hashp->cpage = NULL;
+ }
+
+ for (bp = NULL; !bp || !bp[0]; ) {
+ if (!(bufp = hashp->cpage)) {
+ for (bucket = hashp->cbucket;
+ bucket <= hashp->MAX_BUCKET;
+ bucket++, hashp->cndx = 1) {
+ bufp = __get_buf(hashp, bucket, NULL, 0);
+ if (!bufp)
+ return (ERROR);
+ hashp->cpage = bufp;
+ bp = (u_int16_t *)bufp->page;
+ if (bp[0])
+ break;
+ }
+ hashp->cbucket = bucket;
+ if (hashp->cbucket > hashp->MAX_BUCKET) {
+ hashp->cbucket = -1;
+ return (ABNORMAL);
+ }
+ } else
+ bp = (u_int16_t *)hashp->cpage->page;
+
+#ifdef DEBUG
+ assert(bp);
+ assert(bufp);
+#endif
+ while (bp[hashp->cndx + 1] == OVFLPAGE) {
+ bufp = hashp->cpage =
+ __get_buf(hashp, bp[hashp->cndx], bufp, 0);
+ if (!bufp)
+ return (ERROR);
+ bp = (u_int16_t *)(bufp->page);
+ hashp->cndx = 1;
+ }
+ if (!bp[0]) {
+ hashp->cpage = NULL;
+ ++hashp->cbucket;
+ }
+ }
+ ndx = hashp->cndx;
+ if (bp[ndx + 1] < REAL_KEY) {
+ if (__big_keydata(hashp, bufp, key, data, 1))
+ return (ERROR);
+ } else {
+ key->data = (u_char *)hashp->cpage->page + bp[ndx];
+ key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx];
+ data->data = (u_char *)hashp->cpage->page + bp[ndx + 1];
+ data->size = bp[ndx] - bp[ndx + 1];
+ ndx += 2;
+ if (ndx > bp[0]) {
+ hashp->cpage = NULL;
+ hashp->cbucket++;
+ hashp->cndx = 1;
+ } else
+ hashp->cndx = ndx;
+ }
+ return (SUCCESS);
+}
+
+/********************************* UTILITIES ************************/
+
+/*
+ * Returns:
+ * 0 ==> OK
+ * -1 ==> Error
+ */
+extern int
+__expand_table(hashp)
+ HTAB *hashp;
+{
+ u_int32_t old_bucket, new_bucket;
+ int dirsize, new_segnum, spare_ndx;
+
+#ifdef HASH_STATISTICS
+ hash_expansions++;
+#endif
+ new_bucket = ++hashp->MAX_BUCKET;
+ old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK);
+
+ new_segnum = new_bucket >> hashp->SSHIFT;
+
+ /* Check if we need a new segment */
+ if (new_segnum >= hashp->nsegs) {
+ /* Check if we need to expand directory */
+ if (new_segnum >= hashp->DSIZE) {
+ /* Reallocate directory */
+ dirsize = hashp->DSIZE * sizeof(SEGMENT *);
+ if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1))
+ return (-1);
+ hashp->DSIZE = dirsize << 1;
+ }
+ if ((hashp->dir[new_segnum] =
+ (SEGMENT)calloc(hashp->SGSIZE, sizeof(SEGMENT))) == NULL)
+ return (-1);
+ hashp->exsegs++;
+ hashp->nsegs++;
+ }
+ /*
+ * If the split point is increasing (MAX_BUCKET's log base 2
+ * * increases), we need to copy the current contents of the spare
+ * split bucket to the next bucket.
+ */
+ spare_ndx = __log2(hashp->MAX_BUCKET + 1);
+ if (spare_ndx > hashp->OVFL_POINT) {
+ hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];
+ hashp->OVFL_POINT = spare_ndx;
+ }
+
+ if (new_bucket > hashp->HIGH_MASK) {
+ /* Starting a new doubling */
+ hashp->LOW_MASK = hashp->HIGH_MASK;
+ hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK;
+ }
+ /* Relocate records to the new bucket */
+ return (__split_page(hashp, old_bucket, new_bucket));
+}
+
+/*
+ * If realloc guarantees that the pointer is not destroyed if the realloc
+ * fails, then this routine can go away.
+ */
+static void *
+hash_realloc(p_ptr, oldsize, newsize)
+ SEGMENT **p_ptr;
+ int oldsize, newsize;
+{
+ void *p;
+
+ if ( (p = malloc(newsize)) ) {
+ memmove(p, *p_ptr, oldsize);
+ memset((char *)p + oldsize, 0, newsize - oldsize);
+ free(*p_ptr);
+ *p_ptr = p;
+ }
+ return (p);
+}
+
+extern u_int32_t
+__call_hash(hashp, k, len)
+ HTAB *hashp;
+ char *k;
+ int len;
+{
+ int n, bucket;
+
+ n = hashp->hash(k, len);
+ bucket = n & hashp->HIGH_MASK;
+ if (bucket > hashp->MAX_BUCKET)
+ bucket = bucket & hashp->LOW_MASK;
+ return (bucket);
+}
+
+/*
+ * Allocate segment table. On error, destroy the table and set errno.
+ *
+ * Returns 0 on success
+ */
+static int
+alloc_segs(hashp, nsegs)
+ HTAB *hashp;
+ int nsegs;
+{
+ int i;
+ SEGMENT store;
+
+ int save_errno;
+
+ if ((hashp->dir =
+ (SEGMENT *)calloc(hashp->DSIZE, sizeof(SEGMENT *))) == NULL) {
+ save_errno = errno;
+ (void)hdestroy(hashp);
+ errno = save_errno;
+ return (-1);
+ }
+ /* Allocate segments */
+ if ((store =
+ (SEGMENT)calloc(nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) {
+ save_errno = errno;
+ (void)hdestroy(hashp);
+ errno = save_errno;
+ return (-1);
+ }
+ for (i = 0; i < nsegs; i++, hashp->nsegs++)
+ hashp->dir[i] = &store[i << hashp->SSHIFT];
+ return (0);
+}
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+/*
+ * Hashp->hdr needs to be byteswapped.
+ */
+static void
+swap_header_copy(srcp, destp)
+ HASHHDR *srcp, *destp;
+{
+ int i;
+
+ P_32_COPY(srcp->magic, destp->magic);
+ P_32_COPY(srcp->version, destp->version);
+ P_32_COPY(srcp->lorder, destp->lorder);
+ P_32_COPY(srcp->bsize, destp->bsize);
+ P_32_COPY(srcp->bshift, destp->bshift);
+ P_32_COPY(srcp->dsize, destp->dsize);
+ P_32_COPY(srcp->ssize, destp->ssize);
+ P_32_COPY(srcp->sshift, destp->sshift);
+ P_32_COPY(srcp->ovfl_point, destp->ovfl_point);
+ P_32_COPY(srcp->last_freed, destp->last_freed);
+ P_32_COPY(srcp->max_bucket, destp->max_bucket);
+ P_32_COPY(srcp->high_mask, destp->high_mask);
+ P_32_COPY(srcp->low_mask, destp->low_mask);
+ P_32_COPY(srcp->ffactor, destp->ffactor);
+ P_32_COPY(srcp->nkeys, destp->nkeys);
+ P_32_COPY(srcp->hdrpages, destp->hdrpages);
+ P_32_COPY(srcp->h_charkey, destp->h_charkey);
+ for (i = 0; i < NCACHED; i++) {
+ P_32_COPY(srcp->spares[i], destp->spares[i]);
+ P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]);
+ }
+}
+
+static void
+swap_header(hashp)
+ HTAB *hashp;
+{
+ HASHHDR *hdrp;
+ int i;
+
+ hdrp = &hashp->hdr;
+
+ M_32_SWAP(hdrp->magic);
+ M_32_SWAP(hdrp->version);
+ M_32_SWAP(hdrp->lorder);
+ M_32_SWAP(hdrp->bsize);
+ M_32_SWAP(hdrp->bshift);
+ M_32_SWAP(hdrp->dsize);
+ M_32_SWAP(hdrp->ssize);
+ M_32_SWAP(hdrp->sshift);
+ M_32_SWAP(hdrp->ovfl_point);
+ M_32_SWAP(hdrp->last_freed);
+ M_32_SWAP(hdrp->max_bucket);
+ M_32_SWAP(hdrp->high_mask);
+ M_32_SWAP(hdrp->low_mask);
+ M_32_SWAP(hdrp->ffactor);
+ M_32_SWAP(hdrp->nkeys);
+ M_32_SWAP(hdrp->hdrpages);
+ M_32_SWAP(hdrp->h_charkey);
+ for (i = 0; i < NCACHED; i++) {
+ M_32_SWAP(hdrp->spares[i]);
+ M_16_SWAP(hdrp->bitmaps[i]);
+ }
+}
+#endif
--- /dev/null
+--- hash.c.orig Thu Mar 21 14:46:26 2002
++++ hash.c Sat Oct 18 18:30:33 2003
+@@ -58,7 +58,7 @@
+ #include <db.h>
+ #include "hash.h"
+ #include "page.h"
+-#include "extern.h"
++#include "hash_extern.h"
+
+ static int alloc_segs(HTAB *, int);
+ static int flush_meta(HTAB *);
--- /dev/null
+/*-
+ * 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
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)hash.h 8.3 (Berkeley) 5/31/94
+ * $FreeBSD: src/lib/libc/db/hash/hash.h,v 1.6 2002/03/21 22:46:26 obrien Exp $
+ */
+
+/* Operations */
+typedef enum {
+ HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE, HASH_FIRST, HASH_NEXT
+} ACTION;
+
+/* Buffer Management structures */
+typedef struct _bufhead BUFHEAD;
+
+struct _bufhead {
+ BUFHEAD *prev; /* LRU links */
+ BUFHEAD *next; /* LRU links */
+ BUFHEAD *ovfl; /* Overflow page buffer header */
+ u_int32_t addr; /* Address of this page */
+ char *page; /* Actual page data */
+ char flags;
+#define BUF_MOD 0x0001
+#define BUF_DISK 0x0002
+#define BUF_BUCKET 0x0004
+#define BUF_PIN 0x0008
+};
+
+#define IS_BUCKET(X) ((X) & BUF_BUCKET)
+
+typedef BUFHEAD **SEGMENT;
+
+/* Hash Table Information */
+typedef struct hashhdr { /* Disk resident portion */
+ int magic; /* Magic NO for hash tables */
+ int version; /* Version ID */
+ u_int32_t lorder; /* Byte Order */
+ int bsize; /* Bucket/Page Size */
+ int bshift; /* Bucket shift */
+ int dsize; /* Directory Size */
+ int ssize; /* Segment Size */
+ int sshift; /* Segment shift */
+ int ovfl_point; /* Where overflow pages are being
+ * allocated */
+ int last_freed; /* Last overflow page freed */
+ int max_bucket; /* ID of Maximum bucket in use */
+ int high_mask; /* Mask to modulo into entire table */
+ int low_mask; /* Mask to modulo into lower half of
+ * table */
+ int ffactor; /* Fill factor */
+ int nkeys; /* Number of keys in hash table */
+ int hdrpages; /* Size of table header */
+ int h_charkey; /* value of hash(CHARKEY) */
+#define NCACHED 32 /* number of bit maps and spare
+ * points */
+ int spares[NCACHED];/* spare pages for overflow */
+ u_int16_t bitmaps[NCACHED]; /* address of overflow page
+ * bitmaps */
+} HASHHDR;
+
+typedef struct htab { /* Memory resident data structure */
+ HASHHDR hdr; /* Header */
+ int nsegs; /* Number of allocated segments */
+ int exsegs; /* Number of extra allocated
+ * segments */
+ u_int32_t /* Hash function */
+ (*hash)(const void *, size_t);
+ int flags; /* Flag values */
+ int fp; /* File pointer */
+ char *tmp_buf; /* Temporary Buffer for BIG data */
+ char *tmp_key; /* Temporary Buffer for BIG keys */
+ BUFHEAD *cpage; /* Current page */
+ int cbucket; /* Current bucket */
+ int cndx; /* Index of next item on cpage */
+ int error; /* Error Number -- for DBM
+ * compatibility */
+ int new_file; /* Indicates if fd is backing store
+ * or no */
+ int save_file; /* Indicates whether we need to flush
+ * file at
+ * exit */
+ u_int32_t *mapp[NCACHED]; /* Pointers to page maps */
+ int nmaps; /* Initial number of bitmaps */
+ int nbufs; /* Number of buffers left to
+ * allocate */
+ BUFHEAD bufhead; /* Header of buffer lru list */
+ SEGMENT *dir; /* Hash Bucket directory */
+} HTAB;
+
+/*
+ * Constants
+ */
+#define MAX_BSIZE 65536 /* 2^16 */
+#define MIN_BUFFERS 6
+#define MINHDRSIZE 512
+#define DEF_BUFSIZE 65536 /* 64 K */
+#define DEF_BUCKET_SIZE 4096
+#define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */
+#define DEF_SEGSIZE 256
+#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */
+#define DEF_DIRSIZE 256
+#define DEF_FFACTOR 65536
+#define MIN_FFACTOR 4
+#define SPLTMAX 8
+#define CHARKEY "%$sniglet^&"
+#define NUMKEY 1038583
+#define BYTE_SHIFT 3
+#define INT_TO_BYTE 2
+#define INT_BYTE_SHIFT 5
+#define ALL_SET ((u_int32_t)0xFFFFFFFF)
+#define ALL_CLEAR 0
+
+#define PTROF(X) ((BUFHEAD *)((ptrdiff_t)(X)&~0x3))
+#define ISMOD(X) ((u_int32_t)(ptrdiff_t)(X)&0x1)
+#define DOMOD(X) ((X) = (char *)((ptrdiff_t)(X)|0x1))
+#define ISDISK(X) ((u_int32_t)(ptrdiff_t)(X)&0x2)
+#define DODISK(X) ((X) = (char *)((ptrdiff_t)(X)|0x2))
+
+#define BITS_PER_MAP 32
+
+/* Given the address of the beginning of a big map, clear/set the nth bit */
+#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP)))
+#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP)))
+#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP)))
+
+/* Overflow management */
+/*
+ * Overflow page numbers are allocated per split point. At each doubling of
+ * the table, we can allocate extra pages. So, an overflow page number has
+ * the top 5 bits indicate which split point and the lower 11 bits indicate
+ * which page at that split point is indicated (pages within split points are
+ * numberered starting with 1).
+ */
+
+#define SPLITSHIFT 11
+#define SPLITMASK 0x7FF
+#define SPLITNUM(N) (((u_int32_t)(N)) >> SPLITSHIFT)
+#define OPAGENUM(N) ((N) & SPLITMASK)
+#define OADDR_OF(S,O) ((u_int32_t)((u_int32_t)(S) << SPLITSHIFT) + (O))
+
+#define BUCKET_TO_PAGE(B) \
+ (B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__log2((B)+1)-1] : 0)
+#define OADDR_TO_PAGE(B) \
+ BUCKET_TO_PAGE ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B));
+
+/*
+ * page.h contains a detailed description of the page format.
+ *
+ * Normally, keys and data are accessed from offset tables in the top of
+ * each page which point to the beginning of the key and data. There are
+ * four flag values which may be stored in these offset tables which indicate
+ * the following:
+ *
+ *
+ * OVFLPAGE Rather than a key data pair, this pair contains
+ * the address of an overflow page. The format of
+ * the pair is:
+ * OVERFLOW_PAGE_NUMBER OVFLPAGE
+ *
+ * PARTIAL_KEY This must be the first key/data pair on a page
+ * and implies that page contains only a partial key.
+ * That is, the key is too big to fit on a single page
+ * so it starts on this page and continues on the next.
+ * The format of the page is:
+ * KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE
+ *
+ * KEY_OFF -- offset of the beginning of the key
+ * PARTIAL_KEY -- 1
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
+ *
+ * FULL_KEY This must be the first key/data pair on the page. It
+ * is used in two cases.
+ *
+ * Case 1:
+ * There is a complete key on the page but no data
+ * (because it wouldn't fit). The next page contains
+ * the data.
+ *
+ * Page format it:
+ * KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
+ *
+ * KEY_OFF -- offset of the beginning of the key
+ * FULL_KEY -- 2
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
+ *
+ * Case 2:
+ * This page contains no key, but part of a large
+ * data field, which is continued on the next page.
+ *
+ * Page format it:
+ * DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
+ *
+ * KEY_OFF -- offset of the beginning of the data on
+ * this page
+ * FULL_KEY -- 2
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
+ *
+ * FULL_KEY_DATA
+ * This must be the first key/data pair on the page.
+ * There are two cases:
+ *
+ * Case 1:
+ * This page contains a key and the beginning of the
+ * data field, but the data field is continued on the
+ * next page.
+ *
+ * Page format is:
+ * KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF
+ *
+ * KEY_OFF -- offset of the beginning of the key
+ * FULL_KEY_DATA -- 3
+ * OVFL_PAGENO - page number of the next overflow page
+ * DATA_OFF -- offset of the beginning of the data
+ *
+ * Case 2:
+ * This page contains the last page of a big data pair.
+ * There is no key, only the tail end of the data
+ * on this page.
+ *
+ * Page format is:
+ * DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE>
+ *
+ * DATA_OFF -- offset of the beginning of the data on
+ * this page
+ * FULL_KEY_DATA -- 3
+ * OVFL_PAGENO - page number of the next overflow page
+ * OVFLPAGE -- 0
+ *
+ * OVFL_PAGENO and OVFLPAGE are optional (they are
+ * not present if there is no next page).
+ */
+
+#define OVFLPAGE 0
+#define PARTIAL_KEY 1
+#define FULL_KEY 2
+#define FULL_KEY_DATA 3
+#define REAL_KEY 4
+
+/* Short hands for accessing structure */
+#define BSIZE hdr.bsize
+#define BSHIFT hdr.bshift
+#define DSIZE hdr.dsize
+#define SGSIZE hdr.ssize
+#define SSHIFT hdr.sshift
+#define LORDER hdr.lorder
+#define OVFL_POINT hdr.ovfl_point
+#define LAST_FREED hdr.last_freed
+#define MAX_BUCKET hdr.max_bucket
+#define FFACTOR hdr.ffactor
+#define HIGH_MASK hdr.high_mask
+#define LOW_MASK hdr.low_mask
+#define NKEYS hdr.nkeys
+#define HDRPAGES hdr.hdrpages
+#define SPARES hdr.spares
+#define BITMAPS hdr.bitmaps
+#define VERSION hdr.version
+#define MAGIC hdr.magic
+#define NEXT_FREE hdr.next_free
+#define H_CHARKEY hdr.h_charkey
--- /dev/null
+/*-
+ * 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
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_bigkey.c,v 1.5 2003/02/16 17:29:09 nectar Exp $");
+
+/*
+ * PACKAGE: hash
+ * DESCRIPTION:
+ * Big key/data handling for the hashing package.
+ *
+ * ROUTINES:
+ * External
+ * __big_keydata
+ * __big_split
+ * __big_insert
+ * __big_return
+ * __big_delete
+ * __find_last_page
+ * Internal
+ * collect_key
+ * collect_data
+ */
+
+#include <sys/param.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef DEBUG
+#include <assert.h>
+#endif
+
+#include <db.h>
+#include "hash.h"
+#include "page.h"
+#include "extern.h"
+
+static int collect_key(HTAB *, BUFHEAD *, int, DBT *, int);
+static int collect_data(HTAB *, BUFHEAD *, int, int);
+
+/*
+ * Big_insert
+ *
+ * You need to do an insert and the key/data pair is too big
+ *
+ * Returns:
+ * 0 ==> OK
+ *-1 ==> ERROR
+ */
+extern int
+__big_insert(hashp, bufp, key, val)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ const DBT *key, *val;
+{
+ u_int16_t *p;
+ int key_size, n, val_size;
+ u_int16_t space, move_bytes, off;
+ char *cp, *key_data, *val_data;
+
+ cp = bufp->page; /* Character pointer of p. */
+ p = (u_int16_t *)cp;
+
+ key_data = (char *)key->data;
+ key_size = key->size;
+ val_data = (char *)val->data;
+ val_size = val->size;
+
+ /* First move the Key */
+ for (space = FREESPACE(p) - BIGOVERHEAD; key_size;
+ space = FREESPACE(p) - BIGOVERHEAD) {
+ move_bytes = MIN(space, key_size);
+ off = OFFSET(p) - move_bytes;
+ memmove(cp + off, key_data, move_bytes);
+ key_size -= move_bytes;
+ key_data += move_bytes;
+ n = p[0];
+ p[++n] = off;
+ p[0] = ++n;
+ FREESPACE(p) = off - PAGE_META(n);
+ OFFSET(p) = off;
+ p[n] = PARTIAL_KEY;
+ bufp = __add_ovflpage(hashp, bufp);
+ if (!bufp)
+ return (-1);
+ n = p[0];
+ if (!key_size) {
+ if (FREESPACE(p)) {
+ move_bytes = MIN(FREESPACE(p), val_size);
+ off = OFFSET(p) - move_bytes;
+ p[n] = off;
+ memmove(cp + off, val_data, move_bytes);
+ val_data += move_bytes;
+ val_size -= move_bytes;
+ p[n - 2] = FULL_KEY_DATA;
+ FREESPACE(p) = FREESPACE(p) - move_bytes;
+ OFFSET(p) = off;
+ } else
+ p[n - 2] = FULL_KEY;
+ }
+ p = (u_int16_t *)bufp->page;
+ cp = bufp->page;
+ bufp->flags |= BUF_MOD;
+ }
+
+ /* Now move the data */
+ for (space = FREESPACE(p) - BIGOVERHEAD; val_size;
+ space = FREESPACE(p) - BIGOVERHEAD) {
+ move_bytes = MIN(space, val_size);
+ /*
+ * Here's the hack to make sure that if the data ends on the
+ * same page as the key ends, FREESPACE is at least one.
+ */
+ if (space == val_size && val_size == val->size)
+ move_bytes--;
+ off = OFFSET(p) - move_bytes;
+ memmove(cp + off, val_data, move_bytes);
+ val_size -= move_bytes;
+ val_data += move_bytes;
+ n = p[0];
+ p[++n] = off;
+ p[0] = ++n;
+ FREESPACE(p) = off - PAGE_META(n);
+ OFFSET(p) = off;
+ if (val_size) {
+ p[n] = FULL_KEY;
+ bufp = __add_ovflpage(hashp, bufp);
+ if (!bufp)
+ return (-1);
+ cp = bufp->page;
+ p = (u_int16_t *)cp;
+ } else
+ p[n] = FULL_KEY_DATA;
+ bufp->flags |= BUF_MOD;
+ }
+ return (0);
+}
+
+/*
+ * Called when bufp's page contains a partial key (index should be 1)
+ *
+ * All pages in the big key/data pair except bufp are freed. We cannot
+ * free bufp because the page pointing to it is lost and we can't get rid
+ * of its pointer.
+ *
+ * Returns:
+ * 0 => OK
+ *-1 => ERROR
+ */
+extern int
+__big_delete(hashp, bufp)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+{
+ BUFHEAD *last_bfp, *rbufp;
+ u_int16_t *bp, pageno;
+ int key_done, n;
+
+ rbufp = bufp;
+ last_bfp = NULL;
+ bp = (u_int16_t *)bufp->page;
+ pageno = 0;
+ key_done = 0;
+
+ while (!key_done || (bp[2] != FULL_KEY_DATA)) {
+ if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA)
+ key_done = 1;
+
+ /*
+ * If there is freespace left on a FULL_KEY_DATA page, then
+ * the data is short and fits entirely on this page, and this
+ * is the last page.
+ */
+ if (bp[2] == FULL_KEY_DATA && FREESPACE(bp))
+ break;
+ pageno = bp[bp[0] - 1];
+ rbufp->flags |= BUF_MOD;
+ rbufp = __get_buf(hashp, pageno, rbufp, 0);
+ if (last_bfp)
+ __free_ovflpage(hashp, last_bfp);
+ last_bfp = rbufp;
+ if (!rbufp)
+ return (-1); /* Error. */
+ bp = (u_int16_t *)rbufp->page;
+ }
+
+ /*
+ * If we get here then rbufp points to the last page of the big
+ * key/data pair. Bufp points to the first one -- it should now be
+ * empty pointing to the next page after this pair. Can't free it
+ * because we don't have the page pointing to it.
+ */
+
+ /* This is information from the last page of the pair. */
+ n = bp[0];
+ pageno = bp[n - 1];
+
+ /* Now, bp is the first page of the pair. */
+ bp = (u_int16_t *)bufp->page;
+ if (n > 2) {
+ /* There is an overflow page. */
+ bp[1] = pageno;
+ bp[2] = OVFLPAGE;
+ bufp->ovfl = rbufp->ovfl;
+ } else
+ /* This is the last page. */
+ bufp->ovfl = NULL;
+ n -= 2;
+ bp[0] = n;
+ FREESPACE(bp) = hashp->BSIZE - PAGE_META(n);
+ OFFSET(bp) = hashp->BSIZE - 1;
+
+ bufp->flags |= BUF_MOD;
+ if (rbufp)
+ __free_ovflpage(hashp, rbufp);
+ if (last_bfp != rbufp)
+ __free_ovflpage(hashp, last_bfp);
+
+ hashp->NKEYS--;
+ return (0);
+}
+/*
+ * Returns:
+ * 0 = key not found
+ * -1 = get next overflow page
+ * -2 means key not found and this is big key/data
+ * -3 error
+ */
+extern int
+__find_bigpair(hashp, bufp, ndx, key, size)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ int ndx;
+ char *key;
+ int size;
+{
+ u_int16_t *bp;
+ char *p;
+ int ksize;
+ u_int16_t bytes;
+ char *kkey;
+
+ bp = (u_int16_t *)bufp->page;
+ p = bufp->page;
+ ksize = size;
+ kkey = key;
+
+ for (bytes = hashp->BSIZE - bp[ndx];
+ bytes <= size && bp[ndx + 1] == PARTIAL_KEY;
+ bytes = hashp->BSIZE - bp[ndx]) {
+ if (memcmp(p + bp[ndx], kkey, bytes))
+ return (-2);
+ kkey += bytes;
+ ksize -= bytes;
+ bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0);
+ if (!bufp)
+ return (-3);
+ p = bufp->page;
+ bp = (u_int16_t *)p;
+ ndx = 1;
+ }
+
+ if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) {
+#ifdef HASH_STATISTICS
+ ++hash_collisions;
+#endif
+ return (-2);
+ } else
+ return (ndx);
+}
+
+/*
+ * Given the buffer pointer of the first overflow page of a big pair,
+ * find the end of the big pair
+ *
+ * This will set bpp to the buffer header of the last page of the big pair.
+ * It will return the pageno of the overflow page following the last page
+ * of the pair; 0 if there isn't any (i.e. big pair is the last key in the
+ * bucket)
+ */
+extern u_int16_t
+__find_last_page(hashp, bpp)
+ HTAB *hashp;
+ BUFHEAD **bpp;
+{
+ BUFHEAD *bufp;
+ u_int16_t *bp, pageno;
+ int n;
+
+ bufp = *bpp;
+ bp = (u_int16_t *)bufp->page;
+ for (;;) {
+ n = bp[0];
+
+ /*
+ * This is the last page if: the tag is FULL_KEY_DATA and
+ * either only 2 entries OVFLPAGE marker is explicit there
+ * is freespace on the page.
+ */
+ if (bp[2] == FULL_KEY_DATA &&
+ ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp))))
+ break;
+
+ pageno = bp[n - 1];
+ bufp = __get_buf(hashp, pageno, bufp, 0);
+ if (!bufp)
+ return (0); /* Need to indicate an error! */
+ bp = (u_int16_t *)bufp->page;
+ }
+
+ *bpp = bufp;
+ if (bp[0] > 2)
+ return (bp[3]);
+ else
+ return (0);
+}
+
+/*
+ * Return the data for the key/data pair that begins on this page at this
+ * index (index should always be 1).
+ */
+extern int
+__big_return(hashp, bufp, ndx, val, set_current)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ int ndx;
+ DBT *val;
+ int set_current;
+{
+ BUFHEAD *save_p;
+ u_int16_t *bp, len, off, save_addr;
+ char *tp;
+
+ bp = (u_int16_t *)bufp->page;
+ while (bp[ndx + 1] == PARTIAL_KEY) {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (u_int16_t *)bufp->page;
+ ndx = 1;
+ }
+
+ if (bp[ndx + 1] == FULL_KEY) {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (u_int16_t *)bufp->page;
+ save_p = bufp;
+ save_addr = save_p->addr;
+ off = bp[1];
+ len = 0;
+ } else
+ if (!FREESPACE(bp)) {
+ /*
+ * This is a hack. We can't distinguish between
+ * FULL_KEY_DATA that contains complete data or
+ * incomplete data, so we require that if the data
+ * is complete, there is at least 1 byte of free
+ * space left.
+ */
+ off = bp[bp[0]];
+ len = bp[1] - off;
+ save_p = bufp;
+ save_addr = bufp->addr;
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (u_int16_t *)bufp->page;
+ } else {
+ /* The data is all on one page. */
+ tp = (char *)bp;
+ off = bp[bp[0]];
+ val->data = (u_char *)tp + off;
+ val->size = bp[1] - off;
+ if (set_current) {
+ if (bp[0] == 2) { /* No more buckets in
+ * chain */
+ hashp->cpage = NULL;
+ hashp->cbucket++;
+ hashp->cndx = 1;
+ } else {
+ hashp->cpage = __get_buf(hashp,
+ bp[bp[0] - 1], bufp, 0);
+ if (!hashp->cpage)
+ return (-1);
+ hashp->cndx = 1;
+ if (!((u_int16_t *)
+ hashp->cpage->page)[0]) {
+ hashp->cbucket++;
+ hashp->cpage = NULL;
+ }
+ }
+ }
+ return (0);
+ }
+
+ val->size = collect_data(hashp, bufp, (int)len, set_current);
+ if (val->size == -1)
+ return (-1);
+ if (save_p->addr != save_addr) {
+ /* We are pretty short on buffers. */
+ errno = EINVAL; /* OUT OF BUFFERS */
+ return (-1);
+ }
+ memmove(hashp->tmp_buf, (save_p->page) + off, len);
+ val->data = (u_char *)hashp->tmp_buf;
+ return (0);
+}
+/*
+ * Count how big the total datasize is by recursing through the pages. Then
+ * allocate a buffer and copy the data as you recurse up.
+ */
+static int
+collect_data(hashp, bufp, len, set)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ int len, set;
+{
+ u_int16_t *bp;
+ char *p;
+ BUFHEAD *xbp;
+ u_int16_t save_addr;
+ int mylen, totlen;
+
+ p = bufp->page;
+ bp = (u_int16_t *)p;
+ mylen = hashp->BSIZE - bp[1];
+ save_addr = bufp->addr;
+
+ if (bp[2] == FULL_KEY_DATA) { /* End of Data */
+ totlen = len + mylen;
+ if (hashp->tmp_buf)
+ free(hashp->tmp_buf);
+ if ((hashp->tmp_buf = (char *)malloc(totlen)) == NULL)
+ return (-1);
+ if (set) {
+ hashp->cndx = 1;
+ if (bp[0] == 2) { /* No more buckets in chain */
+ hashp->cpage = NULL;
+ hashp->cbucket++;
+ } else {
+ hashp->cpage =
+ __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!hashp->cpage)
+ return (-1);
+ else if (!((u_int16_t *)hashp->cpage->page)[0]) {
+ hashp->cbucket++;
+ hashp->cpage = NULL;
+ }
+ }
+ }
+ } else {
+ xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!xbp || ((totlen =
+ collect_data(hashp, xbp, len + mylen, set)) < 1))
+ return (-1);
+ }
+ if (bufp->addr != save_addr) {
+ errno = EINVAL; /* Out of buffers. */
+ return (-1);
+ }
+ memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], mylen);
+ return (totlen);
+}
+
+/*
+ * Fill in the key and data for this big pair.
+ */
+extern int
+__big_keydata(hashp, bufp, key, val, set)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ DBT *key, *val;
+ int set;
+{
+ key->size = collect_key(hashp, bufp, 0, val, set);
+ if (key->size == -1)
+ return (-1);
+ key->data = (u_char *)hashp->tmp_key;
+ return (0);
+}
+
+/*
+ * Count how big the total key size is by recursing through the pages. Then
+ * collect the data, allocate a buffer and copy the key as you recurse up.
+ */
+static int
+collect_key(hashp, bufp, len, val, set)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ int len;
+ DBT *val;
+ int set;
+{
+ BUFHEAD *xbp;
+ char *p;
+ int mylen, totlen;
+ u_int16_t *bp, save_addr;
+
+ p = bufp->page;
+ bp = (u_int16_t *)p;
+ mylen = hashp->BSIZE - bp[1];
+
+ save_addr = bufp->addr;
+ totlen = len + mylen;
+ if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */
+ if (hashp->tmp_key != NULL)
+ free(hashp->tmp_key);
+ if ((hashp->tmp_key = (char *)malloc(totlen)) == NULL)
+ return (-1);
+ if (__big_return(hashp, bufp, 1, val, set))
+ return (-1);
+ } else {
+ xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!xbp || ((totlen =
+ collect_key(hashp, xbp, totlen, val, set)) < 1))
+ return (-1);
+ }
+ if (bufp->addr != save_addr) {
+ errno = EINVAL; /* MIS -- OUT OF BUFFERS */
+ return (-1);
+ }
+ memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], mylen);
+ return (totlen);
+}
+
+/*
+ * Returns:
+ * 0 => OK
+ * -1 => error
+ */
+extern int
+__big_split(hashp, op, np, big_keyp, addr, obucket, ret)
+ HTAB *hashp;
+ BUFHEAD *op; /* Pointer to where to put keys that go in old bucket */
+ BUFHEAD *np; /* Pointer to new bucket page */
+ /* Pointer to first page containing the big key/data */
+ BUFHEAD *big_keyp;
+ int addr; /* Address of big_keyp */
+ u_int32_t obucket;/* Old Bucket */
+ SPLIT_RETURN *ret;
+{
+ BUFHEAD *tmpp;
+ u_int16_t *tp;
+ BUFHEAD *bp;
+ DBT key, val;
+ u_int32_t change;
+ u_int16_t free_space, n, off;
+
+ bp = big_keyp;
+
+ /* Now figure out where the big key/data goes */
+ if (__big_keydata(hashp, big_keyp, &key, &val, 0))
+ return (-1);
+ change = (__call_hash(hashp, key.data, key.size) != obucket);
+
+ if ( (ret->next_addr = __find_last_page(hashp, &big_keyp)) ) {
+ if (!(ret->nextp =
+ __get_buf(hashp, ret->next_addr, big_keyp, 0)))
+ return (-1);;
+ } else
+ ret->nextp = NULL;
+
+ /* Now make one of np/op point to the big key/data pair */
+#ifdef DEBUG
+ assert(np->ovfl == NULL);
+#endif
+ if (change)
+ tmpp = np;
+ else
+ tmpp = op;
+
+ tmpp->flags |= BUF_MOD;
+#ifdef DEBUG1
+ (void)fprintf(stderr,
+ "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr,
+ (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0));
+#endif
+ tmpp->ovfl = bp; /* one of op/np point to big_keyp */
+ tp = (u_int16_t *)tmpp->page;
+#ifdef DEBUG
+ assert(FREESPACE(tp) >= OVFLSIZE);
+#endif
+ n = tp[0];
+ off = OFFSET(tp);
+ free_space = FREESPACE(tp);
+ tp[++n] = (u_int16_t)addr;
+ tp[++n] = OVFLPAGE;
+ tp[0] = n;
+ OFFSET(tp) = off;
+ FREESPACE(tp) = free_space - OVFLSIZE;
+
+ /*
+ * Finally, set the new and old return values. BIG_KEYP contains a
+ * pointer to the last page of the big key_data pair. Make sure that
+ * big_keyp has no following page (2 elements) or create an empty
+ * following page.
+ */
+
+ ret->newp = np;
+ ret->oldp = op;
+
+ tp = (u_int16_t *)big_keyp->page;
+ big_keyp->flags |= BUF_MOD;
+ if (tp[0] > 2) {
+ /*
+ * There may be either one or two offsets on this page. If
+ * there is one, then the overflow page is linked on normally
+ * and tp[4] is OVFLPAGE. If there are two, tp[4] contains
+ * the second offset and needs to get stuffed in after the
+ * next overflow page is added.
+ */
+ n = tp[4];
+ free_space = FREESPACE(tp);
+ off = OFFSET(tp);
+ tp[0] -= 2;
+ FREESPACE(tp) = free_space + OVFLSIZE;
+ OFFSET(tp) = off;
+ tmpp = __add_ovflpage(hashp, big_keyp);
+ if (!tmpp)
+ return (-1);
+ tp[4] = n;
+ } else
+ tmpp = big_keyp;
+
+ if (change)
+ ret->newp = tmpp;
+ else
+ ret->oldp = tmpp;
+ return (0);
+}
--- /dev/null
+--- hash_bigkey.c.orig Sun Feb 16 09:29:09 2003
++++ hash_bigkey.c Sat Oct 18 18:30:43 2003
+@@ -72,7 +72,7 @@
+ #include <db.h>
+ #include "hash.h"
+ #include "page.h"
+-#include "extern.h"
++#include "hash_extern.h"
+
+ static int collect_key(HTAB *, BUFHEAD *, int, DBT *, int);
+ static int collect_data(HTAB *, BUFHEAD *, int, int);
--- /dev/null
+/*-
+ * 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
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_buf.c,v 1.7 2002/03/21 22:46:26 obrien Exp $");
+
+/*
+ * PACKAGE: hash
+ *
+ * DESCRIPTION:
+ * Contains buffer management
+ *
+ * ROUTINES:
+ * External
+ * __buf_init
+ * __get_buf
+ * __buf_free
+ * __reclaim_buf
+ * Internal
+ * newbuf
+ */
+
+#include <sys/param.h>
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef DEBUG
+#include <assert.h>
+#endif
+
+#include <db.h>
+#include "hash.h"
+#include "page.h"
+#include "extern.h"
+
+static BUFHEAD *newbuf(HTAB *, u_int32_t, BUFHEAD *);
+
+/* Unlink B from its place in the lru */
+#define BUF_REMOVE(B) { \
+ (B)->prev->next = (B)->next; \
+ (B)->next->prev = (B)->prev; \
+}
+
+/* Insert B after P */
+#define BUF_INSERT(B, P) { \
+ (B)->next = (P)->next; \
+ (B)->prev = (P); \
+ (P)->next = (B); \
+ (B)->next->prev = (B); \
+}
+
+#define MRU hashp->bufhead.next
+#define LRU hashp->bufhead.prev
+
+#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead)
+#define LRU_INSERT(B) BUF_INSERT((B), LRU)
+
+/*
+ * We are looking for a buffer with address "addr". If prev_bp is NULL, then
+ * address is a bucket index. If prev_bp is not NULL, then it points to the
+ * page previous to an overflow page that we are trying to find.
+ *
+ * CAVEAT: The buffer header accessed via prev_bp's ovfl field may no longer
+ * be valid. Therefore, you must always verify that its address matches the
+ * address you are seeking.
+ */
+extern BUFHEAD *
+__get_buf(hashp, addr, prev_bp, newpage)
+ HTAB *hashp;
+ u_int32_t addr;
+ BUFHEAD *prev_bp;
+ int newpage; /* If prev_bp set, indicates a new overflow page. */
+{
+ BUFHEAD *bp;
+ u_int32_t is_disk_mask;
+ int is_disk, segment_ndx;
+ SEGMENT segp;
+
+ is_disk = 0;
+ is_disk_mask = 0;
+ if (prev_bp) {
+ bp = prev_bp->ovfl;
+ if (!bp || (bp->addr != addr))
+ bp = NULL;
+ if (!newpage)
+ is_disk = BUF_DISK;
+ } else {
+ /* Grab buffer out of directory */
+ segment_ndx = addr & (hashp->SGSIZE - 1);
+
+ /* valid segment ensured by __call_hash() */
+ segp = hashp->dir[addr >> hashp->SSHIFT];
+#ifdef DEBUG
+ assert(segp != NULL);
+#endif
+ bp = PTROF(segp[segment_ndx]);
+ is_disk_mask = ISDISK(segp[segment_ndx]);
+ is_disk = is_disk_mask || !hashp->new_file;
+ }
+
+ if (!bp) {
+ bp = newbuf(hashp, addr, prev_bp);
+ if (!bp ||
+ __get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0))
+ return (NULL);
+ if (!prev_bp)
+ segp[segment_ndx] =
+ (BUFHEAD *)((ptrdiff_t)bp | is_disk_mask);
+ } else {
+ BUF_REMOVE(bp);
+ MRU_INSERT(bp);
+ }
+ return (bp);
+}
+
+/*
+ * We need a buffer for this page. Either allocate one, or evict a resident
+ * one (if we have as many buffers as we're allowed) and put this one in.
+ *
+ * If newbuf finds an error (returning NULL), it also sets errno.
+ */
+static BUFHEAD *
+newbuf(hashp, addr, prev_bp)
+ HTAB *hashp;
+ u_int32_t addr;
+ BUFHEAD *prev_bp;
+{
+ BUFHEAD *bp; /* The buffer we're going to use */
+ BUFHEAD *xbp; /* Temp pointer */
+ BUFHEAD *next_xbp;
+ SEGMENT segp;
+ int segment_ndx;
+ u_int16_t oaddr, *shortp;
+
+ oaddr = 0;
+ bp = LRU;
+ /*
+ * If LRU buffer is pinned, the buffer pool is too small. We need to
+ * allocate more buffers.
+ */
+ if (hashp->nbufs || (bp->flags & BUF_PIN)) {
+ /* Allocate a new one */
+ if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL)
+ return (NULL);
+#ifdef PURIFY
+ memset(bp, 0xff, sizeof(BUFHEAD));
+#endif
+ if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) {
+ free(bp);
+ return (NULL);
+ }
+#ifdef PURIFY
+ memset(bp->page, 0xff, hashp->BSIZE);
+#endif
+ if (hashp->nbufs)
+ hashp->nbufs--;
+ } else {
+ /* Kick someone out */
+ BUF_REMOVE(bp);
+ /*
+ * If this is an overflow page with addr 0, it's already been
+ * flushed back in an overflow chain and initialized.
+ */
+ if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) {
+ /*
+ * Set oaddr before __put_page so that you get it
+ * before bytes are swapped.
+ */
+ shortp = (u_int16_t *)bp->page;
+ if (shortp[0])
+ oaddr = shortp[shortp[0] - 1];
+ if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page,
+ bp->addr, (int)IS_BUCKET(bp->flags), 0))
+ return (NULL);
+ /*
+ * Update the pointer to this page (i.e. invalidate it).
+ *
+ * If this is a new file (i.e. we created it at open
+ * time), make sure that we mark pages which have been
+ * written to disk so we retrieve them from disk later,
+ * rather than allocating new pages.
+ */
+ if (IS_BUCKET(bp->flags)) {
+ segment_ndx = bp->addr & (hashp->SGSIZE - 1);
+ segp = hashp->dir[bp->addr >> hashp->SSHIFT];
+#ifdef DEBUG
+ assert(segp != NULL);
+#endif
+
+ if (hashp->new_file &&
+ ((bp->flags & BUF_MOD) ||
+ ISDISK(segp[segment_ndx])))
+ segp[segment_ndx] = (BUFHEAD *)BUF_DISK;
+ else
+ segp[segment_ndx] = NULL;
+ }
+ /*
+ * Since overflow pages can only be access by means of
+ * their bucket, free overflow pages associated with
+ * this bucket.
+ */
+ for (xbp = bp; xbp->ovfl;) {
+ next_xbp = xbp->ovfl;
+ xbp->ovfl = 0;
+ xbp = next_xbp;
+
+ /* Check that ovfl pointer is up date. */
+ if (IS_BUCKET(xbp->flags) ||
+ (oaddr != xbp->addr))
+ break;
+
+ shortp = (u_int16_t *)xbp->page;
+ if (shortp[0])
+ /* set before __put_page */
+ oaddr = shortp[shortp[0] - 1];
+ if ((xbp->flags & BUF_MOD) && __put_page(hashp,
+ xbp->page, xbp->addr, 0, 0))
+ return (NULL);
+ xbp->addr = 0;
+ xbp->flags = 0;
+ BUF_REMOVE(xbp);
+ LRU_INSERT(xbp);
+ }
+ }
+ }
+
+ /* Now assign this buffer */
+ bp->addr = addr;
+#ifdef DEBUG1
+ (void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n",
+ bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0);
+#endif
+ bp->ovfl = NULL;
+ if (prev_bp) {
+ /*
+ * If prev_bp is set, this is an overflow page, hook it in to
+ * the buffer overflow links.
+ */
+#ifdef DEBUG1
+ (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n",
+ prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0),
+ (bp ? bp->addr : 0));
+#endif
+ prev_bp->ovfl = bp;
+ bp->flags = 0;
+ } else
+ bp->flags = BUF_BUCKET;
+ MRU_INSERT(bp);
+ return (bp);
+}
+
+extern void
+__buf_init(hashp, nbytes)
+ HTAB *hashp;
+ int nbytes;
+{
+ BUFHEAD *bfp;
+ int npages;
+
+ bfp = &(hashp->bufhead);
+ npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT;
+ npages = MAX(npages, MIN_BUFFERS);
+
+ hashp->nbufs = npages;
+ bfp->next = bfp;
+ bfp->prev = bfp;
+ /*
+ * This space is calloc'd so these are already null.
+ *
+ * bfp->ovfl = NULL;
+ * bfp->flags = 0;
+ * bfp->page = NULL;
+ * bfp->addr = 0;
+ */
+}
+
+extern int
+__buf_free(hashp, do_free, to_disk)
+ HTAB *hashp;
+ int do_free, to_disk;
+{
+ BUFHEAD *bp;
+
+ /* Need to make sure that buffer manager has been initialized */
+ if (!LRU)
+ return (0);
+ for (bp = LRU; bp != &hashp->bufhead;) {
+ /* Check that the buffer is valid */
+ if (bp->addr || IS_BUCKET(bp->flags)) {
+ if (to_disk && (bp->flags & BUF_MOD) &&
+ __put_page(hashp, bp->page,
+ bp->addr, IS_BUCKET(bp->flags), 0))
+ return (-1);
+ }
+ /* Check if we are freeing stuff */
+ if (do_free) {
+ if (bp->page)
+ free(bp->page);
+ BUF_REMOVE(bp);
+ free(bp);
+ bp = LRU;
+ } else
+ bp = bp->prev;
+ }
+ return (0);
+}
+
+extern void
+__reclaim_buf(hashp, bp)
+ HTAB *hashp;
+ BUFHEAD *bp;
+{
+ bp->ovfl = 0;
+ bp->addr = 0;
+ bp->flags = 0;
+ BUF_REMOVE(bp);
+ LRU_INSERT(bp);
+}
--- /dev/null
+--- hash_buf.c.orig Thu Mar 21 14:46:26 2002
++++ hash_buf.c Sat Oct 18 18:30:49 2003
+@@ -69,7 +69,7 @@
+ #include <db.h>
+ #include "hash.h"
+ #include "page.h"
+-#include "extern.h"
++#include "hash_extern.h"
+
+ static BUFHEAD *newbuf(HTAB *, u_int32_t, BUFHEAD *);
+
--- /dev/null
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_func.c,v 1.5 2003/02/16 17:29:09 nectar Exp $");
+
+#include <sys/types.h>
+
+#include <db.h>
+#include "hash.h"
+#include "page.h"
+#include "extern.h"
+
+static u_int32_t hash1(const void *, size_t) __unused;
+static u_int32_t hash2(const void *, size_t) __unused;
+static u_int32_t hash3(const void *, size_t) __unused;
+static u_int32_t hash4(const void *, size_t);
+
+/* Global default hash function */
+u_int32_t (*__default_hash)(const void *, size_t) = hash4;
+
+/*
+ * HASH FUNCTIONS
+ *
+ * Assume that we've already split the bucket to which this key hashes,
+ * calculate that bucket, and check that in fact we did already split it.
+ *
+ * This came from ejb's hsearch.
+ */
+
+#define PRIME1 37
+#define PRIME2 1048583
+
+static u_int32_t
+hash1(keyarg, len)
+ const void *keyarg;
+ size_t len;
+{
+ const u_char *key;
+ u_int32_t h;
+
+ /* Convert string to integer */
+ for (key = keyarg, h = 0; len--;)
+ h = h * PRIME1 ^ (*key++ - ' ');
+ h %= PRIME2;
+ return (h);
+}
+
+/*
+ * Phong's linear congruential hash
+ */
+#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
+
+static u_int32_t
+hash2(keyarg, len)
+ const void *keyarg;
+ size_t len;
+{
+ const u_char *e, *key;
+ u_int32_t h;
+ u_char c;
+
+ key = keyarg;
+ e = key + len;
+ for (h = 0; key != e;) {
+ c = *key++;
+ if (!c && key > e)
+ break;
+ dcharhash(h, c);
+ }
+ return (h);
+}
+
+/*
+ * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte
+ * units. On the first time through the loop we get the "leftover bytes"
+ * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle
+ * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If
+ * this routine is heavily used enough, it's worth the ugly coding.
+ *
+ * OZ's original sdbm hash
+ */
+static u_int32_t
+hash3(keyarg, len)
+ const void *keyarg;
+ size_t len;
+{
+ const u_char *key;
+ size_t loop;
+ u_int32_t h;
+
+#define HASHC h = *key++ + 65599 * h
+
+ h = 0;
+ key = keyarg;
+ if (len > 0) {
+ loop = (len + 8 - 1) >> 3;
+
+ switch (len & (8 - 1)) {
+ case 0:
+ do {
+ HASHC;
+ /* FALLTHROUGH */
+ case 7:
+ HASHC;
+ /* FALLTHROUGH */
+ case 6:
+ HASHC;
+ /* FALLTHROUGH */
+ case 5:
+ HASHC;
+ /* FALLTHROUGH */
+ case 4:
+ HASHC;
+ /* FALLTHROUGH */
+ case 3:
+ HASHC;
+ /* FALLTHROUGH */
+ case 2:
+ HASHC;
+ /* FALLTHROUGH */
+ case 1:
+ HASHC;
+ } while (--loop);
+ }
+ }
+ return (h);
+}
+
+/* Hash function from Chris Torek. */
+static u_int32_t
+hash4(keyarg, len)
+ const void *keyarg;
+ size_t len;
+{
+ const u_char *key;
+ size_t loop;
+ u_int32_t h;
+
+#define HASH4a h = (h << 5) - h + *key++;
+#define HASH4b h = (h << 5) + h + *key++;
+#define HASH4 HASH4b
+
+ h = 0;
+ key = keyarg;
+ if (len > 0) {
+ loop = (len + 8 - 1) >> 3;
+
+ switch (len & (8 - 1)) {
+ case 0:
+ do {
+ HASH4;
+ /* FALLTHROUGH */
+ case 7:
+ HASH4;
+ /* FALLTHROUGH */
+ case 6:
+ HASH4;
+ /* FALLTHROUGH */
+ case 5:
+ HASH4;
+ /* FALLTHROUGH */
+ case 4:
+ HASH4;
+ /* FALLTHROUGH */
+ case 3:
+ HASH4;
+ /* FALLTHROUGH */
+ case 2:
+ HASH4;
+ /* FALLTHROUGH */
+ case 1:
+ HASH4;
+ } while (--loop);
+ }
+ }
+ return (h);
+}
--- /dev/null
+--- hash_func.c.orig Sun Feb 16 09:29:09 2003
++++ hash_func.c Sat Oct 18 18:30:57 2003
+@@ -45,7 +45,7 @@
+ #include <db.h>
+ #include "hash.h"
+ #include "page.h"
+-#include "extern.h"
++#include "hash_extern.h"
+
+ static u_int32_t hash1(const void *, size_t) __unused;
+ static u_int32_t hash2(const void *, size_t) __unused;
--- /dev/null
+/*-
+ * 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
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_log2.c,v 1.2 2002/03/21 18:47:38 obrien Exp $");
+
+#include <sys/types.h>
+
+#include <db.h>
+
+u_int32_t
+__log2(num)
+ u_int32_t num;
+{
+ u_int32_t i, limit;
+
+ limit = 1;
+ for (i = 0; limit < num; limit = limit << 1, i++);
+ return (i);
+}
--- /dev/null
+/*-
+ * 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
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_page.c,v 1.8 2002/03/21 22:46:26 obrien Exp $");
+
+/*
+ * PACKAGE: hashing
+ *
+ * DESCRIPTION:
+ * Page manipulation for hashing package.
+ *
+ * ROUTINES:
+ *
+ * External
+ * __get_page
+ * __add_ovflpage
+ * Internal
+ * overflow_page
+ * open_temp
+ */
+
+#include "namespace.h"
+#include <sys/types.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef DEBUG
+#include <assert.h>
+#endif
+#include "un-namespace.h"
+
+#include <db.h>
+#include "hash.h"
+#include "page.h"
+#include "extern.h"
+
+static u_int32_t *fetch_bitmap(HTAB *, int);
+static u_int32_t first_free(u_int32_t);
+static int open_temp(HTAB *);
+static u_int16_t overflow_page(HTAB *);
+static void putpair(char *, const DBT *, const DBT *);
+static void squeeze_key(u_int16_t *, const DBT *, const DBT *);
+static int ugly_split
+(HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int);
+
+#define PAGE_INIT(P) { \
+ ((u_int16_t *)(P))[0] = 0; \
+ ((u_int16_t *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_int16_t); \
+ ((u_int16_t *)(P))[2] = hashp->BSIZE; \
+}
+
+/*
+ * This is called AFTER we have verified that there is room on the page for
+ * the pair (PAIRFITS has returned true) so we go right ahead and start moving
+ * stuff on.
+ */
+static void
+putpair(p, key, val)
+ char *p;
+ const DBT *key, *val;
+{
+ u_int16_t *bp, n, off;
+
+ bp = (u_int16_t *)p;
+
+ /* Enter the key first. */
+ n = bp[0];
+
+ off = OFFSET(bp) - key->size;
+ memmove(p + off, key->data, key->size);
+ bp[++n] = off;
+
+ /* Now the data. */
+ off -= val->size;
+ memmove(p + off, val->data, val->size);
+ bp[++n] = off;
+
+ /* Adjust page info. */
+ bp[0] = n;
+ bp[n + 1] = off - ((n + 3) * sizeof(u_int16_t));
+ bp[n + 2] = off;
+}
+
+/*
+ * Returns:
+ * 0 OK
+ * -1 error
+ */
+extern int
+__delpair(hashp, bufp, ndx)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ int ndx;
+{
+ u_int16_t *bp, newoff;
+ int n;
+ u_int16_t pairlen;
+
+ bp = (u_int16_t *)bufp->page;
+ n = bp[0];
+
+ if (bp[ndx + 1] < REAL_KEY)
+ return (__big_delete(hashp, bufp));
+ if (ndx != 1)
+ newoff = bp[ndx - 1];
+ else
+ newoff = hashp->BSIZE;
+ pairlen = newoff - bp[ndx + 1];
+
+ if (ndx != (n - 1)) {
+ /* Hard Case -- need to shuffle keys */
+ int i;
+ char *src = bufp->page + (int)OFFSET(bp);
+ char *dst = src + (int)pairlen;
+ memmove(dst, src, bp[ndx + 1] - OFFSET(bp));
+
+ /* Now adjust the pointers */
+ for (i = ndx + 2; i <= n; i += 2) {
+ if (bp[i + 1] == OVFLPAGE) {
+ bp[i - 2] = bp[i];
+ bp[i - 1] = bp[i + 1];
+ } else {
+ bp[i - 2] = bp[i] + pairlen;
+ bp[i - 1] = bp[i + 1] + pairlen;
+ }
+ }
+ }
+ /* Finally adjust the page data */
+ bp[n] = OFFSET(bp) + pairlen;
+ bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t);
+ bp[0] = n - 2;
+ hashp->NKEYS--;
+
+ bufp->flags |= BUF_MOD;
+ return (0);
+}
+/*
+ * Returns:
+ * 0 ==> OK
+ * -1 ==> Error
+ */
+extern int
+__split_page(hashp, obucket, nbucket)
+ HTAB *hashp;
+ u_int32_t obucket, nbucket;
+{
+ BUFHEAD *new_bufp, *old_bufp;
+ u_int16_t *ino;
+ char *np;
+ DBT key, val;
+ int n, ndx, retval;
+ u_int16_t copyto, diff, off, moved;
+ char *op;
+
+ copyto = (u_int16_t)hashp->BSIZE;
+ off = (u_int16_t)hashp->BSIZE;
+ old_bufp = __get_buf(hashp, obucket, NULL, 0);
+ if (old_bufp == NULL)
+ return (-1);
+ new_bufp = __get_buf(hashp, nbucket, NULL, 0);
+ if (new_bufp == NULL)
+ return (-1);
+
+ old_bufp->flags |= (BUF_MOD | BUF_PIN);
+ new_bufp->flags |= (BUF_MOD | BUF_PIN);
+
+ ino = (u_int16_t *)(op = old_bufp->page);
+ np = new_bufp->page;
+
+ moved = 0;
+
+ for (n = 1, ndx = 1; n < ino[0]; n += 2) {
+ if (ino[n + 1] < REAL_KEY) {
+ retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
+ (int)copyto, (int)moved);
+ old_bufp->flags &= ~BUF_PIN;
+ new_bufp->flags &= ~BUF_PIN;
+ return (retval);
+
+ }
+ key.data = (u_char *)op + ino[n];
+ key.size = off - ino[n];
+
+ if (__call_hash(hashp, key.data, key.size) == obucket) {
+ /* Don't switch page */
+ diff = copyto - off;
+ if (diff) {
+ copyto = ino[n + 1] + diff;
+ memmove(op + copyto, op + ino[n + 1],
+ off - ino[n + 1]);
+ ino[ndx] = copyto + ino[n] - ino[n + 1];
+ ino[ndx + 1] = copyto;
+ } else
+ copyto = ino[n + 1];
+ ndx += 2;
+ } else {
+ /* Switch page */
+ val.data = (u_char *)op + ino[n + 1];
+ val.size = ino[n] - ino[n + 1];
+ putpair(np, &key, &val);
+ moved += 2;
+ }
+
+ off = ino[n + 1];
+ }
+
+ /* Now clean up the page */
+ ino[0] -= moved;
+ FREESPACE(ino) = copyto - sizeof(u_int16_t) * (ino[0] + 3);
+ OFFSET(ino) = copyto;
+
+#ifdef DEBUG3
+ (void)fprintf(stderr, "split %d/%d\n",
+ ((u_int16_t *)np)[0] / 2,
+ ((u_int16_t *)op)[0] / 2);
+#endif
+ /* unpin both pages */
+ old_bufp->flags &= ~BUF_PIN;
+ new_bufp->flags &= ~BUF_PIN;
+ return (0);
+}
+
+/*
+ * Called when we encounter an overflow or big key/data page during split
+ * handling. This is special cased since we have to begin checking whether
+ * the key/data pairs fit on their respective pages and because we may need
+ * overflow pages for both the old and new pages.
+ *
+ * The first page might be a page with regular key/data pairs in which case
+ * we have a regular overflow condition and just need to go on to the next
+ * page or it might be a big key/data pair in which case we need to fix the
+ * big key/data pair.
+ *
+ * Returns:
+ * 0 ==> success
+ * -1 ==> failure
+ */
+static int
+ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
+ HTAB *hashp;
+ u_int32_t obucket; /* Same as __split_page. */
+ BUFHEAD *old_bufp, *new_bufp;
+ int copyto; /* First byte on page which contains key/data values. */
+ int moved; /* Number of pairs moved to new page. */
+{
+ BUFHEAD *bufp; /* Buffer header for ino */
+ u_int16_t *ino; /* Page keys come off of */
+ u_int16_t *np; /* New page */
+ u_int16_t *op; /* Page keys go on to if they aren't moving */
+
+ BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */
+ DBT key, val;
+ SPLIT_RETURN ret;
+ u_int16_t n, off, ov_addr, scopyto;
+ char *cino; /* Character value of ino */
+
+ bufp = old_bufp;
+ ino = (u_int16_t *)old_bufp->page;
+ np = (u_int16_t *)new_bufp->page;
+ op = (u_int16_t *)old_bufp->page;
+ last_bfp = NULL;
+ scopyto = (u_int16_t)copyto; /* ANSI */
+
+ n = ino[0] - 1;
+ while (n < ino[0]) {
+ if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
+ if (__big_split(hashp, old_bufp,
+ new_bufp, bufp, bufp->addr, obucket, &ret))
+ return (-1);
+ old_bufp = ret.oldp;
+ if (!old_bufp)
+ return (-1);
+ op = (u_int16_t *)old_bufp->page;
+ new_bufp = ret.newp;
+ if (!new_bufp)
+ return (-1);
+ np = (u_int16_t *)new_bufp->page;
+ bufp = ret.nextp;
+ if (!bufp)
+ return (0);
+ cino = (char *)bufp->page;
+ ino = (u_int16_t *)cino;
+ last_bfp = ret.nextp;
+ } else if (ino[n + 1] == OVFLPAGE) {
+ ov_addr = ino[n];
+ /*
+ * Fix up the old page -- the extra 2 are the fields
+ * which contained the overflow information.
+ */
+ ino[0] -= (moved + 2);
+ FREESPACE(ino) =
+ scopyto - sizeof(u_int16_t) * (ino[0] + 3);
+ OFFSET(ino) = scopyto;
+
+ bufp = __get_buf(hashp, ov_addr, bufp, 0);
+ if (!bufp)
+ return (-1);
+
+ ino = (u_int16_t *)bufp->page;
+ n = 1;
+ scopyto = hashp->BSIZE;
+ moved = 0;
+
+ if (last_bfp)
+ __free_ovflpage(hashp, last_bfp);
+ last_bfp = bufp;
+ }
+ /* Move regular sized pairs of there are any */
+ off = hashp->BSIZE;
+ for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
+ cino = (char *)ino;
+ key.data = (u_char *)cino + ino[n];
+ key.size = off - ino[n];
+ val.data = (u_char *)cino + ino[n + 1];
+ val.size = ino[n] - ino[n + 1];
+ off = ino[n + 1];
+
+ if (__call_hash(hashp, key.data, key.size) == obucket) {
+ /* Keep on old page */
+ if (PAIRFITS(op, (&key), (&val)))
+ putpair((char *)op, &key, &val);
+ else {
+ old_bufp =
+ __add_ovflpage(hashp, old_bufp);
+ if (!old_bufp)
+ return (-1);
+ op = (u_int16_t *)old_bufp->page;
+ putpair((char *)op, &key, &val);
+ }
+ old_bufp->flags |= BUF_MOD;
+ } else {
+ /* Move to new page */
+ if (PAIRFITS(np, (&key), (&val)))
+ putpair((char *)np, &key, &val);
+ else {
+ new_bufp =
+ __add_ovflpage(hashp, new_bufp);
+ if (!new_bufp)
+ return (-1);
+ np = (u_int16_t *)new_bufp->page;
+ putpair((char *)np, &key, &val);
+ }
+ new_bufp->flags |= BUF_MOD;
+ }
+ }
+ }
+ if (last_bfp)
+ __free_ovflpage(hashp, last_bfp);
+ return (0);
+}
+
+/*
+ * Add the given pair to the page
+ *
+ * Returns:
+ * 0 ==> OK
+ * 1 ==> failure
+ */
+extern int
+__addel(hashp, bufp, key, val)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ const DBT *key, *val;
+{
+ u_int16_t *bp, *sop;
+ int do_expand;
+
+ bp = (u_int16_t *)bufp->page;
+ do_expand = 0;
+ while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
+ /* Exception case */
+ if (bp[2] == FULL_KEY_DATA && bp[0] == 2)
+ /* This is the last page of a big key/data pair
+ and we need to add another page */
+ break;
+ else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (u_int16_t *)bufp->page;
+ } else
+ /* Try to squeeze key on this page */
+ if (FREESPACE(bp) > PAIRSIZE(key, val)) {
+ squeeze_key(bp, key, val);
+ return (0);
+ } else {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (u_int16_t *)bufp->page;
+ }
+
+ if (PAIRFITS(bp, key, val))
+ putpair(bufp->page, key, val);
+ else {
+ do_expand = 1;
+ bufp = __add_ovflpage(hashp, bufp);
+ if (!bufp)
+ return (-1);
+ sop = (u_int16_t *)bufp->page;
+
+ if (PAIRFITS(sop, key, val))
+ putpair((char *)sop, key, val);
+ else
+ if (__big_insert(hashp, bufp, key, val))
+ return (-1);
+ }
+ bufp->flags |= BUF_MOD;
+ /*
+ * If the average number of keys per bucket exceeds the fill factor,
+ * expand the table.
+ */
+ hashp->NKEYS++;
+ if (do_expand ||
+ (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
+ return (__expand_table(hashp));
+ return (0);
+}
+
+/*
+ *
+ * Returns:
+ * pointer on success
+ * NULL on error
+ */
+extern BUFHEAD *
+__add_ovflpage(hashp, bufp)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+{
+ u_int16_t *sp;
+ u_int16_t ndx, ovfl_num;
+#ifdef DEBUG1
+ int tmp1, tmp2;
+#endif
+ sp = (u_int16_t *)bufp->page;
+
+ /* Check if we are dynamically determining the fill factor */
+ if (hashp->FFACTOR == DEF_FFACTOR) {
+ hashp->FFACTOR = sp[0] >> 1;
+ if (hashp->FFACTOR < MIN_FFACTOR)
+ hashp->FFACTOR = MIN_FFACTOR;
+ }
+ bufp->flags |= BUF_MOD;
+ ovfl_num = overflow_page(hashp);
+#ifdef DEBUG1
+ tmp1 = bufp->addr;
+ tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0;
+#endif
+ if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1)))
+ return (NULL);
+ bufp->ovfl->flags |= BUF_MOD;
+#ifdef DEBUG1
+ (void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n",
+ tmp1, tmp2, bufp->ovfl->addr);
+#endif
+ ndx = sp[0];
+ /*
+ * Since a pair is allocated on a page only if there's room to add
+ * an overflow page, we know that the OVFL information will fit on
+ * the page.
+ */
+ sp[ndx + 4] = OFFSET(sp);
+ sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE;
+ sp[ndx + 1] = ovfl_num;
+ sp[ndx + 2] = OVFLPAGE;
+ sp[0] = ndx + 2;
+#ifdef HASH_STATISTICS
+ hash_overflows++;
+#endif
+ return (bufp->ovfl);
+}
+
+/*
+ * Returns:
+ * 0 indicates SUCCESS
+ * -1 indicates FAILURE
+ */
+extern int
+__get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
+ HTAB *hashp;
+ char *p;
+ u_int32_t bucket;
+ int is_bucket, is_disk, is_bitmap;
+{
+ int fd, page, size;
+ int rsize;
+ u_int16_t *bp;
+
+ fd = hashp->fp;
+ size = hashp->BSIZE;
+
+ if ((fd == -1) || !is_disk) {
+ PAGE_INIT(p);
+ return (0);
+ }
+ if (is_bucket)
+ page = BUCKET_TO_PAGE(bucket);
+ else
+ page = OADDR_TO_PAGE(bucket);
+ if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
+ ((rsize = _read(fd, p, size)) == -1))
+ return (-1);
+ bp = (u_int16_t *)p;
+ if (!rsize)
+ bp[0] = 0; /* We hit the EOF, so initialize a new page */
+ else
+ if (rsize != size) {
+ errno = EFTYPE;
+ return (-1);
+ }
+ if (!is_bitmap && !bp[0]) {
+ PAGE_INIT(p);
+ } else
+ if (hashp->LORDER != BYTE_ORDER) {
+ int i, max;
+
+ if (is_bitmap) {
+ max = hashp->BSIZE >> 2; /* divide by 4 */
+ for (i = 0; i < max; i++)
+ M_32_SWAP(((int *)p)[i]);
+ } else {
+ M_16_SWAP(bp[0]);
+ max = bp[0] + 2;
+ for (i = 1; i <= max; i++)
+ M_16_SWAP(bp[i]);
+ }
+ }
+ return (0);
+}
+
+/*
+ * Write page p to disk
+ *
+ * Returns:
+ * 0 ==> OK
+ * -1 ==>failure
+ */
+extern int
+__put_page(hashp, p, bucket, is_bucket, is_bitmap)
+ HTAB *hashp;
+ char *p;
+ u_int32_t bucket;
+ int is_bucket, is_bitmap;
+{
+ int fd, page, size;
+ int wsize;
+
+ size = hashp->BSIZE;
+ if ((hashp->fp == -1) && open_temp(hashp))
+ return (-1);
+ fd = hashp->fp;
+
+ if (hashp->LORDER != BYTE_ORDER) {
+ int i;
+ int max;
+
+ if (is_bitmap) {
+ max = hashp->BSIZE >> 2; /* divide by 4 */
+ for (i = 0; i < max; i++)
+ M_32_SWAP(((int *)p)[i]);
+ } else {
+ max = ((u_int16_t *)p)[0] + 2;
+ for (i = 0; i <= max; i++)
+ M_16_SWAP(((u_int16_t *)p)[i]);
+ }
+ }
+ if (is_bucket)
+ page = BUCKET_TO_PAGE(bucket);
+ else
+ page = OADDR_TO_PAGE(bucket);
+ if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
+ ((wsize = _write(fd, p, size)) == -1))
+ /* Errno is set */
+ return (-1);
+ if (wsize != size) {
+ errno = EFTYPE;
+ return (-1);
+ }
+ return (0);
+}
+
+#define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1)
+/*
+ * Initialize a new bitmap page. Bitmap pages are left in memory
+ * once they are read in.
+ */
+extern int
+__ibitmap(hashp, pnum, nbits, ndx)
+ HTAB *hashp;
+ int pnum, nbits, ndx;
+{
+ u_int32_t *ip;
+ int clearbytes, clearints;
+
+ if ((ip = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
+ return (1);
+ hashp->nmaps++;
+ clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
+ clearbytes = clearints << INT_TO_BYTE;
+ (void)memset((char *)ip, 0, clearbytes);
+ (void)memset(((char *)ip) + clearbytes, 0xFF,
+ hashp->BSIZE - clearbytes);
+ ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
+ SETBIT(ip, 0);
+ hashp->BITMAPS[ndx] = (u_int16_t)pnum;
+ hashp->mapp[ndx] = ip;
+ return (0);
+}
+
+static u_int32_t
+first_free(map)
+ u_int32_t map;
+{
+ u_int32_t i, mask;
+
+ mask = 0x1;
+ for (i = 0; i < BITS_PER_MAP; i++) {
+ if (!(mask & map))
+ return (i);
+ mask = mask << 1;
+ }
+ return (i);
+}
+
+static u_int16_t
+overflow_page(hashp)
+ HTAB *hashp;
+{
+ u_int32_t *freep;
+ int max_free, offset, splitnum;
+ u_int16_t addr;
+ int bit, first_page, free_bit, free_page, i, in_use_bits, j;
+#ifdef DEBUG2
+ int tmp1, tmp2;
+#endif
+ splitnum = hashp->OVFL_POINT;
+ max_free = hashp->SPARES[splitnum];
+
+ free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
+ free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
+
+ /* Look through all the free maps to find the first free block */
+ first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
+ for ( i = first_page; i <= free_page; i++ ) {
+ if (!(freep = (u_int32_t *)hashp->mapp[i]) &&
+ !(freep = fetch_bitmap(hashp, i)))
+ return (0);
+ if (i == free_page)
+ in_use_bits = free_bit;
+ else
+ in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
+
+ if (i == first_page) {
+ bit = hashp->LAST_FREED &
+ ((hashp->BSIZE << BYTE_SHIFT) - 1);
+ j = bit / BITS_PER_MAP;
+ bit = bit & ~(BITS_PER_MAP - 1);
+ } else {
+ bit = 0;
+ j = 0;
+ }
+ for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
+ if (freep[j] != ALL_SET)
+ goto found;
+ }
+
+ /* No Free Page Found */
+ hashp->LAST_FREED = hashp->SPARES[splitnum];
+ hashp->SPARES[splitnum]++;
+ offset = hashp->SPARES[splitnum] -
+ (splitnum ? hashp->SPARES[splitnum - 1] : 0);
+
+#define OVMSG "HASH: Out of overflow pages. Increase page size\n"
+ if (offset > SPLITMASK) {
+ if (++splitnum >= NCACHED) {
+ (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
+ return (0);
+ }
+ hashp->OVFL_POINT = splitnum;
+ hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
+ hashp->SPARES[splitnum-1]--;
+ offset = 1;
+ }
+
+ /* Check if we need to allocate a new bitmap page */
+ if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
+ free_page++;
+ if (free_page >= NCACHED) {
+ (void)_write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
+ return (0);
+ }
+ /*
+ * This is tricky. The 1 indicates that you want the new page
+ * allocated with 1 clear bit. Actually, you are going to
+ * allocate 2 pages from this map. The first is going to be
+ * the map page, the second is the overflow page we were
+ * looking for. The init_bitmap routine automatically, sets
+ * the first bit of itself to indicate that the bitmap itself
+ * is in use. We would explicitly set the second bit, but
+ * don't have to if we tell init_bitmap not to leave it clear
+ * in the first place.
+ */
+ if (__ibitmap(hashp,
+ (int)OADDR_OF(splitnum, offset), 1, free_page))
+ return (0);
+ hashp->SPARES[splitnum]++;
+#ifdef DEBUG2
+ free_bit = 2;
+#endif
+ offset++;
+ if (offset > SPLITMASK) {
+ if (++splitnum >= NCACHED) {
+ (void)_write(STDERR_FILENO, OVMSG,
+ sizeof(OVMSG) - 1);
+ return (0);
+ }
+ hashp->OVFL_POINT = splitnum;
+ hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
+ hashp->SPARES[splitnum-1]--;
+ offset = 0;
+ }
+ } else {
+ /*
+ * Free_bit addresses the last used bit. Bump it to address
+ * the first available bit.
+ */
+ free_bit++;
+ SETBIT(freep, free_bit);
+ }
+
+ /* Calculate address of the new overflow page */
+ addr = OADDR_OF(splitnum, offset);
+#ifdef DEBUG2
+ (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
+ addr, free_bit, free_page);
+#endif
+ return (addr);
+
+found:
+ bit = bit + first_free(freep[j]);
+ SETBIT(freep, bit);
+#ifdef DEBUG2
+ tmp1 = bit;
+ tmp2 = i;
+#endif
+ /*
+ * Bits are addressed starting with 0, but overflow pages are addressed
+ * beginning at 1. Bit is a bit addressnumber, so we need to increment
+ * it to convert it to a page number.
+ */
+ bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
+ if (bit >= hashp->LAST_FREED)
+ hashp->LAST_FREED = bit - 1;
+
+ /* Calculate the split number for this page */
+ for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
+ offset = (i ? bit - hashp->SPARES[i - 1] : bit);
+ if (offset >= SPLITMASK)
+ return (0); /* Out of overflow pages */
+ addr = OADDR_OF(i, offset);
+#ifdef DEBUG2
+ (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
+ addr, tmp1, tmp2);
+#endif
+
+ /* Allocate and return the overflow page */
+ return (addr);
+}
+
+/*
+ * Mark this overflow page as free.
+ */
+extern void
+__free_ovflpage(hashp, obufp)
+ HTAB *hashp;
+ BUFHEAD *obufp;
+{
+ u_int16_t addr;
+ u_int32_t *freep;
+ int bit_address, free_page, free_bit;
+ u_int16_t ndx;
+
+ addr = obufp->addr;
+#ifdef DEBUG1
+ (void)fprintf(stderr, "Freeing %d\n", addr);
+#endif
+ ndx = (((u_int16_t)addr) >> SPLITSHIFT);
+ bit_address =
+ (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
+ if (bit_address < hashp->LAST_FREED)
+ hashp->LAST_FREED = bit_address;
+ free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
+ free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
+
+ if (!(freep = hashp->mapp[free_page]))
+ freep = fetch_bitmap(hashp, free_page);
+#ifdef DEBUG
+ /*
+ * This had better never happen. It means we tried to read a bitmap
+ * that has already had overflow pages allocated off it, and we
+ * failed to read it from the file.
+ */
+ if (!freep)
+ assert(0);
+#endif
+ CLRBIT(freep, free_bit);
+#ifdef DEBUG2
+ (void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n",
+ obufp->addr, free_bit, free_page);
+#endif
+ __reclaim_buf(hashp, obufp);
+}
+
+/*
+ * Returns:
+ * 0 success
+ * -1 failure
+ */
+static int
+open_temp(hashp)
+ HTAB *hashp;
+{
+ sigset_t set, oset;
+ static char namestr[] = "_hashXXXXXX";
+
+ /* Block signals; make sure file goes away at process exit. */
+ (void)sigfillset(&set);
+ (void)_sigprocmask(SIG_BLOCK, &set, &oset);
+ if ((hashp->fp = mkstemp(namestr)) != -1) {
+ (void)unlink(namestr);
+ (void)_fcntl(hashp->fp, F_SETFD, 1);
+ }
+ (void)_sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
+ return (hashp->fp != -1 ? 0 : -1);
+}
+
+/*
+ * We have to know that the key will fit, but the last entry on the page is
+ * an overflow pair, so we need to shift things.
+ */
+static void
+squeeze_key(sp, key, val)
+ u_int16_t *sp;
+ const DBT *key, *val;
+{
+ char *p;
+ u_int16_t free_space, n, off, pageno;
+
+ p = (char *)sp;
+ n = sp[0];
+ free_space = FREESPACE(sp);
+ off = OFFSET(sp);
+
+ pageno = sp[n - 1];
+ off -= key->size;
+ sp[n - 1] = off;
+ memmove(p + off, key->data, key->size);
+ off -= val->size;
+ sp[n] = off;
+ memmove(p + off, val->data, val->size);
+ sp[0] = n + 2;
+ sp[n + 1] = pageno;
+ sp[n + 2] = OVFLPAGE;
+ FREESPACE(sp) = free_space - PAIRSIZE(key, val);
+ OFFSET(sp) = off;
+}
+
+static u_int32_t *
+fetch_bitmap(hashp, ndx)
+ HTAB *hashp;
+ int ndx;
+{
+ if (ndx >= hashp->nmaps)
+ return (NULL);
+ if ((hashp->mapp[ndx] = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
+ return (NULL);
+ if (__get_page(hashp,
+ (char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) {
+ free(hashp->mapp[ndx]);
+ return (NULL);
+ }
+ return (hashp->mapp[ndx]);
+}
+
+#ifdef DEBUG4
+int
+print_chain(addr)
+ int addr;
+{
+ BUFHEAD *bufp;
+ short *bp, oaddr;
+
+ (void)fprintf(stderr, "%d ", addr);
+ bufp = __get_buf(hashp, addr, NULL, 0);
+ bp = (short *)bufp->page;
+ while (bp[0] && ((bp[bp[0]] == OVFLPAGE) ||
+ ((bp[0] > 2) && bp[2] < REAL_KEY))) {
+ oaddr = bp[bp[0] - 1];
+ (void)fprintf(stderr, "%d ", (int)oaddr);
+ bufp = __get_buf(hashp, (int)oaddr, bufp, 0);
+ bp = (short *)bufp->page;
+ }
+ (void)fprintf(stderr, "\n");
+}
+#endif
--- /dev/null
+--- hash_page.c.orig Thu Mar 21 14:46:26 2002
++++ hash_page.c Sat Oct 18 18:31:10 2003
+@@ -74,7 +74,7 @@
+ #include <db.h>
+ #include "hash.h"
+ #include "page.h"
+-#include "extern.h"
++#include "hash_extern.h"
+
+ static u_int32_t *fetch_bitmap(HTAB *, int);
+ static u_int32_t first_free(u_int32_t);
--- /dev/null
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/hash/ndbm.c,v 1.6 2002/03/22 21:52:01 obrien Exp $");
+
+/*
+ * This package provides a dbm compatible interface to the new hashing
+ * package described in db(3).
+ */
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <ndbm.h>
+#include "hash.h"
+
+/*
+ * Returns:
+ * *DBM on success
+ * NULL on failure
+ */
+extern DBM *
+dbm_open(file, flags, mode)
+ const char *file;
+ int flags, mode;
+{
+ HASHINFO info;
+ char path[MAXPATHLEN];
+
+ info.bsize = 4096;
+ info.ffactor = 40;
+ info.nelem = 1;
+ info.cachesize = 0;
+ info.hash = NULL;
+ info.lorder = 0;
+
+ if( strlen(file) >= sizeof(path) - strlen(DBM_SUFFIX)) {
+ errno = ENAMETOOLONG;
+ return(NULL);
+ }
+ (void)strcpy(path, file);
+ (void)strcat(path, DBM_SUFFIX);
+ return ((DBM *)__hash_open(path, flags, mode, &info, 0));
+}
+
+extern void
+dbm_close(db)
+ DBM *db;
+{
+ (void)(db->close)(db);
+}
+
+/*
+ * Returns:
+ * DATUM on success
+ * NULL on failure
+ */
+extern datum
+dbm_fetch(db, key)
+ DBM *db;
+ datum key;
+{
+ datum retdata;
+ int status;
+ DBT dbtkey, dbtretdata;
+
+ dbtkey.data = key.dptr;
+ dbtkey.size = key.dsize;
+ status = (db->get)(db, &dbtkey, &dbtretdata, 0);
+ if (status) {
+ dbtretdata.data = NULL;
+ dbtretdata.size = 0;
+ }
+ retdata.dptr = dbtretdata.data;
+ retdata.dsize = dbtretdata.size;
+ return (retdata);
+}
+
+/*
+ * Returns:
+ * DATUM on success
+ * NULL on failure
+ */
+extern datum
+dbm_firstkey(db)
+ DBM *db;
+{
+ int status;
+ datum retkey;
+ DBT dbtretkey, dbtretdata;
+
+ status = (db->seq)(db, &dbtretkey, &dbtretdata, R_FIRST);
+ if (status)
+ dbtretkey.data = NULL;
+ retkey.dptr = dbtretkey.data;
+ retkey.dsize = dbtretkey.size;
+ return (retkey);
+}
+
+/*
+ * Returns:
+ * DATUM on success
+ * NULL on failure
+ */
+extern datum
+dbm_nextkey(db)
+ DBM *db;
+{
+ int status;
+ datum retkey;
+ DBT dbtretkey, dbtretdata;
+
+ status = (db->seq)(db, &dbtretkey, &dbtretdata, R_NEXT);
+ if (status)
+ dbtretkey.data = NULL;
+ retkey.dptr = dbtretkey.data;
+ retkey.dsize = dbtretkey.size;
+ return (retkey);
+}
+
+/*
+ * Returns:
+ * 0 on success
+ * <0 failure
+ */
+extern int
+dbm_delete(db, key)
+ DBM *db;
+ datum key;
+{
+ int status;
+ DBT dbtkey;
+
+ dbtkey.data = key.dptr;
+ dbtkey.size = key.dsize;
+ status = (db->del)(db, &dbtkey, 0);
+ if (status)
+ return (-1);
+ else
+ return (0);
+}
+
+/*
+ * Returns:
+ * 0 on success
+ * <0 failure
+ * 1 if DBM_INSERT and entry exists
+ */
+extern int
+dbm_store(db, key, data, flags)
+ DBM *db;
+ datum key, data;
+ int flags;
+{
+ DBT dbtkey, dbtdata;
+
+ dbtkey.data = key.dptr;
+ dbtkey.size = key.dsize;
+ dbtdata.data = data.dptr;
+ dbtdata.size = data.dsize;
+ return ((db->put)(db, &dbtkey, &dbtdata,
+ (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
+}
+
+extern int
+dbm_error(db)
+ DBM *db;
+{
+ HTAB *hp;
+
+ hp = (HTAB *)db->internal;
+ return (hp->error);
+}
+
+extern int
+dbm_clearerr(db)
+ DBM *db;
+{
+ HTAB *hp;
+
+ hp = (HTAB *)db->internal;
+ hp->error = 0;
+ return (0);
+}
+
+extern int
+dbm_dirfno(db)
+ DBM *db;
+{
+ return(((HTAB *)db->internal)->fp);
+}
--- /dev/null
+--- ndbm.c.orig Wed Oct 22 19:07:02 2003
++++ ndbm.c Wed Dec 17 09:24:33 2003
+@@ -51,6 +51,7 @@
+ #include <string.h>
+ #include <errno.h>
+
++#include <db.h>
+ #include <ndbm.h>
+ #include "hash.h"
+
+@@ -62,7 +63,8 @@
+ extern DBM *
+ dbm_open(file, flags, mode)
+ const char *file;
+- int flags, mode;
++ int flags;
++ mode_t mode;
+ {
+ HASHINFO info;
+ char path[MAXPATHLEN];
--- /dev/null
+/*-
+ * 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
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)page.h 8.2 (Berkeley) 5/31/94
+ * $FreeBSD: src/lib/libc/db/hash/page.h,v 1.2 2002/03/22 23:41:40 obrien Exp $
+ */
+
+/*
+ * Definitions for hashing page file format.
+ */
+
+/*
+ * routines dealing with a data page
+ *
+ * page format:
+ * +------------------------------+
+ * p | n | keyoff | datoff | keyoff |
+ * +------------+--------+--------+
+ * | datoff | free | ptr | --> |
+ * +--------+---------------------+
+ * | F R E E A R E A |
+ * +--------------+---------------+
+ * | <---- - - - | data |
+ * +--------+-----+----+----------+
+ * | key | data | key |
+ * +--------+----------+----------+
+ *
+ * Pointer to the free space is always: p[p[0] + 2]
+ * Amount of free space on the page is: p[p[0] + 1]
+ */
+
+/*
+ * How many bytes required for this pair?
+ * 2 shorts in the table at the top of the page + room for the
+ * key and room for the data
+ *
+ * We prohibit entering a pair on a page unless there is also room to append
+ * an overflow page. The reason for this it that you can get in a situation
+ * where a single key/data pair fits on a page, but you can't append an
+ * overflow page and later you'd have to split the key/data and handle like
+ * a big pair.
+ * You might as well do this up front.
+ */
+
+#define PAIRSIZE(K,D) (2*sizeof(u_int16_t) + (K)->size + (D)->size)
+#define BIGOVERHEAD (4*sizeof(u_int16_t))
+#define KEYSIZE(K) (4*sizeof(u_int16_t) + (K)->size);
+#define OVFLSIZE (2*sizeof(u_int16_t))
+#define FREESPACE(P) ((P)[(P)[0]+1])
+#define OFFSET(P) ((P)[(P)[0]+2])
+#define PAIRFITS(P,K,D) \
+ (((P)[2] >= REAL_KEY) && \
+ (PAIRSIZE((K),(D)) + OVFLSIZE) <= FREESPACE((P)))
+#define PAGE_META(N) (((N)+3) * sizeof(u_int16_t))
+
+typedef struct {
+ BUFHEAD *newp;
+ BUFHEAD *oldp;
+ BUFHEAD *nextp;
+ u_int16_t next_addr;
+} SPLIT_RETURN;
# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
-# $FreeBSD: src/lib/libc/db/hash/Makefile.inc,v 1.4 2001/05/15 07:08:17 ru Exp $
+# $FreeBSD: src/lib/libc/db/hash/Makefile.inc,v 1.5 2002/11/18 09:50:54 ru Exp $
.PATH: ${.CURDIR}/db/hash
-SRCS+= hash.c hash_bigkey.c hash_buf.c hash_func.c hash_log2.c \
- hash_page.c ndbm.c
+.include "Makefile.fbsd_begin"
+FBSDMISRCS= hash.c hash_bigkey.c hash_buf.c hash_func.c hash_log2.c \
+ hash_page.c ndbm.c
+.for _src in ${FBSDMISRCS}
+CFLAGS-${_src:R}-fbsd.${_src:E} += -D__DBINTERFACE_PRIVATE
+.endfor
+FBSDHDRS= hash.h page.h
+.include "Makefile.fbsd_end"
+
+# need to rename extern.h to make it unique
+${SYMROOT}/hash_extern.h: ${.CURDIR}/db/hash/FreeBSD/extern.h _AUTOPATCHSYM
+AUTOPATCHHDRS+= ${SYMROOT}/hash_extern.h
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)extern.h 8.4 (Berkeley) 6/16/94
- * $FreeBSD: src/lib/libc/db/hash/extern.h,v 1.3 2002/03/22 09:18:22 obrien Exp $
- */
-
-BUFHEAD *__add_ovflpage(HTAB *, BUFHEAD *);
-int __addel(HTAB *, BUFHEAD *, const DBT *, const DBT *);
-int __big_delete(HTAB *, BUFHEAD *);
-int __big_insert(HTAB *, BUFHEAD *, const DBT *, const DBT *);
-int __big_keydata(HTAB *, BUFHEAD *, DBT *, DBT *, int);
-int __big_return(HTAB *, BUFHEAD *, int, DBT *, int);
-int __big_split(HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *,
- int, u_int32_t, SPLIT_RETURN *);
-int __buf_free(HTAB *, int, int);
-void __buf_init(HTAB *, int);
-u_int32_t __call_hash(HTAB *, char *, int);
-int __delpair(HTAB *, BUFHEAD *, int);
-int __expand_table(HTAB *);
-int __find_bigpair(HTAB *, BUFHEAD *, int, char *, int);
-u_int16_t __find_last_page(HTAB *, BUFHEAD **);
-void __free_ovflpage(HTAB *, BUFHEAD *);
-BUFHEAD *__get_buf(HTAB *, u_int32_t, BUFHEAD *, int);
-int __get_page(HTAB *, char *, u_int32_t, int, int, int);
-int __ibitmap(HTAB *, int, int, int);
-u_int32_t __log2(u_int32_t);
-int __put_page(HTAB *, char *, u_int32_t, int, int);
-void __reclaim_buf(HTAB *, BUFHEAD *);
-int __split_page(HTAB *, u_int32_t, u_int32_t);
-
-/* Default hash routine. */
-extern u_int32_t (*__default_hash)(const void *, size_t);
-
-#ifdef HASH_STATISTICS
-extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include <db.h>
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static int alloc_segs(HTAB *, int);
-static int flush_meta(HTAB *);
-static int hash_access(HTAB *, ACTION, DBT *, DBT *);
-static int hash_close(DB *);
-static int hash_delete(const DB *, const DBT *, u_int32_t);
-static int hash_fd(const DB *);
-static int hash_get(const DB *, const DBT *, DBT *, u_int32_t);
-static int hash_put(const DB *, DBT *, const DBT *, u_int32_t);
-static void *hash_realloc(SEGMENT **, int, int);
-static int hash_seq(const DB *, DBT *, DBT *, u_int32_t);
-static int hash_sync(const DB *, u_int32_t);
-static int hdestroy(HTAB *);
-static HTAB *init_hash(HTAB *, const char *, HASHINFO *);
-static int init_htab(HTAB *, int);
-#if BYTE_ORDER == LITTLE_ENDIAN
-static void swap_header(HTAB *);
-static void swap_header_copy(HASHHDR *, HASHHDR *);
-#endif
-
-/* Fast arithmetic, relying on powers of 2, */
-#define MOD(x, y) ((x) & ((y) - 1))
-
-#define RETURN_ERROR(ERR, LOC) { save_errno = ERR; goto LOC; }
-
-/* Return values */
-#define SUCCESS (0)
-#define ERROR (-1)
-#define ABNORMAL (1)
-
-#ifdef HASH_STATISTICS
-int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
-#endif
-
-/************************** INTERFACE ROUTINES ***************************/
-/* OPEN/CLOSE */
-
-extern DB *
-__hash_open(file, flags, mode, info, dflags)
- const char *file;
- int flags, mode, dflags;
- const HASHINFO *info; /* Special directives for create */
-{
- HTAB *hashp;
- struct stat statbuf;
- DB *dbp;
- int bpages, hdrsize, new_table, nsegs, save_errno;
-
- if ((flags & O_ACCMODE) == O_WRONLY) {
- errno = EINVAL;
- return (NULL);
- }
-
- if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB))))
- return (NULL);
- hashp->fp = -1;
-
- /*
- * Even if user wants write only, we need to be able to read
- * the actual file, so we need to open it read/write. But, the
- * field in the hashp structure needs to be accurate so that
- * we can check accesses.
- */
- hashp->flags = flags;
-
- new_table = 0;
- if (!file || (flags & O_TRUNC) ||
- (stat(file, &statbuf) && (errno == ENOENT))) {
- if (errno == ENOENT)
- errno = 0; /* Just in case someone looks at errno */
- new_table = 1;
- }
- if (file) {
- if ((hashp->fp = open(file, flags, mode)) == -1)
- RETURN_ERROR(errno, error0);
-
- /* if the .db file is empty, and we had permission to create
- a new .db file, then reinitialize the database */
- if ((flags & O_CREAT) &&
- fstat(hashp->fp, &statbuf) == 0 && statbuf.st_size == 0)
- new_table = 1;
-
- (void)fcntl(hashp->fp, F_SETFD, 1);
- }
- if (new_table) {
- if (!(hashp = init_hash(hashp, file, (HASHINFO *)info)))
- RETURN_ERROR(errno, error1);
- } else {
- /* Table already exists */
- if (info && info->hash)
- hashp->hash = info->hash;
- else
- hashp->hash = __default_hash;
-
- hdrsize = read(hashp->fp, &hashp->hdr, sizeof(HASHHDR));
-#if BYTE_ORDER == LITTLE_ENDIAN
- swap_header(hashp);
-#endif
- if (hdrsize == -1)
- RETURN_ERROR(errno, error1);
- if (hdrsize != sizeof(HASHHDR))
- RETURN_ERROR(EFTYPE, error1);
- /* Verify file type, versions and hash function */
- if (hashp->MAGIC != HASHMAGIC)
- RETURN_ERROR(EFTYPE, error1);
-#define OLDHASHVERSION 1
- if (hashp->VERSION != HASHVERSION &&
- hashp->VERSION != OLDHASHVERSION)
- RETURN_ERROR(EFTYPE, error1);
- if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY)
- RETURN_ERROR(EFTYPE, error1);
- /*
- * Figure out how many segments we need. Max_Bucket is the
- * maximum bucket number, so the number of buckets is
- * max_bucket + 1.
- */
- nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) /
- hashp->SGSIZE;
- hashp->nsegs = 0;
- if (alloc_segs(hashp, nsegs))
- /*
- * If alloc_segs fails, table will have been destroyed
- * and errno will have been set.
- */
- return (NULL);
- /* Read in bitmaps */
- bpages = (hashp->SPARES[hashp->OVFL_POINT] +
- (hashp->BSIZE << BYTE_SHIFT) - 1) >>
- (hashp->BSHIFT + BYTE_SHIFT);
-
- hashp->nmaps = bpages;
- (void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_int32_t *));
- }
-
- /* Initialize Buffer Manager */
- if (info && info->cachesize)
- __buf_init(hashp, info->cachesize);
- else
- __buf_init(hashp, DEF_BUFSIZE);
-
- hashp->new_file = new_table;
- hashp->save_file = file && (hashp->flags & O_RDWR);
- hashp->cbucket = -1;
- if (!(dbp = (DB *)malloc(sizeof(DB)))) {
- save_errno = errno;
- hdestroy(hashp);
- errno = save_errno;
- return (NULL);
- }
- dbp->internal = hashp;
- dbp->close = hash_close;
- dbp->del = hash_delete;
- dbp->fd = hash_fd;
- dbp->get = hash_get;
- dbp->put = hash_put;
- dbp->seq = hash_seq;
- dbp->sync = hash_sync;
- dbp->type = DB_HASH;
-
-#ifdef DEBUG
- (void)fprintf(stderr,
-"%s\n%s%x\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
- "init_htab:",
- "TABLE POINTER ", hashp,
- "BUCKET SIZE ", hashp->BSIZE,
- "BUCKET SHIFT ", hashp->BSHIFT,
- "DIRECTORY SIZE ", hashp->DSIZE,
- "SEGMENT SIZE ", hashp->SGSIZE,
- "SEGMENT SHIFT ", hashp->SSHIFT,
- "FILL FACTOR ", hashp->FFACTOR,
- "MAX BUCKET ", hashp->MAX_BUCKET,
- "OVFL POINT ", hashp->OVFL_POINT,
- "LAST FREED ", hashp->LAST_FREED,
- "HIGH MASK ", hashp->HIGH_MASK,
- "LOW MASK ", hashp->LOW_MASK,
- "NSEGS ", hashp->nsegs,
- "NKEYS ", hashp->NKEYS);
-#endif
-#ifdef HASH_STATISTICS
- hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0;
-#endif
- return (dbp);
-
-error1:
- if (hashp != NULL)
- (void)close(hashp->fp);
-
-error0:
- free(hashp);
- errno = save_errno;
- return (NULL);
-}
-
-static int
-hash_close(dbp)
- DB *dbp;
-{
- HTAB *hashp;
- int retval;
-
- if (!dbp)
- return (ERROR);
-
- hashp = (HTAB *)dbp->internal;
- retval = hdestroy(hashp);
- free(dbp);
- return (retval);
-}
-
-static int
-hash_fd(dbp)
- const DB *dbp;
-{
- HTAB *hashp;
-
- if (!dbp)
- return (ERROR);
-
- hashp = (HTAB *)dbp->internal;
- if (hashp->fp == -1) {
- errno = ENOENT;
- return (-1);
- }
- return (hashp->fp);
-}
-
-/************************** LOCAL CREATION ROUTINES **********************/
-static HTAB *
-init_hash(hashp, file, info)
- HTAB *hashp;
- const char *file;
- HASHINFO *info;
-{
- struct stat statbuf;
- int nelem;
-
- nelem = 1;
- hashp->NKEYS = 0;
- hashp->LORDER = BYTE_ORDER;
- hashp->BSIZE = DEF_BUCKET_SIZE;
- hashp->BSHIFT = DEF_BUCKET_SHIFT;
- hashp->SGSIZE = DEF_SEGSIZE;
- hashp->SSHIFT = DEF_SEGSIZE_SHIFT;
- hashp->DSIZE = DEF_DIRSIZE;
- hashp->FFACTOR = DEF_FFACTOR;
- hashp->hash = __default_hash;
- memset(hashp->SPARES, 0, sizeof(hashp->SPARES));
- memset(hashp->BITMAPS, 0, sizeof (hashp->BITMAPS));
-
- /* Fix bucket size to be optimal for file system */
- if (file != NULL) {
- if (stat(file, &statbuf))
- return (NULL);
- hashp->BSIZE = statbuf.st_blksize;
- hashp->BSHIFT = __log2(hashp->BSIZE);
- }
-
- if (info) {
- if (info->bsize) {
- /* Round pagesize up to power of 2 */
- hashp->BSHIFT = __log2(info->bsize);
- hashp->BSIZE = 1 << hashp->BSHIFT;
- if (hashp->BSIZE > MAX_BSIZE) {
- errno = EINVAL;
- return (NULL);
- }
- }
- if (info->ffactor)
- hashp->FFACTOR = info->ffactor;
- if (info->hash)
- hashp->hash = info->hash;
- if (info->nelem)
- nelem = info->nelem;
- if (info->lorder) {
- if (info->lorder != BIG_ENDIAN &&
- info->lorder != LITTLE_ENDIAN) {
- errno = EINVAL;
- return (NULL);
- }
- hashp->LORDER = info->lorder;
- }
- }
- /* init_htab should destroy the table and set errno if it fails */
- if (init_htab(hashp, nelem))
- return (NULL);
- else
- return (hashp);
-}
-/*
- * This calls alloc_segs which may run out of memory. Alloc_segs will destroy
- * the table and set errno, so we just pass the error information along.
- *
- * Returns 0 on No Error
- */
-static int
-init_htab(hashp, nelem)
- HTAB *hashp;
- int nelem;
-{
- int nbuckets, nsegs;
- int l2;
-
- /*
- * Divide number of elements by the fill factor and determine a
- * desired number of buckets. Allocate space for the next greater
- * power of two number of buckets.
- */
- nelem = (nelem - 1) / hashp->FFACTOR + 1;
-
- l2 = __log2(MAX(nelem, 2));
- nbuckets = 1 << l2;
-
- hashp->SPARES[l2] = l2 + 1;
- hashp->SPARES[l2 + 1] = l2 + 1;
- hashp->OVFL_POINT = l2;
- hashp->LAST_FREED = 2;
-
- /* First bitmap page is at: splitpoint l2 page offset 1 */
- if (__ibitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0))
- return (-1);
-
- hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1;
- hashp->HIGH_MASK = (nbuckets << 1) - 1;
- hashp->HDRPAGES = ((MAX(sizeof(HASHHDR), MINHDRSIZE) - 1) >>
- hashp->BSHIFT) + 1;
-
- nsegs = (nbuckets - 1) / hashp->SGSIZE + 1;
- nsegs = 1 << __log2(nsegs);
-
- if (nsegs > hashp->DSIZE)
- hashp->DSIZE = nsegs;
- return (alloc_segs(hashp, nsegs));
-}
-
-/********************** DESTROY/CLOSE ROUTINES ************************/
-
-/*
- * Flushes any changes to the file if necessary and destroys the hashp
- * structure, freeing all allocated space.
- */
-static int
-hdestroy(hashp)
- HTAB *hashp;
-{
- int i, save_errno;
-
- save_errno = 0;
-
-#ifdef HASH_STATISTICS
- (void)fprintf(stderr, "hdestroy: accesses %ld collisions %ld\n",
- hash_accesses, hash_collisions);
- (void)fprintf(stderr, "hdestroy: expansions %ld\n",
- hash_expansions);
- (void)fprintf(stderr, "hdestroy: overflows %ld\n",
- hash_overflows);
- (void)fprintf(stderr, "keys %ld maxp %d segmentcount %d\n",
- hashp->NKEYS, hashp->MAX_BUCKET, hashp->nsegs);
-
- for (i = 0; i < NCACHED; i++)
- (void)fprintf(stderr,
- "spares[%d] = %d\n", i, hashp->SPARES[i]);
-#endif
- /*
- * Call on buffer manager to free buffers, and if required,
- * write them to disk.
- */
- if (__buf_free(hashp, 1, hashp->save_file))
- save_errno = errno;
- if (hashp->dir) {
- free(*hashp->dir); /* Free initial segments */
- /* Free extra segments */
- while (hashp->exsegs--)
- free(hashp->dir[--hashp->nsegs]);
- free(hashp->dir);
- }
- if (flush_meta(hashp) && !save_errno)
- save_errno = errno;
- /* Free Bigmaps */
- for (i = 0; i < hashp->nmaps; i++)
- if (hashp->mapp[i])
- free(hashp->mapp[i]);
-
- if (hashp->fp != -1)
- (void)close(hashp->fp);
-
- free(hashp);
-
- if (save_errno) {
- errno = save_errno;
- return (ERROR);
- }
- return (SUCCESS);
-}
-/*
- * Write modified pages to disk
- *
- * Returns:
- * 0 == OK
- * -1 ERROR
- */
-static int
-hash_sync(dbp, flags)
- const DB *dbp;
- u_int32_t flags;
-{
- HTAB *hashp;
-
- if (flags != 0) {
- errno = EINVAL;
- return (ERROR);
- }
-
- if (!dbp)
- return (ERROR);
-
- hashp = (HTAB *)dbp->internal;
- if (!hashp->save_file)
- return (0);
- if (__buf_free(hashp, 0, 1) || flush_meta(hashp))
- return (ERROR);
- hashp->new_file = 0;
- return (0);
-}
-
-/*
- * Returns:
- * 0 == OK
- * -1 indicates that errno should be set
- */
-static int
-flush_meta(hashp)
- HTAB *hashp;
-{
- HASHHDR *whdrp;
-#if BYTE_ORDER == LITTLE_ENDIAN
- HASHHDR whdr;
-#endif
- int fp, i, wsize;
-
- if (!hashp->save_file)
- return (0);
- hashp->MAGIC = HASHMAGIC;
- hashp->VERSION = HASHVERSION;
- hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY));
-
- fp = hashp->fp;
- whdrp = &hashp->hdr;
-#if BYTE_ORDER == LITTLE_ENDIAN
- whdrp = &whdr;
- swap_header_copy(&hashp->hdr, whdrp);
-#endif
- if ((lseek(fp, (off_t)0, SEEK_SET) == -1) ||
- ((wsize = write(fp, whdrp, sizeof(HASHHDR))) == -1))
- return (-1);
- else
- if (wsize != sizeof(HASHHDR)) {
- errno = EFTYPE;
- hashp->error = errno;
- return (-1);
- }
- for (i = 0; i < NCACHED; i++)
- if (hashp->mapp[i])
- if (__put_page(hashp, (char *)hashp->mapp[i],
- hashp->BITMAPS[i], 0, 1))
- return (-1);
- return (0);
-}
-
-/*******************************SEARCH ROUTINES *****************************/
-/*
- * All the access routines return
- *
- * Returns:
- * 0 on SUCCESS
- * 1 to indicate an external ERROR (i.e. key not found, etc)
- * -1 to indicate an internal ERROR (i.e. out of memory, etc)
- */
-static int
-hash_get(dbp, key, data, flag)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int32_t flag;
-{
- HTAB *hashp;
-
- hashp = (HTAB *)dbp->internal;
- if (flag) {
- hashp->error = errno = EINVAL;
- return (ERROR);
- }
- return (hash_access(hashp, HASH_GET, (DBT *)key, data));
-}
-
-static int
-hash_put(dbp, key, data, flag)
- const DB *dbp;
- DBT *key;
- const DBT *data;
- u_int32_t flag;
-{
- HTAB *hashp;
-
- hashp = (HTAB *)dbp->internal;
- if (flag && flag != R_NOOVERWRITE) {
- hashp->error = EINVAL;
- errno = EINVAL;
- return (ERROR);
- }
- if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
- hashp->error = errno = EPERM;
- return (ERROR);
- }
- return (hash_access(hashp, flag == R_NOOVERWRITE ?
- HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data));
-}
-
-static int
-hash_delete(dbp, key, flag)
- const DB *dbp;
- const DBT *key;
- u_int32_t flag; /* Ignored */
-{
- HTAB *hashp;
-
- hashp = (HTAB *)dbp->internal;
- if (flag && flag != R_CURSOR) {
- hashp->error = errno = EINVAL;
- return (ERROR);
- }
- if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
- hashp->error = errno = EPERM;
- return (ERROR);
- }
- return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL));
-}
-
-/*
- * Assume that hashp has been set in wrapper routine.
- */
-static int
-hash_access(hashp, action, key, val)
- HTAB *hashp;
- ACTION action;
- DBT *key, *val;
-{
- BUFHEAD *rbufp;
- BUFHEAD *bufp, *save_bufp;
- u_int16_t *bp;
- int n, ndx, off, size;
- char *kp;
- u_int16_t pageno;
-
-#ifdef HASH_STATISTICS
- hash_accesses++;
-#endif
-
- off = hashp->BSIZE;
- size = key->size;
- kp = (char *)key->data;
- rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0);
- if (!rbufp)
- return (ERROR);
- save_bufp = rbufp;
-
- /* Pin the bucket chain */
- rbufp->flags |= BUF_PIN;
- for (bp = (u_int16_t *)rbufp->page, n = *bp++, ndx = 1; ndx < n;)
- if (bp[1] >= REAL_KEY) {
- /* Real key/data pair */
- if (size == off - *bp &&
- memcmp(kp, rbufp->page + *bp, size) == 0)
- goto found;
- off = bp[1];
-#ifdef HASH_STATISTICS
- hash_collisions++;
-#endif
- bp += 2;
- ndx += 2;
- } else if (bp[1] == OVFLPAGE) {
- rbufp = __get_buf(hashp, *bp, rbufp, 0);
- if (!rbufp) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- /* FOR LOOP INIT */
- bp = (u_int16_t *)rbufp->page;
- n = *bp++;
- ndx = 1;
- off = hashp->BSIZE;
- } else if (bp[1] < REAL_KEY) {
- if ((ndx =
- __find_bigpair(hashp, rbufp, ndx, kp, size)) > 0)
- goto found;
- if (ndx == -2) {
- bufp = rbufp;
- if (!(pageno =
- __find_last_page(hashp, &bufp))) {
- ndx = 0;
- rbufp = bufp;
- break; /* FOR */
- }
- rbufp = __get_buf(hashp, pageno, bufp, 0);
- if (!rbufp) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- /* FOR LOOP INIT */
- bp = (u_int16_t *)rbufp->page;
- n = *bp++;
- ndx = 1;
- off = hashp->BSIZE;
- } else {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- }
-
- /* Not found */
- switch (action) {
- case HASH_PUT:
- case HASH_PUTNEW:
- if (__addel(hashp, rbufp, key, val)) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- } else {
- save_bufp->flags &= ~BUF_PIN;
- return (SUCCESS);
- }
- case HASH_GET:
- case HASH_DELETE:
- default:
- save_bufp->flags &= ~BUF_PIN;
- return (ABNORMAL);
- }
-
-found:
- switch (action) {
- case HASH_PUTNEW:
- save_bufp->flags &= ~BUF_PIN;
- return (ABNORMAL);
- case HASH_GET:
- bp = (u_int16_t *)rbufp->page;
- if (bp[ndx + 1] < REAL_KEY) {
- if (__big_return(hashp, rbufp, ndx, val, 0))
- return (ERROR);
- } else {
- val->data = (u_char *)rbufp->page + (int)bp[ndx + 1];
- val->size = bp[ndx] - bp[ndx + 1];
- }
- break;
- case HASH_PUT:
- if ((__delpair(hashp, rbufp, ndx)) ||
- (__addel(hashp, rbufp, key, val))) {
- save_bufp->flags &= ~BUF_PIN;
- return (ERROR);
- }
- break;
- case HASH_DELETE:
- if (__delpair(hashp, rbufp, ndx))
- return (ERROR);
- break;
- default:
- abort();
- }
- save_bufp->flags &= ~BUF_PIN;
- return (SUCCESS);
-}
-
-static int
-hash_seq(dbp, key, data, flag)
- const DB *dbp;
- DBT *key, *data;
- u_int32_t flag;
-{
- u_int32_t bucket;
- BUFHEAD *bufp;
- HTAB *hashp;
- u_int16_t *bp, ndx;
-
- hashp = (HTAB *)dbp->internal;
- if (flag && flag != R_FIRST && flag != R_NEXT) {
- hashp->error = errno = EINVAL;
- return (ERROR);
- }
-#ifdef HASH_STATISTICS
- hash_accesses++;
-#endif
- if ((hashp->cbucket < 0) || (flag == R_FIRST)) {
- hashp->cbucket = 0;
- hashp->cndx = 1;
- hashp->cpage = NULL;
- }
-
- for (bp = NULL; !bp || !bp[0]; ) {
- if (!(bufp = hashp->cpage)) {
- for (bucket = hashp->cbucket;
- bucket <= hashp->MAX_BUCKET;
- bucket++, hashp->cndx = 1) {
- bufp = __get_buf(hashp, bucket, NULL, 0);
- if (!bufp)
- return (ERROR);
- hashp->cpage = bufp;
- bp = (u_int16_t *)bufp->page;
- if (bp[0])
- break;
- }
- hashp->cbucket = bucket;
- if (hashp->cbucket > hashp->MAX_BUCKET) {
- hashp->cbucket = -1;
- return (ABNORMAL);
- }
- } else
- bp = (u_int16_t *)hashp->cpage->page;
-
-#ifdef DEBUG
- assert(bp);
- assert(bufp);
-#endif
- while (bp[hashp->cndx + 1] == OVFLPAGE) {
- bufp = hashp->cpage =
- __get_buf(hashp, bp[hashp->cndx], bufp, 0);
- if (!bufp)
- return (ERROR);
- bp = (u_int16_t *)(bufp->page);
- hashp->cndx = 1;
- }
- if (!bp[0]) {
- hashp->cpage = NULL;
- ++hashp->cbucket;
- }
- }
- ndx = hashp->cndx;
- if (bp[ndx + 1] < REAL_KEY) {
- if (__big_keydata(hashp, bufp, key, data, 1))
- return (ERROR);
- } else {
- key->data = (u_char *)hashp->cpage->page + bp[ndx];
- key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx];
- data->data = (u_char *)hashp->cpage->page + bp[ndx + 1];
- data->size = bp[ndx] - bp[ndx + 1];
- ndx += 2;
- if (ndx > bp[0]) {
- hashp->cpage = NULL;
- hashp->cbucket++;
- hashp->cndx = 1;
- } else
- hashp->cndx = ndx;
- }
- return (SUCCESS);
-}
-
-/********************************* UTILITIES ************************/
-
-/*
- * Returns:
- * 0 ==> OK
- * -1 ==> Error
- */
-extern int
-__expand_table(hashp)
- HTAB *hashp;
-{
- u_int32_t old_bucket, new_bucket;
- int dirsize, new_segnum, spare_ndx;
-
-#ifdef HASH_STATISTICS
- hash_expansions++;
-#endif
- new_bucket = ++hashp->MAX_BUCKET;
- old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK);
-
- new_segnum = new_bucket >> hashp->SSHIFT;
-
- /* Check if we need a new segment */
- if (new_segnum >= hashp->nsegs) {
- /* Check if we need to expand directory */
- if (new_segnum >= hashp->DSIZE) {
- /* Reallocate directory */
- dirsize = hashp->DSIZE * sizeof(SEGMENT *);
- if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1))
- return (-1);
- hashp->DSIZE = dirsize << 1;
- }
- if ((hashp->dir[new_segnum] =
- (SEGMENT)calloc(hashp->SGSIZE, sizeof(SEGMENT))) == NULL)
- return (-1);
- hashp->exsegs++;
- hashp->nsegs++;
- }
- /*
- * If the split point is increasing (MAX_BUCKET's log base 2
- * * increases), we need to copy the current contents of the spare
- * split bucket to the next bucket.
- */
- spare_ndx = __log2(hashp->MAX_BUCKET + 1);
- if (spare_ndx > hashp->OVFL_POINT) {
- hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];
- hashp->OVFL_POINT = spare_ndx;
- }
-
- if (new_bucket > hashp->HIGH_MASK) {
- /* Starting a new doubling */
- hashp->LOW_MASK = hashp->HIGH_MASK;
- hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK;
- }
- /* Relocate records to the new bucket */
- return (__split_page(hashp, old_bucket, new_bucket));
-}
-
-/*
- * If realloc guarantees that the pointer is not destroyed if the realloc
- * fails, then this routine can go away.
- */
-static void *
-hash_realloc(p_ptr, oldsize, newsize)
- SEGMENT **p_ptr;
- int oldsize, newsize;
-{
- void *p;
-
- if ( (p = malloc(newsize)) ) {
- memmove(p, *p_ptr, oldsize);
- memset((char *)p + oldsize, 0, newsize - oldsize);
- free(*p_ptr);
- *p_ptr = p;
- }
- return (p);
-}
-
-extern u_int32_t
-__call_hash(hashp, k, len)
- HTAB *hashp;
- char *k;
- int len;
-{
- int n, bucket;
-
- n = hashp->hash(k, len);
- bucket = n & hashp->HIGH_MASK;
- if (bucket > hashp->MAX_BUCKET)
- bucket = bucket & hashp->LOW_MASK;
- return (bucket);
-}
-
-/*
- * Allocate segment table. On error, destroy the table and set errno.
- *
- * Returns 0 on success
- */
-static int
-alloc_segs(hashp, nsegs)
- HTAB *hashp;
- int nsegs;
-{
- int i;
- SEGMENT store;
-
- int save_errno;
-
- if ((hashp->dir =
- (SEGMENT *)calloc(hashp->DSIZE, sizeof(SEGMENT *))) == NULL) {
- save_errno = errno;
- (void)hdestroy(hashp);
- errno = save_errno;
- return (-1);
- }
- /* Allocate segments */
- if ((store =
- (SEGMENT)calloc(nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) {
- save_errno = errno;
- (void)hdestroy(hashp);
- errno = save_errno;
- return (-1);
- }
- for (i = 0; i < nsegs; i++, hashp->nsegs++)
- hashp->dir[i] = &store[i << hashp->SSHIFT];
- return (0);
-}
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-/*
- * Hashp->hdr needs to be byteswapped.
- */
-static void
-swap_header_copy(srcp, destp)
- HASHHDR *srcp, *destp;
-{
- int i;
-
- P_32_COPY(srcp->magic, destp->magic);
- P_32_COPY(srcp->version, destp->version);
- P_32_COPY(srcp->lorder, destp->lorder);
- P_32_COPY(srcp->bsize, destp->bsize);
- P_32_COPY(srcp->bshift, destp->bshift);
- P_32_COPY(srcp->dsize, destp->dsize);
- P_32_COPY(srcp->ssize, destp->ssize);
- P_32_COPY(srcp->sshift, destp->sshift);
- P_32_COPY(srcp->ovfl_point, destp->ovfl_point);
- P_32_COPY(srcp->last_freed, destp->last_freed);
- P_32_COPY(srcp->max_bucket, destp->max_bucket);
- P_32_COPY(srcp->high_mask, destp->high_mask);
- P_32_COPY(srcp->low_mask, destp->low_mask);
- P_32_COPY(srcp->ffactor, destp->ffactor);
- P_32_COPY(srcp->nkeys, destp->nkeys);
- P_32_COPY(srcp->hdrpages, destp->hdrpages);
- P_32_COPY(srcp->h_charkey, destp->h_charkey);
- for (i = 0; i < NCACHED; i++) {
- P_32_COPY(srcp->spares[i], destp->spares[i]);
- P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]);
- }
-}
-
-static void
-swap_header(hashp)
- HTAB *hashp;
-{
- HASHHDR *hdrp;
- int i;
-
- hdrp = &hashp->hdr;
-
- M_32_SWAP(hdrp->magic);
- M_32_SWAP(hdrp->version);
- M_32_SWAP(hdrp->lorder);
- M_32_SWAP(hdrp->bsize);
- M_32_SWAP(hdrp->bshift);
- M_32_SWAP(hdrp->dsize);
- M_32_SWAP(hdrp->ssize);
- M_32_SWAP(hdrp->sshift);
- M_32_SWAP(hdrp->ovfl_point);
- M_32_SWAP(hdrp->last_freed);
- M_32_SWAP(hdrp->max_bucket);
- M_32_SWAP(hdrp->high_mask);
- M_32_SWAP(hdrp->low_mask);
- M_32_SWAP(hdrp->ffactor);
- M_32_SWAP(hdrp->nkeys);
- M_32_SWAP(hdrp->hdrpages);
- M_32_SWAP(hdrp->h_charkey);
- for (i = 0; i < NCACHED; i++) {
- M_32_SWAP(hdrp->spares[i]);
- M_16_SWAP(hdrp->bitmaps[i]);
- }
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)hash.h 8.3 (Berkeley) 5/31/94
- * $FreeBSD: src/lib/libc/db/hash/hash.h,v 1.6 2002/03/21 22:46:26 obrien Exp $
- */
-
-/* Operations */
-typedef enum {
- HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE, HASH_FIRST, HASH_NEXT
-} ACTION;
-
-/* Buffer Management structures */
-typedef struct _bufhead BUFHEAD;
-
-struct _bufhead {
- BUFHEAD *prev; /* LRU links */
- BUFHEAD *next; /* LRU links */
- BUFHEAD *ovfl; /* Overflow page buffer header */
- u_int32_t addr; /* Address of this page */
- char *page; /* Actual page data */
- char flags;
-#define BUF_MOD 0x0001
-#define BUF_DISK 0x0002
-#define BUF_BUCKET 0x0004
-#define BUF_PIN 0x0008
-};
-
-#define IS_BUCKET(X) ((X) & BUF_BUCKET)
-
-typedef BUFHEAD **SEGMENT;
-
-/* Hash Table Information */
-typedef struct hashhdr { /* Disk resident portion */
- int magic; /* Magic NO for hash tables */
- int version; /* Version ID */
- u_int32_t lorder; /* Byte Order */
- int bsize; /* Bucket/Page Size */
- int bshift; /* Bucket shift */
- int dsize; /* Directory Size */
- int ssize; /* Segment Size */
- int sshift; /* Segment shift */
- int ovfl_point; /* Where overflow pages are being
- * allocated */
- int last_freed; /* Last overflow page freed */
- int max_bucket; /* ID of Maximum bucket in use */
- int high_mask; /* Mask to modulo into entire table */
- int low_mask; /* Mask to modulo into lower half of
- * table */
- int ffactor; /* Fill factor */
- int nkeys; /* Number of keys in hash table */
- int hdrpages; /* Size of table header */
- int h_charkey; /* value of hash(CHARKEY) */
-#define NCACHED 32 /* number of bit maps and spare
- * points */
- int spares[NCACHED];/* spare pages for overflow */
- u_int16_t bitmaps[NCACHED]; /* address of overflow page
- * bitmaps */
-} HASHHDR;
-
-typedef struct htab { /* Memory resident data structure */
- HASHHDR hdr; /* Header */
- int nsegs; /* Number of allocated segments */
- int exsegs; /* Number of extra allocated
- * segments */
- u_int32_t /* Hash function */
- (*hash)(const void *, size_t);
- int flags; /* Flag values */
- int fp; /* File pointer */
- char *tmp_buf; /* Temporary Buffer for BIG data */
- char *tmp_key; /* Temporary Buffer for BIG keys */
- BUFHEAD *cpage; /* Current page */
- int cbucket; /* Current bucket */
- int cndx; /* Index of next item on cpage */
- int error; /* Error Number -- for DBM
- * compatibility */
- int new_file; /* Indicates if fd is backing store
- * or no */
- int save_file; /* Indicates whether we need to flush
- * file at
- * exit */
- u_int32_t *mapp[NCACHED]; /* Pointers to page maps */
- int nmaps; /* Initial number of bitmaps */
- int nbufs; /* Number of buffers left to
- * allocate */
- BUFHEAD bufhead; /* Header of buffer lru list */
- SEGMENT *dir; /* Hash Bucket directory */
-} HTAB;
-
-/*
- * Constants
- */
-#define MAX_BSIZE 65536 /* 2^16 */
-#define MIN_BUFFERS 6
-#define MINHDRSIZE 512
-#define DEF_BUFSIZE 65536 /* 64 K */
-#define DEF_BUCKET_SIZE 4096
-#define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */
-#define DEF_SEGSIZE 256
-#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */
-#define DEF_DIRSIZE 256
-#define DEF_FFACTOR 65536
-#define MIN_FFACTOR 4
-#define SPLTMAX 8
-#define CHARKEY "%$sniglet^&"
-#define NUMKEY 1038583
-#define BYTE_SHIFT 3
-#define INT_TO_BYTE 2
-#define INT_BYTE_SHIFT 5
-#define ALL_SET ((u_int32_t)0xFFFFFFFF)
-#define ALL_CLEAR 0
-
-#define PTROF(X) ((BUFHEAD *)((ptrdiff_t)(X)&~0x3))
-#define ISMOD(X) ((u_int32_t)(ptrdiff_t)(X)&0x1)
-#define DOMOD(X) ((X) = (char *)((ptrdiff_t)(X)|0x1))
-#define ISDISK(X) ((u_int32_t)(ptrdiff_t)(X)&0x2)
-#define DODISK(X) ((X) = (char *)((ptrdiff_t)(X)|0x2))
-
-#define BITS_PER_MAP 32
-
-/* Given the address of the beginning of a big map, clear/set the nth bit */
-#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP)))
-#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP)))
-#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP)))
-
-/* Overflow management */
-/*
- * Overflow page numbers are allocated per split point. At each doubling of
- * the table, we can allocate extra pages. So, an overflow page number has
- * the top 5 bits indicate which split point and the lower 11 bits indicate
- * which page at that split point is indicated (pages within split points are
- * numberered starting with 1).
- */
-
-#define SPLITSHIFT 11
-#define SPLITMASK 0x7FF
-#define SPLITNUM(N) (((u_int32_t)(N)) >> SPLITSHIFT)
-#define OPAGENUM(N) ((N) & SPLITMASK)
-#define OADDR_OF(S,O) ((u_int32_t)((u_int32_t)(S) << SPLITSHIFT) + (O))
-
-#define BUCKET_TO_PAGE(B) \
- (B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__log2((B)+1)-1] : 0)
-#define OADDR_TO_PAGE(B) \
- BUCKET_TO_PAGE ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B));
-
-/*
- * page.h contains a detailed description of the page format.
- *
- * Normally, keys and data are accessed from offset tables in the top of
- * each page which point to the beginning of the key and data. There are
- * four flag values which may be stored in these offset tables which indicate
- * the following:
- *
- *
- * OVFLPAGE Rather than a key data pair, this pair contains
- * the address of an overflow page. The format of
- * the pair is:
- * OVERFLOW_PAGE_NUMBER OVFLPAGE
- *
- * PARTIAL_KEY This must be the first key/data pair on a page
- * and implies that page contains only a partial key.
- * That is, the key is too big to fit on a single page
- * so it starts on this page and continues on the next.
- * The format of the page is:
- * KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE
- *
- * KEY_OFF -- offset of the beginning of the key
- * PARTIAL_KEY -- 1
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * FULL_KEY This must be the first key/data pair on the page. It
- * is used in two cases.
- *
- * Case 1:
- * There is a complete key on the page but no data
- * (because it wouldn't fit). The next page contains
- * the data.
- *
- * Page format it:
- * KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
- *
- * KEY_OFF -- offset of the beginning of the key
- * FULL_KEY -- 2
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * Case 2:
- * This page contains no key, but part of a large
- * data field, which is continued on the next page.
- *
- * Page format it:
- * DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
- *
- * KEY_OFF -- offset of the beginning of the data on
- * this page
- * FULL_KEY -- 2
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * FULL_KEY_DATA
- * This must be the first key/data pair on the page.
- * There are two cases:
- *
- * Case 1:
- * This page contains a key and the beginning of the
- * data field, but the data field is continued on the
- * next page.
- *
- * Page format is:
- * KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF
- *
- * KEY_OFF -- offset of the beginning of the key
- * FULL_KEY_DATA -- 3
- * OVFL_PAGENO - page number of the next overflow page
- * DATA_OFF -- offset of the beginning of the data
- *
- * Case 2:
- * This page contains the last page of a big data pair.
- * There is no key, only the tail end of the data
- * on this page.
- *
- * Page format is:
- * DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE>
- *
- * DATA_OFF -- offset of the beginning of the data on
- * this page
- * FULL_KEY_DATA -- 3
- * OVFL_PAGENO - page number of the next overflow page
- * OVFLPAGE -- 0
- *
- * OVFL_PAGENO and OVFLPAGE are optional (they are
- * not present if there is no next page).
- */
-
-#define OVFLPAGE 0
-#define PARTIAL_KEY 1
-#define FULL_KEY 2
-#define FULL_KEY_DATA 3
-#define REAL_KEY 4
-
-/* Short hands for accessing structure */
-#define BSIZE hdr.bsize
-#define BSHIFT hdr.bshift
-#define DSIZE hdr.dsize
-#define SGSIZE hdr.ssize
-#define SSHIFT hdr.sshift
-#define LORDER hdr.lorder
-#define OVFL_POINT hdr.ovfl_point
-#define LAST_FREED hdr.last_freed
-#define MAX_BUCKET hdr.max_bucket
-#define FFACTOR hdr.ffactor
-#define HIGH_MASK hdr.high_mask
-#define LOW_MASK hdr.low_mask
-#define NKEYS hdr.nkeys
-#define HDRPAGES hdr.hdrpages
-#define SPARES hdr.spares
-#define BITMAPS hdr.bitmaps
-#define VERSION hdr.version
-#define MAGIC hdr.magic
-#define NEXT_FREE hdr.next_free
-#define H_CHARKEY hdr.h_charkey
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-/*
- * PACKAGE: hash
- * DESCRIPTION:
- * Big key/data handling for the hashing package.
- *
- * ROUTINES:
- * External
- * __big_keydata
- * __big_split
- * __big_insert
- * __big_return
- * __big_delete
- * __find_last_page
- * Internal
- * collect_key
- * collect_data
- */
-
-#include <sys/param.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include <db.h>
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static int collect_key(HTAB *, BUFHEAD *, int, DBT *, int);
-static int collect_data(HTAB *, BUFHEAD *, int, int);
-
-/*
- * Big_insert
- *
- * You need to do an insert and the key/data pair is too big
- *
- * Returns:
- * 0 ==> OK
- *-1 ==> ERROR
- */
-extern int
-__big_insert(hashp, bufp, key, val)
- HTAB *hashp;
- BUFHEAD *bufp;
- const DBT *key, *val;
-{
- u_int16_t *p;
- int key_size, n, val_size;
- u_int16_t space, move_bytes, off;
- char *cp, *key_data, *val_data;
-
- cp = bufp->page; /* Character pointer of p. */
- p = (u_int16_t *)cp;
-
- key_data = (char *)key->data;
- key_size = key->size;
- val_data = (char *)val->data;
- val_size = val->size;
-
- /* First move the Key */
- for (space = FREESPACE(p) - BIGOVERHEAD; key_size;
- space = FREESPACE(p) - BIGOVERHEAD) {
- move_bytes = MIN(space, key_size);
- off = OFFSET(p) - move_bytes;
- memmove(cp + off, key_data, move_bytes);
- key_size -= move_bytes;
- key_data += move_bytes;
- n = p[0];
- p[++n] = off;
- p[0] = ++n;
- FREESPACE(p) = off - PAGE_META(n);
- OFFSET(p) = off;
- p[n] = PARTIAL_KEY;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- return (-1);
- n = p[0];
- if (!key_size) {
- if (FREESPACE(p)) {
- move_bytes = MIN(FREESPACE(p), val_size);
- off = OFFSET(p) - move_bytes;
- p[n] = off;
- memmove(cp + off, val_data, move_bytes);
- val_data += move_bytes;
- val_size -= move_bytes;
- p[n - 2] = FULL_KEY_DATA;
- FREESPACE(p) = FREESPACE(p) - move_bytes;
- OFFSET(p) = off;
- } else
- p[n - 2] = FULL_KEY;
- }
- p = (u_int16_t *)bufp->page;
- cp = bufp->page;
- bufp->flags |= BUF_MOD;
- }
-
- /* Now move the data */
- for (space = FREESPACE(p) - BIGOVERHEAD; val_size;
- space = FREESPACE(p) - BIGOVERHEAD) {
- move_bytes = MIN(space, val_size);
- /*
- * Here's the hack to make sure that if the data ends on the
- * same page as the key ends, FREESPACE is at least one.
- */
- if (space == val_size && val_size == val->size)
- move_bytes--;
- off = OFFSET(p) - move_bytes;
- memmove(cp + off, val_data, move_bytes);
- val_size -= move_bytes;
- val_data += move_bytes;
- n = p[0];
- p[++n] = off;
- p[0] = ++n;
- FREESPACE(p) = off - PAGE_META(n);
- OFFSET(p) = off;
- if (val_size) {
- p[n] = FULL_KEY;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- return (-1);
- cp = bufp->page;
- p = (u_int16_t *)cp;
- } else
- p[n] = FULL_KEY_DATA;
- bufp->flags |= BUF_MOD;
- }
- return (0);
-}
-
-/*
- * Called when bufp's page contains a partial key (index should be 1)
- *
- * All pages in the big key/data pair except bufp are freed. We cannot
- * free bufp because the page pointing to it is lost and we can't get rid
- * of its pointer.
- *
- * Returns:
- * 0 => OK
- *-1 => ERROR
- */
-extern int
-__big_delete(hashp, bufp)
- HTAB *hashp;
- BUFHEAD *bufp;
-{
- BUFHEAD *last_bfp, *rbufp;
- u_int16_t *bp, pageno;
- int key_done, n;
-
- rbufp = bufp;
- last_bfp = NULL;
- bp = (u_int16_t *)bufp->page;
- pageno = 0;
- key_done = 0;
-
- while (!key_done || (bp[2] != FULL_KEY_DATA)) {
- if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA)
- key_done = 1;
-
- /*
- * If there is freespace left on a FULL_KEY_DATA page, then
- * the data is short and fits entirely on this page, and this
- * is the last page.
- */
- if (bp[2] == FULL_KEY_DATA && FREESPACE(bp))
- break;
- pageno = bp[bp[0] - 1];
- rbufp->flags |= BUF_MOD;
- rbufp = __get_buf(hashp, pageno, rbufp, 0);
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- last_bfp = rbufp;
- if (!rbufp)
- return (-1); /* Error. */
- bp = (u_int16_t *)rbufp->page;
- }
-
- /*
- * If we get here then rbufp points to the last page of the big
- * key/data pair. Bufp points to the first one -- it should now be
- * empty pointing to the next page after this pair. Can't free it
- * because we don't have the page pointing to it.
- */
-
- /* This is information from the last page of the pair. */
- n = bp[0];
- pageno = bp[n - 1];
-
- /* Now, bp is the first page of the pair. */
- bp = (u_int16_t *)bufp->page;
- if (n > 2) {
- /* There is an overflow page. */
- bp[1] = pageno;
- bp[2] = OVFLPAGE;
- bufp->ovfl = rbufp->ovfl;
- } else
- /* This is the last page. */
- bufp->ovfl = NULL;
- n -= 2;
- bp[0] = n;
- FREESPACE(bp) = hashp->BSIZE - PAGE_META(n);
- OFFSET(bp) = hashp->BSIZE - 1;
-
- bufp->flags |= BUF_MOD;
- if (rbufp)
- __free_ovflpage(hashp, rbufp);
- if (last_bfp != rbufp)
- __free_ovflpage(hashp, last_bfp);
-
- hashp->NKEYS--;
- return (0);
-}
-/*
- * Returns:
- * 0 = key not found
- * -1 = get next overflow page
- * -2 means key not found and this is big key/data
- * -3 error
- */
-extern int
-__find_bigpair(hashp, bufp, ndx, key, size)
- HTAB *hashp;
- BUFHEAD *bufp;
- int ndx;
- char *key;
- int size;
-{
- u_int16_t *bp;
- char *p;
- int ksize;
- u_int16_t bytes;
- char *kkey;
-
- bp = (u_int16_t *)bufp->page;
- p = bufp->page;
- ksize = size;
- kkey = key;
-
- for (bytes = hashp->BSIZE - bp[ndx];
- bytes <= size && bp[ndx + 1] == PARTIAL_KEY;
- bytes = hashp->BSIZE - bp[ndx]) {
- if (memcmp(p + bp[ndx], kkey, bytes))
- return (-2);
- kkey += bytes;
- ksize -= bytes;
- bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0);
- if (!bufp)
- return (-3);
- p = bufp->page;
- bp = (u_int16_t *)p;
- ndx = 1;
- }
-
- if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) {
-#ifdef HASH_STATISTICS
- ++hash_collisions;
-#endif
- return (-2);
- } else
- return (ndx);
-}
-
-/*
- * Given the buffer pointer of the first overflow page of a big pair,
- * find the end of the big pair
- *
- * This will set bpp to the buffer header of the last page of the big pair.
- * It will return the pageno of the overflow page following the last page
- * of the pair; 0 if there isn't any (i.e. big pair is the last key in the
- * bucket)
- */
-extern u_int16_t
-__find_last_page(hashp, bpp)
- HTAB *hashp;
- BUFHEAD **bpp;
-{
- BUFHEAD *bufp;
- u_int16_t *bp, pageno;
- int n;
-
- bufp = *bpp;
- bp = (u_int16_t *)bufp->page;
- for (;;) {
- n = bp[0];
-
- /*
- * This is the last page if: the tag is FULL_KEY_DATA and
- * either only 2 entries OVFLPAGE marker is explicit there
- * is freespace on the page.
- */
- if (bp[2] == FULL_KEY_DATA &&
- ((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp))))
- break;
-
- pageno = bp[n - 1];
- bufp = __get_buf(hashp, pageno, bufp, 0);
- if (!bufp)
- return (0); /* Need to indicate an error! */
- bp = (u_int16_t *)bufp->page;
- }
-
- *bpp = bufp;
- if (bp[0] > 2)
- return (bp[3]);
- else
- return (0);
-}
-
-/*
- * Return the data for the key/data pair that begins on this page at this
- * index (index should always be 1).
- */
-extern int
-__big_return(hashp, bufp, ndx, val, set_current)
- HTAB *hashp;
- BUFHEAD *bufp;
- int ndx;
- DBT *val;
- int set_current;
-{
- BUFHEAD *save_p;
- u_int16_t *bp, len, off, save_addr;
- char *tp;
-
- bp = (u_int16_t *)bufp->page;
- while (bp[ndx + 1] == PARTIAL_KEY) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- ndx = 1;
- }
-
- if (bp[ndx + 1] == FULL_KEY) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- save_p = bufp;
- save_addr = save_p->addr;
- off = bp[1];
- len = 0;
- } else
- if (!FREESPACE(bp)) {
- /*
- * This is a hack. We can't distinguish between
- * FULL_KEY_DATA that contains complete data or
- * incomplete data, so we require that if the data
- * is complete, there is at least 1 byte of free
- * space left.
- */
- off = bp[bp[0]];
- len = bp[1] - off;
- save_p = bufp;
- save_addr = bufp->addr;
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- } else {
- /* The data is all on one page. */
- tp = (char *)bp;
- off = bp[bp[0]];
- val->data = (u_char *)tp + off;
- val->size = bp[1] - off;
- if (set_current) {
- if (bp[0] == 2) { /* No more buckets in
- * chain */
- hashp->cpage = NULL;
- hashp->cbucket++;
- hashp->cndx = 1;
- } else {
- hashp->cpage = __get_buf(hashp,
- bp[bp[0] - 1], bufp, 0);
- if (!hashp->cpage)
- return (-1);
- hashp->cndx = 1;
- if (!((u_int16_t *)
- hashp->cpage->page)[0]) {
- hashp->cbucket++;
- hashp->cpage = NULL;
- }
- }
- }
- return (0);
- }
-
- val->size = collect_data(hashp, bufp, (int)len, set_current);
- if (val->size == -1)
- return (-1);
- if (save_p->addr != save_addr) {
- /* We are pretty short on buffers. */
- errno = EINVAL; /* OUT OF BUFFERS */
- return (-1);
- }
- memmove(hashp->tmp_buf, (save_p->page) + off, len);
- val->data = (u_char *)hashp->tmp_buf;
- return (0);
-}
-/*
- * Count how big the total datasize is by recursing through the pages. Then
- * allocate a buffer and copy the data as you recurse up.
- */
-static int
-collect_data(hashp, bufp, len, set)
- HTAB *hashp;
- BUFHEAD *bufp;
- int len, set;
-{
- u_int16_t *bp;
- char *p;
- BUFHEAD *xbp;
- u_int16_t save_addr;
- int mylen, totlen;
-
- p = bufp->page;
- bp = (u_int16_t *)p;
- mylen = hashp->BSIZE - bp[1];
- save_addr = bufp->addr;
-
- if (bp[2] == FULL_KEY_DATA) { /* End of Data */
- totlen = len + mylen;
- if (hashp->tmp_buf)
- free(hashp->tmp_buf);
- if ((hashp->tmp_buf = (char *)malloc(totlen)) == NULL)
- return (-1);
- if (set) {
- hashp->cndx = 1;
- if (bp[0] == 2) { /* No more buckets in chain */
- hashp->cpage = NULL;
- hashp->cbucket++;
- } else {
- hashp->cpage =
- __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!hashp->cpage)
- return (-1);
- else if (!((u_int16_t *)hashp->cpage->page)[0]) {
- hashp->cbucket++;
- hashp->cpage = NULL;
- }
- }
- }
- } else {
- xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!xbp || ((totlen =
- collect_data(hashp, xbp, len + mylen, set)) < 1))
- return (-1);
- }
- if (bufp->addr != save_addr) {
- errno = EINVAL; /* Out of buffers. */
- return (-1);
- }
- memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], mylen);
- return (totlen);
-}
-
-/*
- * Fill in the key and data for this big pair.
- */
-extern int
-__big_keydata(hashp, bufp, key, val, set)
- HTAB *hashp;
- BUFHEAD *bufp;
- DBT *key, *val;
- int set;
-{
- key->size = collect_key(hashp, bufp, 0, val, set);
- if (key->size == -1)
- return (-1);
- key->data = (u_char *)hashp->tmp_key;
- return (0);
-}
-
-/*
- * Count how big the total key size is by recursing through the pages. Then
- * collect the data, allocate a buffer and copy the key as you recurse up.
- */
-static int
-collect_key(hashp, bufp, len, val, set)
- HTAB *hashp;
- BUFHEAD *bufp;
- int len;
- DBT *val;
- int set;
-{
- BUFHEAD *xbp;
- char *p;
- int mylen, totlen;
- u_int16_t *bp, save_addr;
-
- p = bufp->page;
- bp = (u_int16_t *)p;
- mylen = hashp->BSIZE - bp[1];
-
- save_addr = bufp->addr;
- totlen = len + mylen;
- if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */
- if (hashp->tmp_key != NULL)
- free(hashp->tmp_key);
- if ((hashp->tmp_key = (char *)malloc(totlen)) == NULL)
- return (-1);
- if (__big_return(hashp, bufp, 1, val, set))
- return (-1);
- } else {
- xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!xbp || ((totlen =
- collect_key(hashp, xbp, totlen, val, set)) < 1))
- return (-1);
- }
- if (bufp->addr != save_addr) {
- errno = EINVAL; /* MIS -- OUT OF BUFFERS */
- return (-1);
- }
- memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], mylen);
- return (totlen);
-}
-
-/*
- * Returns:
- * 0 => OK
- * -1 => error
- */
-extern int
-__big_split(hashp, op, np, big_keyp, addr, obucket, ret)
- HTAB *hashp;
- BUFHEAD *op; /* Pointer to where to put keys that go in old bucket */
- BUFHEAD *np; /* Pointer to new bucket page */
- /* Pointer to first page containing the big key/data */
- BUFHEAD *big_keyp;
- int addr; /* Address of big_keyp */
- u_int32_t obucket;/* Old Bucket */
- SPLIT_RETURN *ret;
-{
- BUFHEAD *tmpp;
- u_int16_t *tp;
- BUFHEAD *bp;
- DBT key, val;
- u_int32_t change;
- u_int16_t free_space, n, off;
-
- bp = big_keyp;
-
- /* Now figure out where the big key/data goes */
- if (__big_keydata(hashp, big_keyp, &key, &val, 0))
- return (-1);
- change = (__call_hash(hashp, key.data, key.size) != obucket);
-
- if ( (ret->next_addr = __find_last_page(hashp, &big_keyp)) ) {
- if (!(ret->nextp =
- __get_buf(hashp, ret->next_addr, big_keyp, 0)))
- return (-1);;
- } else
- ret->nextp = NULL;
-
- /* Now make one of np/op point to the big key/data pair */
-#ifdef DEBUG
- assert(np->ovfl == NULL);
-#endif
- if (change)
- tmpp = np;
- else
- tmpp = op;
-
- tmpp->flags |= BUF_MOD;
-#ifdef DEBUG1
- (void)fprintf(stderr,
- "BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr,
- (tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0));
-#endif
- tmpp->ovfl = bp; /* one of op/np point to big_keyp */
- tp = (u_int16_t *)tmpp->page;
-#ifdef DEBUG
- assert(FREESPACE(tp) >= OVFLSIZE);
-#endif
- n = tp[0];
- off = OFFSET(tp);
- free_space = FREESPACE(tp);
- tp[++n] = (u_int16_t)addr;
- tp[++n] = OVFLPAGE;
- tp[0] = n;
- OFFSET(tp) = off;
- FREESPACE(tp) = free_space - OVFLSIZE;
-
- /*
- * Finally, set the new and old return values. BIG_KEYP contains a
- * pointer to the last page of the big key_data pair. Make sure that
- * big_keyp has no following page (2 elements) or create an empty
- * following page.
- */
-
- ret->newp = np;
- ret->oldp = op;
-
- tp = (u_int16_t *)big_keyp->page;
- big_keyp->flags |= BUF_MOD;
- if (tp[0] > 2) {
- /*
- * There may be either one or two offsets on this page. If
- * there is one, then the overflow page is linked on normally
- * and tp[4] is OVFLPAGE. If there are two, tp[4] contains
- * the second offset and needs to get stuffed in after the
- * next overflow page is added.
- */
- n = tp[4];
- free_space = FREESPACE(tp);
- off = OFFSET(tp);
- tp[0] -= 2;
- FREESPACE(tp) = free_space + OVFLSIZE;
- OFFSET(tp) = off;
- tmpp = __add_ovflpage(hashp, big_keyp);
- if (!tmpp)
- return (-1);
- tp[4] = n;
- } else
- tmpp = big_keyp;
-
- if (change)
- ret->newp = tmpp;
- else
- ret->oldp = tmpp;
- return (0);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-/*
- * PACKAGE: hash
- *
- * DESCRIPTION:
- * Contains buffer management
- *
- * ROUTINES:
- * External
- * __buf_init
- * __get_buf
- * __buf_free
- * __reclaim_buf
- * Internal
- * newbuf
- */
-
-#include <sys/param.h>
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include <db.h>
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static BUFHEAD *newbuf(HTAB *, u_int32_t, BUFHEAD *);
-
-/* Unlink B from its place in the lru */
-#define BUF_REMOVE(B) { \
- (B)->prev->next = (B)->next; \
- (B)->next->prev = (B)->prev; \
-}
-
-/* Insert B after P */
-#define BUF_INSERT(B, P) { \
- (B)->next = (P)->next; \
- (B)->prev = (P); \
- (P)->next = (B); \
- (B)->next->prev = (B); \
-}
-
-#define MRU hashp->bufhead.next
-#define LRU hashp->bufhead.prev
-
-#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead)
-#define LRU_INSERT(B) BUF_INSERT((B), LRU)
-
-/*
- * We are looking for a buffer with address "addr". If prev_bp is NULL, then
- * address is a bucket index. If prev_bp is not NULL, then it points to the
- * page previous to an overflow page that we are trying to find.
- *
- * CAVEAT: The buffer header accessed via prev_bp's ovfl field may no longer
- * be valid. Therefore, you must always verify that its address matches the
- * address you are seeking.
- */
-extern BUFHEAD *
-__get_buf(hashp, addr, prev_bp, newpage)
- HTAB *hashp;
- u_int32_t addr;
- BUFHEAD *prev_bp;
- int newpage; /* If prev_bp set, indicates a new overflow page. */
-{
- BUFHEAD *bp;
- u_int32_t is_disk_mask;
- int is_disk, segment_ndx;
- SEGMENT segp;
-
- is_disk = 0;
- is_disk_mask = 0;
- if (prev_bp) {
- bp = prev_bp->ovfl;
- if (!bp || (bp->addr != addr))
- bp = NULL;
- if (!newpage)
- is_disk = BUF_DISK;
- } else {
- /* Grab buffer out of directory */
- segment_ndx = addr & (hashp->SGSIZE - 1);
-
- /* valid segment ensured by __call_hash() */
- segp = hashp->dir[addr >> hashp->SSHIFT];
-#ifdef DEBUG
- assert(segp != NULL);
-#endif
- bp = PTROF(segp[segment_ndx]);
- is_disk_mask = ISDISK(segp[segment_ndx]);
- is_disk = is_disk_mask || !hashp->new_file;
- }
-
- if (!bp) {
- bp = newbuf(hashp, addr, prev_bp);
- if (!bp ||
- __get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0))
- return (NULL);
- if (!prev_bp)
- segp[segment_ndx] =
- (BUFHEAD *)((ptrdiff_t)bp | is_disk_mask);
- } else {
- BUF_REMOVE(bp);
- MRU_INSERT(bp);
- }
- return (bp);
-}
-
-/*
- * We need a buffer for this page. Either allocate one, or evict a resident
- * one (if we have as many buffers as we're allowed) and put this one in.
- *
- * If newbuf finds an error (returning NULL), it also sets errno.
- */
-static BUFHEAD *
-newbuf(hashp, addr, prev_bp)
- HTAB *hashp;
- u_int32_t addr;
- BUFHEAD *prev_bp;
-{
- BUFHEAD *bp; /* The buffer we're going to use */
- BUFHEAD *xbp; /* Temp pointer */
- BUFHEAD *next_xbp;
- SEGMENT segp;
- int segment_ndx;
- u_int16_t oaddr, *shortp;
-
- oaddr = 0;
- bp = LRU;
- /*
- * If LRU buffer is pinned, the buffer pool is too small. We need to
- * allocate more buffers.
- */
- if (hashp->nbufs || (bp->flags & BUF_PIN)) {
- /* Allocate a new one */
- if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL)
- return (NULL);
-#ifdef PURIFY
- memset(bp, 0xff, sizeof(BUFHEAD));
-#endif
- if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) {
- free(bp);
- return (NULL);
- }
-#ifdef PURIFY
- memset(bp->page, 0xff, hashp->BSIZE);
-#endif
- if (hashp->nbufs)
- hashp->nbufs--;
- } else {
- /* Kick someone out */
- BUF_REMOVE(bp);
- /*
- * If this is an overflow page with addr 0, it's already been
- * flushed back in an overflow chain and initialized.
- */
- if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) {
- /*
- * Set oaddr before __put_page so that you get it
- * before bytes are swapped.
- */
- shortp = (u_int16_t *)bp->page;
- if (shortp[0])
- oaddr = shortp[shortp[0] - 1];
- if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page,
- bp->addr, (int)IS_BUCKET(bp->flags), 0))
- return (NULL);
- /*
- * Update the pointer to this page (i.e. invalidate it).
- *
- * If this is a new file (i.e. we created it at open
- * time), make sure that we mark pages which have been
- * written to disk so we retrieve them from disk later,
- * rather than allocating new pages.
- */
- if (IS_BUCKET(bp->flags)) {
- segment_ndx = bp->addr & (hashp->SGSIZE - 1);
- segp = hashp->dir[bp->addr >> hashp->SSHIFT];
-#ifdef DEBUG
- assert(segp != NULL);
-#endif
-
- if (hashp->new_file &&
- ((bp->flags & BUF_MOD) ||
- ISDISK(segp[segment_ndx])))
- segp[segment_ndx] = (BUFHEAD *)BUF_DISK;
- else
- segp[segment_ndx] = NULL;
- }
- /*
- * Since overflow pages can only be access by means of
- * their bucket, free overflow pages associated with
- * this bucket.
- */
- for (xbp = bp; xbp->ovfl;) {
- next_xbp = xbp->ovfl;
- xbp->ovfl = 0;
- xbp = next_xbp;
-
- /* Check that ovfl pointer is up date. */
- if (IS_BUCKET(xbp->flags) ||
- (oaddr != xbp->addr))
- break;
-
- shortp = (u_int16_t *)xbp->page;
- if (shortp[0])
- /* set before __put_page */
- oaddr = shortp[shortp[0] - 1];
- if ((xbp->flags & BUF_MOD) && __put_page(hashp,
- xbp->page, xbp->addr, 0, 0))
- return (NULL);
- xbp->addr = 0;
- xbp->flags = 0;
- BUF_REMOVE(xbp);
- LRU_INSERT(xbp);
- }
- }
- }
-
- /* Now assign this buffer */
- bp->addr = addr;
-#ifdef DEBUG1
- (void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n",
- bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0);
-#endif
- bp->ovfl = NULL;
- if (prev_bp) {
- /*
- * If prev_bp is set, this is an overflow page, hook it in to
- * the buffer overflow links.
- */
-#ifdef DEBUG1
- (void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n",
- prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0),
- (bp ? bp->addr : 0));
-#endif
- prev_bp->ovfl = bp;
- bp->flags = 0;
- } else
- bp->flags = BUF_BUCKET;
- MRU_INSERT(bp);
- return (bp);
-}
-
-extern void
-__buf_init(hashp, nbytes)
- HTAB *hashp;
- int nbytes;
-{
- BUFHEAD *bfp;
- int npages;
-
- bfp = &(hashp->bufhead);
- npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT;
- npages = MAX(npages, MIN_BUFFERS);
-
- hashp->nbufs = npages;
- bfp->next = bfp;
- bfp->prev = bfp;
- /*
- * This space is calloc'd so these are already null.
- *
- * bfp->ovfl = NULL;
- * bfp->flags = 0;
- * bfp->page = NULL;
- * bfp->addr = 0;
- */
-}
-
-extern int
-__buf_free(hashp, do_free, to_disk)
- HTAB *hashp;
- int do_free, to_disk;
-{
- BUFHEAD *bp;
-
- /* Need to make sure that buffer manager has been initialized */
- if (!LRU)
- return (0);
- for (bp = LRU; bp != &hashp->bufhead;) {
- /* Check that the buffer is valid */
- if (bp->addr || IS_BUCKET(bp->flags)) {
- if (to_disk && (bp->flags & BUF_MOD) &&
- __put_page(hashp, bp->page,
- bp->addr, IS_BUCKET(bp->flags), 0))
- return (-1);
- }
- /* Check if we are freeing stuff */
- if (do_free) {
- if (bp->page)
- free(bp->page);
- BUF_REMOVE(bp);
- free(bp);
- bp = LRU;
- } else
- bp = bp->prev;
- }
- return (0);
-}
-
-extern void
-__reclaim_buf(hashp, bp)
- HTAB *hashp;
- BUFHEAD *bp;
-{
- bp->ovfl = 0;
- bp->addr = 0;
- bp->flags = 0;
- BUF_REMOVE(bp);
- LRU_INSERT(bp);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <db.h>
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static u_int32_t hash1(const void *, size_t) ;
-static u_int32_t hash2(const void *, size_t) ;
-static u_int32_t hash3(const void *, size_t) ;
-static u_int32_t hash4(const void *, size_t);
-
-/* Global default hash function */
-u_int32_t (*__default_hash)(const void *, size_t) = hash4;
-
-/*
- * HASH FUNCTIONS
- *
- * Assume that we've already split the bucket to which this key hashes,
- * calculate that bucket, and check that in fact we did already split it.
- *
- * This came from ejb's hsearch.
- */
-
-#define PRIME1 37
-#define PRIME2 1048583
-
-static u_int32_t
-hash1(keyarg, len)
- const void *keyarg;
- size_t len;
-{
- const u_char *key;
- u_int32_t h;
-
- /* Convert string to integer */
- for (key = keyarg, h = 0; len--;)
- h = h * PRIME1 ^ (*key++ - ' ');
- h %= PRIME2;
- return (h);
-}
-
-/*
- * Phong's linear congruential hash
- */
-#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
-
-static u_int32_t
-hash2(keyarg, len)
- const void *keyarg;
- size_t len;
-{
- const u_char *e, *key;
- u_int32_t h;
- u_char c;
-
- key = keyarg;
- e = key + len;
- for (h = 0; key != e;) {
- c = *key++;
- if (!c && key > e)
- break;
- dcharhash(h, c);
- }
- return (h);
-}
-
-/*
- * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte
- * units. On the first time through the loop we get the "leftover bytes"
- * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle
- * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If
- * this routine is heavily used enough, it's worth the ugly coding.
- *
- * OZ's original sdbm hash
- */
-static u_int32_t
-hash3(keyarg, len)
- const void *keyarg;
- size_t len;
-{
- const u_char *key;
- size_t loop;
- u_int32_t h;
-
-#define HASHC h = *key++ + 65599 * h
-
- h = 0;
- key = keyarg;
- if (len > 0) {
- loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1)) {
- case 0:
- do {
- HASHC;
- /* FALLTHROUGH */
- case 7:
- HASHC;
- /* FALLTHROUGH */
- case 6:
- HASHC;
- /* FALLTHROUGH */
- case 5:
- HASHC;
- /* FALLTHROUGH */
- case 4:
- HASHC;
- /* FALLTHROUGH */
- case 3:
- HASHC;
- /* FALLTHROUGH */
- case 2:
- HASHC;
- /* FALLTHROUGH */
- case 1:
- HASHC;
- } while (--loop);
- }
- }
- return (h);
-}
-
-/* Hash function from Chris Torek. */
-static u_int32_t
-hash4(keyarg, len)
- const void *keyarg;
- size_t len;
-{
- const u_char *key;
- size_t loop;
- u_int32_t h;
-
-#define HASH4a h = (h << 5) - h + *key++;
-#define HASH4b h = (h << 5) + h + *key++;
-#define HASH4 HASH4b
-
- h = 0;
- key = keyarg;
- if (len > 0) {
- loop = (len + 8 - 1) >> 3;
-
- switch (len & (8 - 1)) {
- case 0:
- do {
- HASH4;
- /* FALLTHROUGH */
- case 7:
- HASH4;
- /* FALLTHROUGH */
- case 6:
- HASH4;
- /* FALLTHROUGH */
- case 5:
- HASH4;
- /* FALLTHROUGH */
- case 4:
- HASH4;
- /* FALLTHROUGH */
- case 3:
- HASH4;
- /* FALLTHROUGH */
- case 2:
- HASH4;
- /* FALLTHROUGH */
- case 1:
- HASH4;
- } while (--loop);
- }
- }
- return (h);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <db.h>
-
-u_int32_t
-__log2(num)
- u_int32_t num;
-{
- u_int32_t i, limit;
-
- limit = 1;
- for (i = 0; limit < num; limit = limit << 1, i++);
- return (i);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-/*
- * PACKAGE: hashing
- *
- * DESCRIPTION:
- * Page manipulation for hashing package.
- *
- * ROUTINES:
- *
- * External
- * __get_page
- * __add_ovflpage
- * Internal
- * overflow_page
- * open_temp
- */
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#ifdef DEBUG
-#include <assert.h>
-#endif
-
-#include <db.h>
-#include "hash.h"
-#include "page.h"
-#include "extern.h"
-
-static u_int32_t *fetch_bitmap(HTAB *, int);
-static u_int32_t first_free(u_int32_t);
-static int open_temp(HTAB *);
-static u_int16_t overflow_page(HTAB *);
-static void putpair(char *, const DBT *, const DBT *);
-static void squeeze_key(u_int16_t *, const DBT *, const DBT *);
-static int ugly_split
-(HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int);
-
-#define PAGE_INIT(P) { \
- ((u_int16_t *)(P))[0] = 0; \
- ((u_int16_t *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_int16_t); \
- ((u_int16_t *)(P))[2] = hashp->BSIZE; \
-}
-
-/*
- * This is called AFTER we have verified that there is room on the page for
- * the pair (PAIRFITS has returned true) so we go right ahead and start moving
- * stuff on.
- */
-static void
-putpair(p, key, val)
- char *p;
- const DBT *key, *val;
-{
- u_int16_t *bp, n, off;
-
- bp = (u_int16_t *)p;
-
- /* Enter the key first. */
- n = bp[0];
-
- off = OFFSET(bp) - key->size;
- memmove(p + off, key->data, key->size);
- bp[++n] = off;
-
- /* Now the data. */
- off -= val->size;
- memmove(p + off, val->data, val->size);
- bp[++n] = off;
-
- /* Adjust page info. */
- bp[0] = n;
- bp[n + 1] = off - ((n + 3) * sizeof(u_int16_t));
- bp[n + 2] = off;
-}
-
-/*
- * Returns:
- * 0 OK
- * -1 error
- */
-extern int
-__delpair(hashp, bufp, ndx)
- HTAB *hashp;
- BUFHEAD *bufp;
- int ndx;
-{
- u_int16_t *bp, newoff;
- int n;
- u_int16_t pairlen;
-
- bp = (u_int16_t *)bufp->page;
- n = bp[0];
-
- if (bp[ndx + 1] < REAL_KEY)
- return (__big_delete(hashp, bufp));
- if (ndx != 1)
- newoff = bp[ndx - 1];
- else
- newoff = hashp->BSIZE;
- pairlen = newoff - bp[ndx + 1];
-
- if (ndx != (n - 1)) {
- /* Hard Case -- need to shuffle keys */
- int i;
- char *src = bufp->page + (int)OFFSET(bp);
- char *dst = src + (int)pairlen;
- memmove(dst, src, bp[ndx + 1] - OFFSET(bp));
-
- /* Now adjust the pointers */
- for (i = ndx + 2; i <= n; i += 2) {
- if (bp[i + 1] == OVFLPAGE) {
- bp[i - 2] = bp[i];
- bp[i - 1] = bp[i + 1];
- } else {
- bp[i - 2] = bp[i] + pairlen;
- bp[i - 1] = bp[i + 1] + pairlen;
- }
- }
- }
- /* Finally adjust the page data */
- bp[n] = OFFSET(bp) + pairlen;
- bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t);
- bp[0] = n - 2;
- hashp->NKEYS--;
-
- bufp->flags |= BUF_MOD;
- return (0);
-}
-/*
- * Returns:
- * 0 ==> OK
- * -1 ==> Error
- */
-extern int
-__split_page(hashp, obucket, nbucket)
- HTAB *hashp;
- u_int32_t obucket, nbucket;
-{
- BUFHEAD *new_bufp, *old_bufp;
- u_int16_t *ino;
- char *np;
- DBT key, val;
- int n, ndx, retval;
- u_int16_t copyto, diff, off, moved;
- char *op;
-
- copyto = (u_int16_t)hashp->BSIZE;
- off = (u_int16_t)hashp->BSIZE;
- old_bufp = __get_buf(hashp, obucket, NULL, 0);
- if (old_bufp == NULL)
- return (-1);
- new_bufp = __get_buf(hashp, nbucket, NULL, 0);
- if (new_bufp == NULL)
- return (-1);
-
- old_bufp->flags |= (BUF_MOD | BUF_PIN);
- new_bufp->flags |= (BUF_MOD | BUF_PIN);
-
- ino = (u_int16_t *)(op = old_bufp->page);
- np = new_bufp->page;
-
- moved = 0;
-
- for (n = 1, ndx = 1; n < ino[0]; n += 2) {
- if (ino[n + 1] < REAL_KEY) {
- retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
- (int)copyto, (int)moved);
- old_bufp->flags &= ~BUF_PIN;
- new_bufp->flags &= ~BUF_PIN;
- return (retval);
-
- }
- key.data = (u_char *)op + ino[n];
- key.size = off - ino[n];
-
- if (__call_hash(hashp, key.data, key.size) == obucket) {
- /* Don't switch page */
- diff = copyto - off;
- if (diff) {
- copyto = ino[n + 1] + diff;
- memmove(op + copyto, op + ino[n + 1],
- off - ino[n + 1]);
- ino[ndx] = copyto + ino[n] - ino[n + 1];
- ino[ndx + 1] = copyto;
- } else
- copyto = ino[n + 1];
- ndx += 2;
- } else {
- /* Switch page */
- val.data = (u_char *)op + ino[n + 1];
- val.size = ino[n] - ino[n + 1];
- putpair(np, &key, &val);
- moved += 2;
- }
-
- off = ino[n + 1];
- }
-
- /* Now clean up the page */
- ino[0] -= moved;
- FREESPACE(ino) = copyto - sizeof(u_int16_t) * (ino[0] + 3);
- OFFSET(ino) = copyto;
-
-#ifdef DEBUG3
- (void)fprintf(stderr, "split %d/%d\n",
- ((u_int16_t *)np)[0] / 2,
- ((u_int16_t *)op)[0] / 2);
-#endif
- /* unpin both pages */
- old_bufp->flags &= ~BUF_PIN;
- new_bufp->flags &= ~BUF_PIN;
- return (0);
-}
-
-/*
- * Called when we encounter an overflow or big key/data page during split
- * handling. This is special cased since we have to begin checking whether
- * the key/data pairs fit on their respective pages and because we may need
- * overflow pages for both the old and new pages.
- *
- * The first page might be a page with regular key/data pairs in which case
- * we have a regular overflow condition and just need to go on to the next
- * page or it might be a big key/data pair in which case we need to fix the
- * big key/data pair.
- *
- * Returns:
- * 0 ==> success
- * -1 ==> failure
- */
-static int
-ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
- HTAB *hashp;
- u_int32_t obucket; /* Same as __split_page. */
- BUFHEAD *old_bufp, *new_bufp;
- int copyto; /* First byte on page which contains key/data values. */
- int moved; /* Number of pairs moved to new page. */
-{
- BUFHEAD *bufp; /* Buffer header for ino */
- u_int16_t *ino; /* Page keys come off of */
- u_int16_t *np; /* New page */
- u_int16_t *op; /* Page keys go on to if they aren't moving */
-
- BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */
- DBT key, val;
- SPLIT_RETURN ret;
- u_int16_t n, off, ov_addr, scopyto;
- char *cino; /* Character value of ino */
-
- bufp = old_bufp;
- ino = (u_int16_t *)old_bufp->page;
- np = (u_int16_t *)new_bufp->page;
- op = (u_int16_t *)old_bufp->page;
- last_bfp = NULL;
- scopyto = (u_int16_t)copyto; /* ANSI */
-
- n = ino[0] - 1;
- while (n < ino[0]) {
- if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
- if (__big_split(hashp, old_bufp,
- new_bufp, bufp, bufp->addr, obucket, &ret))
- return (-1);
- old_bufp = ret.oldp;
- if (!old_bufp)
- return (-1);
- op = (u_int16_t *)old_bufp->page;
- new_bufp = ret.newp;
- if (!new_bufp)
- return (-1);
- np = (u_int16_t *)new_bufp->page;
- bufp = ret.nextp;
- if (!bufp)
- return (0);
- cino = (char *)bufp->page;
- ino = (u_int16_t *)cino;
- last_bfp = ret.nextp;
- } else if (ino[n + 1] == OVFLPAGE) {
- ov_addr = ino[n];
- /*
- * Fix up the old page -- the extra 2 are the fields
- * which contained the overflow information.
- */
- ino[0] -= (moved + 2);
- FREESPACE(ino) =
- scopyto - sizeof(u_int16_t) * (ino[0] + 3);
- OFFSET(ino) = scopyto;
-
- bufp = __get_buf(hashp, ov_addr, bufp, 0);
- if (!bufp)
- return (-1);
-
- ino = (u_int16_t *)bufp->page;
- n = 1;
- scopyto = hashp->BSIZE;
- moved = 0;
-
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- last_bfp = bufp;
- }
- /* Move regular sized pairs of there are any */
- off = hashp->BSIZE;
- for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
- cino = (char *)ino;
- key.data = (u_char *)cino + ino[n];
- key.size = off - ino[n];
- val.data = (u_char *)cino + ino[n + 1];
- val.size = ino[n] - ino[n + 1];
- off = ino[n + 1];
-
- if (__call_hash(hashp, key.data, key.size) == obucket) {
- /* Keep on old page */
- if (PAIRFITS(op, (&key), (&val)))
- putpair((char *)op, &key, &val);
- else {
- old_bufp =
- __add_ovflpage(hashp, old_bufp);
- if (!old_bufp)
- return (-1);
- op = (u_int16_t *)old_bufp->page;
- putpair((char *)op, &key, &val);
- }
- old_bufp->flags |= BUF_MOD;
- } else {
- /* Move to new page */
- if (PAIRFITS(np, (&key), (&val)))
- putpair((char *)np, &key, &val);
- else {
- new_bufp =
- __add_ovflpage(hashp, new_bufp);
- if (!new_bufp)
- return (-1);
- np = (u_int16_t *)new_bufp->page;
- putpair((char *)np, &key, &val);
- }
- new_bufp->flags |= BUF_MOD;
- }
- }
- }
- if (last_bfp)
- __free_ovflpage(hashp, last_bfp);
- return (0);
-}
-
-/*
- * Add the given pair to the page
- *
- * Returns:
- * 0 ==> OK
- * 1 ==> failure
- */
-extern int
-__addel(hashp, bufp, key, val)
- HTAB *hashp;
- BUFHEAD *bufp;
- const DBT *key, *val;
-{
- u_int16_t *bp, *sop;
- int do_expand;
-
- bp = (u_int16_t *)bufp->page;
- do_expand = 0;
- while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
- /* Exception case */
- if (bp[2] == FULL_KEY_DATA && bp[0] == 2)
- /* This is the last page of a big key/data pair
- and we need to add another page */
- break;
- else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- } else
- /* Try to squeeze key on this page */
- if (FREESPACE(bp) > PAIRSIZE(key, val)) {
- squeeze_key(bp, key, val);
- return (0);
- } else {
- bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
- if (!bufp)
- return (-1);
- bp = (u_int16_t *)bufp->page;
- }
-
- if (PAIRFITS(bp, key, val))
- putpair(bufp->page, key, val);
- else {
- do_expand = 1;
- bufp = __add_ovflpage(hashp, bufp);
- if (!bufp)
- return (-1);
- sop = (u_int16_t *)bufp->page;
-
- if (PAIRFITS(sop, key, val))
- putpair((char *)sop, key, val);
- else
- if (__big_insert(hashp, bufp, key, val))
- return (-1);
- }
- bufp->flags |= BUF_MOD;
- /*
- * If the average number of keys per bucket exceeds the fill factor,
- * expand the table.
- */
- hashp->NKEYS++;
- if (do_expand ||
- (hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
- return (__expand_table(hashp));
- return (0);
-}
-
-/*
- *
- * Returns:
- * pointer on success
- * NULL on error
- */
-extern BUFHEAD *
-__add_ovflpage(hashp, bufp)
- HTAB *hashp;
- BUFHEAD *bufp;
-{
- u_int16_t *sp;
- u_int16_t ndx, ovfl_num;
-#ifdef DEBUG1
- int tmp1, tmp2;
-#endif
- sp = (u_int16_t *)bufp->page;
-
- /* Check if we are dynamically determining the fill factor */
- if (hashp->FFACTOR == DEF_FFACTOR) {
- hashp->FFACTOR = sp[0] >> 1;
- if (hashp->FFACTOR < MIN_FFACTOR)
- hashp->FFACTOR = MIN_FFACTOR;
- }
- bufp->flags |= BUF_MOD;
- ovfl_num = overflow_page(hashp);
-#ifdef DEBUG1
- tmp1 = bufp->addr;
- tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0;
-#endif
- if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1)))
- return (NULL);
- bufp->ovfl->flags |= BUF_MOD;
-#ifdef DEBUG1
- (void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n",
- tmp1, tmp2, bufp->ovfl->addr);
-#endif
- ndx = sp[0];
- /*
- * Since a pair is allocated on a page only if there's room to add
- * an overflow page, we know that the OVFL information will fit on
- * the page.
- */
- sp[ndx + 4] = OFFSET(sp);
- sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE;
- sp[ndx + 1] = ovfl_num;
- sp[ndx + 2] = OVFLPAGE;
- sp[0] = ndx + 2;
-#ifdef HASH_STATISTICS
- hash_overflows++;
-#endif
- return (bufp->ovfl);
-}
-
-/*
- * Returns:
- * 0 indicates SUCCESS
- * -1 indicates FAILURE
- */
-extern int
-__get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
- HTAB *hashp;
- char *p;
- u_int32_t bucket;
- int is_bucket, is_disk, is_bitmap;
-{
- int fd, page, size;
- int rsize;
- u_int16_t *bp;
-
- fd = hashp->fp;
- size = hashp->BSIZE;
-
- if ((fd == -1) || !is_disk) {
- PAGE_INIT(p);
- return (0);
- }
- if (is_bucket)
- page = BUCKET_TO_PAGE(bucket);
- else
- page = OADDR_TO_PAGE(bucket);
- if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
- ((rsize = read(fd, p, size)) == -1))
- return (-1);
- bp = (u_int16_t *)p;
- if (!rsize)
- bp[0] = 0; /* We hit the EOF, so initialize a new page */
- else
- if (rsize != size) {
- errno = EFTYPE;
- return (-1);
- }
- if (!is_bitmap && !bp[0]) {
- PAGE_INIT(p);
- } else
- if (hashp->LORDER != BYTE_ORDER) {
- int i, max;
-
- if (is_bitmap) {
- max = hashp->BSIZE >> 2; /* divide by 4 */
- for (i = 0; i < max; i++)
- M_32_SWAP(((int *)p)[i]);
- } else {
- M_16_SWAP(bp[0]);
- max = bp[0] + 2;
- for (i = 1; i <= max; i++)
- M_16_SWAP(bp[i]);
- }
- }
- return (0);
-}
-
-/*
- * Write page p to disk
- *
- * Returns:
- * 0 ==> OK
- * -1 ==>failure
- */
-extern int
-__put_page(hashp, p, bucket, is_bucket, is_bitmap)
- HTAB *hashp;
- char *p;
- u_int32_t bucket;
- int is_bucket, is_bitmap;
-{
- int fd, page, size;
- int wsize;
-
- size = hashp->BSIZE;
- if ((hashp->fp == -1) && open_temp(hashp))
- return (-1);
- fd = hashp->fp;
-
- if (hashp->LORDER != BYTE_ORDER) {
- int i;
- int max;
-
- if (is_bitmap) {
- max = hashp->BSIZE >> 2; /* divide by 4 */
- for (i = 0; i < max; i++)
- M_32_SWAP(((int *)p)[i]);
- } else {
- max = ((u_int16_t *)p)[0] + 2;
- for (i = 0; i <= max; i++)
- M_16_SWAP(((u_int16_t *)p)[i]);
- }
- }
- if (is_bucket)
- page = BUCKET_TO_PAGE(bucket);
- else
- page = OADDR_TO_PAGE(bucket);
- if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
- ((wsize = write(fd, p, size)) == -1))
- /* Errno is set */
- return (-1);
- if (wsize != size) {
- errno = EFTYPE;
- return (-1);
- }
- return (0);
-}
-
-#define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1)
-/*
- * Initialize a new bitmap page. Bitmap pages are left in memory
- * once they are read in.
- */
-extern int
-__ibitmap(hashp, pnum, nbits, ndx)
- HTAB *hashp;
- int pnum, nbits, ndx;
-{
- u_int32_t *ip;
- int clearbytes, clearints;
-
- if ((ip = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
- return (1);
- hashp->nmaps++;
- clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
- clearbytes = clearints << INT_TO_BYTE;
- (void)memset((char *)ip, 0, clearbytes);
- (void)memset(((char *)ip) + clearbytes, 0xFF,
- hashp->BSIZE - clearbytes);
- ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
- SETBIT(ip, 0);
- hashp->BITMAPS[ndx] = (u_int16_t)pnum;
- hashp->mapp[ndx] = ip;
- return (0);
-}
-
-static u_int32_t
-first_free(map)
- u_int32_t map;
-{
- u_int32_t i, mask;
-
- mask = 0x1;
- for (i = 0; i < BITS_PER_MAP; i++) {
- if (!(mask & map))
- return (i);
- mask = mask << 1;
- }
- return (i);
-}
-
-static u_int16_t
-overflow_page(hashp)
- HTAB *hashp;
-{
- u_int32_t *freep;
- int max_free, offset, splitnum;
- u_int16_t addr;
- int bit, first_page, free_bit, free_page, i, in_use_bits, j;
-#ifdef DEBUG2
- int tmp1, tmp2;
-#endif
- splitnum = hashp->OVFL_POINT;
- max_free = hashp->SPARES[splitnum];
-
- free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
- free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
-
- /* Look through all the free maps to find the first free block */
- first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
- for ( i = first_page; i <= free_page; i++ ) {
- if (!(freep = (u_int32_t *)hashp->mapp[i]) &&
- !(freep = fetch_bitmap(hashp, i)))
- return (0);
- if (i == free_page)
- in_use_bits = free_bit;
- else
- in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
-
- if (i == first_page) {
- bit = hashp->LAST_FREED &
- ((hashp->BSIZE << BYTE_SHIFT) - 1);
- j = bit / BITS_PER_MAP;
- bit = bit & ~(BITS_PER_MAP - 1);
- } else {
- bit = 0;
- j = 0;
- }
- for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
- if (freep[j] != ALL_SET)
- goto found;
- }
-
- /* No Free Page Found */
- hashp->LAST_FREED = hashp->SPARES[splitnum];
- hashp->SPARES[splitnum]++;
- offset = hashp->SPARES[splitnum] -
- (splitnum ? hashp->SPARES[splitnum - 1] : 0);
-
-#define OVMSG "HASH: Out of overflow pages. Increase page size\n"
- if (offset > SPLITMASK) {
- if (++splitnum >= NCACHED) {
- (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
- return (0);
- }
- hashp->OVFL_POINT = splitnum;
- hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
- hashp->SPARES[splitnum-1]--;
- offset = 1;
- }
-
- /* Check if we need to allocate a new bitmap page */
- if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
- free_page++;
- if (free_page >= NCACHED) {
- (void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
- return (0);
- }
- /*
- * This is tricky. The 1 indicates that you want the new page
- * allocated with 1 clear bit. Actually, you are going to
- * allocate 2 pages from this map. The first is going to be
- * the map page, the second is the overflow page we were
- * looking for. The init_bitmap routine automatically, sets
- * the first bit of itself to indicate that the bitmap itself
- * is in use. We would explicitly set the second bit, but
- * don't have to if we tell init_bitmap not to leave it clear
- * in the first place.
- */
- if (__ibitmap(hashp,
- (int)OADDR_OF(splitnum, offset), 1, free_page))
- return (0);
- hashp->SPARES[splitnum]++;
-#ifdef DEBUG2
- free_bit = 2;
-#endif
- offset++;
- if (offset > SPLITMASK) {
- if (++splitnum >= NCACHED) {
- (void)write(STDERR_FILENO, OVMSG,
- sizeof(OVMSG) - 1);
- return (0);
- }
- hashp->OVFL_POINT = splitnum;
- hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
- hashp->SPARES[splitnum-1]--;
- offset = 0;
- }
- } else {
- /*
- * Free_bit addresses the last used bit. Bump it to address
- * the first available bit.
- */
- free_bit++;
- SETBIT(freep, free_bit);
- }
-
- /* Calculate address of the new overflow page */
- addr = OADDR_OF(splitnum, offset);
-#ifdef DEBUG2
- (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
- addr, free_bit, free_page);
-#endif
- return (addr);
-
-found:
- bit = bit + first_free(freep[j]);
- SETBIT(freep, bit);
-#ifdef DEBUG2
- tmp1 = bit;
- tmp2 = i;
-#endif
- /*
- * Bits are addressed starting with 0, but overflow pages are addressed
- * beginning at 1. Bit is a bit addressnumber, so we need to increment
- * it to convert it to a page number.
- */
- bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
- if (bit >= hashp->LAST_FREED)
- hashp->LAST_FREED = bit - 1;
-
- /* Calculate the split number for this page */
- for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
- offset = (i ? bit - hashp->SPARES[i - 1] : bit);
- if (offset >= SPLITMASK)
- return (0); /* Out of overflow pages */
- addr = OADDR_OF(i, offset);
-#ifdef DEBUG2
- (void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
- addr, tmp1, tmp2);
-#endif
-
- /* Allocate and return the overflow page */
- return (addr);
-}
-
-/*
- * Mark this overflow page as free.
- */
-extern void
-__free_ovflpage(hashp, obufp)
- HTAB *hashp;
- BUFHEAD *obufp;
-{
- u_int16_t addr;
- u_int32_t *freep;
- int bit_address, free_page, free_bit;
- u_int16_t ndx;
-
- addr = obufp->addr;
-#ifdef DEBUG1
- (void)fprintf(stderr, "Freeing %d\n", addr);
-#endif
- ndx = (((u_int16_t)addr) >> SPLITSHIFT);
- bit_address =
- (ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
- if (bit_address < hashp->LAST_FREED)
- hashp->LAST_FREED = bit_address;
- free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
- free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
-
- if (!(freep = hashp->mapp[free_page]))
- freep = fetch_bitmap(hashp, free_page);
-#ifdef DEBUG
- /*
- * This had better never happen. It means we tried to read a bitmap
- * that has already had overflow pages allocated off it, and we
- * failed to read it from the file.
- */
- if (!freep)
- assert(0);
-#endif
- CLRBIT(freep, free_bit);
-#ifdef DEBUG2
- (void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n",
- obufp->addr, free_bit, free_page);
-#endif
- __reclaim_buf(hashp, obufp);
-}
-
-/*
- * Returns:
- * 0 success
- * -1 failure
- */
-static int
-open_temp(hashp)
- HTAB *hashp;
-{
- sigset_t set, oset;
- static char namestr[] = "_hashXXXXXX";
-
- /* Block signals; make sure file goes away at process exit. */
- (void)sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
- if ((hashp->fp = mkstemp(namestr)) != -1) {
- (void)unlink(namestr);
- (void)fcntl(hashp->fp, F_SETFD, 1);
- }
- (void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
- return (hashp->fp != -1 ? 0 : -1);
-}
-
-/*
- * We have to know that the key will fit, but the last entry on the page is
- * an overflow pair, so we need to shift things.
- */
-static void
-squeeze_key(sp, key, val)
- u_int16_t *sp;
- const DBT *key, *val;
-{
- char *p;
- u_int16_t free_space, n, off, pageno;
-
- p = (char *)sp;
- n = sp[0];
- free_space = FREESPACE(sp);
- off = OFFSET(sp);
-
- pageno = sp[n - 1];
- off -= key->size;
- sp[n - 1] = off;
- memmove(p + off, key->data, key->size);
- off -= val->size;
- sp[n] = off;
- memmove(p + off, val->data, val->size);
- sp[0] = n + 2;
- sp[n + 1] = pageno;
- sp[n + 2] = OVFLPAGE;
- FREESPACE(sp) = free_space - PAIRSIZE(key, val);
- OFFSET(sp) = off;
-}
-
-static u_int32_t *
-fetch_bitmap(hashp, ndx)
- HTAB *hashp;
- int ndx;
-{
- if (ndx >= hashp->nmaps)
- return (NULL);
- if ((hashp->mapp[ndx] = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
- return (NULL);
- if (__get_page(hashp,
- (char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) {
- free(hashp->mapp[ndx]);
- return (NULL);
- }
- return (hashp->mapp[ndx]);
-}
-
-#ifdef DEBUG4
-int
-print_chain(addr)
- int addr;
-{
- BUFHEAD *bufp;
- short *bp, oaddr;
-
- (void)fprintf(stderr, "%d ", addr);
- bufp = __get_buf(hashp, addr, NULL, 0);
- bp = (short *)bufp->page;
- while (bp[0] && ((bp[bp[0]] == OVFLPAGE) ||
- ((bp[0] > 2) && bp[2] < REAL_KEY))) {
- oaddr = bp[bp[0] - 1];
- (void)fprintf(stderr, "%d ", (int)oaddr);
- bufp = __get_buf(hashp, (int)oaddr, bufp, 0);
- bp = (short *)bufp->page;
- }
- (void)fprintf(stderr, "\n");
-}
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-
-#include <sys/types.h>
-
-#include <fcntl.h>
-#include <string.h>
-
-#include <db.h>
-#include "search.h"
-
-static DB *dbp = NULL;
-static ENTRY retval;
-
-extern int
-hcreate(nel)
- u_int nel;
-{
- HASHINFO info;
-
- info.nelem = nel;
- info.bsize = 256;
- info.ffactor = 8;
- info.cachesize = NULL;
- info.hash = NULL;
- info.lorder = 0;
- dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info, 0);
- return ((int)dbp);
-}
-
-extern ENTRY *
-hsearch(item, action)
- ENTRY item;
- ACTION action;
-{
- DBT key, val;
- int status;
-
- if (!dbp)
- return (NULL);
- key.data = (u_char *)item.key;
- key.size = strlen(item.key) + 1;
-
- if (action == ENTER) {
- val.data = (u_char *)item.data;
- val.size = strlen(item.data) + 1;
- status = (dbp->put)(dbp, &key, &val, R_NOOVERWRITE);
- if (status)
- return (NULL);
- } else {
- /* FIND */
- status = (dbp->get)(dbp, &key, &val, 0);
- if (status)
- return (NULL);
- else
- item.data = (char *)val.data;
- }
- retval.key = item.key;
- retval.data = item.data;
- return (&retval);
-}
-
-extern void
-hdestroy()
-{
- if (dbp) {
- (void)(dbp->close)(dbp);
- dbp = NULL;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-/*
- * This package provides a dbm compatible interface to the new hashing
- * package described in db(3).
- */
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <ndbm.h>
-#include "hash.h"
-
-/*
- * Returns:
- * *DBM on success
- * NULL on failure
- */
-extern DBM *
-dbm_open(file, flags, mode)
- const char *file;
- int flags, mode;
-{
- HASHINFO info;
- char path[MAXPATHLEN];
-
- info.bsize = 4096;
- info.ffactor = 40;
- info.nelem = 1;
- info.cachesize = 0;
- info.hash = NULL;
- info.lorder = 0;
-
- if( strlen(file) >= sizeof(path) - strlen(DBM_SUFFIX)) {
- errno = ENAMETOOLONG;
- return(NULL);
- }
- (void)strcpy(path, file);
- (void)strcat(path, DBM_SUFFIX);
- return ((DBM *)__hash_open(path, flags, mode, &info, 0));
-}
-
-extern void
-dbm_close(db)
- DBM *db;
-{
- (void)(db->close)(db);
-}
-
-/*
- * Returns:
- * DATUM on success
- * NULL on failure
- */
-extern datum
-dbm_fetch(db, key)
- DBM *db;
- datum key;
-{
- datum retdata;
- int status;
- DBT dbtkey, dbtretdata;
-
- dbtkey.data = key.dptr;
- dbtkey.size = key.dsize;
- status = (db->get)(db, &dbtkey, &dbtretdata, 0);
- if (status) {
- dbtretdata.data = NULL;
- dbtretdata.size = 0;
- }
- retdata.dptr = dbtretdata.data;
- retdata.dsize = dbtretdata.size;
- return (retdata);
-}
-
-/*
- * Returns:
- * DATUM on success
- * NULL on failure
- */
-extern datum
-dbm_firstkey(db)
- DBM *db;
-{
- int status;
- datum retkey;
- DBT dbtretkey, dbtretdata;
-
- status = (db->seq)(db, &dbtretkey, &dbtretdata, R_FIRST);
- if (status)
- dbtretkey.data = NULL;
- retkey.dptr = dbtretkey.data;
- retkey.dsize = dbtretkey.size;
- return (retkey);
-}
-
-/*
- * Returns:
- * DATUM on success
- * NULL on failure
- */
-extern datum
-dbm_nextkey(db)
- DBM *db;
-{
- int status;
- datum retkey;
- DBT dbtretkey, dbtretdata;
-
- status = (db->seq)(db, &dbtretkey, &dbtretdata, R_NEXT);
- if (status)
- dbtretkey.data = NULL;
- retkey.dptr = dbtretkey.data;
- retkey.dsize = dbtretkey.size;
- return (retkey);
-}
-
-/*
- * Returns:
- * 0 on success
- * <0 failure
- */
-extern int
-dbm_delete(db, key)
- DBM *db;
- datum key;
-{
- int status;
- DBT dbtkey;
-
- dbtkey.data = key.dptr;
- dbtkey.size = key.dsize;
- status = (db->del)(db, &dbtkey, 0);
- if (status)
- return (-1);
- else
- return (0);
-}
-
-/*
- * Returns:
- * 0 on success
- * <0 failure
- * 1 if DBM_INSERT and entry exists
- */
-extern int
-dbm_store(db, key, data, flags)
- DBM *db;
- datum key, data;
- int flags;
-{
- DBT dbtkey, dbtdata;
-
- dbtkey.data = key.dptr;
- dbtkey.size = key.dsize;
- dbtdata.data = data.dptr;
- dbtdata.size = data.dsize;
- return ((db->put)(db, &dbtkey, &dbtdata,
- (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
-}
-
-extern int
-dbm_error(db)
- DBM *db;
-{
- HTAB *hp;
-
- hp = (HTAB *)db->internal;
- return (hp->error);
-}
-
-extern int
-dbm_clearerr(db)
- DBM *db;
-{
- HTAB *hp;
-
- hp = (HTAB *)db->internal;
- hp->error = 0;
- return (0);
-}
-
-extern int
-dbm_dirfno(db)
- DBM *db;
-{
- return(((HTAB *)db->internal)->fp);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)page.h 8.2 (Berkeley) 5/31/94
- * $FreeBSD: src/lib/libc/db/hash/page.h,v 1.2 2002/03/22 23:41:40 obrien Exp $
- */
-
-/*
- * Definitions for hashing page file format.
- */
-
-/*
- * routines dealing with a data page
- *
- * page format:
- * +------------------------------+
- * p | n | keyoff | datoff | keyoff |
- * +------------+--------+--------+
- * | datoff | free | ptr | --> |
- * +--------+---------------------+
- * | F R E E A R E A |
- * +--------------+---------------+
- * | <---- - - - | data |
- * +--------+-----+----+----------+
- * | key | data | key |
- * +--------+----------+----------+
- *
- * Pointer to the free space is always: p[p[0] + 2]
- * Amount of free space on the page is: p[p[0] + 1]
- */
-
-/*
- * How many bytes required for this pair?
- * 2 shorts in the table at the top of the page + room for the
- * key and room for the data
- *
- * We prohibit entering a pair on a page unless there is also room to append
- * an overflow page. The reason for this it that you can get in a situation
- * where a single key/data pair fits on a page, but you can't append an
- * overflow page and later you'd have to split the key/data and handle like
- * a big pair.
- * You might as well do this up front.
- */
-
-#define PAIRSIZE(K,D) (2*sizeof(u_int16_t) + (K)->size + (D)->size)
-#define BIGOVERHEAD (4*sizeof(u_int16_t))
-#define KEYSIZE(K) (4*sizeof(u_int16_t) + (K)->size);
-#define OVFLSIZE (2*sizeof(u_int16_t))
-#define FREESPACE(P) ((P)[(P)[0]+1])
-#define OFFSET(P) ((P)[(P)[0]+2])
-#define PAIRFITS(P,K,D) \
- (((P)[2] >= REAL_KEY) && \
- (PAIRSIZE((K),(D)) + OVFLSIZE) <= FREESPACE((P)))
-#define PAGE_META(N) (((N)+3) * sizeof(u_int16_t))
-
-typedef struct {
- BUFHEAD *newp;
- BUFHEAD *oldp;
- BUFHEAD *nextp;
- u_int16_t next_addr;
-} SPLIT_RETURN;
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* Backward compatibility to hsearch interface. */
-typedef struct entry {
- char *key;
- char *data;
-} ENTRY;
-
-typedef enum {
- FIND, ENTER
-} ACTION;
-
-int hcreate __P((unsigned int));
-void hdestroy __P((void));
-ENTRY *hsearch __P((ENTRY, ACTION));
--- /dev/null
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)btree.3 8.4 (Berkeley) 8/18/94
+.\" $FreeBSD: src/lib/libc/db/man/btree.3,v 1.6 2002/12/19 09:40:21 ru Exp $
+.\"
+.Dd August 18, 1994
+.Dt BTREE 3
+.Os
+.Sh NAME
+.Nm btree
+.Nd "btree database access method"
+.Sh SYNOPSIS
+.In sys/types.h
+.In db.h
+.Sh DESCRIPTION
+The routine
+.Fn dbopen
+is the library interface to database files.
+One of the supported file formats is
+.Nm
+files.
+The general description of the database access methods is in
+.Xr dbopen 3 ,
+this manual page describes only the
+.Nm
+specific information.
+.Pp
+The
+.Nm
+data structure is a sorted, balanced tree structure storing
+associated key/data pairs.
+.Pp
+The
+.Nm
+access method specific data structure provided to
+.Fn dbopen
+is defined in the
+.Aq Pa db.h
+include file as follows:
+.Bd -literal
+typedef struct {
+ u_long flags;
+ u_int cachesize;
+ int maxkeypage;
+ int minkeypage;
+ u_int psize;
+ int (*compare)(const DBT *key1, const DBT *key2);
+ size_t (*prefix)(const DBT *key1, const DBT *key2);
+ int lorder;
+} BTREEINFO;
+.Ed
+.Pp
+The elements of this structure are as follows:
+.Bl -tag -width indent
+.It Va flags
+The flag value is specified by
+.Em or Ns 'ing
+any of the following values:
+.Bl -tag -width indent
+.It Dv R_DUP
+Permit duplicate keys in the tree, i.e. permit insertion if the key to be
+inserted already exists in the tree.
+The default behavior, as described in
+.Xr dbopen 3 ,
+is to overwrite a matching key when inserting a new key or to fail if
+the
+.Dv R_NOOVERWRITE
+flag is specified.
+The
+.Dv R_DUP
+flag is overridden by the
+.Dv R_NOOVERWRITE
+flag, and if the
+.Dv R_NOOVERWRITE
+flag is specified, attempts to insert duplicate keys into
+the tree will fail.
+.Pp
+If the database contains duplicate keys, the order of retrieval of
+key/data pairs is undefined if the
+.Va get
+routine is used, however,
+.Va seq
+routine calls with the
+.Dv R_CURSOR
+flag set will always return the logical
+.Dq first
+of any group of duplicate keys.
+.El
+.It Va cachesize
+A suggested maximum size (in bytes) of the memory cache.
+This value is
+.Em only
+advisory, and the access method will allocate more memory rather than fail.
+Since every search examines the root page of the tree, caching the most
+recently used pages substantially improves access time.
+In addition, physical writes are delayed as long as possible, so a moderate
+cache can reduce the number of I/O operations significantly.
+Obviously, using a cache increases (but only increases) the likelihood of
+corruption or lost data if the system crashes while a tree is being modified.
+If
+.Va cachesize
+is 0 (no size is specified) a default cache is used.
+.It Va maxkeypage
+The maximum number of keys which will be stored on any single page.
+Not currently implemented.
+.\" The maximum number of keys which will be stored on any single page.
+.\" Because of the way the
+.\" .Nm
+.\" data structure works,
+.\" .Va maxkeypage
+.\" must always be greater than or equal to 2.
+.\" If
+.\" .Va maxkeypage
+.\" is 0 (no maximum number of keys is specified) the page fill factor is
+.\" made as large as possible (which is almost invariably what is wanted).
+.It Va minkeypage
+The minimum number of keys which will be stored on any single page.
+This value is used to determine which keys will be stored on overflow
+pages, i.e. if a key or data item is longer than the pagesize divided
+by the minkeypage value, it will be stored on overflow pages instead
+of in the page itself.
+If
+.Va minkeypage
+is 0 (no minimum number of keys is specified) a value of 2 is used.
+.It Va psize
+Page size is the size (in bytes) of the pages used for nodes in the tree.
+The minimum page size is 512 bytes and the maximum page size is 64K.
+If
+.Va psize
+is 0 (no page size is specified) a page size is chosen based on the
+underlying file system I/O block size.
+.It Va compare
+Compare is the key comparison function.
+It must return an integer less than, equal to, or greater than zero if the
+first key argument is considered to be respectively less than, equal to,
+or greater than the second key argument.
+The same comparison function must be used on a given tree every time it
+is opened.
+If
+.Va compare
+is
+.Dv NULL
+(no comparison function is specified), the keys are compared
+lexically, with shorter keys considered less than longer keys.
+.It Va prefix
+The
+.Va prefix
+element
+is the prefix comparison function.
+If specified, this routine must return the number of bytes of the second key
+argument which are necessary to determine that it is greater than the first
+key argument.
+If the keys are equal, the key length should be returned.
+Note, the usefulness of this routine is very data dependent, but, in some
+data sets can produce significantly reduced tree sizes and search times.
+If
+.Va prefix
+is
+.Dv NULL
+(no prefix function is specified),
+.Em and
+no comparison function is specified, a default lexical comparison routine
+is used.
+If
+.Va prefix
+is
+.Dv NULL
+and a comparison routine is specified, no prefix comparison is
+done.
+.It Va lorder
+The byte order for integers in the stored database metadata.
+The number should represent the order as an integer; for example,
+big endian order would be the number 4,321.
+If
+.Va lorder
+is 0 (no order is specified) the current host order is used.
+.El
+.Pp
+If the file already exists (and the
+.Dv O_TRUNC
+flag is not specified), the
+values specified for the
+.Va flags , lorder
+and
+.Va psize
+arguments
+are ignored
+in favor of the values used when the tree was created.
+.Pp
+Forward sequential scans of a tree are from the least key to the greatest.
+.Pp
+Space freed up by deleting key/data pairs from the tree is never reclaimed,
+although it is normally made available for reuse.
+This means that the
+.Nm
+storage structure is grow-only.
+The only solutions are to avoid excessive deletions, or to create a fresh
+tree periodically from a scan of an existing one.
+.Pp
+Searches, insertions, and deletions in a
+.Nm
+will all complete in
+O lg base N where base is the average fill factor.
+Often, inserting ordered data into
+.Nm Ns s
+results in a low fill factor.
+This implementation has been modified to make ordered insertion the best
+case, resulting in a much better than normal page fill factor.
+.Sh ERRORS
+The
+.Nm
+access method routines may fail and set
+.Va errno
+for any of the errors specified for the library routine
+.Xr dbopen 3 .
+.Sh SEE ALSO
+.Xr dbopen 3 ,
+.Xr hash 3 ,
+.Xr mpool 3 ,
+.Xr recno 3
+.Rs
+.%T "The Ubiquitous B-tree"
+.%A Douglas Comer
+.%J "ACM Comput. Surv. 11"
+.%N 2
+.%D June 1979
+.%P 121-138
+.Re
+.Rs
+.%A Bayer
+.%A Unterauer
+.%T "Prefix B-trees"
+.%J "ACM Transactions on Database Systems"
+.%N 1
+.%V Vol. 2
+.%D March 1977
+.%P 11-26
+.Re
+.Rs
+.%B "The Art of Computer Programming Vol. 3: Sorting and Searching"
+.%A D. E. Knuth
+.%D 1968
+.%P 471-480
+.Re
+.Sh BUGS
+Only big and little endian byte order is supported.
--- /dev/null
+.\" Copyright (c) 1999 Tim Singletary
+.\" No copyright is claimed.
+.\"
+.\" 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.
+.\"
+.\" $FreeBSD: src/lib/libc/db/man/dbm.3,v 1.7 2002/12/19 09:40:21 ru Exp $
+.\"
+.\" Note: The date here should be updated whenever a non-trivial
+.\" change is made to the manual page.
+.Dd July 7, 1999
+.Dt DBM 3
+.Os
+.Sh NAME
+.Nm dbm_clearerr ,
+.Nm dbm_close ,
+.Nm dbm_delete ,
+.Nm dbm_dirfno ,
+.Nm dbm_error ,
+.Nm dbm_fetch ,
+.Nm dbm_firstkey ,
+.Nm dbm_nextkey ,
+.Nm dbm_open ,
+.Nm dbm_store
+.Nd database access functions
+.Sh SYNOPSIS
+.In fcntl.h
+.In ndbm.h
+.Ft DBM *
+.Fn dbm_open "const char *base" "int flags" "int mode"
+.Ft void
+.Fn dbm_close "DBM *db"
+.Ft int
+.Fn dbm_store "DBM *db" "datum key" "datum data" "int flags"
+.Ft datum
+.Fn dbm_fetch "DBM *db" "datum key"
+.Ft int
+.Fn dbm_delete "DBM *db" "datum key"
+.Ft datum
+.Fn dbm_firstkey "DBM *db"
+.Ft datum
+.Fn dbm_nextkey "DBM *db"
+.Ft int
+.Fn dbm_error "DBM *db"
+.Ft int
+.Fn dbm_clearerr "DBM *db"
+.Ft int
+.Fn dbm_dirfno "DBM *db"
+.Sh DESCRIPTION
+Database access functions.
+These functions are implemented using
+.Xr dbopen 3
+with a
+.Xr hash 3
+database.
+.Pp
+.Vt datum
+is declared in
+.Aq Pa ndbm.h :
+.Bd -literal
+typedef struct {
+ char *dptr;
+ int dsize;
+} datum;
+.Ed
+.Pp
+The
+.Fn dbm_open base flags mode
+function
+opens or creates a database.
+The
+.Fa base
+argument
+is the basename of the file containing
+the database; the actual database has a
+.Pa .db
+suffix.
+I.e., if
+.Fa base
+is
+.Qq Li /home/me/mystuff
+then the actual database is in the file
+.Pa /home/me/mystuff.db .
+The
+.Fa flags
+and
+.Fa mode
+arguments
+are passed to
+.Xr open 2 .
+.Pq Dv O_RDWR | O_CREAT
+is a typical value for
+.Fa flags ;
+.Li 0660
+is a typical value for
+.Fa mode .
+.Dv O_WRONLY
+is not allowed in
+.Fa flags .
+The pointer returned by
+.Fn dbm_open
+identifies the database and is the
+.Fa db
+argument to the other functions.
+The
+.Fn dbm_open
+function
+returns
+.Dv NULL
+and sets
+.Va errno
+if there were any errors.
+.Pp
+The
+.Fn dbm_close db
+function
+closes the database.
+The
+.Fn dbm_close
+function
+normally returns zero.
+.Pp
+The
+.Fn dbm_store db key data flags
+function
+inserts or replaces an entry in the database.
+The
+.Fa flags
+argument
+is either
+.Dv DBM_INSERT
+or
+.Dv DBM_REPLACE .
+If
+.Fa flags
+is
+.Dv DBM_INSERT
+and the database already contains an entry for
+.Fa key ,
+that entry is not replaced.
+Otherwise the entry is replaced or inserted.
+The
+.Fn dbm_store
+function
+normally returns zero but returns 1 if the entry could not be
+inserted (because
+.Fa flags
+is
+.Dv DBM_INSERT ,
+and an entry with
+.Fa key
+already exists) or returns -1 and sets
+.Va errno
+if there were any errors.
+.Pp
+The
+.Fn dbm_fetch db key
+function
+returns
+.Dv NULL
+or the
+.Fa data
+corresponding to
+.Fa key .
+.Pp
+The
+.Fn dbm_delete db key
+function
+deletes the entry for
+.Fa key .
+The
+.Fn dbm_delete
+function
+normally returns zero but returns 1 if there was no entry with
+.Fa key
+in the database or returns -1 and sets
+.Va errno
+if there were any errors.
+.Pp
+The
+.Fn dbm_firstkey db
+function
+returns the first key in the database.
+The
+.Fn dbm_nextkey db
+function
+returns subsequent keys.
+The
+.Fn db_firstkey
+function
+must be called before
+.Fn dbm_nextkey .
+The order in which keys are returned is unspecified and may appear
+random.
+The
+.Fn dbm_nextkey
+function
+returns
+.Dv NULL
+after all keys have been returned.
+.Pp
+The
+.Fn dbm_error db
+function
+returns the
+.Va errno
+value of the most recent error.
+The
+.Fn dbm_clearerr db
+function
+resets this value to 0 and returns 0.
+.Pp
+The
+.Fn dbm_dirfno db
+function
+returns the file descriptor to the database.
+.Sh SEE ALSO
+.Xr open 2 ,
+.Xr dbopen 3 ,
+.Xr hash 3
+.Sh STANDARDS
+These functions (except
+.Fn dbm_dirfno )
+are included in the
+.St -susv2 .
--- /dev/null
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)dbopen.3 8.5 (Berkeley) 1/2/94
+.\" $FreeBSD: src/lib/libc/db/man/dbopen.3,v 1.8 2002/12/19 09:40:21 ru Exp $
+.\"
+.Dd January 2, 1994
+.Dt DBOPEN 3
+.Os
+.Sh NAME
+.Nm dbopen
+.Nd "database access methods"
+.Sh SYNOPSIS
+.In sys/types.h
+.In db.h
+.In fcntl.h
+.In limits.h
+.Ft DB *
+.Fn dbopen "const char *file" "int flags" "int mode" "DBTYPE type" "const void *openinfo"
+.Sh DESCRIPTION
+The
+.Fn dbopen
+function
+is the library interface to database files.
+The supported file formats are btree, hashed and UNIX file oriented.
+The btree format is a representation of a sorted, balanced tree structure.
+The hashed format is an extensible, dynamic hashing scheme.
+The flat-file format is a byte stream file with fixed or variable length
+records.
+The formats and file format specific information are described in detail
+in their respective manual pages
+.Xr btree 3 ,
+.Xr hash 3
+and
+.Xr recno 3 .
+.Pp
+The
+.Fn dbopen
+function
+opens
+.Fa file
+for reading and/or writing.
+Files never intended to be preserved on disk may be created by setting
+the
+.Fa file
+argument to
+.Dv NULL .
+.Pp
+The
+.Fa flags
+and
+.Fa mode
+arguments
+are as specified to the
+.Xr open 2
+routine, however, only the
+.Dv O_CREAT , O_EXCL , O_EXLOCK , O_NONBLOCK ,
+.Dv O_RDONLY , O_RDWR , O_SHLOCK
+and
+.Dv O_TRUNC
+flags are meaningful.
+(Note, opening a database file
+.Dv O_WRONLY
+is not possible.)
+.\"Three additional options may be specified by
+.\".Em or Ns 'ing
+.\"them into the
+.\".Fa flags
+.\"argument.
+.\".Bl -tag -width indent
+.\".It Dv DB_LOCK
+.\"Do the necessary locking in the database to support concurrent access.
+.\"If concurrent access isn't needed or the database is read-only this
+.\"flag should not be set, as it tends to have an associated performance
+.\"penalty.
+.\".It Dv DB_SHMEM
+.\"Place the underlying memory pool used by the database in shared
+.\"memory.
+.\"Necessary for concurrent access.
+.\".It Dv DB_TXN
+.\"Support transactions in the database.
+.\"The
+.\".Dv DB_LOCK
+.\"and
+.\".Dv DB_SHMEM
+.\"flags must be set as well.
+.\".El
+.Pp
+The
+.Fa type
+argument is of type
+.Ft DBTYPE
+(as defined in the
+.Aq Pa db.h
+include file) and
+may be set to
+.Dv DB_BTREE , DB_HASH
+or
+.Dv DB_RECNO .
+.Pp
+The
+.Fa openinfo
+argument is a pointer to an access method specific structure described
+in the access method's manual page.
+If
+.Fa openinfo
+is
+.Dv NULL ,
+each access method will use defaults appropriate for the system
+and the access method.
+.Pp
+The
+.Fn dbopen
+function
+returns a pointer to a
+.Ft DB
+structure on success and
+.Dv NULL
+on error.
+The
+.Ft DB
+structure is defined in the
+.Aq Pa db.h
+include file, and contains at
+least the following fields:
+.Bd -literal
+typedef struct {
+ DBTYPE type;
+ int (*close)(const DB *db);
+ int (*del)(const DB *db, const DBT *key, u_int flags);
+ int (*fd)(const DB *db);
+ int (*get)(const DB *db, DBT *key, DBT *data, u_int flags);
+ int (*put)(const DB *db, DBT *key, const DBT *data,
+ u_int flags);
+ int (*sync)(const DB *db, u_int flags);
+ int (*seq)(const DB *db, DBT *key, DBT *data, u_int flags);
+} DB;
+.Ed
+.Pp
+These elements describe a database type and a set of functions performing
+various actions.
+These functions take a pointer to a structure as returned by
+.Fn dbopen ,
+and sometimes one or more pointers to key/data structures and a flag value.
+.Bl -tag -width indent
+.It Va type
+The type of the underlying access method (and file format).
+.It Va close
+A pointer to a routine to flush any cached information to disk, free any
+allocated resources, and close the underlying file(s).
+Since key/data pairs may be cached in memory, failing to sync the file
+with a
+.Va close
+or
+.Va sync
+function may result in inconsistent or lost information.
+.Va close
+routines return -1 on error (setting
+.Va errno )
+and 0 on success.
+.It Va del
+A pointer to a routine to remove key/data pairs from the database.
+.Pp
+The
+.Fa flags
+argument
+may be set to the following value:
+.Bl -tag -width indent
+.It Dv R_CURSOR
+Delete the record referenced by the cursor.
+The cursor must have previously been initialized.
+.El
+.Pp
+.Va delete
+routines return -1 on error (setting
+.Va errno ) ,
+0 on success, and 1 if the specified
+.Fa key
+was not in the file.
+.It Va fd
+A pointer to a routine which returns a file descriptor representative
+of the underlying database.
+A file descriptor referencing the same file will be returned to all
+processes which call
+.Fn dbopen
+with the same
+.Fa file
+name.
+This file descriptor may be safely used as an argument to the
+.Xr fcntl 2
+and
+.Xr flock 2
+locking functions.
+The file descriptor is not necessarily associated with any of the
+underlying files used by the access method.
+No file descriptor is available for in memory databases.
+.Va \&Fd
+routines return -1 on error (setting
+.Va errno ) ,
+and the file descriptor on success.
+.It Va get
+A pointer to a routine which is the interface for keyed retrieval from
+the database.
+The address and length of the data associated with the specified
+.Fa key
+are returned in the structure referenced by
+.Fa data .
+.Va get
+routines return -1 on error (setting
+.Va errno ) ,
+0 on success, and 1 if the
+.Fa key
+was not in the file.
+.It Va put
+A pointer to a routine to store key/data pairs in the database.
+.Pp
+The
+.Fa flags
+argument
+may be set to one of the following values:
+.Bl -tag -width indent
+.It Dv R_CURSOR
+Replace the key/data pair referenced by the cursor.
+The cursor must have previously been initialized.
+.It Dv R_IAFTER
+Append the data immediately after the data referenced by
+.Fa key ,
+creating a new key/data pair.
+The record number of the appended key/data pair is returned in the
+.Fa key
+structure.
+(Applicable only to the
+.Dv DB_RECNO
+access method.)
+.It Dv R_IBEFORE
+Insert the data immediately before the data referenced by
+.Fa key ,
+creating a new key/data pair.
+The record number of the inserted key/data pair is returned in the
+.Fa key
+structure.
+(Applicable only to the
+.Dv DB_RECNO
+access method.)
+.It Dv R_NOOVERWRITE
+Enter the new key/data pair only if the key does not previously exist.
+.It Dv R_SETCURSOR
+Store the key/data pair, setting or initializing the position of the
+cursor to reference it.
+(Applicable only to the
+.Dv DB_BTREE
+and
+.Dv DB_RECNO
+access methods.)
+.El
+.Pp
+.Dv R_SETCURSOR
+is available only for the
+.Dv DB_BTREE
+and
+.Dv DB_RECNO
+access
+methods because it implies that the keys have an inherent order
+which does not change.
+.Pp
+.Dv R_IAFTER
+and
+.Dv R_IBEFORE
+are available only for the
+.Dv DB_RECNO
+access method because they each imply that the access method is able to
+create new keys.
+This is only true if the keys are ordered and independent, record numbers
+for example.
+.Pp
+The default behavior of the
+.Va put
+routines is to enter the new key/data pair, replacing any previously
+existing key.
+.Pp
+.Va put
+routines return -1 on error (setting
+.Va errno ) ,
+0 on success, and 1 if the
+.Dv R_NOOVERWRITE
+flag
+was set and the key already exists in the file.
+.It Va seq
+A pointer to a routine which is the interface for sequential
+retrieval from the database.
+The address and length of the key are returned in the structure
+referenced by
+.Fa key ,
+and the address and length of the data are returned in the
+structure referenced
+by
+.Fa data .
+.Pp
+Sequential key/data pair retrieval may begin at any time, and the
+position of the
+.Dq cursor
+is not affected by calls to the
+.Va del ,
+.Va get ,
+.Va put ,
+or
+.Va sync
+routines.
+Modifications to the database during a sequential scan will be reflected
+in the scan, i.e. records inserted behind the cursor will not be returned
+while records inserted in front of the cursor will be returned.
+.Pp
+The
+.Fa flags
+argument
+.Em must
+be set to one of the following values:
+.Bl -tag -width indent
+.It Dv R_CURSOR
+The data associated with the specified key is returned.
+This differs from the
+.Va get
+routines in that it sets or initializes the cursor to the location of
+the key as well.
+(Note, for the
+.Dv DB_BTREE
+access method, the returned key is not necessarily an
+exact match for the specified key.
+The returned key is the smallest key greater than or equal to the specified
+key, permitting partial key matches and range searches.)
+.It Dv R_FIRST
+The first key/data pair of the database is returned, and the cursor
+is set or initialized to reference it.
+.It Dv R_LAST
+The last key/data pair of the database is returned, and the cursor
+is set or initialized to reference it.
+(Applicable only to the
+.Dv DB_BTREE
+and
+.Dv DB_RECNO
+access methods.)
+.It Dv R_NEXT
+Retrieve the key/data pair immediately after the cursor.
+If the cursor is not yet set, this is the same as the
+.Dv R_FIRST
+flag.
+.It Dv R_PREV
+Retrieve the key/data pair immediately before the cursor.
+If the cursor is not yet set, this is the same as the
+.Dv R_LAST
+flag.
+(Applicable only to the
+.Dv DB_BTREE
+and
+.Dv DB_RECNO
+access methods.)
+.El
+.Pp
+.Dv R_LAST
+and
+.Dv R_PREV
+are available only for the
+.Dv DB_BTREE
+and
+.Dv DB_RECNO
+access methods because they each imply that the keys have an inherent
+order which does not change.
+.Pp
+.Va seq
+routines return -1 on error (setting
+.Va errno ) ,
+0 on success and 1 if there are no key/data pairs less than or greater
+than the specified or current key.
+If the
+.Dv DB_RECNO
+access method is being used, and if the database file
+is a character special file and no complete key/data pairs are currently
+available, the
+.Va seq
+routines return 2.
+.It Va sync
+A pointer to a routine to flush any cached information to disk.
+If the database is in memory only, the
+.Va sync
+routine has no effect and will always succeed.
+.Pp
+The
+.Fa flags
+argument may be set to the following value:
+.Bl -tag -width indent
+.It Dv R_RECNOSYNC
+If the
+.Dv DB_RECNO
+access method is being used, this flag causes
+the
+.Va sync
+routine to apply to the btree file which underlies the
+recno file, not the recno file itself.
+(See the
+.Va bfname
+field of the
+.Xr recno 3
+manual page for more information.)
+.El
+.Pp
+.Va sync
+routines return -1 on error (setting
+.Va errno )
+and 0 on success.
+.El
+.Sh "KEY/DATA PAIRS"
+Access to all file types is based on key/data pairs.
+Both keys and data are represented by the following data structure:
+.Bd -literal
+typedef struct {
+ void *data;
+ size_t size;
+} DBT;
+.Ed
+.Pp
+The elements of the
+.Ft DBT
+structure are defined as follows:
+.Bl -tag -width "data"
+.It Va data
+A pointer to a byte string.
+.It Va size
+The length of the byte string.
+.El
+.Pp
+Key and data byte strings may reference strings of essentially unlimited
+length although any two of them must fit into available memory at the same
+time.
+It should be noted that the access methods provide no guarantees about
+byte string alignment.
+.Sh ERRORS
+The
+.Fn dbopen
+routine may fail and set
+.Va errno
+for any of the errors specified for the library routines
+.Xr open 2
+and
+.Xr malloc 3
+or the following:
+.Bl -tag -width Er
+.It Bq Er EFTYPE
+A file is incorrectly formatted.
+.It Bq Er EINVAL
+An argument has been specified (hash function, pad byte etc.) that is
+incompatible with the current file specification or which is not
+meaningful for the function (for example, use of the cursor without
+prior initialization) or there is a mismatch between the version
+number of file and the software.
+.El
+.Pp
+The
+.Va close
+routines may fail and set
+.Va errno
+for any of the errors specified for the library routines
+.Xr close 2 ,
+.Xr read 2 ,
+.Xr write 2 ,
+.Xr free 3 ,
+or
+.Xr fsync 2 .
+.Pp
+The
+.Va del ,
+.Va get ,
+.Va put
+and
+.Va seq
+routines may fail and set
+.Va errno
+for any of the errors specified for the library routines
+.Xr read 2 ,
+.Xr write 2 ,
+.Xr free 3
+or
+.Xr malloc 3 .
+.Pp
+The
+.Va fd
+routines will fail and set
+.Va errno
+to
+.Er ENOENT
+for in memory databases.
+.Pp
+The
+.Va sync
+routines may fail and set
+.Va errno
+for any of the errors specified for the library routine
+.Xr fsync 2 .
+.Sh SEE ALSO
+.Xr btree 3 ,
+.Xr hash 3 ,
+.Xr mpool 3 ,
+.Xr recno 3
+.Rs
+.%T "LIBTP: Portable, Modular Transactions for UNIX"
+.%A Margo Seltzer
+.%A Michael Olson
+.%R "USENIX proceedings"
+.%D Winter 1992
+.Re
+.Sh BUGS
+The typedef
+.Ft DBT
+is a mnemonic for
+.Dq "data base thang" ,
+and was used
+because noone could think of a reasonable name that wasn't already used.
+.Pp
+The file descriptor interface is a kluge and will be deleted in a
+future version of the interface.
+.Pp
+None of the access methods provide any form of concurrent access,
+locking, or transactions.
--- /dev/null
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)hash.3 8.6 (Berkeley) 8/18/94
+.\" $FreeBSD: src/lib/libc/db/man/hash.3,v 1.7 2002/12/19 09:40:21 ru Exp $
+.\"
+.Dd August 18, 1994
+.Dt HASH 3
+.Os
+.Sh NAME
+.Nm hash
+.Nd "hash database access method"
+.Sh SYNOPSIS
+.In sys/types.h
+.In db.h
+.Sh DESCRIPTION
+The routine
+.Fn dbopen
+is the library interface to database files.
+One of the supported file formats is
+.Nm
+files.
+The general description of the database access methods is in
+.Xr dbopen 3 ,
+this manual page describes only the
+.Nm
+specific information.
+.Pp
+The
+.Nm
+data structure is an extensible, dynamic hashing scheme.
+.Pp
+The access method specific data structure provided to
+.Fn dbopen
+is defined in the
+.Aq Pa db.h
+include file as follows:
+.Bd -literal
+typedef struct {
+ u_int bsize;
+ u_int ffactor;
+ u_int nelem;
+ u_int cachesize;
+ u_int32_t (*hash)(const void *, size_t);
+ int lorder;
+} HASHINFO;
+.Ed
+.Pp
+The elements of this structure are as follows:
+.Bl -tag -width indent
+.It Va bsize
+The
+.Va bsize
+element
+defines the
+.Nm
+table bucket size, and is, by default, 256 bytes.
+It may be preferable to increase the page size for disk-resident tables
+and tables with large data items.
+.It Va ffactor
+The
+.Va ffactor
+element
+indicates a desired density within the
+.Nm
+table.
+It is an approximation of the number of keys allowed to accumulate in any
+one bucket, determining when the
+.Nm
+table grows or shrinks.
+The default value is 8.
+.It Va nelem
+The
+.Va nelem
+element
+is an estimate of the final size of the
+.Nm
+table.
+If not set or set too low,
+.Nm
+tables will expand gracefully as keys
+are entered, although a slight performance degradation may be noticed.
+The default value is 1.
+.It Va cachesize
+A suggested maximum size, in bytes, of the memory cache.
+This value is
+.Em only
+advisory, and the access method will allocate more memory rather
+than fail.
+.It Va hash
+The
+.Va hash
+element
+is a user defined
+.Nm
+function.
+Since no
+.Nm
+function performs equally well on all possible data, the
+user may find that the built-in
+.Nm
+function does poorly on a particular
+data set.
+User specified
+.Nm
+functions must take two arguments (a pointer to a byte
+string and a length) and return a 32-bit quantity to be used as the
+.Nm
+value.
+.It Va lorder
+The byte order for integers in the stored database metadata.
+The number should represent the order as an integer; for example,
+big endian order would be the number 4,321.
+If
+.Va lorder
+is 0 (no order is specified) the current host order is used.
+If the file already exists, the specified value is ignored and the
+value specified when the tree was created is used.
+.El
+.Pp
+If the file already exists (and the
+.Dv O_TRUNC
+flag is not specified), the
+values specified for the
+.Va bsize , ffactor , lorder
+and
+.Va nelem
+arguments
+are
+ignored and the values specified when the tree was created are used.
+.Pp
+If a
+.Nm
+function is specified,
+.Fn hash_open
+will attempt to determine if the
+.Nm
+function specified is the same as
+the one with which the database was created, and will fail if it is not.
+.Pp
+Backward compatible interfaces to the older
+.Em dbm
+and
+.Em ndbm
+routines are provided, however these interfaces are not compatible with
+previous file formats.
+.Sh ERRORS
+The
+.Nm
+access method routines may fail and set
+.Va errno
+for any of the errors specified for the library routine
+.Xr dbopen 3 .
+.Sh SEE ALSO
+.Xr btree 3 ,
+.Xr dbopen 3 ,
+.Xr mpool 3 ,
+.Xr recno 3
+.Rs
+.%T "Dynamic Hash Tables"
+.%A Per-Ake Larson
+.%R "Communications of the ACM"
+.%D April 1988
+.Re
+.Rs
+.%T "A New Hash Package for UNIX"
+.%A Margo Seltzer
+.%R "USENIX Proceedings"
+.%D Winter 1991
+.Re
+.Sh BUGS
+Only big and little endian byte order is supported.
--- /dev/null
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mpool.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD: src/lib/libc/db/man/mpool.3,v 1.12 2003/02/06 11:04:46 charnier Exp $
+.\"
+.Dd June 4, 1993
+.Dt MPOOL 3
+.Os
+.Sh NAME
+.Nm mpool
+.Nd "shared memory buffer pool"
+.Sh SYNOPSIS
+.In db.h
+.In mpool.h
+.Ft MPOOL *
+.Fn mpool_open "void *key" "int fd" "pgno_t pagesize" "pgno_t maxcache"
+.Ft void
+.Fo mpool_filter
+.Fa "MPOOL *mp"
+.Fa "void (*pgin)(void *, pgno_t, void *)"
+.Fa "void (*pgout)(void *, pgno_t, void *)"
+.Fa "void *pgcookie"
+.Fc
+.Ft void *
+.Fn mpool_new "MPOOL *mp" "pgno_t *pgnoaddr"
+.Ft void *
+.Fn mpool_get "MPOOL *mp" "pgno_t pgno" "u_int flags"
+.Ft int
+.Fn mpool_put "MPOOL *mp" "void *pgaddr" "u_int flags"
+.Ft int
+.Fn mpool_sync "MPOOL *mp"
+.Ft int
+.Fn mpool_close "MPOOL *mp"
+.Sh DESCRIPTION
+The
+.Nm mpool
+library interface is intended to provide page oriented buffer management
+of files.
+The buffers may be shared between processes.
+.Pp
+The
+.Fn mpool_open
+function initializes a memory pool.
+The
+.Fa key
+argument is the byte string used to negotiate between multiple
+processes wishing to share buffers.
+If the file buffers are mapped in shared memory, all processes using
+the same key will share the buffers.
+If
+.Fa key
+is
+.Dv NULL ,
+the buffers are mapped into private memory.
+The
+.Fa fd
+argument is a file descriptor for the underlying file, which must be seekable.
+If
+.Fa key
+is
+.No non\- Ns Dv NULL
+and matches a file already being mapped, the
+.Fa fd
+argument is ignored.
+.Pp
+The
+.Fa pagesize
+argument is the size, in bytes, of the pages into which the file is broken up.
+The
+.Fa maxcache
+argument is the maximum number of pages from the underlying file to cache
+at any one time.
+This value is not relative to the number of processes which share a file's
+buffers, but will be the largest value specified by any of the processes
+sharing the file.
+.Pp
+The
+.Fn mpool_filter
+function is intended to make transparent input and output processing of the
+pages possible.
+If the
+.Fa pgin
+function is specified, it is called each time a buffer is read into the memory
+pool from the backing file.
+If the
+.Fa pgout
+function is specified, it is called each time a buffer is written into the
+backing file.
+Both functions are called with the
+.Fa pgcookie
+pointer, the page number and a pointer to the page to being read or written.
+.Pp
+The
+.Fn mpool_new
+function takes an
+.Ft MPOOL
+pointer and an address as arguments.
+If a new page can be allocated, a pointer to the page is returned and
+the page number is stored into the
+.Fa pgnoaddr
+address.
+Otherwise,
+.Dv NULL
+is returned and
+.Va errno
+is set.
+.Pp
+The
+.Fn mpool_get
+function takes a
+.Ft MPOOL
+pointer and a page number as arguments.
+If the page exists, a pointer to the page is returned.
+Otherwise,
+.Dv NULL
+is returned and
+.Va errno
+is set.
+The
+.Fa flags
+argument is not currently used.
+.Pp
+The
+.Fn mpool_put
+function unpins the page referenced by
+.Fa pgaddr .
+The
+.Fa pgaddr
+argument
+must be an address previously returned by
+.Fn mpool_get
+or
+.Fn mpool_new .
+The
+.Fa flags
+argument is specified by
+.Em or Ns 'ing
+any of the following values:
+.Bl -tag -width indent
+.It Dv MPOOL_DIRTY
+The page has been modified and needs to be written to the backing file.
+.El
+.Pp
+The
+.Fn mpool_put
+function
+returns 0 on success and -1 if an error occurs.
+.Pp
+The
+.Fn mpool_sync
+function writes all modified pages associated with the
+.Ft MPOOL
+pointer to the
+backing file.
+The
+.Fn mpool_sync
+function
+returns 0 on success and -1 if an error occurs.
+.Pp
+The
+.Fn mpool_close
+function free's up any allocated memory associated with the memory pool
+cookie.
+Modified pages are
+.Em not
+written to the backing file.
+The
+.Fn mpool_close
+function
+returns 0 on success and -1 if an error occurs.
+.Sh ERRORS
+The
+.Fn mpool_open
+function may fail and set
+.Va errno
+for any of the errors specified for the library routine
+.Xr malloc 3 .
+.Pp
+The
+.Fn mpool_get
+function may fail and set
+.Va errno
+for the following:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The requested record doesn't exist.
+.El
+.Pp
+The
+.Fn mpool_new
+and
+.Fn mpool_get
+functions may fail and set
+.Va errno
+for any of the errors specified for the library routines
+.Xr read 2 ,
+.Xr write 2 ,
+and
+.Xr malloc 3 .
+.Pp
+The
+.Fn mpool_sync
+function may fail and set
+.Va errno
+for any of the errors specified for the library routine
+.Xr write 2 .
+.Pp
+The
+.Fn mpool_close
+function may fail and set
+.Va errno
+for any of the errors specified for the library routine
+.Xr free 3 .
+.Sh SEE ALSO
+.Xr btree 3 ,
+.Xr dbopen 3 ,
+.Xr hash 3 ,
+.Xr recno 3
--- /dev/null
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)recno.3 8.5 (Berkeley) 8/18/94
+.\" $FreeBSD: src/lib/libc/db/man/recno.3,v 1.6 2001/10/01 16:08:50 ru Exp $
+.\"
+.Dd August 18, 1994
+.Dt RECNO 3
+.Os
+.Sh NAME
+.Nm recno
+.Nd "record number database access method"
+.Sh SYNOPSIS
+.In sys/types.h
+.In db.h
+.Sh DESCRIPTION
+The routine
+.Fn dbopen
+is the library interface to database files.
+One of the supported file formats is record number files.
+The general description of the database access methods is in
+.Xr dbopen 3 ,
+this manual page describes only the
+.Nm
+specific information.
+.Pp
+The record number data structure is either variable or fixed-length
+records stored in a flat-file format, accessed by the logical record
+number.
+The existence of record number five implies the existence of records
+one through four, and the deletion of record number one causes
+record number five to be renumbered to record number four, as well
+as the cursor, if positioned after record number one, to shift down
+one record.
+.Pp
+The
+.Nm
+access method specific data structure provided to
+.Fn dbopen
+is defined in the
+.Aq Pa db.h
+include file as follows:
+.Bd -literal
+typedef struct {
+ u_long flags;
+ u_int cachesize;
+ u_int psize;
+ int lorder;
+ size_t reclen;
+ u_char bval;
+ char *bfname;
+} RECNOINFO;
+.Ed
+.Pp
+The elements of this structure are defined as follows:
+.Bl -tag -width indent
+.It Va flags
+The flag value is specified by
+.Em or Ns 'ing
+any of the following values:
+.Bl -tag -width indent
+.It Dv R_FIXEDLEN
+The records are fixed-length, not byte delimited.
+The structure element
+.Va reclen
+specifies the length of the record, and the structure element
+.Va bval
+is used as the pad character.
+Any records, inserted into the database, that are less than
+.Va reclen
+bytes long are automatically padded.
+.It Dv R_NOKEY
+In the interface specified by
+.Fn dbopen ,
+the sequential record retrieval fills in both the caller's key and
+data structures.
+If the
+.Dv R_NOKEY
+flag is specified, the
+.Em cursor
+routines are not required to fill in the key structure.
+This permits applications to retrieve records at the end of files without
+reading all of the intervening records.
+.It Dv R_SNAPSHOT
+This flag requires that a snapshot of the file be taken when
+.Fn dbopen
+is called, instead of permitting any unmodified records to be read from
+the original file.
+.El
+.It Va cachesize
+A suggested maximum size, in bytes, of the memory cache.
+This value is
+.Em only
+advisory, and the access method will allocate more memory rather than fail.
+If
+.Va cachesize
+is 0 (no size is specified) a default cache is used.
+.It Va psize
+The
+.Nm
+access method stores the in-memory copies of its records
+in a btree.
+This value is the size (in bytes) of the pages used for nodes in that tree.
+If
+.Va psize
+is 0 (no page size is specified) a page size is chosen based on the
+underlying file system I/O block size.
+See
+.Xr btree 3
+for more information.
+.It Va lorder
+The byte order for integers in the stored database metadata.
+The number should represent the order as an integer; for example,
+big endian order would be the number 4,321.
+If
+.Va lorder
+is 0 (no order is specified) the current host order is used.
+.It Va reclen
+The length of a fixed-length record.
+.It Va bval
+The delimiting byte to be used to mark the end of a record for
+variable-length records, and the pad character for fixed-length
+records.
+If no value is specified, newlines
+.Pq Dq \en
+are used to mark the end
+of variable-length records and fixed-length records are padded with
+spaces.
+.It Va bfname
+The
+.Nm
+access method stores the in-memory copies of its records
+in a btree.
+If
+.Va bfname
+is
+.No non\- Ns Dv NULL ,
+it specifies the name of the btree file,
+as if specified as the file name for a
+.Fn dbopen
+of a btree file.
+.El
+.Pp
+The data part of the key/data pair used by the
+.Nm
+access method
+is the same as other access methods.
+The key is different.
+The
+.Va data
+field of the key should be a pointer to a memory location of type
+.Ft recno_t ,
+as defined in the
+.Aq Pa db.h
+include file.
+This type is normally the largest unsigned integral type available to
+the implementation.
+The
+.Va size
+field of the key should be the size of that type.
+.Pp
+Because there can be no meta-data associated with the underlying
+.Nm
+access method files, any changes made to the default values
+(e.g. fixed record length or byte separator value) must be explicitly
+specified each time the file is opened.
+.Pp
+In the interface specified by
+.Fn dbopen ,
+using the
+.Va put
+interface to create a new record will cause the creation of multiple,
+empty records if the record number is more than one greater than the
+largest record currently in the database.
+.Sh ERRORS
+The
+.Nm
+access method routines may fail and set
+.Va errno
+for any of the errors specified for the library routine
+.Xr dbopen 3
+or the following:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+An attempt was made to add a record to a fixed-length database that
+was too large to fit.
+.El
+.Sh SEE ALSO
+.Xr btree 3 ,
+.Xr dbopen 3 ,
+.Xr hash 3 ,
+.Xr mpool 3
+.Rs
+.%T "Document Processing in a Relational Database System"
+.%A Michael Stonebraker
+.%A Heidi Stettner
+.%A Joseph Kalash
+.%A Antonin Guttman
+.%A Nadene Lynn
+.%R "Memorandum No. UCB/ERL M82/32"
+.%D May 1982
+.Re
+.Sh BUGS
+Only big and little endian byte order is supported.
# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
-# $FreeBSD: src/lib/libc/db/man/Makefile.inc,v 1.10 2001/03/27 17:26:46 ru Exp $
+# $FreeBSD: src/lib/libc/db/man/Makefile.inc,v 1.11 2002/11/18 09:50:54 ru Exp $
.PATH: ${.CURDIR}/db/man
.if ${LIB} == "c"
-MAN3+= btree.3 dbm.3 dbopen.3 hash.3 mpool.3 recno.3
+.include "Makefile.fbsd_begin"
+FBSDMAN3= btree.3 dbm.3 dbopen.3 hash.3 mpool.3 recno.3
+.include "Makefile.fbsd_end"
MLINKS+= dbm.3 dbm_clearerr.3
MLINKS+= dbm.3 dbm_close.3
+++ /dev/null
-.\" Copyright (c) 1990, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)btree.3 8.4 (Berkeley) 8/18/94
-.\" $FreeBSD: src/lib/libc/db/man/btree.3,v 1.5 2001/10/01 16:08:50 ru Exp $
-.\"
-.Dd August 18, 1994
-.Dt BTREE 3
-.Os
-.Sh NAME
-.Nm btree
-.Nd "btree database access method"
-.Sh SYNOPSIS
-.In sys/types.h
-.In db.h
-.Sh DESCRIPTION
-The routine
-.Fn dbopen
-is the library interface to database files.
-One of the supported file formats is
-.Nm
-files.
-The general description of the database access methods is in
-.Xr dbopen 3 ,
-this manual page describes only the
-.Nm
-specific information.
-.Pp
-The
-.Nm
-data structure is a sorted, balanced tree structure storing
-associated key/data pairs.
-.Pp
-The
-.Nm
-access method specific data structure provided to
-.Fn dbopen
-is defined in the
-.Aq Pa db.h
-include file as follows:
-.Bd -literal
-typedef struct {
- u_long flags;
- u_int cachesize;
- int maxkeypage;
- int minkeypage;
- u_int psize;
- int (*compare)(const DBT *key1, const DBT *key2);
- size_t (*prefix)(const DBT *key1, const DBT *key2);
- int lorder;
-} BTREEINFO;
-.Ed
-.Pp
-The elements of this structure are as follows:
-.Bl -tag -width indent
-.It Va flags
-The flag value is specified by
-.Em or Ns 'ing
-any of the following values:
-.Bl -tag -width indent
-.It Dv R_DUP
-Permit duplicate keys in the tree, i.e. permit insertion if the key to be
-inserted already exists in the tree.
-The default behavior, as described in
-.Xr dbopen 3 ,
-is to overwrite a matching key when inserting a new key or to fail if
-the
-.Dv R_NOOVERWRITE
-flag is specified.
-The
-.Dv R_DUP
-flag is overridden by the
-.Dv R_NOOVERWRITE
-flag, and if the
-.Dv R_NOOVERWRITE
-flag is specified, attempts to insert duplicate keys into
-the tree will fail.
-.Pp
-If the database contains duplicate keys, the order of retrieval of
-key/data pairs is undefined if the
-.Va get
-routine is used, however,
-.Va seq
-routine calls with the
-.Dv R_CURSOR
-flag set will always return the logical
-.Dq first
-of any group of duplicate keys.
-.El
-.It Va cachesize
-A suggested maximum size (in bytes) of the memory cache.
-This value is
-.Em only
-advisory, and the access method will allocate more memory rather than fail.
-Since every search examines the root page of the tree, caching the most
-recently used pages substantially improves access time.
-In addition, physical writes are delayed as long as possible, so a moderate
-cache can reduce the number of I/O operations significantly.
-Obviously, using a cache increases (but only increases) the likelihood of
-corruption or lost data if the system crashes while a tree is being modified.
-If
-.Va cachesize
-is 0 (no size is specified) a default cache is used.
-.It Va maxkeypage
-The maximum number of keys which will be stored on any single page.
-Not currently implemented.
-.\" The maximum number of keys which will be stored on any single page.
-.\" Because of the way the
-.\" .Nm
-.\" data structure works,
-.\" .Va maxkeypage
-.\" must always be greater than or equal to 2.
-.\" If
-.\" .Va maxkeypage
-.\" is 0 (no maximum number of keys is specified) the page fill factor is
-.\" made as large as possible (which is almost invariably what is wanted).
-.It Va minkeypage
-The minimum number of keys which will be stored on any single page.
-This value is used to determine which keys will be stored on overflow
-pages, i.e. if a key or data item is longer than the pagesize divided
-by the minkeypage value, it will be stored on overflow pages instead
-of in the page itself.
-If
-.Va minkeypage
-is 0 (no minimum number of keys is specified) a value of 2 is used.
-.It Va psize
-Page size is the size (in bytes) of the pages used for nodes in the tree.
-The minimum page size is 512 bytes and the maximum page size is 64K.
-If
-.Va psize
-is 0 (no page size is specified) a page size is chosen based on the
-underlying file system I/O block size.
-.It Va compare
-Compare is the key comparison function.
-It must return an integer less than, equal to, or greater than zero if the
-first key argument is considered to be respectively less than, equal to,
-or greater than the second key argument.
-The same comparison function must be used on a given tree every time it
-is opened.
-If
-.Va compare
-is
-.Dv NULL
-(no comparison function is specified), the keys are compared
-lexically, with shorter keys considered less than longer keys.
-.It Va prefix
-.Va Prefix
-is the prefix comparison function.
-If specified, this routine must return the number of bytes of the second key
-argument which are necessary to determine that it is greater than the first
-key argument.
-If the keys are equal, the key length should be returned.
-Note, the usefulness of this routine is very data dependent, but, in some
-data sets can produce significantly reduced tree sizes and search times.
-If
-.Va prefix
-is
-.Dv NULL
-(no prefix function is specified),
-.Em and
-no comparison function is specified, a default lexical comparison routine
-is used.
-If
-.Va prefix
-is
-.Dv NULL
-and a comparison routine is specified, no prefix comparison is
-done.
-.It Va lorder
-The byte order for integers in the stored database metadata.
-The number should represent the order as an integer; for example,
-big endian order would be the number 4,321.
-If
-.Va lorder
-is 0 (no order is specified) the current host order is used.
-.El
-.Pp
-If the file already exists (and the
-.Dv O_TRUNC
-flag is not specified), the
-values specified for the parameters
-.Va flags , lorder
-and
-.Va psize
-are ignored
-in favor of the values used when the tree was created.
-.Pp
-Forward sequential scans of a tree are from the least key to the greatest.
-.Pp
-Space freed up by deleting key/data pairs from the tree is never reclaimed,
-although it is normally made available for reuse.
-This means that the
-.Nm
-storage structure is grow-only.
-The only solutions are to avoid excessive deletions, or to create a fresh
-tree periodically from a scan of an existing one.
-.Pp
-Searches, insertions, and deletions in a
-.Nm
-will all complete in
-O lg base N where base is the average fill factor.
-Often, inserting ordered data into
-.Nm Ns s
-results in a low fill factor.
-This implementation has been modified to make ordered insertion the best
-case, resulting in a much better than normal page fill factor.
-.Sh ERRORS
-The
-.Nm
-access method routines may fail and set
-.Va errno
-for any of the errors specified for the library routine
-.Xr dbopen 3 .
-.Sh SEE ALSO
-.Xr dbopen 3 ,
-.Xr hash 3 ,
-.Xr mpool 3 ,
-.Xr recno 3
-.Rs
-.%T "The Ubiquitous B-tree"
-.%A Douglas Comer
-.%J "ACM Comput. Surv. 11"
-.%N 2
-.%D June 1979
-.%P 121-138
-.Re
-.Rs
-.%A Bayer
-.%A Unterauer
-.%T "Prefix B-trees"
-.%J "ACM Transactions on Database Systems"
-.%N 1
-.%V Vol. 2
-.%D March 1977
-.%P 11-26
-.Re
-.Rs
-.%B "The Art of Computer Programming Vol. 3: Sorting and Searching"
-.%A D. E. Knuth
-.%D 1968
-.%P 471-480
-.Re
-.Sh BUGS
-Only big and little endian byte order is supported.
+++ /dev/null
-.\" Copyright (c) 1999 Tim Singletary
-.\" No copyright is claimed.
-.\"
-.\" 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.
-.\"
-.\" $FreeBSD: src/lib/libc/db/man/dbm.3,v 1.5 2001/10/01 16:08:50 ru Exp $
-.\"
-.\" Note: The date here should be updated whenever a non-trivial
-.\" change is made to the manual page.
-.Dd July 7, 1999
-.Dt DBM 3
-.Os
-.Sh NAME
-.Nm dbm_clearerr ,
-.Nm dbm_close ,
-.Nm dbm_delete ,
-.Nm dbm_dirfno ,
-.Nm dbm_error ,
-.Nm dbm_fetch ,
-.Nm dbm_firstkey ,
-.Nm dbm_nextkey ,
-.Nm dbm_open ,
-.Nm dbm_store
-.Nd database access functions
-.Sh SYNOPSIS
-.In fcntl.h
-.In ndbm.h
-.Ft DBM *
-.Fn dbm_open "const char *base" "int flags" "int mode"
-.Ft void
-.Fn dbm_close "DBM *db"
-.Ft int
-.Fn dbm_store "DBM *db" "datum key" "datum data" "int flags"
-.Ft datum
-.Fn dbm_fetch "DBM *db" "datum key"
-.Ft int
-.Fn dbm_delete "DBM *db" "datum key"
-.Ft datum
-.Fn dbm_firstkey "DBM *db"
-.Ft datum
-.Fn dbm_nextkey "DBM *db"
-.Ft int
-.Fn dbm_error "DBM *db"
-.Ft int
-.Fn dbm_clearerr "DBM *db"
-.Ft int
-.Fn dbm_dirfno "DBM *db"
-.Sh DESCRIPTION
-Database access functions.
-These functions are implemented using
-.Xr dbopen 3
-with a
-.Xr hash 3
-database.
-.Pp
-.Vt datum
-is declared in
-.Aq Pa ndbm.h :
-.Bd -literal
-typedef struct {
- char *dptr;
- int dsize;
-} datum;
-.Ed
-.Pp
-.Fn dbm_open base flags mode
-opens or creates a database.
-.Fa base
-is the basename of the file containing
-the database; the actual database has a
-.Pa .db
-suffix.
-I.e., if
-.Fa base
-is
-.Qq Li /home/me/mystuff
-then the actual database is in the file
-.Pa /home/me/mystuff.db .
-.Fa flags
-and
-.Fa mode
-are passed to
-.Xr open 2 .
-.Pq Dv O_RDWR | O_CREAT
-is a typical value for
-.Fa flags ;
-.Li 0660
-is a typical value for
-.Fa mode .
-.Dv O_WRONLY
-is not allowed in
-.Fa flags .
-The pointer returned by
-.Fn dbm_open
-identifies the database and is the
-.Fa db
-argument to the other functions.
-.Fn dbm_open
-returns
-.Dv NULL
-and sets
-.Va errno
-if there were any errors.
-.Pp
-.Fn dbm_close db
-closes the database.
-.Fn dbm_close
-normally returns zero.
-.Pp
-.Fn dbm_store db key data flags
-inserts or replaces an entry in the database.
-.Fa flags
-is either
-.Dv DBM_INSERT
-or
-.Dv DBM_REPLACE .
-If
-.Fa flags
-is
-.Dv DBM_INSERT
-and the database already contains an entry for
-.Fa key ,
-that entry is not replaced.
-Otherwise the entry is replaced or inserted.
-.Fn dbm_store
-normally returns zero but returns 1 if the entry could not be
-inserted (because
-.Fa flags
-is
-.Dv DBM_INSERT ,
-and an entry with
-.Fa key
-already exists) or returns -1 and sets
-.Va errno
-if there were any errors.
-.Pp
-.Fn dbm_fetch db key
-returns
-.Dv NULL
-or the
-.Fa data
-corresponding to
-.Fa key .
-.Pp
-.Fn dbm_delete db key
-deletes the entry for
-.Fa key .
-.Fn dbm_delete
-normally returns zero but returns 1 if there was no entry with
-.Fa key
-in the database or returns -1 and sets
-.Va errno
-if there were any errors.
-.Pp
-.Fn dbm_firstkey db
-returns the first key in the database.
-.Fn dbm_nextkey db
-returns subsequent keys.
-.Fn db_firstkey
-must be called before
-.Fn dbm_nextkey .
-The order in which keys are returned is unspecified and may appear
-random.
-.Fn dbm_nextkey
-returns
-.Dv NULL
-after all keys have been returned.
-.Pp
-.Fn dbm_error db
-returns the
-.Va errno
-value of the most recent error.
-.Fn dbm_clearerr db
-resets this value to 0 and returns 0.
-.Pp
-.Fn dbm_dirfno db
-returns the file descriptor to the database.
-.Sh SEE ALSO
-.Xr open 2 ,
-.Xr dbopen 3 ,
-.Xr hash 3
-.Sh STANDARDS
-These functions (except
-.Fn dbm_dirfno )
-are included in the
-.St -susv2 .
+++ /dev/null
-.\" Copyright (c) 1990, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)dbopen.3 8.5 (Berkeley) 1/2/94
-.\" $FreeBSD: src/lib/libc/db/man/dbopen.3,v 1.5 2001/10/01 16:08:50 ru Exp $
-.\"
-.Dd January 2, 1994
-.Dt DBOPEN 3
-.Os
-.Sh NAME
-.Nm dbopen
-.Nd "database access methods"
-.Sh SYNOPSIS
-.In sys/types.h
-.In limits.h
-.In db.h
-.Ft DB *
-.Fn dbopen "const char *file" "int flags" "int mode" "DBTYPE type" "const void *openinfo"
-.Sh DESCRIPTION
-.Fn Dbopen
-is the library interface to database files.
-The supported file formats are btree, hashed and UNIX file oriented.
-The btree format is a representation of a sorted, balanced tree structure.
-The hashed format is an extensible, dynamic hashing scheme.
-The flat-file format is a byte stream file with fixed or variable length
-records.
-The formats and file format specific information are described in detail
-in their respective manual pages
-.Xr btree 3 ,
-.Xr hash 3
-and
-.Xr recno 3 .
-.Pp
-.Fn Dbopen
-opens
-.Fa file
-for reading and/or writing.
-Files never intended to be preserved on disk may be created by setting
-the file parameter to
-.Dv NULL .
-.Pp
-The
-.Fa flags
-and
-.Fa mode
-arguments
-are as specified to the
-.Xr open 2
-routine, however, only the
-.Dv O_CREAT , O_EXCL , O_EXLOCK , O_NONBLOCK ,
-.Dv O_RDONLY , O_RDWR , O_SHLOCK
-and
-.Dv O_TRUNC
-flags are meaningful.
-(Note, opening a database file
-.Dv O_WRONLY
-is not possible.)
-.\"Three additional options may be specified by
-.\".Em or Ns 'ing
-.\"them into the
-.\".Fa flags
-.\"argument.
-.\".Bl -tag -width indent
-.\".It Dv DB_LOCK
-.\"Do the necessary locking in the database to support concurrent access.
-.\"If concurrent access isn't needed or the database is read-only this
-.\"flag should not be set, as it tends to have an associated performance
-.\"penalty.
-.\".It Dv DB_SHMEM
-.\"Place the underlying memory pool used by the database in shared
-.\"memory.
-.\"Necessary for concurrent access.
-.\".It Dv DB_TXN
-.\"Support transactions in the database.
-.\"The
-.\".Dv DB_LOCK
-.\"and
-.\".Dv DB_SHMEM
-.\"flags must be set as well.
-.\".El
-.Pp
-The
-.Fa type
-argument is of type
-.Ft DBTYPE
-(as defined in the
-.Aq Pa db.h
-include file) and
-may be set to
-.Dv DB_BTREE , DB_HASH
-or
-.Dv DB_RECNO .
-.Pp
-The
-.Fa openinfo
-argument is a pointer to an access method specific structure described
-in the access method's manual page.
-If
-.Fa openinfo
-is
-.Dv NULL ,
-each access method will use defaults appropriate for the system
-and the access method.
-.Pp
-.Fn Dbopen
-returns a pointer to a
-.Ft DB
-structure on success and
-.Dv NULL
-on error.
-The
-.Ft DB
-structure is defined in the
-.Aq Pa db.h
-include file, and contains at
-least the following fields:
-.Bd -literal
-typedef struct {
- DBTYPE type;
- int (*close)(const DB *db);
- int (*del)(const DB *db, const DBT *key, u_int flags);
- int (*fd)(const DB *db);
- int (*get)(const DB *db, DBT *key, DBT *data, u_int flags);
- int (*put)(const DB *db, DBT *key, const DBT *data,
- u_int flags);
- int (*sync)(const DB *db, u_int flags);
- int (*seq)(const DB *db, DBT *key, DBT *data, u_int flags);
-} DB;
-.Ed
-.Pp
-These elements describe a database type and a set of functions performing
-various actions.
-These functions take a pointer to a structure as returned by
-.Fn dbopen ,
-and sometimes one or more pointers to key/data structures and a flag value.
-.Bl -tag -width indent
-.It Va type
-The type of the underlying access method (and file format).
-.It Va close
-A pointer to a routine to flush any cached information to disk, free any
-allocated resources, and close the underlying file(s).
-Since key/data pairs may be cached in memory, failing to sync the file
-with a
-.Va close
-or
-.Va sync
-function may result in inconsistent or lost information.
-.Va Close
-routines return -1 on error (setting
-.Va errno )
-and 0 on success.
-.It Va del
-A pointer to a routine to remove key/data pairs from the database.
-.Pp
-The parameter
-.Fa flags
-may be set to the following value:
-.Bl -tag -width indent
-.It Dv R_CURSOR
-Delete the record referenced by the cursor.
-The cursor must have previously been initialized.
-.El
-.Pp
-.Va Delete
-routines return -1 on error (setting
-.Va errno ) ,
-0 on success, and 1 if the specified
-.Fa key
-was not in the file.
-.It Va fd
-A pointer to a routine which returns a file descriptor representative
-of the underlying database.
-A file descriptor referencing the same file will be returned to all
-processes which call
-.Fn dbopen
-with the same
-.Fa file
-name.
-This file descriptor may be safely used as an argument to the
-.Xr fcntl 2
-and
-.Xr flock 2
-locking functions.
-The file descriptor is not necessarily associated with any of the
-underlying files used by the access method.
-No file descriptor is available for in memory databases.
-.Va \&Fd
-routines return -1 on error (setting
-.Va errno ) ,
-and the file descriptor on success.
-.It Va get
-A pointer to a routine which is the interface for keyed retrieval from
-the database.
-The address and length of the data associated with the specified
-.Fa key
-are returned in the structure referenced by
-.Fa data .
-.Va Get
-routines return -1 on error (setting
-.Va errno ) ,
-0 on success, and 1 if the
-.Fa key
-was not in the file.
-.It Va put
-A pointer to a routine to store key/data pairs in the database.
-.Pp
-The parameter
-.Fa flags
-may be set to one of the following values:
-.Bl -tag -width indent
-.It Dv R_CURSOR
-Replace the key/data pair referenced by the cursor.
-The cursor must have previously been initialized.
-.It Dv R_IAFTER
-Append the data immediately after the data referenced by
-.Fa key ,
-creating a new key/data pair.
-The record number of the appended key/data pair is returned in the
-.Fa key
-structure.
-(Applicable only to the
-.Dv DB_RECNO
-access method.)
-.It Dv R_IBEFORE
-Insert the data immediately before the data referenced by
-.Fa key ,
-creating a new key/data pair.
-The record number of the inserted key/data pair is returned in the
-.Fa key
-structure.
-(Applicable only to the
-.Dv DB_RECNO
-access method.)
-.It Dv R_NOOVERWRITE
-Enter the new key/data pair only if the key does not previously exist.
-.It Dv R_SETCURSOR
-Store the key/data pair, setting or initializing the position of the
-cursor to reference it.
-(Applicable only to the
-.Dv DB_BTREE
-and
-.Dv DB_RECNO
-access methods.)
-.El
-.Pp
-.Dv R_SETCURSOR
-is available only for the
-.Dv DB_BTREE
-and
-.Dv DB_RECNO
-access
-methods because it implies that the keys have an inherent order
-which does not change.
-.Pp
-.Dv R_IAFTER
-and
-.Dv R_IBEFORE
-are available only for the
-.Dv DB_RECNO
-access method because they each imply that the access method is able to
-create new keys.
-This is only true if the keys are ordered and independent, record numbers
-for example.
-.Pp
-The default behavior of the
-.Va put
-routines is to enter the new key/data pair, replacing any previously
-existing key.
-.Pp
-.Va Put
-routines return -1 on error (setting
-.Va errno ) ,
-0 on success, and 1 if the
-.Dv R_NOOVERWRITE
-flag
-was set and the key already exists in the file.
-.It Va seq
-A pointer to a routine which is the interface for sequential
-retrieval from the database.
-The address and length of the key are returned in the structure
-referenced by
-.Fa key ,
-and the address and length of the data are returned in the
-structure referenced
-by
-.Fa data .
-.Pp
-Sequential key/data pair retrieval may begin at any time, and the
-position of the
-.Dq cursor
-is not affected by calls to the
-.Va del ,
-.Va get ,
-.Va put ,
-or
-.Va sync
-routines.
-Modifications to the database during a sequential scan will be reflected
-in the scan, i.e. records inserted behind the cursor will not be returned
-while records inserted in front of the cursor will be returned.
-.Pp
-The
-.Fa flags
-value
-.Em must
-be set to one of the following values:
-.Bl -tag -width indent
-.It Dv R_CURSOR
-The data associated with the specified key is returned.
-This differs from the
-.Va get
-routines in that it sets or initializes the cursor to the location of
-the key as well.
-(Note, for the
-.Dv DB_BTREE
-access method, the returned key is not necessarily an
-exact match for the specified key.
-The returned key is the smallest key greater than or equal to the specified
-key, permitting partial key matches and range searches.)
-.It Dv R_FIRST
-The first key/data pair of the database is returned, and the cursor
-is set or initialized to reference it.
-.It Dv R_LAST
-The last key/data pair of the database is returned, and the cursor
-is set or initialized to reference it.
-(Applicable only to the
-.Dv DB_BTREE
-and
-.Dv DB_RECNO
-access methods.)
-.It Dv R_NEXT
-Retrieve the key/data pair immediately after the cursor.
-If the cursor is not yet set, this is the same as the
-.Dv R_FIRST
-flag.
-.It Dv R_PREV
-Retrieve the key/data pair immediately before the cursor.
-If the cursor is not yet set, this is the same as the
-.Dv R_LAST
-flag.
-(Applicable only to the
-.Dv DB_BTREE
-and
-.Dv DB_RECNO
-access methods.)
-.El
-.Pp
-.Dv R_LAST
-and
-.Dv R_PREV
-are available only for the
-.Dv DB_BTREE
-and
-.Dv DB_RECNO
-access methods because they each imply that the keys have an inherent
-order which does not change.
-.Pp
-.Va Seq
-routines return -1 on error (setting
-.Va errno ) ,
-0 on success and 1 if there are no key/data pairs less than or greater
-than the specified or current key.
-If the
-.Dv DB_RECNO
-access method is being used, and if the database file
-is a character special file and no complete key/data pairs are currently
-available, the
-.Va seq
-routines return 2.
-.It Va sync
-A pointer to a routine to flush any cached information to disk.
-If the database is in memory only, the
-.Va sync
-routine has no effect and will always succeed.
-.Pp
-The
-.Fa flags
-value may be set to the following value:
-.Bl -tag -width indent
-.It Dv R_RECNOSYNC
-If the
-.Dv DB_RECNO
-access method is being used, this flag causes
-the
-.Va sync
-routine to apply to the btree file which underlies the
-recno file, not the recno file itself.
-(See the
-.Va bfname
-field of the
-.Xr recno 3
-manual page for more information.)
-.El
-.Pp
-.Va Sync
-routines return -1 on error (setting
-.Va errno )
-and 0 on success.
-.El
-.Sh "KEY/DATA PAIRS"
-Access to all file types is based on key/data pairs.
-Both keys and data are represented by the following data structure:
-.Bd -literal
-typedef struct {
- void *data;
- size_t size;
-} DBT;
-.Ed
-.Pp
-The elements of the
-.Ft DBT
-structure are defined as follows:
-.Bl -tag -width "data"
-.It Va data
-A pointer to a byte string.
-.It Va size
-The length of the byte string.
-.El
-.Pp
-Key and data byte strings may reference strings of essentially unlimited
-length although any two of them must fit into available memory at the same
-time.
-It should be noted that the access methods provide no guarantees about
-byte string alignment.
-.Sh ERRORS
-The
-.Fn dbopen
-routine may fail and set
-.Va errno
-for any of the errors specified for the library routines
-.Xr open 2
-and
-.Xr malloc 3
-or the following:
-.Bl -tag -width Er
-.It Bq Er EFTYPE
-A file is incorrectly formatted.
-.It Bq Er EINVAL
-A parameter has been specified (hash function, pad byte etc.) that is
-incompatible with the current file specification or which is not
-meaningful for the function (for example, use of the cursor without
-prior initialization) or there is a mismatch between the version
-number of file and the software.
-.El
-.Pp
-The
-.Va close
-routines may fail and set
-.Va errno
-for any of the errors specified for the library routines
-.Xr close 2 ,
-.Xr read 2 ,
-.Xr write 2 ,
-.Xr free 3 ,
-or
-.Xr fsync 2 .
-.Pp
-The
-.Va del ,
-.Va get ,
-.Va put
-and
-.Va seq
-routines may fail and set
-.Va errno
-for any of the errors specified for the library routines
-.Xr read 2 ,
-.Xr write 2 ,
-.Xr free 3
-or
-.Xr malloc 3 .
-.Pp
-The
-.Va fd
-routines will fail and set
-.Va errno
-to
-.Er ENOENT
-for in memory databases.
-.Pp
-The
-.Va sync
-routines may fail and set
-.Va errno
-for any of the errors specified for the library routine
-.Xr fsync 2 .
-.Sh SEE ALSO
-.Xr btree 3 ,
-.Xr hash 3 ,
-.Xr mpool 3 ,
-.Xr recno 3
-.Rs
-.%T "LIBTP: Portable, Modular Transactions for UNIX"
-.%A Margo Seltzer
-.%A Michael Olson
-.%R "USENIX proceedings"
-.%D Winter 1992
-.Re
-.Sh BUGS
-The typedef
-.Ft DBT
-is a mnemonic for
-.Dq "data base thang" ,
-and was used
-because noone could think of a reasonable name that wasn't already used.
-.Pp
-The file descriptor interface is a kluge and will be deleted in a
-future version of the interface.
-.Pp
-None of the access methods provide any form of concurrent access,
-locking, or transactions.
+++ /dev/null
-.\" Copyright (c) 1990, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)hash.3 8.6 (Berkeley) 8/18/94
-.\" $FreeBSD: src/lib/libc/db/man/hash.3,v 1.6 2001/10/01 16:08:50 ru Exp $
-.\"
-.Dd August 18, 1994
-.Dt HASH 3
-.Os
-.Sh NAME
-.Nm hash
-.Nd "hash database access method"
-.Sh SYNOPSIS
-.In sys/types.h
-.In db.h
-.Sh DESCRIPTION
-The routine
-.Fn dbopen
-is the library interface to database files.
-One of the supported file formats is
-.Nm
-files.
-The general description of the database access methods is in
-.Xr dbopen 3 ,
-this manual page describes only the
-.Nm
-specific information.
-.Pp
-The
-.Nm
-data structure is an extensible, dynamic hashing scheme.
-.Pp
-The access method specific data structure provided to
-.Fn dbopen
-is defined in the
-.Aq Pa db.h
-include file as follows:
-.Bd -literal
-typedef struct {
- u_int bsize;
- u_int ffactor;
- u_int nelem;
- u_int cachesize;
- u_int32_t (*hash)(const void *, size_t);
- int lorder;
-} HASHINFO;
-.Ed
-.Pp
-The elements of this structure are as follows:
-.Bl -tag -width indent
-.It Va bsize
-.Va Bsize
-defines the
-.Nm
-table bucket size, and is, by default, 256 bytes.
-It may be preferable to increase the page size for disk-resident tables
-and tables with large data items.
-.It Va ffactor
-.Va Ffactor
-indicates a desired density within the
-.Nm
-table.
-It is an approximation of the number of keys allowed to accumulate in any
-one bucket, determining when the
-.Nm
-table grows or shrinks.
-The default value is 8.
-.It Va nelem
-.Va Nelem
-is an estimate of the final size of the
-.Nm
-table.
-If not set or set too low,
-.Nm
-tables will expand gracefully as keys
-are entered, although a slight performance degradation may be noticed.
-The default value is 1.
-.It Va cachesize
-A suggested maximum size, in bytes, of the memory cache.
-This value is
-.Em only
-advisory, and the access method will allocate more memory rather
-than fail.
-.It Va hash
-.Va Hash
-is a user defined
-.Nm
-function.
-Since no
-.Nm
-function performs equally well on all possible data, the
-user may find that the built-in
-.Nm
-function does poorly on a particular
-data set.
-User specified
-.Nm
-functions must take two arguments (a pointer to a byte
-string and a length) and return a 32-bit quantity to be used as the
-.Nm
-value.
-.It Va lorder
-The byte order for integers in the stored database metadata.
-The number should represent the order as an integer; for example,
-big endian order would be the number 4,321.
-If
-.Va lorder
-is 0 (no order is specified) the current host order is used.
-If the file already exists, the specified value is ignored and the
-value specified when the tree was created is used.
-.El
-.Pp
-If the file already exists (and the
-.Dv O_TRUNC
-flag is not specified), the
-values specified for the parameters
-.Va bsize , ffactor , lorder
-and
-.Va nelem
-are
-ignored and the values specified when the tree was created are used.
-.Pp
-If a
-.Nm
-function is specified,
-.Fn hash_open
-will attempt to determine if the
-.Nm
-function specified is the same as
-the one with which the database was created, and will fail if it is not.
-.Pp
-Backward compatible interfaces to the older
-.Em dbm
-and
-.Em ndbm
-routines are provided, however these interfaces are not compatible with
-previous file formats.
-.Sh ERRORS
-The
-.Nm
-access method routines may fail and set
-.Va errno
-for any of the errors specified for the library routine
-.Xr dbopen 3 .
-.Sh SEE ALSO
-.Xr btree 3 ,
-.Xr dbopen 3 ,
-.Xr mpool 3 ,
-.Xr recno 3
-.Rs
-.%T "Dynamic Hash Tables"
-.%A Per-Ake Larson
-.%R "Communications of the ACM"
-.%D April 1988
-.Re
-.Rs
-.%T "A New Hash Package for UNIX"
-.%A Margo Seltzer
-.%R "USENIX Proceedings"
-.%D Winter 1991
-.Re
-.Sh BUGS
-Only big and little endian byte order is supported.
+++ /dev/null
-.\" Copyright (c) 1990, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)mpool.3 8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/db/man/mpool.3,v 1.9 2001/10/01 16:08:50 ru Exp $
-.\"
-.Dd June 4, 1993
-.Dt MPOOL 3
-.Os
-.Sh NAME
-.Nm mpool
-.Nd "shared memory buffer pool"
-.Sh SYNOPSIS
-.In db.h
-.In mpool.h
-.Ft MPOOL *
-.Fn mpool_open "void *key" "int fd" "pgno_t pagesize" "pgno_t maxcache"
-.Ft void
-.Fo mpool_filter
-.Fa "MPOOL *mp"
-.Fa "void (*pgin)(void *, pgno_t, void *)"
-.Fa "void (*pgout)(void *, pgno_t, void *)"
-.Fa "void *pgcookie"
-.Fc
-.Ft void *
-.Fn mpool_new "MPOOL *mp" "pgno_t *pgnoaddr"
-.Ft void *
-.Fn mpool_get "MPOOL *mp" "pgno_t pgno" "u_int flags"
-.Ft int
-.Fn mpool_put "MPOOL *mp" "void *pgaddr" "u_int flags"
-.Ft int
-.Fn mpool_sync "MPOOL *mp"
-.Ft int
-.Fn mpool_close "MPOOL *mp"
-.Sh DESCRIPTION
-.Nm Mpool
-is the library interface intended to provide page oriented buffer management
-of files.
-The buffers may be shared between processes.
-.Pp
-The function
-.Fn mpool_open
-initializes a memory pool.
-The
-.Fa key
-argument is the byte string used to negotiate between multiple
-processes wishing to share buffers.
-If the file buffers are mapped in shared memory, all processes using
-the same key will share the buffers.
-If
-.Fa key
-is
-.Dv NULL ,
-the buffers are mapped into private memory.
-The
-.Fa fd
-argument is a file descriptor for the underlying file, which must be seekable.
-If
-.Fa key
-is
-.No non\- Ns Dv NULL
-and matches a file already being mapped, the
-.Fa fd
-argument is ignored.
-.Pp
-The
-.Fa pagesize
-argument is the size, in bytes, of the pages into which the file is broken up.
-The
-.Fa maxcache
-argument is the maximum number of pages from the underlying file to cache
-at any one time.
-This value is not relative to the number of processes which share a file's
-buffers, but will be the largest value specified by any of the processes
-sharing the file.
-.Pp
-The
-.Fn mpool_filter
-function is intended to make transparent input and output processing of the
-pages possible.
-If the
-.Fa pgin
-function is specified, it is called each time a buffer is read into the memory
-pool from the backing file.
-If the
-.Fa pgout
-function is specified, it is called each time a buffer is written into the
-backing file.
-Both functions are called with the
-.Fa pgcookie
-pointer, the page number and a pointer to the page to being read or written.
-.Pp
-The function
-.Fn mpool_new
-takes an
-.Ft MPOOL
-pointer and an address as arguments.
-If a new page can be allocated, a pointer to the page is returned and
-the page number is stored into the
-.Fa pgnoaddr
-address.
-Otherwise,
-.Dv NULL
-is returned and
-.Va errno
-is set.
-.Pp
-The function
-.Fn mpool_get
-takes a
-.Ft MPOOL
-pointer and a page number as arguments.
-If the page exists, a pointer to the page is returned.
-Otherwise,
-.Dv NULL
-is returned and
-.Va errno
-is set.
-The
-.Fa flags
-parameter is not currently used.
-.Pp
-The function
-.Fn mpool_put
-unpins the page referenced by
-.Fa pgaddr .
-.Fa Pgaddr
-must be an address previously returned by
-.Fn mpool_get
-or
-.Fn mpool_new .
-The
-.Fa flags
-value is specified by
-.Em or Ns 'ing
-any of the following values:
-.Bl -tag -width indent
-.It Dv MPOOL_DIRTY
-The page has been modified and needs to be written to the backing file.
-.El
-.Pp
-.Fn Mpool_put
-returns 0 on success and -1 if an error occurs.
-.Pp
-The function
-.Fn mpool_sync
-writes all modified pages associated with the
-.Ft MPOOL
-pointer to the
-backing file.
-.Fn Mpool_sync
-returns 0 on success and -1 if an error occurs.
-.Pp
-The
-.Fn mpool_close
-function free's up any allocated memory associated with the memory pool
-cookie.
-Modified pages are
-.Em not
-written to the backing file.
-.Fn Mpool_close
-returns 0 on success and -1 if an error occurs.
-.Sh ERRORS
-The
-.Fn mpool_open
-function may fail and set
-.Va errno
-for any of the errors specified for the library routine
-.Xr malloc 3 .
-.Pp
-The
-.Fn mpool_get
-function may fail and set
-.Va errno
-for the following:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The requested record doesn't exist.
-.El
-.Pp
-The
-.Fn mpool_new
-and
-.Fn mpool_get
-functions may fail and set
-.Va errno
-for any of the errors specified for the library routines
-.Xr read 2 ,
-.Xr write 2 ,
-and
-.Xr malloc 3 .
-.Pp
-The
-.Fn mpool_sync
-function may fail and set
-.Va errno
-for any of the errors specified for the library routine
-.Xr write 2 .
-.Pp
-The
-.Fn mpool_close
-function may fail and set
-.Va errno
-for any of the errors specified for the library routine
-.Xr free 3 .
-.Sh SEE ALSO
-.Xr btree 3 ,
-.Xr dbopen 3 ,
-.Xr hash 3 ,
-.Xr recno 3
+++ /dev/null
-.\" Copyright (c) 1990, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)recno.3 8.5 (Berkeley) 8/18/94
-.\" $FreeBSD: src/lib/libc/db/man/recno.3,v 1.6 2001/10/01 16:08:50 ru Exp $
-.\"
-.Dd August 18, 1994
-.Dt RECNO 3
-.Os
-.Sh NAME
-.Nm recno
-.Nd "record number database access method"
-.Sh SYNOPSIS
-.In sys/types.h
-.In db.h
-.Sh DESCRIPTION
-The routine
-.Fn dbopen
-is the library interface to database files.
-One of the supported file formats is record number files.
-The general description of the database access methods is in
-.Xr dbopen 3 ,
-this manual page describes only the
-.Nm
-specific information.
-.Pp
-The record number data structure is either variable or fixed-length
-records stored in a flat-file format, accessed by the logical record
-number.
-The existence of record number five implies the existence of records
-one through four, and the deletion of record number one causes
-record number five to be renumbered to record number four, as well
-as the cursor, if positioned after record number one, to shift down
-one record.
-.Pp
-The
-.Nm
-access method specific data structure provided to
-.Fn dbopen
-is defined in the
-.Aq Pa db.h
-include file as follows:
-.Bd -literal
-typedef struct {
- u_long flags;
- u_int cachesize;
- u_int psize;
- int lorder;
- size_t reclen;
- u_char bval;
- char *bfname;
-} RECNOINFO;
-.Ed
-.Pp
-The elements of this structure are defined as follows:
-.Bl -tag -width indent
-.It Va flags
-The flag value is specified by
-.Em or Ns 'ing
-any of the following values:
-.Bl -tag -width indent
-.It Dv R_FIXEDLEN
-The records are fixed-length, not byte delimited.
-The structure element
-.Va reclen
-specifies the length of the record, and the structure element
-.Va bval
-is used as the pad character.
-Any records, inserted into the database, that are less than
-.Va reclen
-bytes long are automatically padded.
-.It Dv R_NOKEY
-In the interface specified by
-.Fn dbopen ,
-the sequential record retrieval fills in both the caller's key and
-data structures.
-If the
-.Dv R_NOKEY
-flag is specified, the
-.Em cursor
-routines are not required to fill in the key structure.
-This permits applications to retrieve records at the end of files without
-reading all of the intervening records.
-.It Dv R_SNAPSHOT
-This flag requires that a snapshot of the file be taken when
-.Fn dbopen
-is called, instead of permitting any unmodified records to be read from
-the original file.
-.El
-.It Va cachesize
-A suggested maximum size, in bytes, of the memory cache.
-This value is
-.Em only
-advisory, and the access method will allocate more memory rather than fail.
-If
-.Va cachesize
-is 0 (no size is specified) a default cache is used.
-.It Va psize
-The
-.Nm
-access method stores the in-memory copies of its records
-in a btree.
-This value is the size (in bytes) of the pages used for nodes in that tree.
-If
-.Va psize
-is 0 (no page size is specified) a page size is chosen based on the
-underlying file system I/O block size.
-See
-.Xr btree 3
-for more information.
-.It Va lorder
-The byte order for integers in the stored database metadata.
-The number should represent the order as an integer; for example,
-big endian order would be the number 4,321.
-If
-.Va lorder
-is 0 (no order is specified) the current host order is used.
-.It Va reclen
-The length of a fixed-length record.
-.It Va bval
-The delimiting byte to be used to mark the end of a record for
-variable-length records, and the pad character for fixed-length
-records.
-If no value is specified, newlines
-.Pq Dq \en
-are used to mark the end
-of variable-length records and fixed-length records are padded with
-spaces.
-.It Va bfname
-The
-.Nm
-access method stores the in-memory copies of its records
-in a btree.
-If
-.Va bfname
-is
-.No non\- Ns Dv NULL ,
-it specifies the name of the btree file,
-as if specified as the file name for a
-.Fn dbopen
-of a btree file.
-.El
-.Pp
-The data part of the key/data pair used by the
-.Nm
-access method
-is the same as other access methods.
-The key is different.
-The
-.Va data
-field of the key should be a pointer to a memory location of type
-.Ft recno_t ,
-as defined in the
-.Aq Pa db.h
-include file.
-This type is normally the largest unsigned integral type available to
-the implementation.
-The
-.Va size
-field of the key should be the size of that type.
-.Pp
-Because there can be no meta-data associated with the underlying
-.Nm
-access method files, any changes made to the default values
-(e.g. fixed record length or byte separator value) must be explicitly
-specified each time the file is opened.
-.Pp
-In the interface specified by
-.Fn dbopen ,
-using the
-.Va put
-interface to create a new record will cause the creation of multiple,
-empty records if the record number is more than one greater than the
-largest record currently in the database.
-.Sh ERRORS
-The
-.Nm
-access method routines may fail and set
-.Va errno
-for any of the errors specified for the library routine
-.Xr dbopen 3
-or the following:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-An attempt was made to add a record to a fixed-length database that
-was too large to fit.
-.El
-.Sh SEE ALSO
-.Xr btree 3 ,
-.Xr dbopen 3 ,
-.Xr hash 3 ,
-.Xr mpool 3
-.Rs
-.%T "Document Processing in a Relational Database System"
-.%A Michael Stonebraker
-.%A Heidi Stettner
-.%A Joseph Kalash
-.%A Antonin Guttman
-.%A Nadene Lynn
-.%R "Memorandum No. UCB/ERL M82/32"
-.%D May 1982
-.Re
-.Sh BUGS
-Only big and little endian byte order is supported.
--- /dev/null
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)mpool.c 8.5 (Berkeley) 7/26/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/mpool/mpool.c,v 1.10 2002/03/22 21:52:01 obrien Exp $");
+
+#include "namespace.h"
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "un-namespace.h"
+
+#include <db.h>
+
+#define __MPOOLINTERFACE_PRIVATE
+#include <mpool.h>
+
+static BKT *mpool_bkt(MPOOL *);
+static BKT *mpool_look(MPOOL *, pgno_t);
+static int mpool_write(MPOOL *, BKT *);
+
+/*
+ * mpool_open --
+ * Initialize a memory pool.
+ */
+MPOOL *
+mpool_open(key, fd, pagesize, maxcache)
+ void *key;
+ int fd;
+ pgno_t pagesize, maxcache;
+{
+ struct stat sb;
+ MPOOL *mp;
+ int entry;
+
+ /*
+ * Get information about the file.
+ *
+ * XXX
+ * We don't currently handle pipes, although we should.
+ */
+ if (_fstat(fd, &sb))
+ return (NULL);
+ if (!S_ISREG(sb.st_mode)) {
+ errno = ESPIPE;
+ return (NULL);
+ }
+
+ /* Allocate and initialize the MPOOL cookie. */
+ if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL)
+ return (NULL);
+ TAILQ_INIT(&mp->lqh);
+ for (entry = 0; entry < HASHSIZE; ++entry)
+ TAILQ_INIT(&mp->hqh[entry]);
+ mp->maxcache = maxcache;
+ mp->npages = sb.st_size / pagesize;
+ mp->pagesize = pagesize;
+ mp->fd = fd;
+ return (mp);
+}
+
+/*
+ * mpool_filter --
+ * Initialize input/output filters.
+ */
+void
+mpool_filter(mp, pgin, pgout, pgcookie)
+ MPOOL *mp;
+ void (*pgin)(void *, pgno_t, void *);
+ void (*pgout)(void *, pgno_t, void *);
+ void *pgcookie;
+{
+ mp->pgin = pgin;
+ mp->pgout = pgout;
+ mp->pgcookie = pgcookie;
+}
+
+/*
+ * mpool_new --
+ * Get a new page of memory.
+ */
+void *
+mpool_new(mp, pgnoaddr)
+ MPOOL *mp;
+ pgno_t *pgnoaddr;
+{
+ struct _hqh *head;
+ BKT *bp;
+
+ if (mp->npages == MAX_PAGE_NUMBER) {
+ (void)fprintf(stderr, "mpool_new: page allocation overflow.\n");
+ abort();
+ }
+#ifdef STATISTICS
+ ++mp->pagenew;
+#endif
+ /*
+ * Get a BKT from the cache. Assign a new page number, attach
+ * it to the head of the hash chain, the tail of the lru chain,
+ * and return.
+ */
+ if ((bp = mpool_bkt(mp)) == NULL)
+ return (NULL);
+ *pgnoaddr = bp->pgno = mp->npages++;
+ bp->flags = MPOOL_PINNED;
+
+ head = &mp->hqh[HASHKEY(bp->pgno)];
+ TAILQ_INSERT_HEAD(head, bp, hq);
+ TAILQ_INSERT_TAIL(&mp->lqh, bp, q);
+ return (bp->page);
+}
+
+/*
+ * mpool_get
+ * Get a page.
+ */
+void *
+mpool_get(mp, pgno, flags)
+ MPOOL *mp;
+ pgno_t pgno;
+ u_int flags; /* XXX not used? */
+{
+ struct _hqh *head;
+ BKT *bp;
+ off_t off;
+ int nr;
+
+ /* Check for attempt to retrieve a non-existent page. */
+ if (pgno >= mp->npages) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+#ifdef STATISTICS
+ ++mp->pageget;
+#endif
+
+ /* Check for a page that is cached. */
+ if ((bp = mpool_look(mp, pgno)) != NULL) {
+#ifdef DEBUG
+ if (bp->flags & MPOOL_PINNED) {
+ (void)fprintf(stderr,
+ "mpool_get: page %d already pinned\n", bp->pgno);
+ abort();
+ }
+#endif
+ /*
+ * Move the page to the head of the hash chain and the tail
+ * of the lru chain.
+ */
+ head = &mp->hqh[HASHKEY(bp->pgno)];
+ TAILQ_REMOVE(head, bp, hq);
+ TAILQ_INSERT_HEAD(head, bp, hq);
+ TAILQ_REMOVE(&mp->lqh, bp, q);
+ TAILQ_INSERT_TAIL(&mp->lqh, bp, q);
+
+ /* Return a pinned page. */
+ bp->flags |= MPOOL_PINNED;
+ return (bp->page);
+ }
+
+ /* Get a page from the cache. */
+ if ((bp = mpool_bkt(mp)) == NULL)
+ return (NULL);
+
+ /* Read in the contents. */
+#ifdef STATISTICS
+ ++mp->pageread;
+#endif
+ off = mp->pagesize * pgno;
+ if (lseek(mp->fd, off, SEEK_SET) != off)
+ return (NULL);
+ if ((nr = _read(mp->fd, bp->page, mp->pagesize)) != mp->pagesize) {
+ if (nr >= 0)
+ errno = EFTYPE;
+ return (NULL);
+ }
+
+ /* Set the page number, pin the page. */
+ bp->pgno = pgno;
+ bp->flags = MPOOL_PINNED;
+
+ /*
+ * Add the page to the head of the hash chain and the tail
+ * of the lru chain.
+ */
+ head = &mp->hqh[HASHKEY(bp->pgno)];
+ TAILQ_INSERT_HEAD(head, bp, hq);
+ TAILQ_INSERT_TAIL(&mp->lqh, bp, q);
+
+ /* Run through the user's filter. */
+ if (mp->pgin != NULL)
+ (mp->pgin)(mp->pgcookie, bp->pgno, bp->page);
+
+ return (bp->page);
+}
+
+/*
+ * mpool_put
+ * Return a page.
+ */
+int
+mpool_put(mp, page, flags)
+ MPOOL *mp;
+ void *page;
+ u_int flags;
+{
+ BKT *bp;
+
+#ifdef STATISTICS
+ ++mp->pageput;
+#endif
+ bp = (BKT *)((char *)page - sizeof(BKT));
+#ifdef DEBUG
+ if (!(bp->flags & MPOOL_PINNED)) {
+ (void)fprintf(stderr,
+ "mpool_put: page %d not pinned\n", bp->pgno);
+ abort();
+ }
+#endif
+ bp->flags &= ~MPOOL_PINNED;
+ bp->flags |= flags & MPOOL_DIRTY;
+ return (RET_SUCCESS);
+}
+
+/*
+ * mpool_close
+ * Close the buffer pool.
+ */
+int
+mpool_close(mp)
+ MPOOL *mp;
+{
+ BKT *bp;
+
+ /* Free up any space allocated to the lru pages. */
+ while (!TAILQ_EMPTY(&mp->lqh)) {
+ bp = TAILQ_FIRST(&mp->lqh);
+ TAILQ_REMOVE(&mp->lqh, bp, q);
+ free(bp);
+ }
+
+ /* Free the MPOOL cookie. */
+ free(mp);
+ return (RET_SUCCESS);
+}
+
+/*
+ * mpool_sync
+ * Sync the pool to disk.
+ */
+int
+mpool_sync(mp)
+ MPOOL *mp;
+{
+ BKT *bp;
+
+ /* Walk the lru chain, flushing any dirty pages to disk. */
+ TAILQ_FOREACH(bp, &mp->lqh, q)
+ if (bp->flags & MPOOL_DIRTY &&
+ mpool_write(mp, bp) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Sync the file descriptor. */
+ return (_fsync(mp->fd) ? RET_ERROR : RET_SUCCESS);
+}
+
+/*
+ * mpool_bkt
+ * Get a page from the cache (or create one).
+ */
+static BKT *
+mpool_bkt(mp)
+ MPOOL *mp;
+{
+ struct _hqh *head;
+ BKT *bp;
+
+ /* If under the max cached, always create a new page. */
+ if (mp->curcache < mp->maxcache)
+ goto new;
+
+ /*
+ * If the cache is max'd out, walk the lru list for a buffer we
+ * can flush. If we find one, write it (if necessary) and take it
+ * off any lists. If we don't find anything we grow the cache anyway.
+ * The cache never shrinks.
+ */
+ TAILQ_FOREACH(bp, &mp->lqh, q)
+ if (!(bp->flags & MPOOL_PINNED)) {
+ /* Flush if dirty. */
+ if (bp->flags & MPOOL_DIRTY &&
+ mpool_write(mp, bp) == RET_ERROR)
+ return (NULL);
+#ifdef STATISTICS
+ ++mp->pageflush;
+#endif
+ /* Remove from the hash and lru queues. */
+ head = &mp->hqh[HASHKEY(bp->pgno)];
+ TAILQ_REMOVE(head, bp, hq);
+ TAILQ_REMOVE(&mp->lqh, bp, q);
+#ifdef DEBUG
+ { void *spage;
+ spage = bp->page;
+ memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
+ bp->page = spage;
+ }
+#endif
+ return (bp);
+ }
+
+new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL)
+ return (NULL);
+#ifdef STATISTICS
+ ++mp->pagealloc;
+#endif
+#if defined(DEBUG) || defined(PURIFY)
+ memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
+#endif
+ bp->page = (char *)bp + sizeof(BKT);
+ ++mp->curcache;
+ return (bp);
+}
+
+/*
+ * mpool_write
+ * Write a page to disk.
+ */
+static int
+mpool_write(mp, bp)
+ MPOOL *mp;
+ BKT *bp;
+{
+ off_t off;
+
+#ifdef STATISTICS
+ ++mp->pagewrite;
+#endif
+
+ /* Run through the user's filter. */
+ if (mp->pgout)
+ (mp->pgout)(mp->pgcookie, bp->pgno, bp->page);
+
+ off = mp->pagesize * bp->pgno;
+ if (lseek(mp->fd, off, SEEK_SET) != off)
+ return (RET_ERROR);
+ if (_write(mp->fd, bp->page, mp->pagesize) != mp->pagesize)
+ return (RET_ERROR);
+
+ bp->flags &= ~MPOOL_DIRTY;
+ return (RET_SUCCESS);
+}
+
+/*
+ * mpool_look
+ * Lookup a page in the cache.
+ */
+static BKT *
+mpool_look(mp, pgno)
+ MPOOL *mp;
+ pgno_t pgno;
+{
+ struct _hqh *head;
+ BKT *bp;
+
+ head = &mp->hqh[HASHKEY(pgno)];
+ TAILQ_FOREACH(bp, head, hq)
+ if (bp->pgno == pgno) {
+#ifdef STATISTICS
+ ++mp->cachehit;
+#endif
+ return (bp);
+ }
+#ifdef STATISTICS
+ ++mp->cachemiss;
+#endif
+ return (NULL);
+}
+
+#ifdef STATISTICS
+/*
+ * mpool_stat
+ * Print out cache statistics.
+ */
+void
+mpool_stat(mp)
+ MPOOL *mp;
+{
+ BKT *bp;
+ int cnt;
+ char *sep;
+
+ (void)fprintf(stderr, "%lu pages in the file\n", mp->npages);
+ (void)fprintf(stderr,
+ "page size %lu, cacheing %lu pages of %lu page max cache\n",
+ mp->pagesize, mp->curcache, mp->maxcache);
+ (void)fprintf(stderr, "%lu page puts, %lu page gets, %lu page new\n",
+ mp->pageput, mp->pageget, mp->pagenew);
+ (void)fprintf(stderr, "%lu page allocs, %lu page flushes\n",
+ mp->pagealloc, mp->pageflush);
+ if (mp->cachehit + mp->cachemiss)
+ (void)fprintf(stderr,
+ "%.0f%% cache hit rate (%lu hits, %lu misses)\n",
+ ((double)mp->cachehit / (mp->cachehit + mp->cachemiss))
+ * 100, mp->cachehit, mp->cachemiss);
+ (void)fprintf(stderr, "%lu page reads, %lu page writes\n",
+ mp->pageread, mp->pagewrite);
+
+ sep = "";
+ cnt = 0;
+ TAILQ_FOREACH(bp, &mp->lqh, q) {
+ (void)fprintf(stderr, "%s%d", sep, bp->pgno);
+ if (bp->flags & MPOOL_DIRTY)
+ (void)fprintf(stderr, "d");
+ if (bp->flags & MPOOL_PINNED)
+ (void)fprintf(stderr, "P");
+ if (++cnt == 10) {
+ sep = "\n";
+ cnt = 0;
+ } else
+ sep = ", ";
+
+ }
+ (void)fprintf(stderr, "\n");
+}
+#endif
# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
-# $FreeBSD: src/lib/libc/db/mpool/Makefile.inc,v 1.3 1999/08/27 23:58:23 peter Exp $
+# $FreeBSD: src/lib/libc/db/mpool/Makefile.inc,v 1.4 2002/11/18 09:50:55 ru Exp $
.PATH: ${.CURDIR}/db/mpool
-SRCS+= mpool.c
+.include "Makefile.fbsd_begin"
+FBSDMISRCS= mpool.c
+.for _src in ${FBSDMISRCS}
+CFLAGS-${_src:R}-fbsd.${_src:E} += -D__DBINTERFACE_PRIVATE
+.endfor
+.include "Makefile.fbsd_end"
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)mpool.c 8.5 (Berkeley) 7/26/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <db.h>
-
-#define __MPOOLINTERFACE_PRIVATE
-#include <mpool.h>
-
-static BKT *mpool_bkt(MPOOL *);
-static BKT *mpool_look(MPOOL *, pgno_t);
-static int mpool_write(MPOOL *, BKT *);
-
-/*
- * mpool_open --
- * Initialize a memory pool.
- */
-MPOOL *
-mpool_open(key, fd, pagesize, maxcache)
- void *key;
- int fd;
- pgno_t pagesize, maxcache;
-{
- struct stat sb;
- MPOOL *mp;
- int entry;
-
- /*
- * Get information about the file.
- *
- * XXX
- * We don't currently handle pipes, although we should.
- */
- if (fstat(fd, &sb))
- return (NULL);
- if (!S_ISREG(sb.st_mode)) {
- errno = ESPIPE;
- return (NULL);
- }
-
- /* Allocate and initialize the MPOOL cookie. */
- if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL)
- return (NULL);
- TAILQ_INIT(&mp->lqh);
- for (entry = 0; entry < HASHSIZE; ++entry)
- TAILQ_INIT(&mp->hqh[entry]);
- mp->maxcache = maxcache;
- mp->npages = sb.st_size / pagesize;
- mp->pagesize = pagesize;
- mp->fd = fd;
- return (mp);
-}
-
-/*
- * mpool_filter --
- * Initialize input/output filters.
- */
-void
-mpool_filter(mp, pgin, pgout, pgcookie)
- MPOOL *mp;
- void (*pgin)(void *, pgno_t, void *);
- void (*pgout)(void *, pgno_t, void *);
- void *pgcookie;
-{
- mp->pgin = pgin;
- mp->pgout = pgout;
- mp->pgcookie = pgcookie;
-}
-
-/*
- * mpool_new --
- * Get a new page of memory.
- */
-void *
-mpool_new(mp, pgnoaddr)
- MPOOL *mp;
- pgno_t *pgnoaddr;
-{
- struct _hqh *head;
- BKT *bp;
-
- if (mp->npages == MAX_PAGE_NUMBER) {
- (void)fprintf(stderr, "mpool_new: page allocation overflow.\n");
- abort();
- }
-#ifdef STATISTICS
- ++mp->pagenew;
-#endif
- /*
- * Get a BKT from the cache. Assign a new page number, attach
- * it to the head of the hash chain, the tail of the lru chain,
- * and return.
- */
- if ((bp = mpool_bkt(mp)) == NULL)
- return (NULL);
- *pgnoaddr = bp->pgno = mp->npages++;
- bp->flags = MPOOL_PINNED;
-
- head = &mp->hqh[HASHKEY(bp->pgno)];
- TAILQ_INSERT_HEAD(head, bp, hq);
- TAILQ_INSERT_TAIL(&mp->lqh, bp, q);
- return (bp->page);
-}
-
-/*
- * mpool_get
- * Get a page.
- */
-void *
-mpool_get(mp, pgno, flags)
- MPOOL *mp;
- pgno_t pgno;
- u_int flags; /* XXX not used? */
-{
- struct _hqh *head;
- BKT *bp;
- off_t off;
- int nr;
-
- /* Check for attempt to retrieve a non-existent page. */
- if (pgno >= mp->npages) {
- errno = EINVAL;
- return (NULL);
- }
-
-#ifdef STATISTICS
- ++mp->pageget;
-#endif
-
- /* Check for a page that is cached. */
- if ((bp = mpool_look(mp, pgno)) != NULL) {
-#ifdef DEBUG
- if (bp->flags & MPOOL_PINNED) {
- (void)fprintf(stderr,
- "mpool_get: page %d already pinned\n", bp->pgno);
- abort();
- }
-#endif
- /*
- * Move the page to the head of the hash chain and the tail
- * of the lru chain.
- */
- head = &mp->hqh[HASHKEY(bp->pgno)];
- TAILQ_REMOVE(head, bp, hq);
- TAILQ_INSERT_HEAD(head, bp, hq);
- TAILQ_REMOVE(&mp->lqh, bp, q);
- TAILQ_INSERT_TAIL(&mp->lqh, bp, q);
-
- /* Return a pinned page. */
- bp->flags |= MPOOL_PINNED;
- return (bp->page);
- }
-
- /* Get a page from the cache. */
- if ((bp = mpool_bkt(mp)) == NULL)
- return (NULL);
-
- /* Read in the contents. */
-#ifdef STATISTICS
- ++mp->pageread;
-#endif
- off = mp->pagesize * pgno;
- if (lseek(mp->fd, off, SEEK_SET) != off)
- return (NULL);
- if ((nr = read(mp->fd, bp->page, mp->pagesize)) != mp->pagesize) {
- if (nr >= 0)
- errno = EFTYPE;
- return (NULL);
- }
-
- /* Set the page number, pin the page. */
- bp->pgno = pgno;
- bp->flags = MPOOL_PINNED;
-
- /*
- * Add the page to the head of the hash chain and the tail
- * of the lru chain.
- */
- head = &mp->hqh[HASHKEY(bp->pgno)];
- TAILQ_INSERT_HEAD(head, bp, hq);
- TAILQ_INSERT_TAIL(&mp->lqh, bp, q);
-
- /* Run through the user's filter. */
- if (mp->pgin != NULL)
- (mp->pgin)(mp->pgcookie, bp->pgno, bp->page);
-
- return (bp->page);
-}
-
-/*
- * mpool_put
- * Return a page.
- */
-int
-mpool_put(mp, page, flags)
- MPOOL *mp;
- void *page;
- u_int flags;
-{
- BKT *bp;
-
-#ifdef STATISTICS
- ++mp->pageput;
-#endif
- bp = (BKT *)((char *)page - sizeof(BKT));
-#ifdef DEBUG
- if (!(bp->flags & MPOOL_PINNED)) {
- (void)fprintf(stderr,
- "mpool_put: page %d not pinned\n", bp->pgno);
- abort();
- }
-#endif
- bp->flags &= ~MPOOL_PINNED;
- bp->flags |= flags & MPOOL_DIRTY;
- return (RET_SUCCESS);
-}
-
-/*
- * mpool_close
- * Close the buffer pool.
- */
-int
-mpool_close(mp)
- MPOOL *mp;
-{
- BKT *bp;
-
- /* Free up any space allocated to the lru pages. */
- while (!TAILQ_EMPTY(&mp->lqh)) {
- bp = TAILQ_FIRST(&mp->lqh);
- TAILQ_REMOVE(&mp->lqh, bp, q);
- free(bp);
- }
-
- /* Free the MPOOL cookie. */
- free(mp);
- return (RET_SUCCESS);
-}
-
-/*
- * mpool_sync
- * Sync the pool to disk.
- */
-int
-mpool_sync(mp)
- MPOOL *mp;
-{
- BKT *bp;
-
- /* Walk the lru chain, flushing any dirty pages to disk. */
- TAILQ_FOREACH(bp, &mp->lqh, q)
- if (bp->flags & MPOOL_DIRTY &&
- mpool_write(mp, bp) == RET_ERROR)
- return (RET_ERROR);
-
- /* Sync the file descriptor. */
- return (fsync(mp->fd) ? RET_ERROR : RET_SUCCESS);
-}
-
-/*
- * mpool_bkt
- * Get a page from the cache (or create one).
- */
-static BKT *
-mpool_bkt(mp)
- MPOOL *mp;
-{
- struct _hqh *head;
- BKT *bp;
-
- /* If under the max cached, always create a new page. */
- if (mp->curcache < mp->maxcache)
- goto new;
-
- /*
- * If the cache is max'd out, walk the lru list for a buffer we
- * can flush. If we find one, write it (if necessary) and take it
- * off any lists. If we don't find anything we grow the cache anyway.
- * The cache never shrinks.
- */
- TAILQ_FOREACH(bp, &mp->lqh, q)
- if (!(bp->flags & MPOOL_PINNED)) {
- /* Flush if dirty. */
- if (bp->flags & MPOOL_DIRTY &&
- mpool_write(mp, bp) == RET_ERROR)
- return (NULL);
-#ifdef STATISTICS
- ++mp->pageflush;
-#endif
- /* Remove from the hash and lru queues. */
- head = &mp->hqh[HASHKEY(bp->pgno)];
- TAILQ_REMOVE(head, bp, hq);
- TAILQ_REMOVE(&mp->lqh, bp, q);
-#ifdef DEBUG
- { void *spage;
- spage = bp->page;
- memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
- bp->page = spage;
- }
-#endif
- return (bp);
- }
-
-new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL)
- return (NULL);
-#ifdef STATISTICS
- ++mp->pagealloc;
-#endif
-#if defined(DEBUG) || defined(PURIFY)
- memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
-#endif
- bp->page = (char *)bp + sizeof(BKT);
- ++mp->curcache;
- return (bp);
-}
-
-/*
- * mpool_write
- * Write a page to disk.
- */
-static int
-mpool_write(mp, bp)
- MPOOL *mp;
- BKT *bp;
-{
- off_t off;
-
-#ifdef STATISTICS
- ++mp->pagewrite;
-#endif
-
- /* Run through the user's filter. */
- if (mp->pgout)
- (mp->pgout)(mp->pgcookie, bp->pgno, bp->page);
-
- off = mp->pagesize * bp->pgno;
- if (lseek(mp->fd, off, SEEK_SET) != off)
- return (RET_ERROR);
- if (write(mp->fd, bp->page, mp->pagesize) != mp->pagesize)
- return (RET_ERROR);
-
- bp->flags &= ~MPOOL_DIRTY;
- return (RET_SUCCESS);
-}
-
-/*
- * mpool_look
- * Lookup a page in the cache.
- */
-static BKT *
-mpool_look(mp, pgno)
- MPOOL *mp;
- pgno_t pgno;
-{
- struct _hqh *head;
- BKT *bp;
-
- head = &mp->hqh[HASHKEY(pgno)];
- TAILQ_FOREACH(bp, head, hq)
- if (bp->pgno == pgno) {
-#ifdef STATISTICS
- ++mp->cachehit;
-#endif
- return (bp);
- }
-#ifdef STATISTICS
- ++mp->cachemiss;
-#endif
- return (NULL);
-}
-
-#ifdef STATISTICS
-/*
- * mpool_stat
- * Print out cache statistics.
- */
-void
-mpool_stat(mp)
- MPOOL *mp;
-{
- BKT *bp;
- int cnt;
- char *sep;
-
- (void)fprintf(stderr, "%lu pages in the file\n", mp->npages);
- (void)fprintf(stderr,
- "page size %lu, cacheing %lu pages of %lu page max cache\n",
- mp->pagesize, mp->curcache, mp->maxcache);
- (void)fprintf(stderr, "%lu page puts, %lu page gets, %lu page new\n",
- mp->pageput, mp->pageget, mp->pagenew);
- (void)fprintf(stderr, "%lu page allocs, %lu page flushes\n",
- mp->pagealloc, mp->pageflush);
- if (mp->cachehit + mp->cachemiss)
- (void)fprintf(stderr,
- "%.0f%% cache hit rate (%lu hits, %lu misses)\n",
- ((double)mp->cachehit / (mp->cachehit + mp->cachemiss))
- * 100, mp->cachehit, mp->cachemiss);
- (void)fprintf(stderr, "%lu page reads, %lu page writes\n",
- mp->pageread, mp->pagewrite);
-
- sep = "";
- cnt = 0;
- TAILQ_FOREACH(bp, &mp->lqh, q) {
- (void)fprintf(stderr, "%s%d", sep, bp->pgno);
- if (bp->flags & MPOOL_DIRTY)
- (void)fprintf(stderr, "d");
- if (bp->flags & MPOOL_PINNED)
- (void)fprintf(stderr, "P");
- if (++cnt == 10) {
- sep = "\n";
- cnt = 0;
- } else
- sep = ", ";
-
- }
- (void)fprintf(stderr, "\n");
-}
-#endif
--- /dev/null
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)extern.h 8.3 (Berkeley) 6/4/94
+ * $FreeBSD: src/lib/libc/db/recno/extern.h,v 1.2 2002/03/21 22:46:28 obrien Exp $
+ */
+
+#include "../btree/extern.h"
+
+int __rec_close(DB *);
+int __rec_delete(const DB *, const DBT *, u_int);
+int __rec_dleaf(BTREE *, PAGE *, u_int32_t);
+int __rec_fd(const DB *);
+int __rec_fmap(BTREE *, recno_t);
+int __rec_fout(BTREE *);
+int __rec_fpipe(BTREE *, recno_t);
+int __rec_get(const DB *, const DBT *, DBT *, u_int);
+int __rec_iput(BTREE *, recno_t, const DBT *, u_int);
+int __rec_put(const DB *dbp, DBT *, const DBT *, u_int);
+int __rec_ret(BTREE *, EPG *, recno_t, DBT *, DBT *);
+EPG *__rec_search(BTREE *, recno_t, enum SRCHOP);
+int __rec_seq(const DB *, DBT *, DBT *, u_int);
+int __rec_sync(const DB *, u_int);
+int __rec_vmap(BTREE *, recno_t);
+int __rec_vout(BTREE *);
+int __rec_vpipe(BTREE *, recno_t);
--- /dev/null
+--- extern.h.orig Thu Mar 21 14:46:28 2002
++++ extern.h Sat Oct 18 19:49:46 2003
+@@ -34,7 +34,7 @@
+ * $FreeBSD: src/lib/libc/db/recno/extern.h,v 1.2 2002/03/21 22:46:28 obrien Exp $
+ */
+
+-#include "../btree/extern.h"
++#include "bt_extern.h"
+
+ int __rec_close(DB *);
+ int __rec_delete(const DB *, const DBT *, u_int);
--- /dev/null
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_close.c 8.6 (Berkeley) 8/18/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_close.c,v 1.7 2003/02/16 17:29:09 nectar Exp $");
+
+#include "namespace.h"
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/mman.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "un-namespace.h"
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __REC_CLOSE -- Close a recno tree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_close(dbp)
+ DB *dbp;
+{
+ BTREE *t;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ if (__rec_sync(dbp, 0) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Committed to closing. */
+ status = RET_SUCCESS;
+ if (F_ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
+ status = RET_ERROR;
+
+ if (!F_ISSET(t, R_INMEM)) {
+ if (F_ISSET(t, R_CLOSEFP)) {
+ if (fclose(t->bt_rfp))
+ status = RET_ERROR;
+ } else
+ if (_close(t->bt_rfd))
+ status = RET_ERROR;
+ }
+
+ if (__bt_close(dbp) == RET_ERROR)
+ status = RET_ERROR;
+
+ return (status);
+}
+
+/*
+ * __REC_SYNC -- sync the recno tree to disk.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__rec_sync(dbp, flags)
+ const DB *dbp;
+ u_int flags;
+{
+ struct iovec iov[2];
+ BTREE *t;
+ DBT data, key;
+ off_t off;
+ recno_t scursor, trec;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ if (flags == R_RECNOSYNC)
+ return (__bt_sync(dbp, 0));
+
+ if (F_ISSET(t, R_RDONLY | R_INMEM) || !F_ISSET(t, R_MODIFIED))
+ return (RET_SUCCESS);
+
+ /* Read any remaining records into the tree. */
+ if (!F_ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
+ return (RET_ERROR);
+
+ /* Rewind the file descriptor. */
+ if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0)
+ return (RET_ERROR);
+
+ /* Save the cursor. */
+ scursor = t->bt_cursor.rcursor;
+
+ key.size = sizeof(recno_t);
+ key.data = &trec;
+
+ if (F_ISSET(t, R_FIXLEN)) {
+ /*
+ * We assume that fixed length records are all fixed length.
+ * Any that aren't are either EINVAL'd or corrected by the
+ * record put code.
+ */
+ status = (dbp->seq)(dbp, &key, &data, R_FIRST);
+ while (status == RET_SUCCESS) {
+ if (_write(t->bt_rfd, data.data, data.size) !=
+ data.size)
+ return (RET_ERROR);
+ status = (dbp->seq)(dbp, &key, &data, R_NEXT);
+ }
+ } else {
+ iov[1].iov_base = (char *)&t->bt_bval;
+ iov[1].iov_len = 1;
+
+ status = (dbp->seq)(dbp, &key, &data, R_FIRST);
+ while (status == RET_SUCCESS) {
+ iov[0].iov_base = data.data;
+ iov[0].iov_len = data.size;
+ if (_writev(t->bt_rfd, iov, 2) != data.size + 1)
+ return (RET_ERROR);
+ status = (dbp->seq)(dbp, &key, &data, R_NEXT);
+ }
+ }
+
+ /* Restore the cursor. */
+ t->bt_cursor.rcursor = scursor;
+
+ if (status == RET_ERROR)
+ return (RET_ERROR);
+ if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1)
+ return (RET_ERROR);
+ if (ftruncate(t->bt_rfd, off))
+ return (RET_ERROR);
+ F_CLR(t, R_MODIFIED);
+ return (RET_SUCCESS);
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_delete.c 8.7 (Berkeley) 7/14/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_delete.c,v 1.2 2002/03/21 22:46:28 obrien Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <db.h>
+#include "recno.h"
+
+static int rec_rdelete(BTREE *, recno_t);
+
+/*
+ * __REC_DELETE -- Delete the item(s) referenced by a key.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key to delete
+ * flags: R_CURSOR if deleting what the cursor references
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
+ */
+int
+__rec_delete(dbp, key, flags)
+ const DB *dbp;
+ const DBT *key;
+ u_int flags;
+{
+ BTREE *t;
+ recno_t nrec;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ switch(flags) {
+ case 0:
+ if ((nrec = *(recno_t *)key->data) == 0)
+ goto einval;
+ if (nrec > t->bt_nrecs)
+ return (RET_SPECIAL);
+ --nrec;
+ status = rec_rdelete(t, nrec);
+ break;
+ case R_CURSOR:
+ if (!F_ISSET(&t->bt_cursor, CURS_INIT))
+ goto einval;
+ if (t->bt_nrecs == 0)
+ return (RET_SPECIAL);
+ status = rec_rdelete(t, t->bt_cursor.rcursor - 1);
+ if (status == RET_SUCCESS)
+ --t->bt_cursor.rcursor;
+ break;
+ default:
+einval: errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if (status == RET_SUCCESS)
+ F_SET(t, B_MODIFIED | R_MODIFIED);
+ return (status);
+}
+
+/*
+ * REC_RDELETE -- Delete the data matching the specified key.
+ *
+ * Parameters:
+ * tree: tree
+ * nrec: record to delete
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
+ */
+static int
+rec_rdelete(t, nrec)
+ BTREE *t;
+ recno_t nrec;
+{
+ EPG *e;
+ PAGE *h;
+ int status;
+
+ /* Find the record; __rec_search pins the page. */
+ if ((e = __rec_search(t, nrec, SDELETE)) == NULL)
+ return (RET_ERROR);
+
+ /* Delete the record. */
+ h = e->page;
+ status = __rec_dleaf(t, h, e->index);
+ if (status != RET_SUCCESS) {
+ mpool_put(t->bt_mp, h, 0);
+ return (status);
+ }
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ return (RET_SUCCESS);
+}
+
+/*
+ * __REC_DLEAF -- Delete a single record from a recno leaf page.
+ *
+ * Parameters:
+ * t: tree
+ * index: index on current page to delete
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__rec_dleaf(t, h, index)
+ BTREE *t;
+ PAGE *h;
+ u_int32_t index;
+{
+ RLEAF *rl;
+ indx_t *ip, cnt, offset;
+ u_int32_t nbytes;
+ char *from;
+ void *to;
+
+ /*
+ * Delete a record from a recno leaf page. Internal records are never
+ * deleted from internal pages, regardless of the records that caused
+ * them to be added being deleted. Pages made empty by deletion are
+ * not reclaimed. They are, however, made available for reuse.
+ *
+ * Pack the remaining entries at the end of the page, shift the indices
+ * down, overwriting the deleted record and its index. If the record
+ * uses overflow pages, make them available for reuse.
+ */
+ to = rl = GETRLEAF(h, index);
+ if (rl->flags & P_BIGDATA && __ovfl_delete(t, rl->bytes) == RET_ERROR)
+ return (RET_ERROR);
+ nbytes = NRLEAF(rl);
+
+ /*
+ * Compress the key/data pairs. Compress and adjust the [BR]LEAF
+ * offsets. Reset the headers.
+ */
+ from = (char *)h + h->upper;
+ memmove(from + nbytes, from, (char *)to - from);
+ h->upper += nbytes;
+
+ offset = h->linp[index];
+ for (cnt = &h->linp[index] - (ip = &h->linp[0]); cnt--; ++ip)
+ if (ip[0] < offset)
+ ip[0] += nbytes;
+ for (cnt = &h->linp[NEXTINDEX(h)] - ip; --cnt; ++ip)
+ ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
+ h->lower -= sizeof(indx_t);
+ --t->bt_nrecs;
+ return (RET_SUCCESS);
+}
--- /dev/null
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_get.c 8.9 (Berkeley) 8/18/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_get.c,v 1.5 2002/03/22 21:52:02 obrien Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __REC_GET -- Get a record from the btree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key to find
+ * data: data to return
+ * flag: currently unused
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
+ */
+int
+__rec_get(dbp, key, data, flags)
+ const DB *dbp;
+ const DBT *key;
+ DBT *data;
+ u_int flags;
+{
+ BTREE *t;
+ EPG *e;
+ recno_t nrec;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* Get currently doesn't take any flags, and keys of 0 are illegal. */
+ if (flags || (nrec = *(recno_t *)key->data) == 0) {
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ /*
+ * If we haven't seen this record yet, try to find it in the
+ * original file.
+ */
+ if (nrec > t->bt_nrecs) {
+ if (F_ISSET(t, R_EOF | R_INMEM))
+ return (RET_SPECIAL);
+ if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
+ return (status);
+ }
+
+ --nrec;
+ if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
+ return (RET_ERROR);
+
+ status = __rec_ret(t, e, 0, NULL, data);
+ if (F_ISSET(t, B_DB_LOCK))
+ mpool_put(t->bt_mp, e->page, 0);
+ else
+ t->bt_pinned = e->page;
+ return (status);
+}
+
+/*
+ * __REC_FPIPE -- Get fixed length records from a pipe.
+ *
+ * Parameters:
+ * t: tree
+ * cnt: records to read
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_fpipe(t, top)
+ BTREE *t;
+ recno_t top;
+{
+ DBT data;
+ recno_t nrec;
+ size_t len;
+ int ch;
+ u_char *p;
+
+ if (t->bt_rdata.size < t->bt_reclen) {
+ t->bt_rdata.data = t->bt_rdata.data == NULL ?
+ malloc(t->bt_reclen) :
+ reallocf(t->bt_rdata.data, t->bt_reclen);
+ if (t->bt_rdata.data == NULL)
+ return (RET_ERROR);
+ t->bt_rdata.size = t->bt_reclen;
+ }
+ data.data = t->bt_rdata.data;
+ data.size = t->bt_reclen;
+
+ for (nrec = t->bt_nrecs; nrec < top;) {
+ len = t->bt_reclen;
+ for (p = t->bt_rdata.data;; *p++ = ch)
+ if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
+ if (ch != EOF)
+ *p = ch;
+ if (len != 0)
+ memset(p, t->bt_bval, len);
+ if (__rec_iput(t,
+ nrec, &data, 0) != RET_SUCCESS)
+ return (RET_ERROR);
+ ++nrec;
+ break;
+ }
+ if (ch == EOF)
+ break;
+ }
+ if (nrec < top) {
+ F_SET(t, R_EOF);
+ return (RET_SPECIAL);
+ }
+ return (RET_SUCCESS);
+}
+
+/*
+ * __REC_VPIPE -- Get variable length records from a pipe.
+ *
+ * Parameters:
+ * t: tree
+ * cnt: records to read
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_vpipe(t, top)
+ BTREE *t;
+ recno_t top;
+{
+ DBT data;
+ recno_t nrec;
+ size_t len;
+ size_t sz;
+ int bval, ch;
+ u_char *p;
+
+ bval = t->bt_bval;
+ for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
+ for (p = t->bt_rdata.data,
+ sz = t->bt_rdata.size;; *p++ = ch, --sz) {
+ if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
+ data.data = t->bt_rdata.data;
+ data.size = p - (u_char *)t->bt_rdata.data;
+ if (ch == EOF && data.size == 0)
+ break;
+ if (__rec_iput(t, nrec, &data, 0)
+ != RET_SUCCESS)
+ return (RET_ERROR);
+ break;
+ }
+ if (sz == 0) {
+ len = p - (u_char *)t->bt_rdata.data;
+ t->bt_rdata.size += (sz = 256);
+ t->bt_rdata.data = t->bt_rdata.data == NULL ?
+ malloc(t->bt_rdata.size) :
+ reallocf(t->bt_rdata.data, t->bt_rdata.size);
+ if (t->bt_rdata.data == NULL)
+ return (RET_ERROR);
+ p = (u_char *)t->bt_rdata.data + len;
+ }
+ }
+ if (ch == EOF)
+ break;
+ }
+ if (nrec < top) {
+ F_SET(t, R_EOF);
+ return (RET_SPECIAL);
+ }
+ return (RET_SUCCESS);
+}
+
+/*
+ * __REC_FMAP -- Get fixed length records from a file.
+ *
+ * Parameters:
+ * t: tree
+ * cnt: records to read
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_fmap(t, top)
+ BTREE *t;
+ recno_t top;
+{
+ DBT data;
+ recno_t nrec;
+ u_char *sp, *ep, *p;
+ size_t len;
+
+ if (t->bt_rdata.size < t->bt_reclen) {
+ t->bt_rdata.data = t->bt_rdata.data == NULL ?
+ malloc(t->bt_reclen) :
+ reallocf(t->bt_rdata.data, t->bt_reclen);
+ if (t->bt_rdata.data == NULL)
+ return (RET_ERROR);
+ t->bt_rdata.size = t->bt_reclen;
+ }
+ data.data = t->bt_rdata.data;
+ data.size = t->bt_reclen;
+
+ sp = (u_char *)t->bt_cmap;
+ ep = (u_char *)t->bt_emap;
+ for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
+ if (sp >= ep) {
+ F_SET(t, R_EOF);
+ return (RET_SPECIAL);
+ }
+ len = t->bt_reclen;
+ for (p = t->bt_rdata.data;
+ sp < ep && len > 0; *p++ = *sp++, --len);
+ if (len != 0)
+ memset(p, t->bt_bval, len);
+ if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
+ return (RET_ERROR);
+ }
+ t->bt_cmap = (caddr_t)sp;
+ return (RET_SUCCESS);
+}
+
+/*
+ * __REC_VMAP -- Get variable length records from a file.
+ *
+ * Parameters:
+ * t: tree
+ * cnt: records to read
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_vmap(t, top)
+ BTREE *t;
+ recno_t top;
+{
+ DBT data;
+ u_char *sp, *ep;
+ recno_t nrec;
+ int bval;
+
+ sp = (u_char *)t->bt_cmap;
+ ep = (u_char *)t->bt_emap;
+ bval = t->bt_bval;
+
+ for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
+ if (sp >= ep) {
+ F_SET(t, R_EOF);
+ return (RET_SPECIAL);
+ }
+ for (data.data = sp; sp < ep && *sp != bval; ++sp);
+ data.size = sp - (u_char *)data.data;
+ if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
+ return (RET_ERROR);
+ ++sp;
+ }
+ t->bt_cmap = (caddr_t)sp;
+ return (RET_SUCCESS);
+}
--- /dev/null
+/*-
+ * 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
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_open.c 8.10 (Berkeley) 9/1/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_open.c,v 1.6 2002/03/22 21:52:02 obrien Exp $");
+
+#include "namespace.h"
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "un-namespace.h"
+
+#include <db.h>
+#include "recno.h"
+
+DB *
+__rec_open(fname, flags, mode, openinfo, dflags)
+ const char *fname;
+ int flags, mode, dflags;
+ const RECNOINFO *openinfo;
+{
+ BTREE *t;
+ BTREEINFO btopeninfo;
+ DB *dbp;
+ PAGE *h;
+ struct stat sb;
+ int rfd, sverrno;
+
+ /* Open the user's file -- if this fails, we're done. */
+ if (fname != NULL && (rfd = _open(fname, flags, mode)) < 0)
+ return (NULL);
+
+ /* Create a btree in memory (backed by disk). */
+ dbp = NULL;
+ if (openinfo) {
+ if (openinfo->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT))
+ goto einval;
+ btopeninfo.flags = 0;
+ btopeninfo.cachesize = openinfo->cachesize;
+ btopeninfo.maxkeypage = 0;
+ btopeninfo.minkeypage = 0;
+ btopeninfo.psize = openinfo->psize;
+ btopeninfo.compare = NULL;
+ btopeninfo.prefix = NULL;
+ btopeninfo.lorder = openinfo->lorder;
+ dbp = __bt_open(openinfo->bfname,
+ O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo, dflags);
+ } else
+ dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL, dflags);
+ if (dbp == NULL)
+ goto err;
+
+ /*
+ * Some fields in the tree structure are recno specific. Fill them
+ * in and make the btree structure look like a recno structure. We
+ * don't change the bt_ovflsize value, it's close enough and slightly
+ * bigger.
+ */
+ t = dbp->internal;
+ if (openinfo) {
+ if (openinfo->flags & R_FIXEDLEN) {
+ F_SET(t, R_FIXLEN);
+ t->bt_reclen = openinfo->reclen;
+ if (t->bt_reclen == 0)
+ goto einval;
+ }
+ t->bt_bval = openinfo->bval;
+ } else
+ t->bt_bval = '\n';
+
+ F_SET(t, R_RECNO);
+ if (fname == NULL)
+ F_SET(t, R_EOF | R_INMEM);
+ else
+ t->bt_rfd = rfd;
+
+ if (fname != NULL) {
+ /*
+ * In 4.4BSD, stat(2) returns true for ISSOCK on pipes.
+ * Unfortunately, that's not portable, so we use lseek
+ * and check the errno values.
+ */
+ errno = 0;
+ if (lseek(rfd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) {
+ switch (flags & O_ACCMODE) {
+ case O_RDONLY:
+ F_SET(t, R_RDONLY);
+ break;
+ default:
+ goto einval;
+ }
+slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL)
+ goto err;
+ F_SET(t, R_CLOSEFP);
+ t->bt_irec =
+ F_ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe;
+ } else {
+ switch (flags & O_ACCMODE) {
+ case O_RDONLY:
+ F_SET(t, R_RDONLY);
+ break;
+ case O_RDWR:
+ break;
+ default:
+ goto einval;
+ }
+
+ if (_fstat(rfd, &sb))
+ goto err;
+ /*
+ * Kluge -- we'd like to test to see if the file is too
+ * big to mmap. Since, we don't know what size or type
+ * off_t's or size_t's are, what the largest unsigned
+ * integral type is, or what random insanity the local
+ * C compiler will perpetrate, doing the comparison in
+ * a portable way is flatly impossible. Hope that mmap
+ * fails if the file is too large.
+ */
+ if (sb.st_size == 0)
+ F_SET(t, R_EOF);
+ else {
+#ifdef MMAP_NOT_AVAILABLE
+ /*
+ * XXX
+ * Mmap doesn't work correctly on many current
+ * systems. In particular, it can fail subtly,
+ * with cache coherency problems. Don't use it
+ * for now.
+ */
+ t->bt_msize = sb.st_size;
+ if ((t->bt_smap = mmap(NULL, t->bt_msize,
+ PROT_READ, MAP_PRIVATE, rfd,
+ (off_t)0)) == MAP_FAILED)
+ goto slow;
+ t->bt_cmap = t->bt_smap;
+ t->bt_emap = t->bt_smap + sb.st_size;
+ t->bt_irec = F_ISSET(t, R_FIXLEN) ?
+ __rec_fmap : __rec_vmap;
+ F_SET(t, R_MEMMAPPED);
+#else
+ goto slow;
+#endif
+ }
+ }
+ }
+
+ /* Use the recno routines. */
+ dbp->close = __rec_close;
+ dbp->del = __rec_delete;
+ dbp->fd = __rec_fd;
+ dbp->get = __rec_get;
+ dbp->put = __rec_put;
+ dbp->seq = __rec_seq;
+ dbp->sync = __rec_sync;
+
+ /* If the root page was created, reset the flags. */
+ if ((h = mpool_get(t->bt_mp, P_ROOT, 0)) == NULL)
+ goto err;
+ if ((h->flags & P_TYPE) == P_BLEAF) {
+ F_CLR(h, P_TYPE);
+ F_SET(h, P_RLEAF);
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ } else
+ mpool_put(t->bt_mp, h, 0);
+
+ if (openinfo && openinfo->flags & R_SNAPSHOT &&
+ !F_ISSET(t, R_EOF | R_INMEM) &&
+ t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
+ goto err;
+ return (dbp);
+
+einval: errno = EINVAL;
+err: sverrno = errno;
+ if (dbp != NULL)
+ (void)__bt_close(dbp);
+ if (fname != NULL)
+ (void)_close(rfd);
+ errno = sverrno;
+ return (NULL);
+}
+
+int
+__rec_fd(dbp)
+ const DB *dbp;
+{
+ BTREE *t;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /* In-memory database can't have a file descriptor. */
+ if (F_ISSET(t, R_INMEM)) {
+ errno = ENOENT;
+ return (-1);
+ }
+ return (t->bt_rfd);
+}
--- /dev/null
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_put.c 8.7 (Berkeley) 8/18/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_put.c,v 1.6 2002/03/22 21:52:02 obrien Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __REC_PUT -- Add a recno item to the tree.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key
+ * data: data
+ * flag: R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is
+ * already in the tree and R_NOOVERWRITE specified.
+ */
+int
+__rec_put(dbp, key, data, flags)
+ const DB *dbp;
+ DBT *key;
+ const DBT *data;
+ u_int flags;
+{
+ BTREE *t;
+ DBT fdata, tdata;
+ recno_t nrec;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ /*
+ * If using fixed-length records, and the record is long, return
+ * EINVAL. If it's short, pad it out. Use the record data return
+ * memory, it's only short-term.
+ */
+ if (F_ISSET(t, R_FIXLEN) && data->size != t->bt_reclen) {
+ if (data->size > t->bt_reclen)
+ goto einval;
+
+ if (t->bt_rdata.size < t->bt_reclen) {
+ t->bt_rdata.data =
+ reallocf(t->bt_rdata.data, t->bt_reclen);
+ if (t->bt_rdata.data == NULL)
+ return (RET_ERROR);
+ t->bt_rdata.size = t->bt_reclen;
+ }
+ memmove(t->bt_rdata.data, data->data, data->size);
+ memset((char *)t->bt_rdata.data + data->size,
+ t->bt_bval, t->bt_reclen - data->size);
+ fdata.data = t->bt_rdata.data;
+ fdata.size = t->bt_reclen;
+ } else {
+ fdata.data = data->data;
+ fdata.size = data->size;
+ }
+
+ switch (flags) {
+ case R_CURSOR:
+ if (!F_ISSET(&t->bt_cursor, CURS_INIT))
+ goto einval;
+ nrec = t->bt_cursor.rcursor;
+ break;
+ case R_SETCURSOR:
+ if ((nrec = *(recno_t *)key->data) == 0)
+ goto einval;
+ break;
+ case R_IAFTER:
+ if ((nrec = *(recno_t *)key->data) == 0) {
+ nrec = 1;
+ flags = R_IBEFORE;
+ }
+ break;
+ case 0:
+ case R_IBEFORE:
+ if ((nrec = *(recno_t *)key->data) == 0)
+ goto einval;
+ break;
+ case R_NOOVERWRITE:
+ if ((nrec = *(recno_t *)key->data) == 0)
+ goto einval;
+ if (nrec <= t->bt_nrecs)
+ return (RET_SPECIAL);
+ break;
+ default:
+einval: errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ /*
+ * Make sure that records up to and including the put record are
+ * already in the database. If skipping records, create empty ones.
+ */
+ if (nrec > t->bt_nrecs) {
+ if (!F_ISSET(t, R_EOF | R_INMEM) &&
+ t->bt_irec(t, nrec) == RET_ERROR)
+ return (RET_ERROR);
+ if (nrec > t->bt_nrecs + 1) {
+ if (F_ISSET(t, R_FIXLEN)) {
+ if ((tdata.data =
+ (void *)malloc(t->bt_reclen)) == NULL)
+ return (RET_ERROR);
+ tdata.size = t->bt_reclen;
+ memset(tdata.data, t->bt_bval, tdata.size);
+ } else {
+ tdata.data = NULL;
+ tdata.size = 0;
+ }
+ while (nrec > t->bt_nrecs + 1)
+ if (__rec_iput(t,
+ t->bt_nrecs, &tdata, 0) != RET_SUCCESS)
+ return (RET_ERROR);
+ if (F_ISSET(t, R_FIXLEN))
+ free(tdata.data);
+ }
+ }
+
+ if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS)
+ return (status);
+
+ switch (flags) {
+ case R_IAFTER:
+ nrec++;
+ break;
+ case R_SETCURSOR:
+ t->bt_cursor.rcursor = nrec;
+ break;
+ }
+
+ F_SET(t, R_MODIFIED);
+ return (__rec_ret(t, NULL, nrec, key, NULL));
+}
+
+/*
+ * __REC_IPUT -- Add a recno item to the tree.
+ *
+ * Parameters:
+ * t: tree
+ * nrec: record number
+ * data: data
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__rec_iput(t, nrec, data, flags)
+ BTREE *t;
+ recno_t nrec;
+ const DBT *data;
+ u_int flags;
+{
+ DBT tdata;
+ EPG *e;
+ PAGE *h;
+ indx_t index, nxtindex;
+ pgno_t pg;
+ u_int32_t nbytes;
+ int dflags, status;
+ char *dest, db[NOVFLSIZE];
+
+ /*
+ * If the data won't fit on a page, store it on indirect pages.
+ *
+ * XXX
+ * If the insert fails later on, these pages aren't recovered.
+ */
+ if (data->size > t->bt_ovflsize) {
+ if (__ovfl_put(t, data, &pg) == RET_ERROR)
+ return (RET_ERROR);
+ tdata.data = db;
+ tdata.size = NOVFLSIZE;
+ *(pgno_t *)db = pg;
+ *(u_int32_t *)(db + sizeof(pgno_t)) = data->size;
+ dflags = P_BIGDATA;
+ data = &tdata;
+ } else
+ dflags = 0;
+
+ /* __rec_search pins the returned page. */
+ if ((e = __rec_search(t, nrec,
+ nrec > t->bt_nrecs || flags == R_IAFTER || flags == R_IBEFORE ?
+ SINSERT : SEARCH)) == NULL)
+ return (RET_ERROR);
+
+ h = e->page;
+ index = e->index;
+
+ /*
+ * Add the specified key/data pair to the tree. The R_IAFTER and
+ * R_IBEFORE flags insert the key after/before the specified key.
+ *
+ * Pages are split as required.
+ */
+ switch (flags) {
+ case R_IAFTER:
+ ++index;
+ break;
+ case R_IBEFORE:
+ break;
+ default:
+ if (nrec < t->bt_nrecs &&
+ __rec_dleaf(t, h, index) == RET_ERROR) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_ERROR);
+ }
+ break;
+ }
+
+ /*
+ * If not enough room, split the page. The split code will insert
+ * the key and data and unpin the current page. If inserting into
+ * the offset array, shift the pointers up.
+ */
+ nbytes = NRLEAFDBT(data->size);
+ if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
+ status = __bt_split(t, h, NULL, data, dflags, nbytes, index);
+ if (status == RET_SUCCESS)
+ ++t->bt_nrecs;
+ return (status);
+ }
+
+ if (index < (nxtindex = NEXTINDEX(h)))
+ memmove(h->linp + index + 1, h->linp + index,
+ (nxtindex - index) * sizeof(indx_t));
+ h->lower += sizeof(indx_t);
+
+ h->linp[index] = h->upper -= nbytes;
+ dest = (char *)h + h->upper;
+ WR_RLEAF(dest, data, dflags);
+
+ ++t->bt_nrecs;
+ F_SET(t, B_MODIFIED);
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+
+ return (RET_SUCCESS);
+}
--- /dev/null
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_search.c 8.4 (Berkeley) 7/14/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_search.c,v 1.4 2002/03/21 18:47:38 obrien Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __REC_SEARCH -- Search a btree for a key.
+ *
+ * Parameters:
+ * t: tree to search
+ * recno: key to find
+ * op: search operation
+ *
+ * Returns:
+ * EPG for matching record, if any, or the EPG for the location of the
+ * key, if it were inserted into the tree.
+ *
+ * Returns:
+ * The EPG for matching record, if any, or the EPG for the location
+ * of the key, if it were inserted into the tree, is entered into
+ * the bt_cur field of the tree. A pointer to the field is returned.
+ */
+EPG *
+__rec_search(t, recno, op)
+ BTREE *t;
+ recno_t recno;
+ enum SRCHOP op;
+{
+ indx_t index;
+ PAGE *h;
+ EPGNO *parent;
+ RINTERNAL *r;
+ pgno_t pg;
+ indx_t top;
+ recno_t total;
+ int sverrno;
+
+ BT_CLR(t);
+ for (pg = P_ROOT, total = 0;;) {
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ goto err;
+ if (h->flags & P_RLEAF) {
+ t->bt_cur.page = h;
+ t->bt_cur.index = recno - total;
+ return (&t->bt_cur);
+ }
+ for (index = 0, top = NEXTINDEX(h);;) {
+ r = GETRINTERNAL(h, index);
+ if (++index == top || total + r->nrecs > recno)
+ break;
+ total += r->nrecs;
+ }
+
+ BT_PUSH(t, pg, index - 1);
+
+ pg = r->pgno;
+ switch (op) {
+ case SDELETE:
+ --GETRINTERNAL(h, (index - 1))->nrecs;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ break;
+ case SINSERT:
+ ++GETRINTERNAL(h, (index - 1))->nrecs;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ break;
+ case SEARCH:
+ mpool_put(t->bt_mp, h, 0);
+ break;
+ }
+
+ }
+ /* Try and recover the tree. */
+err: sverrno = errno;
+ if (op != SEARCH)
+ while ((parent = BT_POP(t)) != NULL) {
+ if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
+ break;
+ if (op == SINSERT)
+ --GETRINTERNAL(h, parent->index)->nrecs;
+ else
+ ++GETRINTERNAL(h, parent->index)->nrecs;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ }
+ errno = sverrno;
+ return (NULL);
+}
--- /dev/null
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+/* XXX use __SCCSID */
+static char sccsid[] __unused = "@(#)rec_seq.c 8.3 (Berkeley) 7/14/94";
+#endif /* not lint */
+__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_seq.c,v 1.5 2003/02/16 17:29:09 nectar Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __REC_SEQ -- Recno sequential scan interface.
+ *
+ * Parameters:
+ * dbp: pointer to access method
+ * key: key for positioning and return value
+ * data: data return value
+ * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
+ */
+int
+__rec_seq(dbp, key, data, flags)
+ const DB *dbp;
+ DBT *key, *data;
+ u_int flags;
+{
+ BTREE *t;
+ EPG *e;
+ recno_t nrec;
+ int status;
+
+ t = dbp->internal;
+
+ /* Toss any page pinned across calls. */
+ if (t->bt_pinned != NULL) {
+ mpool_put(t->bt_mp, t->bt_pinned, 0);
+ t->bt_pinned = NULL;
+ }
+
+ switch(flags) {
+ case R_CURSOR:
+ if ((nrec = *(recno_t *)key->data) == 0)
+ goto einval;
+ break;
+ case R_NEXT:
+ if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
+ nrec = t->bt_cursor.rcursor + 1;
+ break;
+ }
+ /* FALLTHROUGH */
+ case R_FIRST:
+ nrec = 1;
+ break;
+ case R_PREV:
+ if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
+ if ((nrec = t->bt_cursor.rcursor - 1) == 0)
+ return (RET_SPECIAL);
+ break;
+ }
+ /* FALLTHROUGH */
+ case R_LAST:
+ if (!F_ISSET(t, R_EOF | R_INMEM) &&
+ t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
+ return (RET_ERROR);
+ nrec = t->bt_nrecs;
+ break;
+ default:
+einval: errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) {
+ if (!F_ISSET(t, R_EOF | R_INMEM) &&
+ (status = t->bt_irec(t, nrec)) != RET_SUCCESS)
+ return (status);
+ if (t->bt_nrecs == 0 || nrec > t->bt_nrecs)
+ return (RET_SPECIAL);
+ }
+
+ if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL)
+ return (RET_ERROR);
+
+ F_SET(&t->bt_cursor, CURS_INIT);
+ t->bt_cursor.rcursor = nrec;
+
+ status = __rec_ret(t, e, nrec, key, data);
+ if (F_ISSET(t, B_DB_LOCK))
+ mpool_put(t->bt_mp, e->page, 0);
+ else
+ t->bt_pinned = e->page;
+ return (status);
+}
--- /dev/null
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rec_utils.c 8.6 (Berkeley) 7/16/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_utils.c,v 1.2 2002/03/22 21:52:02 obrien Exp $");
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <db.h>
+#include "recno.h"
+
+/*
+ * __rec_ret --
+ * Build return data.
+ *
+ * Parameters:
+ * t: tree
+ * e: key/data pair to be returned
+ * nrec: record number
+ * key: user's key structure
+ * data: user's data structure
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__rec_ret(t, e, nrec, key, data)
+ BTREE *t;
+ EPG *e;
+ recno_t nrec;
+ DBT *key, *data;
+{
+ RLEAF *rl;
+ void *p;
+
+ if (key == NULL)
+ goto dataonly;
+
+ /* We have to copy the key, it's not on the page. */
+ if (sizeof(recno_t) > t->bt_rkey.size) {
+ p = (void *)(t->bt_rkey.data == NULL ?
+ malloc(sizeof(recno_t)) :
+ realloc(t->bt_rkey.data, sizeof(recno_t)));
+ if (p == NULL)
+ return (RET_ERROR);
+ t->bt_rkey.data = p;
+ t->bt_rkey.size = sizeof(recno_t);
+ }
+ memmove(t->bt_rkey.data, &nrec, sizeof(recno_t));
+ key->size = sizeof(recno_t);
+ key->data = t->bt_rkey.data;
+
+dataonly:
+ if (data == NULL)
+ return (RET_SUCCESS);
+
+ /*
+ * We must copy big keys/data to make them contigous. Otherwise,
+ * leave the page pinned and don't copy unless the user specified
+ * concurrent access.
+ */
+ rl = GETRLEAF(e->page, e->index);
+ if (rl->flags & P_BIGDATA) {
+ if (__ovfl_get(t, rl->bytes,
+ &data->size, &t->bt_rdata.data, &t->bt_rdata.size))
+ return (RET_ERROR);
+ data->data = t->bt_rdata.data;
+ } else if (F_ISSET(t, B_DB_LOCK)) {
+ /* Use +1 in case the first record retrieved is 0 length. */
+ if (rl->dsize + 1 > t->bt_rdata.size) {
+ p = (void *)(t->bt_rdata.data == NULL ?
+ malloc(rl->dsize + 1) :
+ realloc(t->bt_rdata.data, rl->dsize + 1));
+ if (p == NULL)
+ return (RET_ERROR);
+ t->bt_rdata.data = p;
+ t->bt_rdata.size = rl->dsize + 1;
+ }
+ memmove(t->bt_rdata.data, rl->bytes, rl->dsize);
+ data->size = rl->dsize;
+ data->data = t->bt_rdata.data;
+ } else {
+ data->size = rl->dsize;
+ data->data = rl->bytes;
+ }
+ return (RET_SUCCESS);
+}
--- /dev/null
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)recno.h 8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/db/recno/recno.h,v 1.2 2002/03/22 23:41:40 obrien Exp $
+ */
+
+enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */
+
+#include "../btree/btree.h"
+#include "extern.h"
--- /dev/null
+--- recno.h.orig Fri Mar 22 15:41:40 2002
++++ recno.h Sat Oct 18 19:48:16 2003
+@@ -36,5 +36,5 @@
+
+ enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */
+
+-#include "../btree/btree.h"
+-#include "extern.h"
++#include "btree.h"
++#include "rec_extern.h"
# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
-# $FreeBSD: src/lib/libc/db/recno/Makefile.inc,v 1.3 1999/08/27 23:58:25 peter Exp $
+# $FreeBSD: src/lib/libc/db/recno/Makefile.inc,v 1.4 2002/11/18 09:50:55 ru Exp $
.PATH: ${.CURDIR}/db/recno
-CFLAGS+= -I${.CURDIR}/db/btree
-
-SRCS+= rec_close.c rec_delete.c rec_get.c rec_open.c rec_put.c rec_search.c \
+.include "Makefile.fbsd_begin"
+FBSDMISRCS= rec_close.c rec_delete.c rec_get.c rec_open.c rec_put.c rec_search.c \
rec_seq.c rec_utils.c
+.for _src in ${FBSDMISRCS}
+CFLAGS-${_src:R}-fbsd.${_src:E} += -D__DBINTERFACE_PRIVATE
+.endfor
+FBSDHDRS= recno.h
+.include "Makefile.fbsd_end"
+
+# need to rename extern.h to make it unique
+${SYMROOT}/rec_extern.h: ${.CURDIR}/db/recno/FreeBSD/extern.h _AUTOPATCHSYM
+AUTOPATCHHDRS+= ${SYMROOT}/rec_extern.h
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)extern.h 8.3 (Berkeley) 6/4/94
- * $FreeBSD: src/lib/libc/db/recno/extern.h,v 1.2 2002/03/21 22:46:28 obrien Exp $
- */
-
-#include "../btree/extern.h"
-
-int __rec_close(DB *);
-int __rec_delete(const DB *, const DBT *, u_int);
-int __rec_dleaf(BTREE *, PAGE *, u_int32_t);
-int __rec_fd(const DB *);
-int __rec_fmap(BTREE *, recno_t);
-int __rec_fout(BTREE *);
-int __rec_fpipe(BTREE *, recno_t);
-int __rec_get(const DB *, const DBT *, DBT *, u_int);
-int __rec_iput(BTREE *, recno_t, const DBT *, u_int);
-int __rec_put(const DB *dbp, DBT *, const DBT *, u_int);
-int __rec_ret(BTREE *, EPG *, recno_t, DBT *, DBT *);
-EPG *__rec_search(BTREE *, recno_t, enum SRCHOP);
-int __rec_seq(const DB *, DBT *, DBT *, u_int);
-int __rec_sync(const DB *, u_int);
-int __rec_vmap(BTREE *, recno_t);
-int __rec_vout(BTREE *);
-int __rec_vpipe(BTREE *, recno_t);
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_close.c 8.6 (Berkeley) 8/18/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/mman.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __REC_CLOSE -- Close a recno tree.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_close(dbp)
- DB *dbp;
-{
- BTREE *t;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- if (__rec_sync(dbp, 0) == RET_ERROR)
- return (RET_ERROR);
-
- /* Committed to closing. */
- status = RET_SUCCESS;
- if (F_ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
- status = RET_ERROR;
-
- if (!F_ISSET(t, R_INMEM)) {
- if (F_ISSET(t, R_CLOSEFP)) {
- if (fclose(t->bt_rfp))
- status = RET_ERROR;
- } else
- if (close(t->bt_rfd))
- status = RET_ERROR;
- }
-
- if (__bt_close(dbp) == RET_ERROR)
- status = RET_ERROR;
-
- return (status);
-}
-
-/*
- * __REC_SYNC -- sync the recno tree to disk.
- *
- * Parameters:
- * dbp: pointer to access method
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__rec_sync(dbp, flags)
- const DB *dbp;
- u_int flags;
-{
- struct iovec iov[2];
- BTREE *t;
- DBT data, key;
- off_t off;
- recno_t scursor, trec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- if (flags == R_RECNOSYNC)
- return (__bt_sync(dbp, 0));
-
- if (F_ISSET(t, R_RDONLY | R_INMEM) || !F_ISSET(t, R_MODIFIED))
- return (RET_SUCCESS);
-
- /* Read any remaining records into the tree. */
- if (!F_ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
- return (RET_ERROR);
-
- /* Rewind the file descriptor. */
- if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0)
- return (RET_ERROR);
-
- /* Save the cursor. */
- scursor = t->bt_cursor.rcursor;
-
- key.size = sizeof(recno_t);
- key.data = &trec;
-
- if (F_ISSET(t, R_FIXLEN)) {
- /*
- * We assume that fixed length records are all fixed length.
- * Any that aren't are either EINVAL'd or corrected by the
- * record put code.
- */
- status = (dbp->seq)(dbp, &key, &data, R_FIRST);
- while (status == RET_SUCCESS) {
- if (write(t->bt_rfd, data.data, data.size) !=
- data.size)
- return (RET_ERROR);
- status = (dbp->seq)(dbp, &key, &data, R_NEXT);
- }
- } else {
- iov[1].iov_base = (char *)&t->bt_bval;
- iov[1].iov_len = 1;
-
- status = (dbp->seq)(dbp, &key, &data, R_FIRST);
- while (status == RET_SUCCESS) {
- iov[0].iov_base = data.data;
- iov[0].iov_len = data.size;
- if (writev(t->bt_rfd, iov, 2) != data.size + 1)
- return (RET_ERROR);
- status = (dbp->seq)(dbp, &key, &data, R_NEXT);
- }
- }
-
- /* Restore the cursor. */
- t->bt_cursor.rcursor = scursor;
-
- if (status == RET_ERROR)
- return (RET_ERROR);
- if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1)
- return (RET_ERROR);
- if (ftruncate(t->bt_rfd, off))
- return (RET_ERROR);
- F_CLR(t, R_MODIFIED);
- return (RET_SUCCESS);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_delete.c 8.7 (Berkeley) 7/14/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <db.h>
-#include "recno.h"
-
-static int rec_rdelete(BTREE *, recno_t);
-
-/*
- * __REC_DELETE -- Delete the item(s) referenced by a key.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key to delete
- * flags: R_CURSOR if deleting what the cursor references
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-int
-__rec_delete(dbp, key, flags)
- const DB *dbp;
- const DBT *key;
- u_int flags;
-{
- BTREE *t;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- switch(flags) {
- case 0:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- if (nrec > t->bt_nrecs)
- return (RET_SPECIAL);
- --nrec;
- status = rec_rdelete(t, nrec);
- break;
- case R_CURSOR:
- if (!F_ISSET(&t->bt_cursor, CURS_INIT))
- goto einval;
- if (t->bt_nrecs == 0)
- return (RET_SPECIAL);
- status = rec_rdelete(t, t->bt_cursor.rcursor - 1);
- if (status == RET_SUCCESS)
- --t->bt_cursor.rcursor;
- break;
- default:
-einval: errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (status == RET_SUCCESS)
- F_SET(t, B_MODIFIED | R_MODIFIED);
- return (status);
-}
-
-/*
- * REC_RDELETE -- Delete the data matching the specified key.
- *
- * Parameters:
- * tree: tree
- * nrec: record to delete
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-static int
-rec_rdelete(t, nrec)
- BTREE *t;
- recno_t nrec;
-{
- EPG *e;
- PAGE *h;
- int status;
-
- /* Find the record; __rec_search pins the page. */
- if ((e = __rec_search(t, nrec, SDELETE)) == NULL)
- return (RET_ERROR);
-
- /* Delete the record. */
- h = e->page;
- status = __rec_dleaf(t, h, e->index);
- if (status != RET_SUCCESS) {
- mpool_put(t->bt_mp, h, 0);
- return (status);
- }
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_DLEAF -- Delete a single record from a recno leaf page.
- *
- * Parameters:
- * t: tree
- * index: index on current page to delete
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__rec_dleaf(t, h, index)
- BTREE *t;
- PAGE *h;
- u_int32_t index;
-{
- RLEAF *rl;
- indx_t *ip, cnt, offset;
- u_int32_t nbytes;
- char *from;
- void *to;
-
- /*
- * Delete a record from a recno leaf page. Internal records are never
- * deleted from internal pages, regardless of the records that caused
- * them to be added being deleted. Pages made empty by deletion are
- * not reclaimed. They are, however, made available for reuse.
- *
- * Pack the remaining entries at the end of the page, shift the indices
- * down, overwriting the deleted record and its index. If the record
- * uses overflow pages, make them available for reuse.
- */
- to = rl = GETRLEAF(h, index);
- if (rl->flags & P_BIGDATA && __ovfl_delete(t, rl->bytes) == RET_ERROR)
- return (RET_ERROR);
- nbytes = NRLEAF(rl);
-
- /*
- * Compress the key/data pairs. Compress and adjust the [BR]LEAF
- * offsets. Reset the headers.
- */
- from = (char *)h + h->upper;
- memmove(from + nbytes, from, (char *)to - from);
- h->upper += nbytes;
-
- offset = h->linp[index];
- for (cnt = &h->linp[index] - (ip = &h->linp[0]); cnt--; ++ip)
- if (ip[0] < offset)
- ip[0] += nbytes;
- for (cnt = &h->linp[NEXTINDEX(h)] - ip; --cnt; ++ip)
- ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
- h->lower -= sizeof(indx_t);
- --t->bt_nrecs;
- return (RET_SUCCESS);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_get.c 8.9 (Berkeley) 8/18/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __REC_GET -- Get a record from the btree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key to find
- * data: data to return
- * flag: currently unused
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
- */
-int
-__rec_get(dbp, key, data, flags)
- const DB *dbp;
- const DBT *key;
- DBT *data;
- u_int flags;
-{
- BTREE *t;
- EPG *e;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* Get currently doesn't take any flags, and keys of 0 are illegal. */
- if (flags || (nrec = *(recno_t *)key->data) == 0) {
- errno = EINVAL;
- return (RET_ERROR);
- }
-
- /*
- * If we haven't seen this record yet, try to find it in the
- * original file.
- */
- if (nrec > t->bt_nrecs) {
- if (F_ISSET(t, R_EOF | R_INMEM))
- return (RET_SPECIAL);
- if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
- return (status);
- }
-
- --nrec;
- if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
- return (RET_ERROR);
-
- status = __rec_ret(t, e, 0, NULL, data);
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e->page, 0);
- else
- t->bt_pinned = e->page;
- return (status);
-}
-
-/*
- * __REC_FPIPE -- Get fixed length records from a pipe.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_fpipe(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- recno_t nrec;
- size_t len;
- int ch;
- u_char *p;
-
- if (t->bt_rdata.size < t->bt_reclen) {
- t->bt_rdata.data = t->bt_rdata.data == NULL ?
- malloc(t->bt_reclen) :
- reallocf(t->bt_rdata.data, t->bt_reclen);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- t->bt_rdata.size = t->bt_reclen;
- }
- data.data = t->bt_rdata.data;
- data.size = t->bt_reclen;
-
- for (nrec = t->bt_nrecs; nrec < top;) {
- len = t->bt_reclen;
- for (p = t->bt_rdata.data;; *p++ = ch)
- if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
- if (ch != EOF)
- *p = ch;
- if (len != 0)
- memset(p, t->bt_bval, len);
- if (__rec_iput(t,
- nrec, &data, 0) != RET_SUCCESS)
- return (RET_ERROR);
- ++nrec;
- break;
- }
- if (ch == EOF)
- break;
- }
- if (nrec < top) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_VPIPE -- Get variable length records from a pipe.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_vpipe(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- recno_t nrec;
- size_t len;
- size_t sz;
- int bval, ch;
- u_char *p;
-
- bval = t->bt_bval;
- for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
- for (p = t->bt_rdata.data,
- sz = t->bt_rdata.size;; *p++ = ch, --sz) {
- if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
- data.data = t->bt_rdata.data;
- data.size = p - (u_char *)t->bt_rdata.data;
- if (ch == EOF && data.size == 0)
- break;
- if (__rec_iput(t, nrec, &data, 0)
- != RET_SUCCESS)
- return (RET_ERROR);
- break;
- }
- if (sz == 0) {
- len = p - (u_char *)t->bt_rdata.data;
- t->bt_rdata.size += (sz = 256);
- t->bt_rdata.data = t->bt_rdata.data == NULL ?
- malloc(t->bt_rdata.size) :
- reallocf(t->bt_rdata.data, t->bt_rdata.size);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- p = (u_char *)t->bt_rdata.data + len;
- }
- }
- if (ch == EOF)
- break;
- }
- if (nrec < top) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_FMAP -- Get fixed length records from a file.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_fmap(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- recno_t nrec;
- u_char *sp, *ep, *p;
- size_t len;
-
- if (t->bt_rdata.size < t->bt_reclen) {
- t->bt_rdata.data = t->bt_rdata.data == NULL ?
- malloc(t->bt_reclen) :
- reallocf(t->bt_rdata.data, t->bt_reclen);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- t->bt_rdata.size = t->bt_reclen;
- }
- data.data = t->bt_rdata.data;
- data.size = t->bt_reclen;
-
- sp = (u_char *)t->bt_cmap;
- ep = (u_char *)t->bt_emap;
- for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
- if (sp >= ep) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- len = t->bt_reclen;
- for (p = t->bt_rdata.data;
- sp < ep && len > 0; *p++ = *sp++, --len);
- if (len != 0)
- memset(p, t->bt_bval, len);
- if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
- return (RET_ERROR);
- }
- t->bt_cmap = (caddr_t)sp;
- return (RET_SUCCESS);
-}
-
-/*
- * __REC_VMAP -- Get variable length records from a file.
- *
- * Parameters:
- * t: tree
- * cnt: records to read
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_vmap(t, top)
- BTREE *t;
- recno_t top;
-{
- DBT data;
- u_char *sp, *ep;
- recno_t nrec;
- int bval;
-
- sp = (u_char *)t->bt_cmap;
- ep = (u_char *)t->bt_emap;
- bval = t->bt_bval;
-
- for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
- if (sp >= ep) {
- F_SET(t, R_EOF);
- return (RET_SPECIAL);
- }
- for (data.data = sp; sp < ep && *sp != bval; ++sp);
- data.size = sp - (u_char *)data.data;
- if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
- return (RET_ERROR);
- ++sp;
- }
- t->bt_cmap = (caddr_t)sp;
- return (RET_SUCCESS);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * 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
- * Mike Olson.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_open.c 8.10 (Berkeley) 9/1/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <db.h>
-#include "recno.h"
-
-DB *
-__rec_open(fname, flags, mode, openinfo, dflags)
- const char *fname;
- int flags, mode, dflags;
- const RECNOINFO *openinfo;
-{
- BTREE *t;
- BTREEINFO btopeninfo;
- DB *dbp;
- PAGE *h;
- struct stat sb;
- int rfd, sverrno;
-
- /* Open the user's file -- if this fails, we're done. */
- if (fname != NULL && (rfd = open(fname, flags, mode)) < 0)
- return (NULL);
-
- /* Create a btree in memory (backed by disk). */
- dbp = NULL;
- if (openinfo) {
- if (openinfo->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT))
- goto einval;
- btopeninfo.flags = 0;
- btopeninfo.cachesize = openinfo->cachesize;
- btopeninfo.maxkeypage = 0;
- btopeninfo.minkeypage = 0;
- btopeninfo.psize = openinfo->psize;
- btopeninfo.compare = NULL;
- btopeninfo.prefix = NULL;
- btopeninfo.lorder = openinfo->lorder;
- dbp = __bt_open(openinfo->bfname,
- O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo, dflags);
- } else
- dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL, dflags);
- if (dbp == NULL)
- goto err;
-
- /*
- * Some fields in the tree structure are recno specific. Fill them
- * in and make the btree structure look like a recno structure. We
- * don't change the bt_ovflsize value, it's close enough and slightly
- * bigger.
- */
- t = dbp->internal;
- if (openinfo) {
- if (openinfo->flags & R_FIXEDLEN) {
- F_SET(t, R_FIXLEN);
- t->bt_reclen = openinfo->reclen;
- if (t->bt_reclen == 0)
- goto einval;
- }
- t->bt_bval = openinfo->bval;
- } else
- t->bt_bval = '\n';
-
- F_SET(t, R_RECNO);
- if (fname == NULL)
- F_SET(t, R_EOF | R_INMEM);
- else
- t->bt_rfd = rfd;
-
- if (fname != NULL) {
- /*
- * In 4.4BSD, stat(2) returns true for ISSOCK on pipes.
- * Unfortunately, that's not portable, so we use lseek
- * and check the errno values.
- */
- errno = 0;
- if (lseek(rfd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) {
- switch (flags & O_ACCMODE) {
- case O_RDONLY:
- F_SET(t, R_RDONLY);
- break;
- default:
- goto einval;
- }
-slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL)
- goto err;
- F_SET(t, R_CLOSEFP);
- t->bt_irec =
- F_ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe;
- } else {
- switch (flags & O_ACCMODE) {
- case O_RDONLY:
- F_SET(t, R_RDONLY);
- break;
- case O_RDWR:
- break;
- default:
- goto einval;
- }
-
- if (fstat(rfd, &sb))
- goto err;
- /*
- * Kluge -- we'd like to test to see if the file is too
- * big to mmap. Since, we don't know what size or type
- * off_t's or size_t's are, what the largest unsigned
- * integral type is, or what random insanity the local
- * C compiler will perpetrate, doing the comparison in
- * a portable way is flatly impossible. Hope that mmap
- * fails if the file is too large.
- */
- if (sb.st_size == 0)
- F_SET(t, R_EOF);
- else {
-#ifdef MMAP_NOT_AVAILABLE
- /*
- * XXX
- * Mmap doesn't work correctly on many current
- * systems. In particular, it can fail subtly,
- * with cache coherency problems. Don't use it
- * for now.
- */
- t->bt_msize = sb.st_size;
- if ((t->bt_smap = mmap(NULL, t->bt_msize,
- PROT_READ, MAP_PRIVATE, rfd,
- (off_t)0)) == MAP_FAILED)
- goto slow;
- t->bt_cmap = t->bt_smap;
- t->bt_emap = t->bt_smap + sb.st_size;
- t->bt_irec = F_ISSET(t, R_FIXLEN) ?
- __rec_fmap : __rec_vmap;
- F_SET(t, R_MEMMAPPED);
-#else
- goto slow;
-#endif
- }
- }
- }
-
- /* Use the recno routines. */
- dbp->close = __rec_close;
- dbp->del = __rec_delete;
- dbp->fd = __rec_fd;
- dbp->get = __rec_get;
- dbp->put = __rec_put;
- dbp->seq = __rec_seq;
- dbp->sync = __rec_sync;
-
- /* If the root page was created, reset the flags. */
- if ((h = mpool_get(t->bt_mp, P_ROOT, 0)) == NULL)
- goto err;
- if ((h->flags & P_TYPE) == P_BLEAF) {
- F_CLR(h, P_TYPE);
- F_SET(h, P_RLEAF);
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- } else
- mpool_put(t->bt_mp, h, 0);
-
- if (openinfo && openinfo->flags & R_SNAPSHOT &&
- !F_ISSET(t, R_EOF | R_INMEM) &&
- t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
- goto err;
- return (dbp);
-
-einval: errno = EINVAL;
-err: sverrno = errno;
- if (dbp != NULL)
- (void)__bt_close(dbp);
- if (fname != NULL)
- (void)close(rfd);
- errno = sverrno;
- return (NULL);
-}
-
-int
-__rec_fd(dbp)
- const DB *dbp;
-{
- BTREE *t;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /* In-memory database can't have a file descriptor. */
- if (F_ISSET(t, R_INMEM)) {
- errno = ENOENT;
- return (-1);
- }
- return (t->bt_rfd);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_put.c 8.7 (Berkeley) 8/18/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __REC_PUT -- Add a recno item to the tree.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key
- * data: data
- * flag: R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is
- * already in the tree and R_NOOVERWRITE specified.
- */
-int
-__rec_put(dbp, key, data, flags)
- const DB *dbp;
- DBT *key;
- const DBT *data;
- u_int flags;
-{
- BTREE *t;
- DBT fdata, tdata;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- /*
- * If using fixed-length records, and the record is long, return
- * EINVAL. If it's short, pad it out. Use the record data return
- * memory, it's only short-term.
- */
- if (F_ISSET(t, R_FIXLEN) && data->size != t->bt_reclen) {
- if (data->size > t->bt_reclen)
- goto einval;
-
- if (t->bt_rdata.size < t->bt_reclen) {
- t->bt_rdata.data =
- reallocf(t->bt_rdata.data, t->bt_reclen);
- if (t->bt_rdata.data == NULL)
- return (RET_ERROR);
- t->bt_rdata.size = t->bt_reclen;
- }
- memmove(t->bt_rdata.data, data->data, data->size);
- memset((char *)t->bt_rdata.data + data->size,
- t->bt_bval, t->bt_reclen - data->size);
- fdata.data = t->bt_rdata.data;
- fdata.size = t->bt_reclen;
- } else {
- fdata.data = data->data;
- fdata.size = data->size;
- }
-
- switch (flags) {
- case R_CURSOR:
- if (!F_ISSET(&t->bt_cursor, CURS_INIT))
- goto einval;
- nrec = t->bt_cursor.rcursor;
- break;
- case R_SETCURSOR:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- break;
- case R_IAFTER:
- if ((nrec = *(recno_t *)key->data) == 0) {
- nrec = 1;
- flags = R_IBEFORE;
- }
- break;
- case 0:
- case R_IBEFORE:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- break;
- case R_NOOVERWRITE:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- if (nrec <= t->bt_nrecs)
- return (RET_SPECIAL);
- break;
- default:
-einval: errno = EINVAL;
- return (RET_ERROR);
- }
-
- /*
- * Make sure that records up to and including the put record are
- * already in the database. If skipping records, create empty ones.
- */
- if (nrec > t->bt_nrecs) {
- if (!F_ISSET(t, R_EOF | R_INMEM) &&
- t->bt_irec(t, nrec) == RET_ERROR)
- return (RET_ERROR);
- if (nrec > t->bt_nrecs + 1) {
- if (F_ISSET(t, R_FIXLEN)) {
- if ((tdata.data =
- (void *)malloc(t->bt_reclen)) == NULL)
- return (RET_ERROR);
- tdata.size = t->bt_reclen;
- memset(tdata.data, t->bt_bval, tdata.size);
- } else {
- tdata.data = NULL;
- tdata.size = 0;
- }
- while (nrec > t->bt_nrecs + 1)
- if (__rec_iput(t,
- t->bt_nrecs, &tdata, 0) != RET_SUCCESS)
- return (RET_ERROR);
- if (F_ISSET(t, R_FIXLEN))
- free(tdata.data);
- }
- }
-
- if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS)
- return (status);
-
- switch (flags) {
- case R_IAFTER:
- nrec++;
- break;
- case R_SETCURSOR:
- t->bt_cursor.rcursor = nrec;
- break;
- }
-
- F_SET(t, R_MODIFIED);
- return (__rec_ret(t, NULL, nrec, key, NULL));
-}
-
-/*
- * __REC_IPUT -- Add a recno item to the tree.
- *
- * Parameters:
- * t: tree
- * nrec: record number
- * data: data
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS
- */
-int
-__rec_iput(t, nrec, data, flags)
- BTREE *t;
- recno_t nrec;
- const DBT *data;
- u_int flags;
-{
- DBT tdata;
- EPG *e;
- PAGE *h;
- indx_t index, nxtindex;
- pgno_t pg;
- u_int32_t nbytes;
- int dflags, status;
- char *dest, db[NOVFLSIZE];
-
- /*
- * If the data won't fit on a page, store it on indirect pages.
- *
- * XXX
- * If the insert fails later on, these pages aren't recovered.
- */
- if (data->size > t->bt_ovflsize) {
- if (__ovfl_put(t, data, &pg) == RET_ERROR)
- return (RET_ERROR);
- tdata.data = db;
- tdata.size = NOVFLSIZE;
- *(pgno_t *)db = pg;
- *(u_int32_t *)(db + sizeof(pgno_t)) = data->size;
- dflags = P_BIGDATA;
- data = &tdata;
- } else
- dflags = 0;
-
- /* __rec_search pins the returned page. */
- if ((e = __rec_search(t, nrec,
- nrec > t->bt_nrecs || flags == R_IAFTER || flags == R_IBEFORE ?
- SINSERT : SEARCH)) == NULL)
- return (RET_ERROR);
-
- h = e->page;
- index = e->index;
-
- /*
- * Add the specified key/data pair to the tree. The R_IAFTER and
- * R_IBEFORE flags insert the key after/before the specified key.
- *
- * Pages are split as required.
- */
- switch (flags) {
- case R_IAFTER:
- ++index;
- break;
- case R_IBEFORE:
- break;
- default:
- if (nrec < t->bt_nrecs &&
- __rec_dleaf(t, h, index) == RET_ERROR) {
- mpool_put(t->bt_mp, h, 0);
- return (RET_ERROR);
- }
- break;
- }
-
- /*
- * If not enough room, split the page. The split code will insert
- * the key and data and unpin the current page. If inserting into
- * the offset array, shift the pointers up.
- */
- nbytes = NRLEAFDBT(data->size);
- if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
- status = __bt_split(t, h, NULL, data, dflags, nbytes, index);
- if (status == RET_SUCCESS)
- ++t->bt_nrecs;
- return (status);
- }
-
- if (index < (nxtindex = NEXTINDEX(h)))
- memmove(h->linp + index + 1, h->linp + index,
- (nxtindex - index) * sizeof(indx_t));
- h->lower += sizeof(indx_t);
-
- h->linp[index] = h->upper -= nbytes;
- dest = (char *)h + h->upper;
- WR_RLEAF(dest, data, dflags);
-
- ++t->bt_nrecs;
- F_SET(t, B_MODIFIED);
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
-
- return (RET_SUCCESS);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_search.c 8.4 (Berkeley) 7/14/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdio.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __REC_SEARCH -- Search a btree for a key.
- *
- * Parameters:
- * t: tree to search
- * recno: key to find
- * op: search operation
- *
- * Returns:
- * EPG for matching record, if any, or the EPG for the location of the
- * key, if it were inserted into the tree.
- *
- * Returns:
- * The EPG for matching record, if any, or the EPG for the location
- * of the key, if it were inserted into the tree, is entered into
- * the bt_cur field of the tree. A pointer to the field is returned.
- */
-EPG *
-__rec_search(t, recno, op)
- BTREE *t;
- recno_t recno;
- enum SRCHOP op;
-{
- indx_t index;
- PAGE *h;
- EPGNO *parent;
- RINTERNAL *r;
- pgno_t pg;
- indx_t top;
- recno_t total;
- int sverrno;
-
- BT_CLR(t);
- for (pg = P_ROOT, total = 0;;) {
- if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
- goto err;
- if (h->flags & P_RLEAF) {
- t->bt_cur.page = h;
- t->bt_cur.index = recno - total;
- return (&t->bt_cur);
- }
- for (index = 0, top = NEXTINDEX(h);;) {
- r = GETRINTERNAL(h, index);
- if (++index == top || total + r->nrecs > recno)
- break;
- total += r->nrecs;
- }
-
- BT_PUSH(t, pg, index - 1);
-
- pg = r->pgno;
- switch (op) {
- case SDELETE:
- --GETRINTERNAL(h, (index - 1))->nrecs;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- case SINSERT:
- ++GETRINTERNAL(h, (index - 1))->nrecs;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- break;
- case SEARCH:
- mpool_put(t->bt_mp, h, 0);
- break;
- }
-
- }
- /* Try and recover the tree. */
-err: sverrno = errno;
- if (op != SEARCH)
- while ((parent = BT_POP(t)) != NULL) {
- if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
- break;
- if (op == SINSERT)
- --GETRINTERNAL(h, parent->index)->nrecs;
- else
- ++GETRINTERNAL(h, parent->index)->nrecs;
- mpool_put(t->bt_mp, h, MPOOL_DIRTY);
- }
- errno = sverrno;
- return (NULL);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __REC_SEQ -- Recno sequential scan interface.
- *
- * Parameters:
- * dbp: pointer to access method
- * key: key for positioning and return value
- * data: data return value
- * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
- *
- * Returns:
- * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
- */
-int
-__rec_seq(dbp, key, data, flags)
- const DB *dbp;
- DBT *key, *data;
- u_int flags;
-{
- BTREE *t;
- EPG *e;
- recno_t nrec;
- int status;
-
- t = dbp->internal;
-
- /* Toss any page pinned across calls. */
- if (t->bt_pinned != NULL) {
- mpool_put(t->bt_mp, t->bt_pinned, 0);
- t->bt_pinned = NULL;
- }
-
- switch(flags) {
- case R_CURSOR:
- if ((nrec = *(recno_t *)key->data) == 0)
- goto einval;
- break;
- case R_NEXT:
- if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
- nrec = t->bt_cursor.rcursor + 1;
- break;
- }
- /* FALLTHROUGH */
- case R_FIRST:
- nrec = 1;
- break;
- case R_PREV:
- if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
- if ((nrec = t->bt_cursor.rcursor - 1) == 0)
- return (RET_SPECIAL);
- break;
- }
- /* FALLTHROUGH */
- case R_LAST:
- if (!F_ISSET(t, R_EOF | R_INMEM) &&
- t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
- return (RET_ERROR);
- nrec = t->bt_nrecs;
- break;
- default:
-einval: errno = EINVAL;
- return (RET_ERROR);
- }
-
- if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) {
- if (!F_ISSET(t, R_EOF | R_INMEM) &&
- (status = t->bt_irec(t, nrec)) != RET_SUCCESS)
- return (status);
- if (t->bt_nrecs == 0 || nrec > t->bt_nrecs)
- return (RET_SPECIAL);
- }
-
- if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL)
- return (RET_ERROR);
-
- F_SET(&t->bt_cursor, CURS_INIT);
- t->bt_cursor.rcursor = nrec;
-
- status = __rec_ret(t, e, nrec, key, data);
- if (F_ISSET(t, B_DB_LOCK))
- mpool_put(t->bt_mp, e->page, 0);
- else
- t->bt_pinned = e->page;
- return (status);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_utils.c 8.6 (Berkeley) 7/16/94";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <db.h>
-#include "recno.h"
-
-/*
- * __rec_ret --
- * Build return data.
- *
- * Parameters:
- * t: tree
- * e: key/data pair to be returned
- * nrec: record number
- * key: user's key structure
- * data: user's data structure
- *
- * Returns:
- * RET_SUCCESS, RET_ERROR.
- */
-int
-__rec_ret(t, e, nrec, key, data)
- BTREE *t;
- EPG *e;
- recno_t nrec;
- DBT *key, *data;
-{
- RLEAF *rl;
- void *p;
-
- if (key == NULL)
- goto dataonly;
-
- /* We have to copy the key, it's not on the page. */
- if (sizeof(recno_t) > t->bt_rkey.size) {
- p = (void *)(t->bt_rkey.data == NULL ?
- malloc(sizeof(recno_t)) :
- realloc(t->bt_rkey.data, sizeof(recno_t)));
- if (p == NULL)
- return (RET_ERROR);
- t->bt_rkey.data = p;
- t->bt_rkey.size = sizeof(recno_t);
- }
- memmove(t->bt_rkey.data, &nrec, sizeof(recno_t));
- key->size = sizeof(recno_t);
- key->data = t->bt_rkey.data;
-
-dataonly:
- if (data == NULL)
- return (RET_SUCCESS);
-
- /*
- * We must copy big keys/data to make them contigous. Otherwise,
- * leave the page pinned and don't copy unless the user specified
- * concurrent access.
- */
- rl = GETRLEAF(e->page, e->index);
- if (rl->flags & P_BIGDATA) {
- if (__ovfl_get(t, rl->bytes,
- &data->size, &t->bt_rdata.data, &t->bt_rdata.size))
- return (RET_ERROR);
- data->data = t->bt_rdata.data;
- } else if (F_ISSET(t, B_DB_LOCK)) {
- /* Use +1 in case the first record retrieved is 0 length. */
- if (rl->dsize + 1 > t->bt_rdata.size) {
- p = (void *)(t->bt_rdata.data == NULL ?
- malloc(rl->dsize + 1) :
- realloc(t->bt_rdata.data, rl->dsize + 1));
- if (p == NULL)
- return (RET_ERROR);
- t->bt_rdata.data = p;
- t->bt_rdata.size = rl->dsize + 1;
- }
- memmove(t->bt_rdata.data, rl->bytes, rl->dsize);
- data->size = rl->dsize;
- data->data = t->bt_rdata.data;
- } else {
- data->size = rl->dsize;
- data->data = rl->bytes;
- }
- return (RET_SUCCESS);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)recno.h 8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/db/recno/recno.h,v 1.2 2002/03/22 23:41:40 obrien Exp $
- */
-
-enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */
-
-#include "../btree/btree.h"
-#include "extern.h"
--- /dev/null
+.PATH: ${.CURDIR}/emulated
+
+MISRCS+=bsd_signal.c \
+ statvfs.c \
+ tcgetsid.c
+
+.if ${LIB} == "c"
+MAN3+= bsd_signal.3 statvfs.3 tcgetsid.3
+
+MLINKS+=statvfs.3 fstatvfs.3
+
+.endif
--- /dev/null
+.\" Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+.\"
+.\" @APPLE_LICENSE_HEADER_START@
+.\"
+.\" The contents of this file constitute Original Code as defined in and
+.\" are subject to the Apple Public Source License Version 1.1 (the
+.\" "License"). You may not use this file except in compliance with the
+.\" License. Please obtain a copy of the License at
+.\" http://www.apple.com/publicsource and read it before using this file.
+.\"
+.\" This Original Code and all software distributed under the License are
+.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+.\" License for the specific language governing rights and limitations
+.\" under the License.
+.\"
+.\" @APPLE_LICENSE_HEADER_END@
+.\"
+.Dd December 20, 2003
+.Dt BSD_SIGNAL 3
+.Os
+.Sh NAME
+.Nm bsd_signal
+.Nd simplified signal facilities
+.Sh SYNOPSIS
+.In signal.h
+.\" The following is Quite Ugly, but syntactically correct. Don't try to
+.\" fix it.
+.Ft void \*(lp*
+.Fn bsd_signal "int sig" "void \*(lp*func\*(rp\*(lpint\*(rp\*(rp\*(rp\*(lpint"
+.Pp
+or in an equivalent but easier to read typedef'd version:
+.Ft typedef "void \*(lp*sig_t\*(rp \*(lpint\*(rp" ;
+.Ft sig_t
+.Fn bsd_signal "int sig" "sig_t func"
+.Sh DESCRIPTION
+The
+.Fn bsd_signal
+function provides a partially compatible interface for programs written
+to historical system interfaces (see USAGE below).
+.Pp
+The function call
+.Fn bsd_signal sig func
+has the effect as if implemented as:
+.Bd -literal -offset indent
+void (*bsd_signal(int sig, void (*func)(int)))(int)
+{
+ struct sigaction act, oact;
+
+ act.sa_handler = func;
+ act.sa_flags = SA_RESTART;
+ sigemptyset(&act.sa_mask);
+ sigaddset(&act.sa_mask, sig);
+ if (sigaction(sig, &act, &oact) == -1)
+ return(SIG_ERR);
+ return(oact.sa_handler);
+}
+.Ed
+.Pp
+The handler function should be declared:
+.Pp
+.D1 Fn "void func" "int sig"
+.Pp
+where
+.Fa sig
+is the signal number.
+The behavior is undefined if
+.Fn func
+is a function that takes more than one argument, or an argument of a
+different type.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn bsd_signal
+returns the previous action for
+.Fa sig .
+Otherwise,
+.Er SIG_ERR
+is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+Refer to
+.Xr sigaction 2 .
+.Sh USAGE
+This function is a direct replacement for the
+.Bx
+.Xr signal(3)
+function for simple applications that are installing a single-argument signal
+handler function.
+If a
+.Bx
+signal handler function is being installed that expects more than one
+argument, the application has to be modified to use
+.Xr sigaction 2 .
+The
+.Fn bsd_signal
+function differs from
+.Xr signal 3
+in that the
+.Dv SA_RESTART
+flag is set and the
+.Dv SA_RESETHAND
+will be clear when
+.Fn bsd_signal
+is used.
+The state of these flags is not specified for
+.Xr signal 3 .
+.Sh SEE ALSO
+.Xr sigaction 2 ,
+.Xr sigaddset 3 ,
+.Xr sigemptyset 3 ,
+.Xr signal 3
+.Sh STANDARDS
+The
+.Fn bsd_signal
+function conforms to
+.St -p1003.1-2001 .
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * bsd_signal() function, per POIX 1003.1-2003
+ */
+#include <sys/signal.h>
+
+void
+(*bsd_signal(int sig, void (*func)(int)))(int)
+{
+ struct sigaction act, oact;
+
+
+ act.sa_handler = func;
+ act.sa_flags = SA_RESTART;
+
+ sigemptyset(&act.sa_mask);
+ sigaddset(&act.sa_mask, sig);
+ if (sigaction(sig, &act, &oact) == -1)
+ return(SIG_ERR);
+
+ return(oact.sa_handler);
+}
--- /dev/null
+.\"
+.\" Copyright 2002 Massachusetts Institute of Technology
+.\"
+.\" Permission to use, copy, modify, and distribute this software and
+.\" its documentation for any purpose and without fee is hereby
+.\" granted, provided that both the above copyright notice and this
+.\" permission notice appear in all copies, that both the above
+.\" copyright notice and this permission notice appear in all
+.\" supporting documentation, and that the name of M.I.T. not be used
+.\" in advertising or publicity pertaining to distribution of the
+.\" software without specific, written prior permission. M.I.T. makes
+.\" no representations about the suitability of this software for any
+.\" purpose. It is provided "as is" without express or implied
+.\" warranty.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+.\" SHALL M.I.T. 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.
+.\"
+.\" $FreeBSD: src/lib/libc/gen/statvfs.3,v 1.7 2003/06/08 10:01:51 charnier Exp $
+.\"
+.Dd July 13, 2002
+.Dt STATVFS 3
+.Os
+.Sh NAME
+.Nm statvfs ,
+.Nm fstatvfs
+.Nd retrieve file system information
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/statvfs.h
+.Ft int
+.Fn statvfs "const char * restrict path" "struct statvfs * restrict buf"
+.Ft int
+.Fn fstatvfs "int fd" "struct statvfs *buf"
+.Sh DESCRIPTION
+The
+.Fn statvfs
+and
+.Fn fstatvfs
+functions attempt to fill the structure pointed to by
+.Fa buf
+with file system
+statistics, but portable applications must not depend on this.
+Applications must pass a pathname or file descriptor which refers to a
+file on the file system in which they are interested.
+.Pp
+The
+.Vt statvfs
+structure contains the following members:
+.Bl -tag -offset indent -width ".Va f_namemax"
+.It Va f_namemax
+The maximum length in bytes of a file name on this file system.
+Applications should use
+.Xr pathconf 2
+instead.
+.It Va f_fsid
+Not meaningful in this implementation.
+.It Va f_frsize
+The size in bytes of the minimum unit of allocation on this
+file system.
+(This corresponds to the
+.Va f_bsize
+member of
+.Vt "struct statfs" . )
+.It Va f_bsize
+The preferred length of I/O requests for files on this file system.
+(Corresponds to the
+.Va f_iosize
+member of
+.Vt "struct statfs" . )
+.It Va f_flag
+Flags describing mount options for this file system; see below.
+.El
+.Pp
+In addition, there are three members of type
+.Vt fsfilcnt_t ,
+which represent counts of file serial numbers
+.Em ( i.e. ,
+inodes); these are named
+.Va f_files , f_favail ,
+and
+.Va f_ffree ,
+and represent the number of file serial numbers which exist in total,
+are available to unprivileged processes, and are available to
+privileged processes, respectively.
+Likewise, the members
+.Va f_blocks , f_bavail ,
+and
+.Va f_bfree
+(all of type
+.Vt fsblkcnt_t )
+represent the respective allocation-block counts.
+.Pp
+There are two flags defined for the
+.Va f_flag
+member:
+.Bl -tag -offset indent -width ".Dv ST_NOSUID"
+.It Dv ST_RDONLY
+The file system is mounted read-only.
+.It Dv ST_NOSUID
+The semantics of the
+.Dv S_ISUID
+and
+.Dv S_ISGID
+file mode bits
+are not supported by, or are disabled on, this file system.
+.El
+.Sh IMPLEMENTATION NOTES
+The
+.Fn statvfs
+and
+.Fn fstatvfs
+functions are implemented as wrappers around the
+.Fn statfs
+and
+.Fn fstatfs
+functions, respectively.
+Not all the information provided by those functions is made available
+through this interface.
+.Sh RETURN VALUES
+.Rv -std statvfs fstatvfs
+.Sh ERRORS
+The
+.Fn statvfs
+function fails if one or more of the following are true:
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the path prefix of
+.Fa Path
+is not a directory.
+.It Bq Er ENAMETOOLONG
+The length of a component of
+.Fa path
+exceeds
+.Dv {NAME_MAX}
+characters, or the length of
+.Fa path
+exceeds
+.Dv {PATH_MAX}
+characters.
+.It Bq Er ENOENT
+The file referred to by
+.Fa path
+does not exist.
+.It Bq Er EACCES
+Search permission is denied for a component of the path prefix of
+.Fa path .
+.It Bq Er ELOOP
+Too many symbolic links were encountered in translating
+.Fa path .
+.It Bq Er EFAULT
+.Fa Buf
+or
+.Fa path
+points to an invalid address.
+.It Bq Er EIO
+An
+.Tn I/O
+error occurred while reading from or writing to the file system.
+.El
+.Pp
+The
+.Fn fstatvfs
+functions fails if one or more of the following are true:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa fd
+is not a valid open file descriptor.
+.It Bq Er EFAULT
+.Fa Buf
+points to an invalid address.
+.It Bq Er EIO
+An
+.Tn I/O
+error occurred while reading from or writing to the file system.
+.El
+.Sh SEE ALSO
+.Xr statfs 2
+.Sh STANDARDS
+The
+.Fn statvfs
+and
+.Fn fstatvfs
+functions conform to
+.St -p1003.1-2001 .
+As standardized, portable applications cannot depend on these functions
+returning any valid information at all.
+This implementation attempts to provide as much useful information as
+is provided by the underlying file system, subject to the limitations
+of the specified data types.
+.Sh AUTHORS
+The
+.Fn statvfs
+and
+.Fn fstatvfs
+manual page was originally written by
+.An Garrett Wollman Aq wollman@FreeBSD.org .
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * sys/statvfs.c
+ */
+#include <sys/param.h>
+#include <sys/mount.h>
+
+#include <sys/statvfs.h> /* glue header */
+
+
+/* Internal common conversion function */
+static void
+cvt_statfs_to_statvfs(struct statfs *from, struct statvfs *to)
+{
+ to->f_bsize = from->f_iosize;
+ to->f_frsize = from->f_bsize;
+ to->f_blocks = from->f_blocks;
+ to->f_bfree = from->f_bfree;
+ to->f_bavail = from->f_bavail;
+ to->f_files = from->f_files;
+ to->f_ffree = from->f_ffree;
+ to->f_favail = from->f_ffree;
+ to->f_fsid = from->f_fsid.val[0]; /* XXX bad if non-root */
+ to->f_namemax = NAME_MAX; /* XXX should be per FS */
+
+ /* Conver FS flags */
+ to->f_flag = 0;
+ if( from->f_flags & MNT_RDONLY)
+ to->f_flag |= ST_RDONLY;
+ if( from->f_flags & MNT_NOSUID)
+ to->f_flag |= ST_NOSUID;
+
+ return;
+}
+
+
+int
+fstatvfs(int fildes, struct statvfs *buf)
+{
+ int rv;
+ struct statfs cvt;
+
+ if ((rv = fstatfs(fildes, &cvt)) == 0)
+ cvt_statfs_to_statvfs(&cvt, buf);
+
+ return(rv);
+}
+
+
+int
+statvfs(const char * __restrict path, struct statvfs * __restrict buf)
+{
+ int rv;
+ struct statfs cvt;
+
+ if ((rv = statfs(path, &cvt)) == 0)
+ cvt_statfs_to_statvfs(&cvt, buf);
+
+ return(rv);
+}
+
+/* EOF */
--- /dev/null
+.\" Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+.\"
+.\" @APPLE_LICENSE_HEADER_START@
+.\"
+.\" The contents of this file constitute Original Code as defined in and
+.\" are subject to the Apple Public Source License Version 1.1 (the
+.\" "License"). You may not use this file except in compliance with the
+.\" License. Please obtain a copy of the License at
+.\" http://www.apple.com/publicsource and read it before using this file.
+.\"
+.\" This Original Code and all software distributed under the License are
+.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+.\" License for the specific language governing rights and limitations
+.\" under the License.
+.\"
+.\" @APPLE_LICENSE_HEADER_END@
+.\"
+.Dd December 20, 2003
+.Dt tcgetsid 3
+.Os
+.Sh NAME
+.Nm tcgetsid
+.Nd get the process group ID for the session leader for the controlling terminal
+.Sh SYNOPSIS
+.In termios.h
+.Ft pid_t
+.Fn tcgetsid "int fildes"
+.Sh DESCRIPTION
+The
+.Fn tcgetsid
+function obtains the process group ID of the session for which the terminal
+specified by
+.Fa fildes
+is the controlling terminal.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn tcgetsid
+returns the process group ID associated with the terminal.
+Otherwise, a value of
+.Po Vt pid_t Pc Ns -1
+is returned and
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn tcgetsid
+function will fail if:
+.Bl -tag -width Er
+.It Bq Er EACCES
+The
+.Vt fildes
+argument is not associated with a controlling terminal.
+.It Bq Er EBADF
+The
+.Vt fildes
+argument is not a valid file descriptor.
+.It Bq Er ENOTTY
+The file associated with
+.Vt fildes
+is not a terminal.
+.El
+.Sh SEE ALSO
+.Xr getsid 2 ,
+.Xr setpgid 2 ,
+.Xr setsid 2 ,
+.Xr tcgetpgrp 3 ,
+.Xr termios 4
+.Sh STANDARDS
+The
+.Fn tcgetsid
+function conforms to
+.St -p1003.1-2001 .
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * tcgetsid.c
+ */
+#define COMPAT_43_TTY 1
+#include <sys/ioctl.h>
+#include <termios.h>
+
+pid_t
+tcgetsid(int fildes)
+{
+ pid_t sid;
+
+ if (ioctl(fildes, TIOCGSID, (char *)&sid) < 0)
+ return ((pid_t)-1);
+
+ return (sid);
+}
+
+/* EOF */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#define _BYTE_ORDER BYTE_ORDER
#define _LITTLE_ENDIAN LITTLE_ENDIAN
#define __ct_rune_t ct_rune_t
-#define __int32_t int32_t
-#define __int64_t int64_t
#define __va_list _BSD_VA_LIST_
/*
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: /repoman/r/ncvs/src/lib/libc/i386/_fpmath.h,v 1.2 2003/04/05 22:10:13 das Exp $
+ * $FreeBSD: src/lib/libc/i386/_fpmath.h,v 1.3 2004/01/18 07:57:01 das Exp $
*/
union IEEEl2bits {
#define mask_nbit_l(u) ((u).bits.manh &= 0x7fffffff)
+#define LDBL_MANH_SIZE 32
+#define LDBL_MANL_SIZE 32
+
#define LDBL_TO_ARRAY32(u, a) do { \
(a)[0] = (uint32_t)(u).bits.manl; \
(a)[1] = (uint32_t)(u).bits.manh; \
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*-
* Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
* Copyright (c) 2002 David Schultz <dschultz@uclink.Berkeley.EDU>
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: /repoman/r/ncvs/src/lib/libc/include/fpmath.h,v 1.1 2003/02/08 20:37:53 mike Exp $
+ * $FreeBSD: src/lib/libc/include/fpmath.h,v 1.2 2004/01/18 08:05:21 das Exp $
*/
#include <sys/endian.h>
} bits;
};
+#define DBL_MANH_SIZE 20
+#define DBL_MANL_SIZE 32
+
union IEEEd2bits {
double d;
struct {
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/<mach\/mig\.h>/;.+1,$g/<mach\/mig\.h>/d
+w
--- /dev/null
+/*-
+ * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/gdtoa/_hdtoa.c,v 1.2 2004/01/21 04:51:50 grehan Exp $");
+
+#include <float.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include "fpmath.h"
+#include "gdtoaimp.h"
+
+/* Strings values used by dtoa() */
+#define INFSTR "Infinity"
+#define NANSTR "NaN"
+
+#define DBL_BIAS (DBL_MAX_EXP - 1)
+#define LDBL_BIAS (LDBL_MAX_EXP - 1)
+
+#ifdef LDBL_IMPLICIT_NBIT
+#define LDBL_NBIT_ADJ 0
+#else
+#define LDBL_NBIT_ADJ 1
+#endif
+
+/*
+ * Efficiently compute the log2 of an integer. Uses a combination of
+ * arcane tricks found in fortune and arcane tricks not (yet) in
+ * fortune. This routine behaves similarly to fls(9).
+ */
+static int
+log2_32(uint32_t n)
+{
+
+ n |= (n >> 1);
+ n |= (n >> 2);
+ n |= (n >> 4);
+ n |= (n >> 8);
+ n |= (n >> 16);
+
+ n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1);
+ n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2);
+ n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4);
+ n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8);
+ n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16);
+ return (n - 1);
+}
+
+#if (LDBL_MANH_SIZE > 32 || LDBL_MANL_SIZE > 32)
+
+static int
+log2_64(uint64_t n)
+{
+
+ if (n >> 32 != 0)
+ return (log2_32((uint32_t)(n >> 32)) + 32);
+ else
+ return (log2_32((uint32_t)n));
+}
+
+#endif /* (LDBL_MANH_SIZE > 32 || LDBL_MANL_SIZE > 32) */
+
+/*
+ * Round up the given digit string. If the digit string is fff...f,
+ * this procedure sets it to 100...0 and returns 1 to indicate that
+ * the exponent needs to be bumped. Otherwise, 0 is returned.
+ */
+static int
+roundup(char *s0, int ndigits)
+{
+ char *s;
+
+ for (s = s0 + ndigits - 1; *s == 0xf; s--) {
+ if (s == s0) {
+ *s = 1;
+ return (1);
+ }
+ ++*s;
+ }
+ ++*s;
+ return (0);
+}
+
+/*
+ * Round the given digit string to ndigits digits according to the
+ * current rounding mode. Note that this could produce a string whose
+ * value is not representable in the corresponding floating-point
+ * type. The exponent pointed to by decpt is adjusted if necessary.
+ */
+static void
+dorounding(char *s0, int ndigits, int sign, int *decpt)
+{
+ int adjust = 0; /* do we need to adjust the exponent? */
+
+ switch (FLT_ROUNDS) {
+ case 0: /* toward zero */
+ default: /* implementation-defined */
+ break;
+ case 1: /* to nearest, halfway rounds to even */
+ if ((s0[ndigits] > 8) ||
+ (s0[ndigits] == 8 && s0[ndigits - 1] & 1))
+ adjust = roundup(s0, ndigits);
+ break;
+ case 2: /* toward +inf */
+ if (sign == 0)
+ adjust = roundup(s0, ndigits);
+ break;
+ case 3: /* toward -inf */
+ if (sign != 0)
+ adjust = roundup(s0, ndigits);
+ break;
+ }
+
+ if (adjust)
+ *decpt += 4;
+}
+
+/*
+ * This procedure converts a double-precision number in IEEE format
+ * into a string of hexadecimal digits and an exponent of 2. Its
+ * behavior is bug-for-bug compatible with dtoa() in mode 2, with the
+ * following exceptions:
+ *
+ * - An ndigits < 0 causes it to use as many digits as necessary to
+ * represent the number exactly.
+ * - The additional xdigs argument should point to either the string
+ * "0123456789ABCDEF" or the string "0123456789abcdef", depending on
+ * which case is desired.
+ * - This routine does not repeat dtoa's mistake of setting decpt
+ * to 9999 in the case of an infinity or NaN. INT_MAX is used
+ * for this purpose instead.
+ *
+ * Note that the C99 standard does not specify what the leading digit
+ * should be for non-zero numbers. For instance, 0x1.3p3 is the same
+ * as 0x2.6p2 is the same as 0x4.cp3. This implementation chooses the
+ * first digit so that subsequent digits are aligned on nibble
+ * boundaries (before rounding).
+ *
+ * Inputs: d, xdigs, ndigits
+ * Outputs: decpt, sign, rve
+ */
+char *
+__hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign,
+ char **rve)
+{
+ union IEEEd2bits u;
+ char *s, *s0;
+ int bufsize;
+ int impnbit; /* implicit normalization bit */
+ int pos;
+ int shift; /* for subnormals, # of shifts required to normalize */
+ int sigfigs; /* number of significant hex figures in result */
+
+ u.d = d;
+ *sign = u.bits.sign;
+
+ switch (fpclassify(d)) {
+ case FP_NORMAL:
+ sigfigs = (DBL_MANT_DIG + 3) / 4;
+ impnbit = 1 << ((DBL_MANT_DIG - 1) % 4);
+ *decpt = u.bits.exp - DBL_BIAS + 1 -
+ ((DBL_MANT_DIG - 1) % 4);
+ break;
+ case FP_ZERO:
+ *decpt = 1;
+ return (nrv_alloc("0", rve, 1));
+ case FP_SUBNORMAL:
+ /*
+ * The position of the highest-order bit tells us by
+ * how much to adjust the exponent (decpt). The
+ * adjustment is raised to the next nibble boundary
+ * since we will later choose the leftmost hexadecimal
+ * digit so that all subsequent digits align on nibble
+ * boundaries.
+ */
+ if (u.bits.manh != 0) {
+ pos = log2_32(u.bits.manh);
+ shift = DBL_MANH_SIZE - pos;
+ } else {
+ pos = log2_32(u.bits.manl);
+ shift = DBL_MANH_SIZE + DBL_MANL_SIZE - pos;
+ }
+ sigfigs = (3 + DBL_MANT_DIG - shift) / 4;
+ impnbit = 0;
+ *decpt = DBL_MIN_EXP - ((shift + 3) & ~(4 - 1));
+ break;
+ case FP_INFINITE:
+ *decpt = INT_MAX;
+ return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1));
+ case FP_NAN:
+ *decpt = INT_MAX;
+ return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1));
+ default:
+ abort();
+ }
+
+ /* FP_NORMAL or FP_SUBNORMAL */
+
+ if (ndigits == 0) /* dtoa() compatibility */
+ ndigits = 1;
+
+ /*
+ * For simplicity, we generate all the digits even if the
+ * caller has requested fewer.
+ */
+ bufsize = (sigfigs > ndigits) ? sigfigs : ndigits;
+ s0 = rv_alloc(bufsize);
+
+ /*
+ * We work from right to left, first adding any requested zero
+ * padding, then the least significant portion of the
+ * mantissa, followed by the most significant. The buffer is
+ * filled with the byte values 0x0 through 0xf, which are
+ * converted to xdigs[0x0] through xdigs[0xf] after the
+ * rounding phase.
+ */
+ for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--)
+ *s = 0;
+ for (; s > s0 + sigfigs - (DBL_MANL_SIZE / 4) - 1 && s > s0; s--) {
+ *s = u.bits.manl & 0xf;
+ u.bits.manl >>= 4;
+ }
+ for (; s > s0; s--) {
+ *s = u.bits.manh & 0xf;
+ u.bits.manh >>= 4;
+ }
+
+ /*
+ * At this point, we have snarfed all the bits in the
+ * mantissa, with the possible exception of the highest-order
+ * (partial) nibble, which is dealt with by the next
+ * statement. That nibble is usually in manh, but it could be
+ * in manl instead for small subnormals. We also tack on the
+ * implicit normalization bit if appropriate.
+ */
+ *s = u.bits.manh | u.bits.manl | impnbit;
+
+ /* If ndigits < 0, we are expected to auto-size the precision. */
+ if (ndigits < 0) {
+ for (ndigits = sigfigs; s0[ndigits - 1] == 0; ndigits--)
+ ;
+ }
+
+ if (sigfigs > ndigits && s0[ndigits] != 0)
+ dorounding(s0, ndigits, u.bits.sign, decpt);
+
+ s = s0 + ndigits;
+ if (rve != NULL)
+ *rve = s;
+ *s-- = '\0';
+ for (; s >= s0; s--)
+ *s = xdigs[(unsigned int)*s];
+
+ return (s0);
+}
+
+#if (LDBL_MANT_DIG > DBL_MANT_DIG)
+
+/*
+ * This is the long double version of __hdtoa().
+ *
+ * On architectures that have an explicit integer bit, unnormals and
+ * pseudo-denormals cause problems in the conversion routine, so they
+ * are ``fixed'' by effectively toggling the integer bit. Although
+ * this is not correct behavior, the hardware will not produce these
+ * formats externally.
+ */
+char *
+__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign,
+ char **rve)
+{
+ union IEEEl2bits u;
+ char *s, *s0;
+ int bufsize;
+ int impnbit; /* implicit normalization bit */
+ int pos;
+ int shift; /* for subnormals, # of shifts required to normalize */
+ int sigfigs; /* number of significant hex figures in result */
+
+ u.e = e;
+ *sign = u.bits.sign;
+
+ switch (fpclassify(e)) {
+ case FP_NORMAL:
+ sigfigs = (LDBL_MANT_DIG + 3) / 4;
+ impnbit = 1 << ((LDBL_MANT_DIG - 1) % 4);
+ *decpt = u.bits.exp - LDBL_BIAS + 1 -
+ ((LDBL_MANT_DIG - 1) % 4);
+ break;
+ case FP_ZERO:
+ *decpt = 1;
+ return (nrv_alloc("0", rve, 1));
+ case FP_SUBNORMAL:
+ /*
+ * The position of the highest-order bit tells us by
+ * how much to adjust the exponent (decpt). The
+ * adjustment is raised to the next nibble boundary
+ * since we will later choose the leftmost hexadecimal
+ * digit so that all subsequent digits align on nibble
+ * boundaries.
+ */
+#ifdef LDBL_IMPLICIT_NBIT
+ /* Don't trust the normalization bit to be off. */
+ u.bits.manh &= ~(~0ULL << (LDBL_MANH_SIZE - 1));
+#endif
+ if (u.bits.manh != 0) {
+#if LDBL_MANH_SIZE > 32
+ pos = log2_64(u.bits.manh);
+#else
+ pos = log2_32(u.bits.manh);
+#endif
+ shift = LDBL_MANH_SIZE - LDBL_NBIT_ADJ - pos;
+ } else {
+#if LDBL_MANL_SIZE > 32
+ pos = log2_64(u.bits.manl);
+#else
+ pos = log2_32(u.bits.manl);
+#endif
+ shift = LDBL_MANH_SIZE + LDBL_MANL_SIZE -
+ LDBL_NBIT_ADJ - pos;
+ }
+ sigfigs = (3 + LDBL_MANT_DIG - LDBL_NBIT_ADJ - shift) / 4;
+ *decpt = LDBL_MIN_EXP + LDBL_NBIT_ADJ -
+ ((shift + 3) & ~(4 - 1));
+ impnbit = 0;
+ break;
+ case FP_INFINITE:
+ *decpt = INT_MAX;
+ return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1));
+ case FP_NAN:
+ *decpt = INT_MAX;
+ return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1));
+ default:
+ abort();
+ }
+
+ /* FP_NORMAL or FP_SUBNORMAL */
+
+ if (ndigits == 0) /* dtoa() compatibility */
+ ndigits = 1;
+
+ /*
+ * For simplicity, we generate all the digits even if the
+ * caller has requested fewer.
+ */
+ bufsize = (sigfigs > ndigits) ? sigfigs : ndigits;
+ s0 = rv_alloc(bufsize);
+
+ /*
+ * We work from right to left, first adding any requested zero
+ * padding, then the least significant portion of the
+ * mantissa, followed by the most significant. The buffer is
+ * filled with the byte values 0x0 through 0xf, which are
+ * converted to xdigs[0x0] through xdigs[0xf] after the
+ * rounding phase.
+ */
+ for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--)
+ *s = 0;
+ for (; s > s0 + sigfigs - (LDBL_MANL_SIZE / 4) - 1 && s > s0; s--) {
+ *s = u.bits.manl & 0xf;
+ u.bits.manl >>= 4;
+ }
+ for (; s > s0; s--) {
+ *s = u.bits.manh & 0xf;
+ u.bits.manh >>= 4;
+ }
+
+ /*
+ * At this point, we have snarfed all the bits in the
+ * mantissa, with the possible exception of the highest-order
+ * (partial) nibble, which is dealt with by the next
+ * statement. That nibble is usually in manh, but it could be
+ * in manl instead for small subnormals. We also tack on the
+ * implicit normalization bit if appropriate.
+ */
+ *s = u.bits.manh | u.bits.manl | impnbit;
+
+ /* If ndigits < 0, we are expected to auto-size the precision. */
+ if (ndigits < 0) {
+ for (ndigits = sigfigs; s0[ndigits - 1] == 0; ndigits--)
+ ;
+ }
+
+ if (sigfigs > ndigits && s0[ndigits] != 0)
+ dorounding(s0, ndigits, u.bits.sign, decpt);
+
+ s = s0 + ndigits;
+ if (rve != NULL)
+ *rve = s;
+ *s-- = '\0';
+ for (; s >= s0; s--)
+ *s = xdigs[(unsigned int)*s];
+
+ return (s0);
+}
+
+#else /* (LDBL_MANT_DIG == DBL_MANT_DIG) */
+
+char *
+__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign,
+ char **rve)
+{
+
+ return (__hdtoa((double)e, xdigs, ndigits, decpt, sign, rve));
+}
+
+#endif /* (LDBL_MANT_DIG == DBL_MANT_DIG) */
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/gdtoa/_ldtoa.c,v 1.1 2003/04/05 22:10:13 das Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/gdtoa/_ldtoa.c,v 1.2 2004/01/18 07:53:49 das Exp $");
#include <float.h>
#include <inttypes.h>
break;
case FP_SUBNORMAL:
kind = STRTOG_Denormal;
+#ifdef LDBL_IMPLICIT_NBIT
+ be++;
+#endif
break;
case FP_INFINITE:
kind = STRTOG_Infinite;
ULong L, lostbits, *x;
Long e, e1;
#ifdef USE_LOCALE
- char decimalpoint = *localeconv()->decimal_point;
+ unsigned char decimalpoint = *localeconv()->decimal_point;
#else
#define decimalpoint '.'
#endif
if (e > fpi->emax) {
ovfl:
Bfree(b);
+ *bp = 0;
return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
}
irv = STRTOG_Normal;
if (n >= nbits) {
switch (fpi->rounding) {
case FPI_Round_near:
- if (n == nbits && n < 2 || any_on(b,n-1))
+ if (n == nbits && (n < 2 || any_on(b,n-1)))
goto one_bit;
break;
case FPI_Round_up:
}
}
Bfree(b);
+ *bp = 0;
return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow;
}
k = n - 1;
k = b->wds;
b = increment(b);
x = b->x;
- if (b->wds > k
+ if (irv == STRTOG_Denormal) {
+ if (nbits == fpi->nbits - 1
+ && x[nbits >> kshift] & 1 << (nbits & kmask))
+ irv = STRTOG_Normal;
+ }
+ else if (b->wds > k
|| (n = nbits & kmask) !=0
&& hi0bits(x[k-1]) < 32-n) {
rshift(b,1);
if (++e > fpi->emax)
goto ovfl;
}
- else if (irv == STRTOG_Denormal) {
- k = nbits - 1;
- if (x[k >> kshift] & 1 << (k & kmask))
- irv = STRTOG_Normal;
- }
irv |= STRTOG_Inexhi;
}
else
switch(s[1]) {
case 'x':
case 'X':
- switch(i = gethex(&s, &fpi, &exp, &bb, sign)) {
+ switch((i = gethex(&s, &fpi, &exp, &bb, sign)) & STRTOG_Retmask) {
case STRTOG_NoNumber:
s = s00;
sign = 0;
case STRTOG_Zero:
break;
default:
- copybits(bits, fpi.nbits, bb);
- Bfree(bb);
+ if (bb) {
+ copybits(bits, fpi.nbits, bb);
+ Bfree(bb);
+ }
ULtod(((U*)&rv)->L, bits, exp, i);
}
goto ret;
CFLAGS += -I${.CURDIR}/gdtoa
.include "Makefile.fbsd_begin"
-FBSDSRCS= _ldtoa.c glue.c \
+FBSDMISRCS= _hdtoa.c _ldtoa.c glue.c \
gdtoa-dmisc.c gdtoa-dtoa.c gdtoa-gdtoa.c gdtoa-gethex.c gdtoa-gmisc.c \
gdtoa-hd_init.c gdtoa-hexnan.c gdtoa-misc.c gdtoa-smisc.c gdtoa-strtoIg.c \
gdtoa-strtod.c gdtoa-strtodg.c gdtoa-strtof.c gdtoa-strtord.c gdtoa-sum.c \
.if exists(${.CURDIR}/${MACHINE_ARCH}/stdlib/gdtoa.mk)
.include "${.CURDIR}/${MACHINE_ARCH}/stdlib/gdtoa.mk"
.endif
-FBSDORIGHDRS= gdtoa.h gdtoaimp.h
+FBSDHDRS= gdtoa.h gdtoaimp.h
.include "Makefile.fbsd_end"
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#define IEEE_MC68k
#define Arith_Kind_ASL 2
#define Double_Align
+#elif defined(__ppc64__)
+#define IEEE_MC68k
+#define Arith_Kind_ASL 2
+#define Double_Align
+#define Long int
#elif defined(__i386__)
#define IEEE_8087
#define Arith_Kind_ASL 1
--- /dev/null
+--- exec.3.orig Tue May 20 15:21:01 2003
++++ exec.3 Mon Oct 27 23:21:54 2003
+@@ -39,7 +39,6 @@
+ .Nm execl ,
+ .Nm execlp ,
+ .Nm execle ,
+-.Nm exect ,
+ .Nm execv ,
+ .Nm execvp
+ .Nd execute a file
+@@ -55,8 +54,6 @@
+ .Ft int
+ .Fn execle "const char *path" "const char *arg" ...
+ .Ft int
+-.Fn exect "const char *path" "char *const argv[]" "char *const envp[]"
+-.Ft int
+ .Fn execv "const char *path" "char *const argv[]"
+ .Ft int
+ .Fn execvp "const char *file" "char *const argv[]"
+@@ -97,8 +94,7 @@
+ pointer.
+ .Pp
+ The
+-.Fn exect ,
+-.Fn execv ,
++.Fn execv
+ and
+ .Fn execvp
+ functions provide an array of pointers to null-terminated strings that
+@@ -113,9 +109,7 @@
+ .Pp
+ The
+ .Fn execle
+-and
+-.Fn exect
+-functions also specify the environment of the executed process by following
++function also specify the environment of the executed process by following
+ the
+ .Dv NULL
+ pointer that terminates the list of arguments in the argument list
+@@ -185,11 +179,6 @@
+ these functions will execute the shell with the path of
+ the file as its first argument.
+ (If this attempt fails, no further searching is done.)
+-.Pp
+-The function
+-.Fn exect
+-executes a file with the program tracing facilities enabled (see
+-.Xr ptrace 2 ) .
+ .Sh RETURN VALUES
+ If any of the
+ .Fn exec
+@@ -218,10 +207,8 @@
+ .Xr malloc 3 .
+ .Pp
+ The
+-.Fn exect
+-and
+ .Fn execv
+-functions
++function
+ may fail and set
+ .Va errno
+ for any of the errors specified for the library function
--- /dev/null
+.\"
+.\" Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+.\" 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.
+.\"
+.\" $FreeBSD: src/lib/libc/gen/fmtmsg.3,v 1.4 2002/12/04 18:57:44 ru Exp $
+.\"
+.Dd August 5, 2002
+.Dt FMTMSG 3
+.Os
+.Sh NAME
+.Nm fmtmsg
+.Nd display a detailed diagnostic message
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In fmtmsg.h
+.Ft int
+.Fo fmtmsg
+.Fa "long classification" "const char *label" "int severity"
+.Fa "const char *text" "const char *action" "const char *tag"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn fmtmsg
+function displays a detailed diagnostic message, based on
+the supplied arguments, to
+.Dv stderr
+and/or the system console.
+.Pp
+The
+.Fa classification
+argument is the bitwise inclusive
+.Tn OR
+of zero or one of the manifest constants from
+each of the classification groups below.
+The Output classification group is an exception since both
+.Dv MM_PRINT
+and
+.Dv MM_CONSOLE
+may be specified.
+.Bl -tag -width indent
+.It Output
+.Bl -tag -width ".Dv MM_CONSOLE"
+.It Dv MM_PRINT
+Output should take place on
+.Dv stderr .
+.It Dv MM_CONSOLE
+Output should take place on the system console.
+.El
+.It "Source of Condition (Major)"
+.Bl -tag -width ".Dv MM_CONSOLE"
+.It Dv MM_HARD
+The source of the condition is hardware related.
+.It Dv MM_SOFT
+The source of the condition is software related.
+.It Dv MM_FIRM
+The source of the condition is firmware related.
+.El
+.It "Source of Condition (Minor)"
+.Bl -tag -width ".Dv MM_CONSOLE"
+.It Dv MM_APPL
+The condition was detected at the application level.
+.It Dv MM_UTIL
+The condition was detected at the utility level.
+.It Dv MM_OPSYS
+The condition was detected at the operating system level.
+.El
+.It Status
+.Bl -tag -width ".Dv MM_CONSOLE"
+.It Dv MM_RECOVER
+The application can recover from the condition.
+.It Dv MM_NRECOV
+The application is unable to recover from the condition.
+.El
+.El
+.Pp
+Alternatively, the
+.Dv MM_NULLMC
+manifest constant may be used to specify no classification.
+.Pp
+The
+.Fa label
+argument indicates the source of the message.
+It is made up of two fields separated by a colon
+.Pq Ql \&: .
+The first field can be up to 10 bytes,
+and the second field can be up to 14 bytes.
+The
+.Dv MM_NULLLBL
+manifest constant may be used to specify no label.
+.Pp
+The
+.Fa severity
+argument identifies the importance of the condition.
+One of the following manifest constants should be used for this argument.
+.Bl -tag -offset indent -width ".Dv MM_WARNING"
+.It Dv MM_HALT
+The application has confronted a serious fault and is halting.
+.It Dv MM_ERROR
+The application has detected a fault.
+.It Dv MM_WARNING
+The application has detected an unusual condition,
+that could be indicative of a problem.
+.It Dv MM_INFO
+The application is providing information about a non-error condition.
+.It Dv MM_NOSEV
+No severity level supplied.
+.El
+.Pp
+The
+.Fa text
+argument details the error condition that caused the message.
+There is no limit on the size of this character string.
+The
+.Dv MM_NULLTXT
+manifest constant may be used to specify no text.
+.Pp
+The
+.Fa action
+argument details how the error-recovery process should begin.
+Upon output,
+.Fn fmtmsg
+will prefix
+.Qq Li "TO FIX:"
+to the beginning of the
+.Fa action
+argument.
+The
+.Dv MM_NULLACT
+manifest constant may be used to specify no action.
+.Pp
+The
+.Fa tag
+argument should reference online documentation for the message.
+This usually includes the
+.Fa label
+and a unique identifying number.
+An example tag is
+.Qq Li BSD:ls:168 .
+The
+.Dv MM_NULLTAG
+manifest constant may be used to specify no tag.
+.Sh RETURN VALUES
+The
+.Fn fmtmsg
+function returns
+.Dv MM_OK
+upon success,
+.Dv MM_NOMSG
+to indicate output to
+.Dv stderr
+failed,
+.Dv MM_NOCON
+to indicate output to the system console failed, or
+.Dv MM_NOTOK
+to indicate output to
+.Dv stderr
+and the system console failed.
+.Sh ENVIRONMENT
+The
+.Ev MSGVERB
+(message verbosity)
+environment variable specifies which arguments to
+.Fn fmtmsg
+will be output to
+.Dv stderr ,
+and in which order.
+.Ev MSGVERB
+should be a colon
+.Pq Ql \&:
+separated list of identifiers.
+Valid identifiers include:
+.Li label , severity , text , action ,
+and
+.Li tag .
+If invalid identifiers are specified or incorrectly separated,
+the default message verbosity and ordering will be used.
+The default ordering is equivalent to a
+.Ev MSGVERB
+with a value of
+.Qq Li label:severity:text:action:tag .
+.Sh EXAMPLES
+The code:
+.Bd -literal -offset indent
+fmtmsg(MM_UTIL | MM_PRINT, "BSD:ls", MM_ERROR,
+ "illegal option -- z", "refer to manual", "BSD:ls:001");
+.Ed
+.Pp
+will output:
+.Bd -literal -offset indent
+BSD:ls: ERROR: illegal option -- z
+TO FIX: refer to manual BSD:ls:001
+.Ed
+.Pp
+to
+.Dv stderr .
+.Pp
+The same code, with
+.Ev MSGVERB
+set to
+.Qq Li "text:severity:action:tag" ,
+produces:
+.Bd -literal -offset indent
+illegal option -- z: ERROR
+TO FIX: refer to manual BSD:ls:001
+.Ed
+.Sh SEE ALSO
+.Xr err 3 ,
+.Xr exit 3 ,
+.Xr strerror 3
+.Sh STANDARDS
+The
+.Fn fmtmsg
+function conforms to
+.St -p1003.1-2001 .
+.Sh HISTORY
+The
+.Fn fmtmsg
+function first appeared in
+.Fx 5.0 .
+.Sh BUGS
+Specifying
+.Dv MM_NULLMC
+for the
+.Fa classification
+argument makes little sense, since without an output specified,
+.Fn fmtmsg
+is unable to do anything useful.
+.Pp
+In order for
+.Fn fmtmsg
+to output to the system console, the effective
+user must have appropriate permission to write to
+.Pa /dev/console .
+This means that on most systems
+.Fn fmtmsg
+will return
+.Dv MM_NOCON
+unless the effective user is root.
--- /dev/null
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/gen/fmtmsg.c,v 1.5 2003/05/01 19:03:13 nectar Exp $");
+
+#include <fmtmsg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Default value for MSGVERB. */
+#define DFLT_MSGVERB "label:severity:text:action:tag"
+
+/* Maximum valid size for a MSGVERB. */
+#define MAX_MSGVERB sizeof(DFLT_MSGVERB)
+
+static char *printfmt(char *, long, const char *, int, const char *,
+ const char *, const char *);
+static char *nextcomp(const char *);
+static const char
+ *sevinfo(int);
+static int validmsgverb(const char *);
+
+static const char *validlist[] = {
+ "label", "severity", "text", "action", "tag", NULL
+};
+
+int
+fmtmsg(long class, const char *label, int sev, const char *text,
+ const char *action, const char *tag)
+{
+ FILE *fp;
+ char *env, *msgverb, *output;
+
+ if (class & MM_PRINT) {
+ if ((env = getenv("MSGVERB")) != NULL && *env != '\0' &&
+ strlen(env) <= strlen(DFLT_MSGVERB)) {
+ if ((msgverb = strdup(env)) == NULL)
+ return (MM_NOTOK);
+ else if (validmsgverb(msgverb) == 0) {
+ free(msgverb);
+ goto def;
+ }
+ } else {
+def:
+ if ((msgverb = strdup(DFLT_MSGVERB)) == NULL)
+ return (MM_NOTOK);
+ }
+ output = printfmt(msgverb, class, label, sev, text, action,
+ tag);
+ if (output == NULL) {
+ free(msgverb);
+ return (MM_NOTOK);
+ }
+ if (*output != '\0')
+ fprintf(stderr, "%s", output);
+ free(msgverb);
+ free(output);
+ }
+ if (class & MM_CONSOLE) {
+ output = printfmt(DFLT_MSGVERB, class, label, sev, text,
+ action, tag);
+ if (output == NULL)
+ return (MM_NOCON);
+ if (*output != '\0') {
+ if ((fp = fopen("/dev/console", "a")) == NULL) {
+ free(output);
+ return (MM_NOCON);
+ }
+ fprintf(fp, "%s", output);
+ fclose(fp);
+ }
+ free(output);
+ }
+ return (MM_OK);
+}
+
+#define INSERT_COLON \
+ if (*output != '\0') \
+ strlcat(output, ": ", size)
+#define INSERT_NEWLINE \
+ if (*output != '\0') \
+ strlcat(output, "\n", size)
+#define INSERT_SPACE \
+ if (*output != '\0') \
+ strlcat(output, " ", size)
+
+/*
+ * Returns NULL on memory allocation failure, otherwise returns a pointer to
+ * a newly malloc()'d output buffer.
+ */
+static char *
+printfmt(char *msgverb, long class, const char *label, int sev,
+ const char *text, const char *act, const char *tag)
+{
+ size_t size;
+ char *comp, *output;
+ const char *sevname;
+
+ size = 32;
+ if (label != MM_NULLLBL)
+ size += strlen(label);
+ if ((sevname = sevinfo(sev)) != NULL)
+ size += strlen(sevname);
+ if (text != MM_NULLTXT)
+ size += strlen(text);
+ if (text != MM_NULLACT)
+ size += strlen(act);
+ if (tag != MM_NULLTAG)
+ size += strlen(tag);
+
+ if ((output = malloc(size)) == NULL)
+ return (NULL);
+ *output = '\0';
+ while ((comp = nextcomp(msgverb)) != NULL) {
+ if (strcmp(comp, "label") == 0 && label != MM_NULLLBL) {
+ INSERT_COLON;
+ strlcat(output, label, size);
+ } else if (strcmp(comp, "severity") == 0 && sevname != NULL) {
+ INSERT_COLON;
+ strlcat(output, sevinfo(sev), size);
+ } else if (strcmp(comp, "text") == 0 && text != MM_NULLTXT) {
+ INSERT_COLON;
+ strlcat(output, text, size);
+ } else if (strcmp(comp, "action") == 0 && act != MM_NULLACT) {
+ INSERT_NEWLINE;
+ strlcat(output, "TO FIX: ", size);
+ strlcat(output, act, size);
+ } else if (strcmp(comp, "tag") == 0 && tag != MM_NULLTAG) {
+ INSERT_SPACE;
+ strlcat(output, tag, size);
+ }
+ }
+ INSERT_NEWLINE;
+ return (output);
+}
+
+/*
+ * Returns a component of a colon delimited string. NULL is returned to
+ * indicate that there are no remaining components. This function must be
+ * called until it returns NULL in order for the local state to be cleared.
+ */
+static char *
+nextcomp(const char *msgverb)
+{
+ static char lmsgverb[MAX_MSGVERB], *state;
+ char *retval;
+
+ if (*lmsgverb == '\0') {
+ strlcpy(lmsgverb, msgverb, sizeof(lmsgverb));
+ retval = strtok_r(lmsgverb, ":", &state);
+ } else {
+ retval = strtok_r(NULL, ":", &state);
+ }
+ if (retval == NULL)
+ *lmsgverb = '\0';
+ return (retval);
+}
+
+static const char *
+sevinfo(int sev)
+{
+
+ switch (sev) {
+ case MM_HALT:
+ return ("HALT");
+ case MM_ERROR:
+ return ("ERROR");
+ case MM_WARNING:
+ return ("WARNING");
+ case MM_INFO:
+ return ("INFO");
+ default:
+ return (NULL);
+ }
+}
+
+/*
+ * Returns 1 if the msgverb list is valid, otherwise 0.
+ */
+static int
+validmsgverb(const char *msgverb)
+{
+ char *msgcomp;
+ int i, equality;
+
+ equality = 0;
+ while ((msgcomp = nextcomp(msgverb)) != NULL) {
+ equality--;
+ for (i = 0; validlist[i] != NULL; i++) {
+ if (strcmp(msgcomp, validlist[i]) == 0)
+ equality++;
+ }
+ }
+ return (!equality);
+}
--- /dev/null
+.\" Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
+.\" 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.
+.\"
+.\" $FreeBSD: src/lib/libc/gen/fpclassify.3,v 1.3 2003/06/01 19:19:59 ru Exp $
+.\"
+.Dd February 12, 2003
+.Dt FPCLASSIFY 3
+.Os
+.Sh NAME
+.Nm fpclassify , isfinite , isinf , isnan , isnormal
+.Nd "classify a floating-point number"
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In math.h
+.Ft int
+.Fn fpclassify "real-floating x"
+.Ft int
+.Fn isfinite "real-floating x"
+.Ft int
+.Fn isinf "real-floating x"
+.Ft int
+.Fn isnan "real-floating x"
+.Ft int
+.Fn isnormal "real-floating x"
+.Sh DESCRIPTION
+The
+.Fn fpclassify
+macro takes an argument of
+.Fa x
+and returns one of the following manifest constants.
+.Bl -tag -width ".Dv FP_SUBNORMAL"
+.It Dv FP_INFINITE
+Indicates that
+.Fa x
+is an infinite number.
+.It Dv FP_NAN
+Indicates that
+.Fa x
+is not a number (NaN).
+.It Dv FP_NORMAL
+Indicates that
+.Fa x
+is a normalized number.
+.It Dv FP_SUBNORMAL
+Indicates that
+.Fa x
+is a denormalized number.
+.It Dv FP_ZERO
+Indicates that
+.Fa x
+is zero (0 or \-0).
+.El
+.Pp
+The
+.Fn isfinite
+macro returns a non-zero value if and only if its argument has
+a finite (zero, subnormal, or normal) value.
+The
+.Fn isinf ,
+.Fn isnan ,
+and
+.Fn isnormal
+macros return non-zero if and only if
+.Fa x
+is an infinity, NaN,
+or a non-zero normalized number, respectively.
+.Pp
+The symbol
+.Fn isnanf
+is provided as an alias to
+.Fn isnan
+for compatibility, and its use is deprecated.
+.Sh SEE ALSO
+.Xr isgreater 3 ,
+.Xr math 3 ,
+.Xr signbit 3
+.Sh STANDARDS
+The
+.Fn fpclassify ,
+.Fn isfinite ,
+.Fn isinf ,
+.Fn isnan ,
+and
+.Fn isnormal
+macros conform to
+.St -isoC-99 .
+.Sh HISTORY
+The
+.Fn fpclassify ,
+.Fn isfinite ,
+.Fn isinf ,
+.Fn isnan ,
+and
+.Fn isnormal
+macros were added in
+.Fx 5.1 .
+.Bx 3
+introduced
+.Fn isinf
+and
+.Fn isnan
+functions, which accepted
+.Vt double
+arguments; these have been superseded by the macros
+described above.
+.Sh BUGS
+By default, the DEC Alpha architecture does not support IEEE rounding.
+See the compiler documentation for additional details.
--- /dev/null
+--- fpclassify.3.orig Fri Oct 3 17:12:53 2003
++++ fpclassify.3 Fri Nov 7 15:46:28 2003
+@@ -107,15 +107,6 @@
+ macros conform to
+ .St -isoC-99 .
+ .Sh HISTORY
+-The
+-.Fn fpclassify ,
+-.Fn isfinite ,
+-.Fn isinf ,
+-.Fn isnan ,
+-and
+-.Fn isnormal
+-macros were added in
+-.Fx 5.1 .
+ .Bx 3
+ introduced
+ .Fn isinf
--- /dev/null
+.\"
+.\" Copyright (c) 2001 Dima Dorfman.
+.\" 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.
+.\"
+.\" $FreeBSD: src/lib/libc/gen/getpeereid.3,v 1.6 2002/12/18 10:13:54 ru Exp $
+.\"
+.Dd July 15, 2001
+.Dt GETPEEREID 3
+.Os
+.Sh NAME
+.Nm getpeereid
+.Nd get the effective credentials of a UNIX-domain peer
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In unistd.h
+.Ft int
+.Fn getpeereid "int s" "uid_t *euid" "gid_t *egid"
+.Sh DESCRIPTION
+The
+.Fn getpeereid
+function returns the effective user and group IDs of the
+peer connected to a
+.Ux Ns -domain
+socket.
+The argument
+.Fa s
+must be a
+.Ux Ns -domain
+socket
+.Pq Xr unix 4
+of type
+.Dv SOCK_STREAM
+on which either
+.Xr connect 2
+or
+.Xr listen 2
+have been called.
+The effective used ID is placed in
+.Fa euid ,
+and the effective group ID in
+.Fa egid .
+.Pp
+The credentials returned to the
+.Xr listen 2
+caller are those of its peer at the time it called
+.Xr connect 2 ;
+the credentials returned to the
+.Xr connect 2
+caller are those of its peer at the time it called
+.Xr listen 2 .
+This mechanism is reliable; there is no way for either side to influence
+the credentials returned to its peer except by calling the appropriate
+system call (i.e., either
+.Xr connect 2
+or
+.Xr listen 2 )
+under different effective credentials.
+.Pp
+One common use of this routine is for a
+.Ux Ns -domain
+server
+to verify the credentials of its client.
+Likewise, the client can verify the credentials of the server.
+.Sh IMPLEMENTATION NOTES
+On
+.Fx ,
+.Fn getpeereid
+is implemented in terms of the
+.Dv LOCAL_PEERCRED
+.Xr unix 4
+socket option.
+.Sh RETURN VALUES
+.Rv -std getpeereid
+.Sh ERRORS
+The
+.Fn getpeereid
+function
+fails if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The argument
+.Fa s
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+The argument
+.Fa s
+is a file, not a socket.
+.It Bq Er ENOTCONN
+The argument
+.Fa s
+does not refer to a socket on which
+.Xr connect 2
+or
+.Xr listen 2
+have been called.
+.It Bq Er EINVAL
+The argument
+.Fa s
+does not refer to a socket of type
+.Dv SOCK_STREAM ,
+or the kernel returned invalid data.
+.El
+.Sh SEE ALSO
+.Xr connect 2 ,
+.Xr getpeername 2 ,
+.Xr getsockname 2 ,
+.Xr getsockopt 2 ,
+.Xr listen 2 ,
+.Xr unix 4
+.Sh HISTORY
+The
+.Fn getpeereid
+function appeared in
+.Fx 4.6 .
--- /dev/null
+/*
+ * Copyright (c) 2001 Dima Dorfman.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/gen/getpeereid.c,v 1.6 2002/12/16 13:42:13 maxim Exp $");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/ucred.h>
+#include <sys/un.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+int
+getpeereid(int s, uid_t *euid, gid_t *egid)
+{
+ struct xucred xuc;
+ socklen_t xuclen;
+ int error;
+
+ xuclen = sizeof(xuc);
+ error = getsockopt(s, 0, LOCAL_PEERCRED, &xuc, &xuclen);
+ if (error != 0)
+ return (error);
+ if (xuc.cr_version != XUCRED_VERSION)
+ return (EINVAL);
+ *euid = xuc.cr_uid;
+ *egid = xuc.cr_gid;
+ return (0);
+}
--- /dev/null
+--- getprogname.3.orig Fri May 28 17:17:08 2004
++++ getprogname.3 Fri May 28 17:17:39 2004
+@@ -85,8 +85,7 @@
+ allows the aforementioned library to learn the program name without
+ modifications to the start-up code.
+ .Sh SEE ALSO
+-.Xr err 3 ,
+-.Xr setproctitle 3
++.Xr err 3
+ .Sh HISTORY
+ These functions first appeared in
+ .Nx 1.6 ,
--- /dev/null
+.\" Copyright (c) 1989, 1991, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Guido van Rossum.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)glob.3 8.3 (Berkeley) 4/16/94
+.\" $FreeBSD: src/lib/libc/gen/glob.3,v 1.23 2003/02/04 16:28:04 mikeh Exp $
+.\"
+.Dd April 16, 1994
+.Dt GLOB 3
+.Os
+.Sh NAME
+.Nm glob ,
+.Nm globfree
+.Nd generate pathnames matching a pattern
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In glob.h
+.Ft int
+.Fn glob "const char *pattern" "int flags" "int (*errfunc)(const char *, int)" "glob_t *pglob"
+.Ft void
+.Fn globfree "glob_t *pglob"
+.Sh DESCRIPTION
+The
+.Fn glob
+function
+is a pathname generator that implements the rules for file name pattern
+matching used by the shell.
+.Pp
+The include file
+.Pa glob.h
+defines the structure type
+.Fa glob_t ,
+which contains at least the following fields:
+.Bd -literal
+typedef struct {
+ int gl_pathc; /* count of total paths so far */
+ int gl_matchc; /* count of paths matching pattern */
+ int gl_offs; /* reserved at beginning of gl_pathv */
+ int gl_flags; /* returned flags */
+ char **gl_pathv; /* list of paths matching pattern */
+} glob_t;
+.Ed
+.Pp
+The argument
+.Fa pattern
+is a pointer to a pathname pattern to be expanded.
+The
+.Fn glob
+argument
+matches all accessible pathnames against the pattern and creates
+a list of the pathnames that match.
+In order to have access to a pathname,
+.Fn glob
+requires search permission on every component of a path except the last
+and read permission on each directory of any filename component of
+.Fa pattern
+that contains any of the special characters
+.Ql * ,
+.Ql ?\&
+or
+.Ql \&[ .
+.Pp
+The
+.Fn glob
+argument
+stores the number of matched pathnames into the
+.Fa gl_pathc
+field, and a pointer to a list of pointers to pathnames into the
+.Fa gl_pathv
+field.
+The first pointer after the last pathname is
+.Dv NULL .
+If the pattern does not match any pathnames, the returned number of
+matched paths is set to zero.
+.Pp
+It is the caller's responsibility to create the structure pointed to by
+.Fa pglob .
+The
+.Fn glob
+function allocates other space as needed, including the memory pointed
+to by
+.Fa gl_pathv .
+.Pp
+The argument
+.Fa flags
+is used to modify the behavior of
+.Fn glob .
+The value of
+.Fa flags
+is the bitwise inclusive
+.Tn OR
+of any of the following
+values defined in
+.Pa glob.h :
+.Bl -tag -width GLOB_ALTDIRFUNC
+.It Dv GLOB_APPEND
+Append pathnames generated to the ones from a previous call (or calls)
+to
+.Fn glob .
+The value of
+.Fa gl_pathc
+will be the total matches found by this call and the previous call(s).
+The pathnames are appended to, not merged with the pathnames returned by
+the previous call(s).
+Between calls, the caller must not change the setting of the
+.Dv GLOB_DOOFFS
+flag, nor change the value of
+.Fa gl_offs
+when
+.Dv GLOB_DOOFFS
+is set, nor (obviously) call
+.Fn globfree
+for
+.Fa pglob .
+.It Dv GLOB_DOOFFS
+Make use of the
+.Fa gl_offs
+field.
+If this flag is set,
+.Fa gl_offs
+is used to specify how many
+.Dv NULL
+pointers to prepend to the beginning
+of the
+.Fa gl_pathv
+field.
+In other words,
+.Fa gl_pathv
+will point to
+.Fa gl_offs
+.Dv NULL
+pointers,
+followed by
+.Fa gl_pathc
+pathname pointers, followed by a
+.Dv NULL
+pointer.
+.It Dv GLOB_ERR
+Causes
+.Fn glob
+to return when it encounters a directory that it cannot open or read.
+Ordinarily,
+.Fn glob
+continues to find matches.
+.It Dv GLOB_MARK
+Each pathname that is a directory that matches
+.Fa pattern
+has a slash
+appended.
+.It Dv GLOB_NOCHECK
+If
+.Fa pattern
+does not match any pathname, then
+.Fn glob
+returns a list
+consisting of only
+.Fa pattern ,
+with the number of total pathnames set to 1, and the number of matched
+pathnames set to 0.
+The effect of backslash escaping is present in the pattern returned.
+.It Dv GLOB_NOESCAPE
+By default, a backslash
+.Pq Ql \e
+character is used to escape the following character in the pattern,
+avoiding any special interpretation of the character.
+If
+.Dv GLOB_NOESCAPE
+is set, backslash escaping is disabled.
+.It Dv GLOB_NOSORT
+By default, the pathnames are sorted in ascending
+.Tn ASCII
+order;
+this flag prevents that sorting (speeding up
+.Fn glob ) .
+.El
+.Pp
+The following values may also be included in
+.Fa flags ,
+however, they are non-standard extensions to
+.St -p1003.2 .
+.Bl -tag -width GLOB_ALTDIRFUNC
+.It Dv GLOB_ALTDIRFUNC
+The following additional fields in the pglob structure have been
+initialized with alternate functions for glob to use to open, read,
+and close directories and to get stat information on names found
+in those directories.
+.Bd -literal
+void *(*gl_opendir)(const char * name);
+struct dirent *(*gl_readdir)(void *);
+void (*gl_closedir)(void *);
+int (*gl_lstat)(const char *name, struct stat *st);
+int (*gl_stat)(const char *name, struct stat *st);
+.Ed
+.Pp
+This extension is provided to allow programs such as
+.Xr restore 8
+to provide globbing from directories stored on tape.
+.It Dv GLOB_BRACE
+Pre-process the pattern string to expand
+.Ql {pat,pat,...}
+strings like
+.Xr csh 1 .
+The pattern
+.Ql {}
+is left unexpanded for historical reasons (and
+.Xr csh 1
+does the same thing to
+ease typing
+of
+.Xr find 1
+patterns).
+.It Dv GLOB_MAGCHAR
+Set by the
+.Fn glob
+function if the pattern included globbing characters.
+See the description of the usage of the
+.Fa gl_matchc
+structure member for more details.
+.It Dv GLOB_NOMAGIC
+Is the same as
+.Dv GLOB_NOCHECK
+but it only appends the
+.Fa pattern
+if it does not contain any of the special characters ``*'', ``?'' or ``[''.
+.Dv GLOB_NOMAGIC
+is provided to simplify implementing the historic
+.Xr csh 1
+globbing behavior and should probably not be used anywhere else.
+.It Dv GLOB_TILDE
+Expand patterns that start with
+.Ql ~
+to user name home directories.
+.It Dv GLOB_LIMIT
+Limit the total number of returned pathnames to the value provided in
+.Fa gl_matchc
+(default
+.Dv ARG_MAX ) .
+This option should be set for programs
+that can be coerced into a denial of service attack
+via patterns that expand to a very large number of matches,
+such as a long string of
+.Ql */../*/.. .
+.El
+.Pp
+If, during the search, a directory is encountered that cannot be opened
+or read and
+.Fa errfunc
+is
+.Pf non- Dv NULL ,
+.Fn glob
+calls
+.Fa \*(lp*errfunc\*(rp Ns ( Fa path , errno ) .
+This may be unintuitive: a pattern like
+.Ql */Makefile
+will try to
+.Xr stat 2
+.Ql foo/Makefile
+even if
+.Ql foo
+is not a directory, resulting in a
+call to
+.Fa errfunc .
+The error routine can suppress this action by testing for
+.Er ENOENT
+and
+.Er ENOTDIR ;
+however, the
+.Dv GLOB_ERR
+flag will still cause an immediate
+return when this happens.
+.Pp
+If
+.Fa errfunc
+returns non-zero,
+.Fn glob
+stops the scan and returns
+.Dv GLOB_ABORTED
+after setting
+.Fa gl_pathc
+and
+.Fa gl_pathv
+to reflect any paths already matched.
+This also happens if an error is encountered and
+.Dv GLOB_ERR
+is set in
+.Fa flags ,
+regardless of the return value of
+.Fa errfunc ,
+if called.
+If
+.Dv GLOB_ERR
+is not set and either
+.Fa errfunc
+is
+.Dv NULL
+or
+.Fa errfunc
+returns zero, the error is ignored.
+.Pp
+The
+.Fn globfree
+function frees any space associated with
+.Fa pglob
+from a previous call(s) to
+.Fn glob .
+.Sh RETURN VALUES
+On successful completion,
+.Fn glob
+returns zero.
+In addition the fields of
+.Fa pglob
+contain the values described below:
+.Bl -tag -width GLOB_NOCHECK
+.It Fa gl_pathc
+contains the total number of matched pathnames so far.
+This includes other matches from previous invocations of
+.Fn glob
+if
+.Dv GLOB_APPEND
+was specified.
+.It Fa gl_matchc
+contains the number of matched pathnames in the current invocation of
+.Fn glob .
+.It Fa gl_flags
+contains a copy of the
+.Fa flags
+argument with the bit
+.Dv GLOB_MAGCHAR
+set if
+.Fa pattern
+contained any of the special characters ``*'', ``?'' or ``['', cleared
+if not.
+.It Fa gl_pathv
+contains a pointer to a
+.Dv NULL Ns -terminated
+list of matched pathnames.
+However, if
+.Fa gl_pathc
+is zero, the contents of
+.Fa gl_pathv
+are undefined.
+.El
+.Pp
+If
+.Fn glob
+terminates due to an error, it sets errno and returns one of the
+following non-zero constants, which are defined in the include
+file
+.Aq Pa glob.h :
+.Bl -tag -width GLOB_NOCHECK
+.It Dv GLOB_NOSPACE
+An attempt to allocate memory failed, or if
+.Fa errno
+was 0
+.Dv GLOB_LIMIT
+was specified in the flags and
+.Fa pglob\->gl_matchc
+or more patterns were matched.
+.It Dv GLOB_ABORTED
+The scan was stopped because an error was encountered and either
+.Dv GLOB_ERR
+was set or
+.Fa \*(lp*errfunc\*(rp\*(lp\*(rp
+returned non-zero.
+.It Dv GLOB_NOMATCH
+The pattern did not match a pathname and
+.Dv GLOB_NOCHECK
+was not set.
+.El
+.Pp
+The arguments
+.Fa pglob\->gl_pathc
+and
+.Fa pglob\->gl_pathv
+are still set as specified above.
+.Sh EXAMPLES
+A rough equivalent of
+.Ql "ls -l *.c *.h"
+can be obtained with the
+following code:
+.Bd -literal -offset indent
+glob_t g;
+
+g.gl_offs = 2;
+glob("*.c", GLOB_DOOFFS, NULL, &g);
+glob("*.h", GLOB_DOOFFS | GLOB_APPEND, NULL, &g);
+g.gl_pathv[0] = "ls";
+g.gl_pathv[1] = "-l";
+execvp("ls", g.gl_pathv);
+.Ed
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr fnmatch 3 ,
+.Xr regexp 3
+.Sh STANDARDS
+The
+.Fn glob
+function is expected to be
+.St -p1003.2
+compatible with the exception
+that the flags
+.Dv GLOB_ALTDIRFUNC ,
+.Dv GLOB_BRACE ,
+.Dv GLOB_LIMIT ,
+.Dv GLOB_MAGCHAR ,
+.Dv GLOB_NOMAGIC ,
+and
+.Dv GLOB_TILDE ,
+and the fields
+.Fa gl_matchc
+and
+.Fa gl_flags
+should not be used by applications striving for strict
+.Tn POSIX
+conformance.
+.Sh HISTORY
+The
+.Fn glob
+and
+.Fn globfree
+functions first appeared in
+.Bx 4.4 .
+.Sh BUGS
+Patterns longer than
+.Dv MAXPATHLEN
+may cause unchecked errors.
+.Pp
+The
+.Fn glob
+argument
+may fail and set errno for any of the errors specified for the
+library routines
+.Xr stat 2 ,
+.Xr closedir 3 ,
+.Xr opendir 3 ,
+.Xr readdir 3 ,
+.Xr malloc 3 ,
+and
+.Xr free 3 .
--- /dev/null
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/gen/glob.c,v 1.20 2002/07/17 04:58:09 mikeh Exp $");
+
+/*
+ * glob(3) -- a superset of the one defined in POSIX 1003.2.
+ *
+ * The [!...] convention to negate a range is supported (SysV, Posix, ksh).
+ *
+ * Optional extra services, controlled by flags not defined by POSIX:
+ *
+ * GLOB_QUOTE:
+ * Escaping convention: \ inhibits any special meaning the following
+ * character might have (except \ at end of string is retained).
+ * GLOB_MAGCHAR:
+ * Set in gl_flags if pattern contained a globbing character.
+ * GLOB_NOMAGIC:
+ * Same as GLOB_NOCHECK, but it will only append pattern if it did
+ * not contain any magic characters. [Used in csh style globbing]
+ * GLOB_ALTDIRFUNC:
+ * Use alternately specified directory access functions.
+ * GLOB_TILDE:
+ * expand ~user/foo to the /home/dir/of/user/foo
+ * GLOB_BRACE:
+ * expand {1,2}{a,b} to 1a 1b 2a 2b
+ * gl_matchc:
+ * Number of matches in the current invocation of glob.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <glob.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "collate.h"
+
+#define DOLLAR '$'
+#define DOT '.'
+#define EOS '\0'
+#define LBRACKET '['
+#define NOT '!'
+#define QUESTION '?'
+#define QUOTE '\\'
+#define RANGE '-'
+#define RBRACKET ']'
+#define SEP '/'
+#define STAR '*'
+#define TILDE '~'
+#define UNDERSCORE '_'
+#define LBRACE '{'
+#define RBRACE '}'
+#define SLASH '/'
+#define COMMA ','
+
+#ifndef DEBUG
+
+#define M_QUOTE 0x8000
+#define M_PROTECT 0x4000
+#define M_MASK 0xffff
+#define M_ASCII 0x00ff
+
+typedef u_short Char;
+
+#else
+
+#define M_QUOTE 0x80
+#define M_PROTECT 0x40
+#define M_MASK 0xff
+#define M_ASCII 0x7f
+
+typedef char Char;
+
+#endif
+
+
+#define CHAR(c) ((Char)((c)&M_ASCII))
+#define META(c) ((Char)((c)|M_QUOTE))
+#define M_ALL META('*')
+#define M_END META(']')
+#define M_NOT META('!')
+#define M_ONE META('?')
+#define M_RNG META('-')
+#define M_SET META('[')
+#define ismeta(c) (((c)&M_QUOTE) != 0)
+
+
+static int compare(const void *, const void *);
+static int g_Ctoc(const Char *, char *, u_int);
+static int g_lstat(Char *, struct stat *, glob_t *);
+static DIR *g_opendir(Char *, glob_t *);
+static Char *g_strchr(Char *, int);
+#ifdef notdef
+static Char *g_strcat(Char *, const Char *);
+#endif
+static int g_stat(Char *, struct stat *, glob_t *);
+static int glob0(const Char *, glob_t *, int *);
+static int glob1(Char *, glob_t *, int *);
+static int glob2(Char *, Char *, Char *, Char *, glob_t *, int *);
+static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, int *);
+static int globextend(const Char *, glob_t *, int *);
+static const Char *
+ globtilde(const Char *, Char *, size_t, glob_t *);
+static int globexp1(const Char *, glob_t *, int *);
+static int globexp2(const Char *, const Char *, glob_t *, int *, int *);
+static int match(Char *, Char *, Char *);
+#ifdef DEBUG
+static void qprintf(const char *, Char *);
+#endif
+
+int
+glob(pattern, flags, errfunc, pglob)
+ const char *pattern;
+ int flags, (*errfunc)(const char *, int);
+ glob_t *pglob;
+{
+ const u_char *patnext;
+ int c, limit;
+ Char *bufnext, *bufend, patbuf[MAXPATHLEN];
+
+ patnext = (u_char *) pattern;
+ if (!(flags & GLOB_APPEND)) {
+ pglob->gl_pathc = 0;
+ pglob->gl_pathv = NULL;
+ if (!(flags & GLOB_DOOFFS))
+ pglob->gl_offs = 0;
+ }
+ if (flags & GLOB_LIMIT) {
+ limit = pglob->gl_matchc;
+ if (limit == 0)
+ limit = ARG_MAX;
+ } else
+ limit = 0;
+ pglob->gl_flags = flags & ~GLOB_MAGCHAR;
+ pglob->gl_errfunc = errfunc;
+ pglob->gl_matchc = 0;
+
+ bufnext = patbuf;
+ bufend = bufnext + MAXPATHLEN - 1;
+ if (flags & GLOB_NOESCAPE)
+ while (bufnext < bufend && (c = *patnext++) != EOS)
+ *bufnext++ = c;
+ else {
+ /* Protect the quoted characters. */
+ while (bufnext < bufend && (c = *patnext++) != EOS)
+ if (c == QUOTE) {
+ if ((c = *patnext++) == EOS) {
+ c = QUOTE;
+ --patnext;
+ }
+ *bufnext++ = c | M_PROTECT;
+ }
+ else
+ *bufnext++ = c;
+ }
+ *bufnext = EOS;
+
+ if (flags & GLOB_BRACE)
+ return globexp1(patbuf, pglob, &limit);
+ else
+ return glob0(patbuf, pglob, &limit);
+}
+
+/*
+ * Expand recursively a glob {} pattern. When there is no more expansion
+ * invoke the standard globbing routine to glob the rest of the magic
+ * characters
+ */
+static int
+globexp1(pattern, pglob, limit)
+ const Char *pattern;
+ glob_t *pglob;
+ int *limit;
+{
+ const Char* ptr = pattern;
+ int rv;
+
+ /* Protect a single {}, for find(1), like csh */
+ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
+ return glob0(pattern, pglob, limit);
+
+ while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
+ if (!globexp2(ptr, pattern, pglob, &rv, limit))
+ return rv;
+
+ return glob0(pattern, pglob, limit);
+}
+
+
+/*
+ * Recursive brace globbing helper. Tries to expand a single brace.
+ * If it succeeds then it invokes globexp1 with the new pattern.
+ * If it fails then it tries to glob the rest of the pattern and returns.
+ */
+static int
+globexp2(ptr, pattern, pglob, rv, limit)
+ const Char *ptr, *pattern;
+ glob_t *pglob;
+ int *rv, *limit;
+{
+ int i;
+ Char *lm, *ls;
+ const Char *pe, *pm, *pl;
+ Char patbuf[MAXPATHLEN];
+
+ /* copy part up to the brace */
+ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
+ continue;
+ *lm = EOS;
+ ls = lm;
+
+ /* Find the balanced brace */
+ for (i = 0, pe = ++ptr; *pe; pe++)
+ if (*pe == LBRACKET) {
+ /* Ignore everything between [] */
+ for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
+ continue;
+ if (*pe == EOS) {
+ /*
+ * We could not find a matching RBRACKET.
+ * Ignore and just look for RBRACE
+ */
+ pe = pm;
+ }
+ }
+ else if (*pe == LBRACE)
+ i++;
+ else if (*pe == RBRACE) {
+ if (i == 0)
+ break;
+ i--;
+ }
+
+ /* Non matching braces; just glob the pattern */
+ if (i != 0 || *pe == EOS) {
+ *rv = glob0(patbuf, pglob, limit);
+ return 0;
+ }
+
+ for (i = 0, pl = pm = ptr; pm <= pe; pm++)
+ switch (*pm) {
+ case LBRACKET:
+ /* Ignore everything between [] */
+ for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
+ continue;
+ if (*pm == EOS) {
+ /*
+ * We could not find a matching RBRACKET.
+ * Ignore and just look for RBRACE
+ */
+ pm = pl;
+ }
+ break;
+
+ case LBRACE:
+ i++;
+ break;
+
+ case RBRACE:
+ if (i) {
+ i--;
+ break;
+ }
+ /* FALLTHROUGH */
+ case COMMA:
+ if (i && *pm == COMMA)
+ break;
+ else {
+ /* Append the current string */
+ for (lm = ls; (pl < pm); *lm++ = *pl++)
+ continue;
+ /*
+ * Append the rest of the pattern after the
+ * closing brace
+ */
+ for (pl = pe + 1; (*lm++ = *pl++) != EOS;)
+ continue;
+
+ /* Expand the current pattern */
+#ifdef DEBUG
+ qprintf("globexp2:", patbuf);
+#endif
+ *rv = globexp1(patbuf, pglob, limit);
+
+ /* move after the comma, to the next string */
+ pl = pm + 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ *rv = 0;
+ return 0;
+}
+
+
+
+/*
+ * expand tilde from the passwd file.
+ */
+static const Char *
+globtilde(pattern, patbuf, patbuf_len, pglob)
+ const Char *pattern;
+ Char *patbuf;
+ size_t patbuf_len;
+ glob_t *pglob;
+{
+ struct passwd *pwd;
+ char *h;
+ const Char *p;
+ Char *b, *eb;
+
+ if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
+ return pattern;
+
+ /*
+ * Copy up to the end of the string or /
+ */
+ eb = &patbuf[patbuf_len - 1];
+ for (p = pattern + 1, h = (char *) patbuf;
+ h < (char *)eb && *p && *p != SLASH; *h++ = *p++)
+ continue;
+
+ *h = EOS;
+
+ if (((char *) patbuf)[0] == EOS) {
+ /*
+ * handle a plain ~ or ~/ by expanding $HOME first (iff
+ * we're not running setuid or setgid) and then trying
+ * the password file
+ */
+ if (
+#ifndef __NETBSD_SYSCALLS
+ issetugid() != 0 ||
+#endif
+ (h = getenv("HOME")) == NULL) {
+ if (((h = getlogin()) != NULL &&
+ (pwd = getpwnam(h)) != NULL) ||
+ (pwd = getpwuid(getuid())) != NULL)
+ h = pwd->pw_dir;
+ else
+ return pattern;
+ }
+ }
+ else {
+ /*
+ * Expand a ~user
+ */
+ if ((pwd = getpwnam((char*) patbuf)) == NULL)
+ return pattern;
+ else
+ h = pwd->pw_dir;
+ }
+
+ /* Copy the home directory */
+ for (b = patbuf; b < eb && *h; *b++ = *h++)
+ continue;
+
+ /* Append the rest of the pattern */
+ while (b < eb && (*b++ = *p++) != EOS)
+ continue;
+ *b = EOS;
+
+ return patbuf;
+}
+
+
+/*
+ * The main glob() routine: compiles the pattern (optionally processing
+ * quotes), calls glob1() to do the real pattern matching, and finally
+ * sorts the list (unless unsorted operation is requested). Returns 0
+ * if things went well, nonzero if errors occurred.
+ */
+static int
+glob0(pattern, pglob, limit)
+ const Char *pattern;
+ glob_t *pglob;
+ int *limit;
+{
+ const Char *qpatnext;
+ int c, err, oldpathc;
+ Char *bufnext, patbuf[MAXPATHLEN];
+
+ qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
+ oldpathc = pglob->gl_pathc;
+ bufnext = patbuf;
+
+ /* We don't need to check for buffer overflow any more. */
+ while ((c = *qpatnext++) != EOS) {
+ switch (c) {
+ case LBRACKET:
+ c = *qpatnext;
+ if (c == NOT)
+ ++qpatnext;
+ if (*qpatnext == EOS ||
+ g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
+ *bufnext++ = LBRACKET;
+ if (c == NOT)
+ --qpatnext;
+ break;
+ }
+ *bufnext++ = M_SET;
+ if (c == NOT)
+ *bufnext++ = M_NOT;
+ c = *qpatnext++;
+ do {
+ *bufnext++ = CHAR(c);
+ if (*qpatnext == RANGE &&
+ (c = qpatnext[1]) != RBRACKET) {
+ *bufnext++ = M_RNG;
+ *bufnext++ = CHAR(c);
+ qpatnext += 2;
+ }
+ } while ((c = *qpatnext++) != RBRACKET);
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ *bufnext++ = M_END;
+ break;
+ case QUESTION:
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ *bufnext++ = M_ONE;
+ break;
+ case STAR:
+ pglob->gl_flags |= GLOB_MAGCHAR;
+ /* collapse adjacent stars to one,
+ * to avoid exponential behavior
+ */
+ if (bufnext == patbuf || bufnext[-1] != M_ALL)
+ *bufnext++ = M_ALL;
+ break;
+ default:
+ *bufnext++ = CHAR(c);
+ break;
+ }
+ }
+ *bufnext = EOS;
+#ifdef DEBUG
+ qprintf("glob0:", patbuf);
+#endif
+
+ if ((err = glob1(patbuf, pglob, limit)) != 0)
+ return(err);
+
+ /*
+ * If there was no match we are going to append the pattern
+ * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
+ * and the pattern did not contain any magic characters
+ * GLOB_NOMAGIC is there just for compatibility with csh.
+ */
+ if (pglob->gl_pathc == oldpathc) {
+ if (((pglob->gl_flags & GLOB_NOCHECK) ||
+ ((pglob->gl_flags & GLOB_NOMAGIC) &&
+ !(pglob->gl_flags & GLOB_MAGCHAR))))
+ return(globextend(pattern, pglob, limit));
+ else
+ return(GLOB_NOMATCH);
+ }
+ if (!(pglob->gl_flags & GLOB_NOSORT))
+ qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
+ pglob->gl_pathc - oldpathc, sizeof(char *), compare);
+ return(0);
+}
+
+static int
+compare(p, q)
+ const void *p, *q;
+{
+ return(strcmp(*(char **)p, *(char **)q));
+}
+
+static int
+glob1(pattern, pglob, limit)
+ Char *pattern;
+ glob_t *pglob;
+ int *limit;
+{
+ Char pathbuf[MAXPATHLEN];
+
+ /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
+ if (*pattern == EOS)
+ return(0);
+ return(glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1,
+ pattern, pglob, limit));
+}
+
+/*
+ * The functions glob2 and glob3 are mutually recursive; there is one level
+ * of recursion for each segment in the pattern that contains one or more
+ * meta characters.
+ */
+static int
+glob2(pathbuf, pathend, pathend_last, pattern, pglob, limit)
+ Char *pathbuf, *pathend, *pathend_last, *pattern;
+ glob_t *pglob;
+ int *limit;
+{
+ struct stat sb;
+ Char *p, *q;
+ int anymeta;
+
+ /*
+ * Loop over pattern segments until end of pattern or until
+ * segment with meta character found.
+ */
+ for (anymeta = 0;;) {
+ if (*pattern == EOS) { /* End of pattern? */
+ *pathend = EOS;
+ if (g_lstat(pathbuf, &sb, pglob))
+ return(0);
+
+ if (((pglob->gl_flags & GLOB_MARK) &&
+ pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
+ || (S_ISLNK(sb.st_mode) &&
+ (g_stat(pathbuf, &sb, pglob) == 0) &&
+ S_ISDIR(sb.st_mode)))) {
+ if (pathend + 1 > pathend_last)
+ return (GLOB_ABORTED);
+ *pathend++ = SEP;
+ *pathend = EOS;
+ }
+ ++pglob->gl_matchc;
+ return(globextend(pathbuf, pglob, limit));
+ }
+
+ /* Find end of next segment, copy tentatively to pathend. */
+ q = pathend;
+ p = pattern;
+ while (*p != EOS && *p != SEP) {
+ if (ismeta(*p))
+ anymeta = 1;
+ if (q + 1 > pathend_last)
+ return (GLOB_ABORTED);
+ *q++ = *p++;
+ }
+
+ if (!anymeta) { /* No expansion, do next segment. */
+ pathend = q;
+ pattern = p;
+ while (*pattern == SEP) {
+ if (pathend + 1 > pathend_last)
+ return (GLOB_ABORTED);
+ *pathend++ = *pattern++;
+ }
+ } else /* Need expansion, recurse. */
+ return(glob3(pathbuf, pathend, pathend_last, pattern, p,
+ pglob, limit));
+ }
+ /* NOTREACHED */
+}
+
+static int
+glob3(pathbuf, pathend, pathend_last, pattern, restpattern, pglob, limit)
+ Char *pathbuf, *pathend, *pathend_last, *pattern, *restpattern;
+ glob_t *pglob;
+ int *limit;
+{
+ struct dirent *dp;
+ DIR *dirp;
+ int err;
+ char buf[MAXPATHLEN];
+
+ /*
+ * The readdirfunc declaration can't be prototyped, because it is
+ * assigned, below, to two functions which are prototyped in glob.h
+ * and dirent.h as taking pointers to differently typed opaque
+ * structures.
+ */
+ struct dirent *(*readdirfunc)();
+
+ if (pathend > pathend_last)
+ return (GLOB_ABORTED);
+ *pathend = EOS;
+ errno = 0;
+
+ if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
+ /* TODO: don't call for ENOENT or ENOTDIR? */
+ if (pglob->gl_errfunc) {
+ if (g_Ctoc(pathbuf, buf, sizeof(buf)))
+ return (GLOB_ABORTED);
+ if (pglob->gl_errfunc(buf, errno) ||
+ pglob->gl_flags & GLOB_ERR)
+ return (GLOB_ABORTED);
+ }
+ return(0);
+ }
+
+ err = 0;
+
+ /* Search directory for matching names. */
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ readdirfunc = pglob->gl_readdir;
+ else
+ readdirfunc = readdir;
+ while ((dp = (*readdirfunc)(dirp))) {
+ u_char *sc;
+ Char *dc;
+
+ /* Initial DOT must be matched literally. */
+ if (dp->d_name[0] == DOT && *pattern != DOT)
+ continue;
+ dc = pathend;
+ sc = (u_char *) dp->d_name;
+ while (dc < pathend_last && (*dc++ = *sc++) != EOS)
+ ;
+ if (!match(pathend, pattern, restpattern)) {
+ *pathend = EOS;
+ continue;
+ }
+ err = glob2(pathbuf, --dc, pathend_last, restpattern,
+ pglob, limit);
+ if (err)
+ break;
+ }
+
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ (*pglob->gl_closedir)(dirp);
+ else
+ closedir(dirp);
+ return(err);
+}
+
+
+/*
+ * Extend the gl_pathv member of a glob_t structure to accomodate a new item,
+ * add the new item, and update gl_pathc.
+ *
+ * This assumes the BSD realloc, which only copies the block when its size
+ * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
+ * behavior.
+ *
+ * Return 0 if new item added, error code if memory couldn't be allocated.
+ *
+ * Invariant of the glob_t structure:
+ * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
+ * gl_pathv points to (gl_offs + gl_pathc + 1) items.
+ */
+static int
+globextend(path, pglob, limit)
+ const Char *path;
+ glob_t *pglob;
+ int *limit;
+{
+ char **pathv;
+ int i;
+ u_int newsize, len;
+ char *copy;
+ const Char *p;
+
+ if (*limit && pglob->gl_pathc > *limit) {
+ errno = 0;
+ return (GLOB_NOSPACE);
+ }
+
+ newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
+ pathv = pglob->gl_pathv ?
+ realloc((char *)pglob->gl_pathv, newsize) :
+ malloc(newsize);
+ if (pathv == NULL) {
+ if (pglob->gl_pathv) {
+ free(pglob->gl_pathv);
+ pglob->gl_pathv = NULL;
+ }
+ return(GLOB_NOSPACE);
+ }
+
+ if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
+ /* first time around -- clear initial gl_offs items */
+ pathv += pglob->gl_offs;
+ for (i = pglob->gl_offs; --i >= 0; )
+ *--pathv = NULL;
+ }
+ pglob->gl_pathv = pathv;
+
+ for (p = path; *p++;)
+ continue;
+ len = (size_t)(p - path);
+ if ((copy = malloc(len)) != NULL) {
+ if (g_Ctoc(path, copy, len)) {
+ free(copy);
+ return (GLOB_NOSPACE);
+ }
+ pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
+ }
+ pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
+ return(copy == NULL ? GLOB_NOSPACE : 0);
+}
+
+/*
+ * pattern matching function for filenames. Each occurrence of the *
+ * pattern causes a recursion level.
+ */
+static int
+match(name, pat, patend)
+ Char *name, *pat, *patend;
+{
+ int ok, negate_range;
+ Char c, k;
+
+ while (pat < patend) {
+ c = *pat++;
+ switch (c & M_MASK) {
+ case M_ALL:
+ if (pat == patend)
+ return(1);
+ do
+ if (match(name, pat, patend))
+ return(1);
+ while (*name++ != EOS);
+ return(0);
+ case M_ONE:
+ if (*name++ == EOS)
+ return(0);
+ break;
+ case M_SET:
+ ok = 0;
+ if ((k = *name++) == EOS)
+ return(0);
+ if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
+ ++pat;
+ while (((c = *pat++) & M_MASK) != M_END)
+ if ((*pat & M_MASK) == M_RNG) {
+ if (__collate_load_error ?
+ CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) :
+ __collate_range_cmp(CHAR(c), CHAR(k)) <= 0
+ && __collate_range_cmp(CHAR(k), CHAR(pat[1])) <= 0
+ )
+ ok = 1;
+ pat += 2;
+ } else if (c == k)
+ ok = 1;
+ if (ok == negate_range)
+ return(0);
+ break;
+ default:
+ if (*name++ != c)
+ return(0);
+ break;
+ }
+ }
+ return(*name == EOS);
+}
+
+/* Free allocated data belonging to a glob_t structure. */
+void
+globfree(pglob)
+ glob_t *pglob;
+{
+ int i;
+ char **pp;
+
+ if (pglob->gl_pathv != NULL) {
+ pp = pglob->gl_pathv + pglob->gl_offs;
+ for (i = pglob->gl_pathc; i--; ++pp)
+ if (*pp)
+ free(*pp);
+ free(pglob->gl_pathv);
+ pglob->gl_pathv = NULL;
+ }
+}
+
+static DIR *
+g_opendir(str, pglob)
+ Char *str;
+ glob_t *pglob;
+{
+ char buf[MAXPATHLEN];
+
+ if (!*str)
+ strcpy(buf, ".");
+ else {
+ if (g_Ctoc(str, buf, sizeof(buf)))
+ return (NULL);
+ }
+
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_opendir)(buf));
+
+ return(opendir(buf));
+}
+
+static int
+g_lstat(fn, sb, pglob)
+ Char *fn;
+ struct stat *sb;
+ glob_t *pglob;
+{
+ char buf[MAXPATHLEN];
+
+ if (g_Ctoc(fn, buf, sizeof(buf))) {
+ errno = ENAMETOOLONG;
+ return (-1);
+ }
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_lstat)(buf, sb));
+ return(lstat(buf, sb));
+}
+
+static int
+g_stat(fn, sb, pglob)
+ Char *fn;
+ struct stat *sb;
+ glob_t *pglob;
+{
+ char buf[MAXPATHLEN];
+
+ if (g_Ctoc(fn, buf, sizeof(buf))) {
+ errno = ENAMETOOLONG;
+ return (-1);
+ }
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC)
+ return((*pglob->gl_stat)(buf, sb));
+ return(stat(buf, sb));
+}
+
+static Char *
+g_strchr(str, ch)
+ Char *str;
+ int ch;
+{
+ do {
+ if (*str == ch)
+ return (str);
+ } while (*str++);
+ return (NULL);
+}
+
+static int
+g_Ctoc(str, buf, len)
+ const Char *str;
+ char *buf;
+ u_int len;
+{
+
+ while (len--) {
+ if ((*buf++ = *str++) == '\0')
+ return (0);
+ }
+ return (1);
+}
+
+#ifdef DEBUG
+static void
+qprintf(str, s)
+ const char *str;
+ Char *s;
+{
+ Char *p;
+
+ (void)printf("%s:\n", str);
+ for (p = s; *p; p++)
+ (void)printf("%c", CHAR(*p));
+ (void)printf("\n");
+ for (p = s; *p; p++)
+ (void)printf("%c", *p & M_PROTECT ? '"' : ' ');
+ (void)printf("\n");
+ for (p = s; *p; p++)
+ (void)printf("%c", ismeta(*p) ? '_' : ' ');
+ (void)printf("\n");
+}
+#endif
--- /dev/null
+.\" Copyright (c) 2003 David Schultz <dschultz@uclink.Berkeley.EDU>
+.\" 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.
+.\"
+.\" $FreeBSD: src/lib/libc/gen/isgreater.3,v 1.2 2003/06/01 19:19:59 ru Exp $
+.\"
+.Dd February 12, 2003
+.Dt ISGREATER 3
+.Os
+.Sh NAME
+.Nm isgreater , isgreaterequal , isless , islessequal ,
+.Nm islessgreater , isunordered
+.Nd "compare two floating-point numbers"
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In math.h
+.Ft int
+.Fn isgreater "real-floating x" "real-floating y"
+.Ft int
+.Fn isgreaterequal "real-floating x" "real-floating y"
+.Ft int
+.Fn isless "real-floating x" "real-floating y"
+.Ft int
+.Fn islessequal "real-floating x" "real-floating y"
+.Ft int
+.Fn islessgreater "real-floating x" "real-floating y"
+.Ft int
+.Fn isunordered "real-floating x" "real-floating y"
+.Sh DESCRIPTION
+Each of the macros
+.Fn isgreater ,
+.Fn isgreaterequal ,
+.Fn isless ,
+.Fn islessequal ,
+and
+.Fn islessgreater
+take arguments
+.Fa x
+and
+.Fa y
+and return a non-zero value if and only if its nominal
+relation on
+.Fa x
+and
+.Fa y
+is true.
+These macros always return zero if either
+argument is not a number (NaN), but unlike the corresponding C
+operators, they never raise a floating point exception.
+.Pp
+The
+.Fn isunordered
+macro takes arguments
+.Fa x
+and
+.Fa y
+and returns non-zero if and only if neither
+.Fa x
+nor
+.Fa y
+are NaNs.
+For any pair of floating-point values, one
+of the relationships (less, greater, equal, unordered) holds.
+.Sh SEE ALSO
+.Xr fpclassify 3 ,
+.Xr math 3 ,
+.Xr signbit 3
+.Sh STANDARDS
+The
+.Fn isgreater ,
+.Fn isgreaterequal ,
+.Fn isless ,
+.Fn islessequal ,
+.Fn islessgreater ,
+and
+.Fn isunordered
+macros conform to
+.St -isoC-99 .
+.Sh HISTORY
+The relational macros described above first appeared in
+.Fx 5.1 .
--- /dev/null
+--- isgreater.3.orig Fri Oct 3 17:12:54 2003
++++ isgreater.3 Fri Nov 7 15:44:33 2003
+@@ -97,6 +97,3 @@
+ .Fn isunordered
+ macros conform to
+ .St -isoC-99 .
+-.Sh HISTORY
+-The relational macros described above first appeared in
+-.Fx 5.1 .
---- popen.c.orig Fri Jan 3 16:15:15 2003
-+++ popen.c Sat May 3 14:05:13 2003
-@@ -55,7 +55,8 @@
+--- popen.c.orig Mon May 24 23:50:41 2004
++++ popen.c Tue May 25 00:09:39 2004
+@@ -43,6 +43,7 @@
+ #include "namespace.h"
+ #include <sys/param.h>
+ #include <sys/wait.h>
++#include <sys/socket.h>
+
+ #include <signal.h>
+ #include <errno.h>
+@@ -55,11 +56,14 @@
#include "un-namespace.h"
#include "libc_private.h"
+#include <crt_externs.h>
+#define environ (*_NSGetEnviron())
++/* 3516149 - store file descriptor and use that to close to prevent blocking */
static struct pid {
struct pid *next;
+ FILE *fp;
++ int fd;
+ pid_t pid;
+ } *pidlist;
+ static pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER;
+@@ -77,20 +81,18 @@
+ char *argv[4];
+ struct pid *p;
+
+- /*
+- * Lite2 introduced two-way popen() pipes using _socketpair().
+- * FreeBSD's pipe() is bidirectional, so we use that.
+- */
+ if (strchr(type, '+')) {
+ twoway = 1;
+ type = "r+";
++ if (socketpair(AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
++ return (NULL);
+ } else {
+ twoway = 0;
+ if ((*type != 'r' && *type != 'w') || type[1])
+ return (NULL);
++ if (pipe(pdes) < 0)
++ return (NULL);
+ }
+- if (pipe(pdes) < 0)
+- return (NULL);
+
+ if ((cur = malloc(sizeof(struct pid))) == NULL) {
+ (void)_close(pdes[0]);
+@@ -138,7 +140,7 @@
+ (void)_close(pdes[1]);
+ }
+ for (p = pidlist; p; p = p->next) {
+- (void)_close(fileno(p->fp));
++ (void)_close(p->fd);
+ }
+ _execve(_PATH_BSHELL, argv, environ);
+ _exit(127);
+@@ -149,9 +151,11 @@
+ /* Parent; assume fdopen can't fail. */
+ if (*type == 'r') {
+ iop = fdopen(pdes[0], type);
++ cur->fd = pdes[0];
+ (void)_close(pdes[1]);
+ } else {
+ iop = fdopen(pdes[1], type);
++ cur->fd = pdes[1];
+ (void)_close(pdes[0]);
+ }
+
--- /dev/null
+--- signal.3.orig Tue May 20 15:21:03 2003
++++ signal.3 Sun Nov 30 22:08:18 2003
+@@ -47,9 +47,7 @@
+ .Ft void \*(lp*
+ .Fn signal "int sig" "void \*(lp*func\*(rp\*(lpint\*(rp\*(rp\*(rp\*(lpint"
+ .Pp
+-or in
+-.Fx Ns 's
+-equivalent but easier to read typedef'd version:
++or in the equivalent but easier to read typedef'd version:
+ .Ft typedef "void \*(lp*sig_t\*(rp \*(lpint\*(rp" ;
+ .Ft sig_t
+ .Fn signal "int sig" "sig_t func"
--- /dev/null
+.\" Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
+.\" 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.
+.\"
+.\" $FreeBSD: src/lib/libc/gen/signbit.3,v 1.3 2003/02/24 22:53:20 ru Exp $
+.\"
+.Dd February 11, 2003
+.Dt SIGNBIT 3
+.Os
+.Sh NAME
+.Nm signbit
+.Nd "determine whether a floating-point number's sign is negative"
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In math.h
+.Ft int
+.Fn signbit "real-floating x"
+.Sh DESCRIPTION
+The
+.Fn signbit
+macro takes an argument of
+.Fa x
+and returns non-zero if the value of its sign is negative, otherwise 0.
+.Sh SEE ALSO
+.Xr fpclassify 3 ,
+.Xr math 3
+.Sh STANDARDS
+The
+.Fn signbit
+macro conforms to
+.St -isoC-99 .
+.Sh HISTORY
+The
+.Fn signbit
+macro was added in
+.Fx 5.1 .
--- /dev/null
+--- signbit.3.orig Fri Oct 3 17:12:55 2003
++++ signbit.3 Fri Nov 7 15:40:35 2003
+@@ -50,8 +50,3 @@
+ .Fn signbit
+ macro conforms to
+ .St -isoC-99 .
+-.Sh HISTORY
+-The
+-.Fn signbit
+-macro was added in
+-.Fx 5.1 .
--- /dev/null
+Index: sleep.3
+===================================================================
+RCS file: /cvs/root/Libc/gen/FreeBSD/sleep.3,v
+retrieving revision 1.2
+diff -u -r1.2 sleep.3
+--- sleep.3 2003/05/20 22:21:03 1.2
++++ sleep.3 2003/10/20 23:09:28
+@@ -37,7 +37,7 @@
+ .Os
+ .Sh NAME
+ .Nm sleep
+-.Nd suspend process execution for an interval measured in seconds
++.Nd suspend thread execution for an interval measured in seconds
+ .Sh LIBRARY
+ .Lb libc
+ .Sh SYNOPSIS
+@@ -47,11 +47,11 @@
+ .Sh DESCRIPTION
+ The
+ .Fn sleep
+-function suspends execution of the calling process until either
++function suspends execution of the calling thread until either
+ .Fa seconds
+-seconds have elapsed or a signal is delivered to the process and its
++seconds have elapsed or a signal is delivered to the thread and its
+ action is to invoke a signal-catching function or to terminate the
+-process.
++thread or process.
+ System activity may lengthen the sleep by an indeterminate amount.
+ .Pp
+ This function is implemented using
--- /dev/null
+.\" Copyright (c) 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sysconf.3 8.3 (Berkeley) 4/19/94
+.\" $FreeBSD: src/lib/libc/gen/sysconf.3,v 1.18 2003/09/08 19:57:14 ru Exp $
+.\"
+.Dd June 18, 2001
+.Dt SYSCONF 3
+.Os
+.Sh NAME
+.Nm sysconf
+.Nd get configurable system variables
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In unistd.h
+.Ft long
+.Fn sysconf "int name"
+.Sh DESCRIPTION
+This interface is defined by
+.St -p1003.1-88 .
+A far more complete interface is available using
+.Xr sysctl 3 .
+.Pp
+The
+.Fn sysconf
+function provides a method for applications to determine the current
+value of a configurable system limit or option variable.
+The
+.Fa name
+argument specifies the system variable to be queried.
+Symbolic constants for each name value are found in the include file
+.In unistd.h .
+Shell programmers who need access to these parameters should use the
+.Xr getconf 1
+utility.
+.Pp
+The available values are as follows:
+.Pp
+.Bl -tag -width 6n
+.Pp
+.It Li _SC_ARG_MAX
+The maximum bytes of argument to
+.Xr execve 2 .
+.It Li _SC_CHILD_MAX
+The maximum number of simultaneous processes per user id.
+.It Li _SC_CLK_TCK
+The frequency of the statistics clock in ticks per second.
+.It Li _SC_IOV_MAX
+The maximum number of elements in the I/O vector used by
+.Xr readv 2 ,
+.Xr writev 2 ,
+.Xr recvmsg 2 ,
+and
+.Xr sendmsg 2 .
+.It Li _SC_NGROUPS_MAX
+The maximum number of supplemental groups.
+.It Li _SC_NPROCESSORS_CONF
+The number of processors configured.
+.It Li _SC_NPROCESSORS_ONLN
+The number of processors currently online.
+.It Li _SC_OPEN_MAX
+The maximum number of open files per user id.
+.It Li _SC_STREAM_MAX
+The minimum maximum number of streams that a process may have open
+at any one time.
+.It Li _SC_TZNAME_MAX
+The minimum maximum number of types supported for the name of a
+timezone.
+.It Li _SC_JOB_CONTROL
+Return 1 if job control is available on this system, otherwise \-1.
+.It Li _SC_SAVED_IDS
+Returns 1 if saved set-group and saved set-user ID is available,
+otherwise \-1.
+.It Li _SC_VERSION
+The version of
+.St -p1003.1
+with which the system
+attempts to comply.
+.It Li _SC_BC_BASE_MAX
+The maximum ibase/obase values in the
+.Xr bc 1
+utility.
+.It Li _SC_BC_DIM_MAX
+The maximum array size in the
+.Xr bc 1
+utility.
+.It Li _SC_BC_SCALE_MAX
+The maximum scale value in the
+.Xr bc 1
+utility.
+.It Li _SC_BC_STRING_MAX
+The maximum string length in the
+.Xr bc 1
+utility.
+.It Li _SC_COLL_WEIGHTS_MAX
+The maximum number of weights that can be assigned to any entry of
+the LC_COLLATE order keyword in the locale definition file.
+.It Li _SC_EXPR_NEST_MAX
+The maximum number of expressions that can be nested within
+parenthesis by the
+.Xr expr 1
+utility.
+.It Li _SC_LINE_MAX
+The maximum length in bytes of a text-processing utility's input
+line.
+.It Li _SC_RE_DUP_MAX
+The maximum number of repeated occurrences of a regular expression
+permitted when using interval notation.
+.It Li _SC_2_VERSION
+The version of
+.St -p1003.2
+with which the system attempts to comply.
+.It Li _SC_2_C_BIND
+Return 1 if the system's C-language development facilities support the
+C-Language Bindings Option, otherwise \-1.
+.It Li _SC_2_C_DEV
+Return 1 if the system supports the C-Language Development Utilities Option,
+otherwise \-1.
+.It Li _SC_2_CHAR_TERM
+Return 1 if the system supports at least one terminal type capable of
+all operations described in
+.St -p1003.2 ,
+otherwise \-1.
+.It Li _SC_2_FORT_DEV
+Return 1 if the system supports the FORTRAN Development Utilities Option,
+otherwise \-1.
+.It Li _SC_2_FORT_RUN
+Return 1 if the system supports the FORTRAN Runtime Utilities Option,
+otherwise \-1.
+.It Li _SC_2_LOCALEDEF
+Return 1 if the system supports the creation of locales, otherwise \-1.
+.It Li _SC_2_SW_DEV
+Return 1 if the system supports the Software Development Utilities Option,
+otherwise \-1.
+.It Li _SC_2_UPE
+Return 1 if the system supports the User Portability Utilities Option,
+otherwise \-1.
+.El
+.Sh RETURN VALUES
+If the call to
+.Fn sysconf
+is not successful, \-1 is returned and
+.Va errno
+is set appropriately.
+Otherwise, if the variable is associated with functionality that is not
+supported, \-1 is returned and
+.Va errno
+is not modified.
+Otherwise, the current variable value is returned.
+.Sh ERRORS
+The
+.Fn sysconf
+function may fail and set
+.Va errno
+for any of the errors specified for the library function
+.Xr sysctl 3 .
+In addition, the following error may be reported:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value of the
+.Fa name
+argument is invalid.
+.El
+.Sh SEE ALSO
+.Xr getconf 1 ,
+.Xr pathconf 2 ,
+.Xr confstr 3 ,
+.Xr sysctl 3
+.Sh BUGS
+The value for _SC_STREAM_MAX is a minimum maximum, and required to be
+the same as ANSI C's FOPEN_MAX, so the returned value is a ridiculously
+small and misleading number.
+.Sh STANDARDS
+Except for the fact that values returned by
+.Fn sysconf
+may change over the lifetime of the calling process,
+this function conforms to
+.St -p1003.1-88 .
+.Sh HISTORY
+The
+.Fn sysconf
+function first appeared in
+.Bx 4.4 .
--- /dev/null
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Sean Eric Fagan of Cygnus Support.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94";
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/gen/sysconf.c,v 1.20 2002/11/17 08:54:29 dougb Exp $");
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/sysctl.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <paths.h>
+#include <pthread.h> /* we just need the limits */
+#include <time.h>
+#include <unistd.h>
+
+#include "../stdlib/atexit.h"
+#include "../stdtime/tzfile.h"
+
+#define _PATH_ZONEINFO TZDIR /* from tzfile.h */
+
+/*
+ * sysconf --
+ * get configurable system variables.
+ *
+ * XXX
+ * POSIX 1003.1 (ISO/IEC 9945-1, 4.8.1.3) states that the variable values
+ * not change during the lifetime of the calling process. This would seem
+ * to require that any change to system limits kill all running processes.
+ * A workaround might be to cache the values when they are first retrieved
+ * and then simply return the cached value on subsequent calls. This is
+ * less useful than returning up-to-date values, however.
+ */
+long
+sysconf(name)
+ int name;
+{
+ struct rlimit rl;
+ size_t len;
+ int mib[2], sverrno, value;
+ long defaultresult;
+ const char *path;
+
+ len = sizeof(value);
+ defaultresult = -1;
+
+ switch (name) {
+ case _SC_ARG_MAX:
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_ARGMAX;
+ break;
+ case _SC_CHILD_MAX:
+ if (getrlimit(RLIMIT_NPROC, &rl) != 0)
+ return (-1);
+ if (rl.rlim_cur == RLIM_INFINITY)
+ return (-1);
+ if (rl.rlim_cur > LONG_MAX) {
+ errno = EOVERFLOW;
+ return (-1);
+ }
+ return ((long)rl.rlim_cur);
+ case _SC_CLK_TCK:
+ return (CLK_TCK);
+ case _SC_NGROUPS_MAX:
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_NGROUPS;
+ break;
+ case _SC_OPEN_MAX:
+ case _SC_STREAM_MAX: /* assume fds run out before memory does */
+ if (getrlimit(RLIMIT_NOFILE, &rl) != 0)
+ return (-1);
+ if (rl.rlim_cur == RLIM_INFINITY)
+ return (-1);
+ if (rl.rlim_cur > LONG_MAX) {
+ errno = EOVERFLOW;
+ return (-1);
+ }
+ return ((long)rl.rlim_cur);
+ case _SC_JOB_CONTROL:
+ return (_POSIX_JOB_CONTROL);
+ case _SC_SAVED_IDS:
+ /* XXX - must be 1 */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_SAVED_IDS;
+ goto yesno;
+ case _SC_VERSION:
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_POSIX1;
+ break;
+ case _SC_BC_BASE_MAX:
+ return (BC_BASE_MAX);
+ case _SC_BC_DIM_MAX:
+ return (BC_DIM_MAX);
+ case _SC_BC_SCALE_MAX:
+ return (BC_SCALE_MAX);
+ case _SC_BC_STRING_MAX:
+ return (BC_STRING_MAX);
+ case _SC_COLL_WEIGHTS_MAX:
+ return (COLL_WEIGHTS_MAX);
+ case _SC_EXPR_NEST_MAX:
+ return (EXPR_NEST_MAX);
+ case _SC_LINE_MAX:
+ return (LINE_MAX);
+ case _SC_RE_DUP_MAX:
+ return (RE_DUP_MAX);
+ case _SC_2_VERSION:
+ /*
+ * This is something of a lie, but it would be silly at
+ * this point to try to deduce this from the contents
+ * of the filesystem.
+ */
+ return (_POSIX2_VERSION);
+ case _SC_2_C_BIND:
+ return (_POSIX2_C_BIND);
+ case _SC_2_C_DEV:
+ return (_POSIX2_C_DEV);
+ case _SC_2_CHAR_TERM:
+ return (_POSIX2_CHAR_TERM);
+ case _SC_2_FORT_DEV:
+ return (_POSIX2_FORT_DEV);
+ case _SC_2_FORT_RUN:
+ return (_POSIX2_FORT_RUN);
+ case _SC_2_LOCALEDEF:
+ return (_POSIX2_LOCALEDEF);
+ case _SC_2_SW_DEV:
+ return (_POSIX2_SW_DEV);
+ case _SC_2_UPE:
+ return (_POSIX2_UPE);
+ case _SC_TZNAME_MAX:
+ path = _PATH_ZONEINFO;
+do_NAME_MAX:
+ sverrno = errno;
+ errno = 0;
+ value = pathconf(path, _PC_NAME_MAX);
+ if (value == -1 && errno != 0)
+ return (-1);
+ errno = sverrno;
+ return (value);
+
+ case _SC_ASYNCHRONOUS_IO:
+#if _POSIX_ASYNCHRONOUS_IO == 0
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_ASYNCHRONOUS_IO;
+ break;
+#else
+ return (_POSIX_ASYNCHRONOUS_IO);
+#endif
+ case _SC_MAPPED_FILES:
+ return (_POSIX_MAPPED_FILES);
+ case _SC_MEMLOCK:
+ return (_POSIX_MEMLOCK);
+ case _SC_MEMLOCK_RANGE:
+ return (_POSIX_MEMLOCK_RANGE);
+ case _SC_MEMORY_PROTECTION:
+ return (_POSIX_MEMORY_PROTECTION);
+ case _SC_MESSAGE_PASSING:
+#if _POSIX_MESSAGE_PASSING == 0
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_MESSAGE_PASSING;
+ goto yesno;
+#else
+ return (_POSIX_MESSAGE_PASSING);
+#endif
+ case _SC_PRIORITIZED_IO:
+#if _POSIX_PRIORITIZED_IO == 0
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_PRIORITIZED_IO;
+ goto yesno;
+#else
+ return (_POSIX_PRIORITIZED_IO);
+#endif
+ case _SC_PRIORITY_SCHEDULING:
+#if _POSIX_PRIORITY_SCHEDULING == 0
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_PRIORITY_SCHEDULING;
+ goto yesno;
+#else
+ return (_POSIX_PRIORITY_SCHEDULING);
+#endif
+ case _SC_REALTIME_SIGNALS:
+#if _POSIX_REALTIME_SIGNALS == 0
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_REALTIME_SIGNALS;
+ goto yesno;
+#else
+ return (_POSIX_REALTIME_SIGNALS);
+#endif
+ case _SC_SEMAPHORES:
+#if _POSIX_SEMAPHORES == 0
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SEMAPHORES;
+ goto yesno;
+#else
+ return (_POSIX_SEMAPHORES);
+#endif
+ case _SC_FSYNC:
+ return (_POSIX_FSYNC);
+
+ case _SC_SHARED_MEMORY_OBJECTS:
+ return (_POSIX_SHARED_MEMORY_OBJECTS);
+ case _SC_SYNCHRONIZED_IO:
+#if _POSIX_SYNCHRONIZED_IO == 0
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SYNCHRONIZED_IO;
+ goto yesno;
+#else
+ return (_POSIX_SYNCHRONIZED_IO);
+#endif
+ case _SC_TIMERS:
+#if _POSIX_TIMERS == 0
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_TIMERS;
+ goto yesno;
+#else
+ return (_POSIX_TIMERS);
+#endif
+ case _SC_AIO_LISTIO_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_AIO_LISTIO_MAX;
+ break;
+ case _SC_AIO_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_AIO_MAX;
+ break;
+ case _SC_AIO_PRIO_DELTA_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_AIO_PRIO_DELTA_MAX;
+ break;
+ case _SC_DELAYTIMER_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_DELAYTIMER_MAX;
+ goto yesno;
+ case _SC_MQ_OPEN_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_MQ_OPEN_MAX;
+ goto yesno;
+ case _SC_PAGESIZE:
+ defaultresult = getpagesize();
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_PAGESIZE;
+ goto yesno;
+ case _SC_RTSIG_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_RTSIG_MAX;
+ goto yesno;
+ case _SC_SEM_NSEMS_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SEM_NSEMS_MAX;
+ goto yesno;
+ case _SC_SEM_VALUE_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SEM_VALUE_MAX;
+ goto yesno;
+ case _SC_SIGQUEUE_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SIGQUEUE_MAX;
+ goto yesno;
+ case _SC_TIMER_MAX:
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_TIMER_MAX;
+
+yesno: if (sysctl(mib, 2, &value, &len, NULL, 0) == -1)
+ return (-1);
+ if (value == 0)
+ return (defaultresult);
+ return (value);
+
+ case _SC_2_PBS:
+ case _SC_2_PBS_ACCOUNTING:
+ case _SC_2_PBS_CHECKPOINT:
+ case _SC_2_PBS_LOCATE:
+ case _SC_2_PBS_MESSAGE:
+ case _SC_2_PBS_TRACK:
+#if _POSIX2_PBS == 0
+#error "don't know how to determine _SC_2_PBS"
+ /*
+ * This probably requires digging through the filesystem
+ * to see if the appropriate package has been installed.
+ * Since we don't currently support this option at all,
+ * it's not worth the effort to write the code now.
+ * Figuring out which of the sub-options are supported
+ * would be even more difficult, so it's probably easier
+ * to always say ``no''.
+ */
+#else
+ return (_POSIX2_PBS);
+#endif
+ case _SC_ADVISORY_INFO:
+#if _POSIX_ADVISORY_INFO == 0
+#error "_POSIX_ADVISORY_INFO"
+#else
+ return (_POSIX_ADVISORY_INFO);
+#endif
+ case _SC_BARRIERS:
+#if _POSIX_BARRIERS == 0
+#error "_POSIX_BARRIERS"
+#else
+ return (_POSIX_BARRIERS);
+#endif
+ case _SC_CLOCK_SELECTION:
+#if _POSIX_CLOCK_SELECTION == 0
+#error "_POSIX_CLOCK_SELECTION"
+#else
+ return (_POSIX_CLOCK_SELECTION);
+#endif
+ case _SC_CPUTIME:
+#if _POSIX_CPUTIME == 0
+#error "_POSIX_CPUTIME"
+#else
+ return (_POSIX_CPUTIME);
+#endif
+#ifdef notdef
+ case _SC_FILE_LOCKING:
+ /*
+ * XXX - The standard doesn't tell us how to define
+ * _POSIX_FILE_LOCKING, so we can't answer this one.
+ */
+#endif
+#if _POSIX_THREAD_SAFE_FUNCTIONS > -1
+ case _SC_GETGR_R_SIZE_MAX:
+ case _SC_GETPW_R_SIZE_MAX:
+#error "somebody needs to implement this"
+#endif
+ case _SC_HOST_NAME_MAX:
+ return (MAXHOSTNAMELEN - 1); /* does not include \0 */
+ case _SC_LOGIN_NAME_MAX:
+ return (MAXLOGNAME);
+ case _SC_MONOTONIC_CLOCK:
+#if _POSIX_MONOTONIC_CLOCK == 0
+#error "_POSIX_MONOTONIC_CLOCK"
+#else
+ return (_POSIX_MONOTONIC_CLOCK);
+#endif
+#if _POSIX_MESSAGE_PASSING > -1
+ case _SC_MQ_PRIO_MAX:
+ return (MQ_PRIO_MAX);
+#endif
+ case _SC_READER_WRITER_LOCKS:
+ return (_POSIX_READER_WRITER_LOCKS);
+ case _SC_REGEXP:
+ return (_POSIX_REGEXP);
+ case _SC_SHELL:
+ return (_POSIX_SHELL);
+ case _SC_SPAWN:
+ return (_POSIX_SPAWN);
+ case _SC_SPIN_LOCKS:
+ return (_POSIX_SPIN_LOCKS);
+ case _SC_SPORADIC_SERVER:
+#if _POSIX_SPORADIC_SERVER == 0
+#error "_POSIX_SPORADIC_SERVER"
+#else
+ return (_POSIX_SPORADIC_SERVER);
+#endif
+ case _SC_THREAD_ATTR_STACKADDR:
+ return (_POSIX_THREAD_ATTR_STACKADDR);
+ case _SC_THREAD_ATTR_STACKSIZE:
+ return (_POSIX_THREAD_ATTR_STACKSIZE);
+ case _SC_THREAD_CPUTIME:
+ return (_POSIX_THREAD_CPUTIME);
+ case _SC_THREAD_DESTRUCTOR_ITERATIONS:
+ return (PTHREAD_DESTRUCTOR_ITERATIONS);
+ case _SC_THREAD_KEYS_MAX:
+ return (PTHREAD_KEYS_MAX);
+ case _SC_THREAD_PRIO_INHERIT:
+ return (_POSIX_THREAD_PRIO_INHERIT);
+ case _SC_THREAD_PRIO_PROTECT:
+ return (_POSIX_THREAD_PRIO_PROTECT);
+ case _SC_THREAD_PRIORITY_SCHEDULING:
+ return (_POSIX_THREAD_PRIORITY_SCHEDULING);
+ case _SC_THREAD_PROCESS_SHARED:
+ return (_POSIX_THREAD_PROCESS_SHARED);
+ case _SC_THREAD_SAFE_FUNCTIONS:
+ return (_POSIX_THREAD_SAFE_FUNCTIONS);
+ case _SC_THREAD_STACK_MIN:
+ return (PTHREAD_STACK_MIN);
+ case _SC_THREAD_THREADS_MAX:
+ return (PTHREAD_THREADS_MAX); /* XXX wrong type! */
+ case _SC_TIMEOUTS:
+ return (_POSIX_TIMEOUTS);
+ case _SC_THREADS:
+ return (_POSIX_THREADS);
+ case _SC_TRACE:
+#if _POSIX_TRACE == 0
+#error "_POSIX_TRACE"
+ /* While you're implementing this, also do the ones below. */
+#else
+ return (_POSIX_TRACE);
+#endif
+#if _POSIX_TRACE > -1
+ case _SC_TRACE_EVENT_FILTER:
+ return (_POSIX_TRACE_EVENT_FILTER);
+ case _SC_TRACE_INHERIT:
+ return (_POSIX_TRACE_INHERIT);
+ case _SC_TRACE_LOG:
+ return (_POSIX_TRACE_LOG);
+#endif
+ case _SC_TTY_NAME_MAX:
+ path = _PATH_DEV;
+ goto do_NAME_MAX;
+ case _SC_TYPED_MEMORY_OBJECTS:
+#if _POSIX_TYPED_MEMORY_OBJECTS == 0
+#error "_POSIX_TYPED_MEMORY_OBJECTS"
+#else
+ return (_POSIX_TYPED_MEMORY_OBJECTS);
+#endif
+ case _SC_V6_ILP32_OFF32:
+#if _V6_ILP32_OFF32 == 0
+ if (sizeof(int) * CHAR_BIT == 32 &&
+ sizeof(int) == sizeof(long) &&
+ sizeof(long) == sizeof(void *) &&
+ sizeof(void *) == sizeof(off_t))
+ return 1;
+ else
+ return -1;
+#else
+ return (_V6_ILP32_OFF32);
+#endif
+ case _SC_V6_ILP32_OFFBIG:
+#if _V6_ILP32_OFFBIG == 0
+ if (sizeof(int) * CHAR_BIT == 32 &&
+ sizeof(int) == sizeof(long) &&
+ sizeof(long) == sizeof(void *) &&
+ sizeof(off_t) * CHAR_BIT >= 64)
+ return 1;
+ else
+ return -1;
+#else
+ return (_V6_ILP32_OFFBIG);
+#endif
+ case _SC_V6_LP64_OFF64:
+#if _V6_LP64_OFF64 == 0
+ if (sizeof(int) * CHAR_BIT == 32 &&
+ sizeof(long) * CHAR_BIT == 64 &&
+ sizeof(long) == sizeof(void *) &&
+ sizeof(void *) == sizeof(off_t))
+ return 1;
+ else
+ return -1;
+#else
+ return (_V6_LP64_OFF64);
+#endif
+ case _SC_V6_LPBIG_OFFBIG:
+#if _V6_LPBIG_OFFBIG == 0
+ if (sizeof(int) * CHAR_BIT >= 32 &&
+ sizeof(long) * CHAR_BIT >= 64 &&
+ sizeof(void *) * CHAR_BIT >= 64 &&
+ sizeof(off_t) * CHAR_BIT >= 64)
+ return 1;
+ else
+ return -1;
+#else
+ return (_V6_LPBIG_OFFBIG);
+#endif
+ case _SC_ATEXIT_MAX:
+ return (ATEXIT_SIZE);
+ case _SC_IOV_MAX:
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_IOV_MAX;
+ break;
+ case _SC_XOPEN_CRYPT:
+ return (_XOPEN_CRYPT);
+ case _SC_XOPEN_ENH_I18N:
+ return (_XOPEN_ENH_I18N);
+ case _SC_XOPEN_LEGACY:
+ return (_XOPEN_LEGACY);
+ case _SC_XOPEN_REALTIME:
+#if _XOPEN_REALTIME == 0
+ sverrno = errno;
+ value = sysconf(_SC_ASYNCHRONOUS_IO) > 0 &&
+ sysconf(_SC_MEMLOCK) > 0 &&
+ sysconf(_SC_MEMLOCK_RANGE) > 0 &&
+ sysconf(_SC_MESSAGE_PASSING) > 0 &&
+ sysconf(_SC_PRIORITY_SCHEDULING) > 0 &&
+ sysconf(_SC_REALTIME_SIGNALS) > 0 &&
+ sysconf(_SC_SEMAPHORES) > 0 &&
+ sysconf(_SC_SHARED_MEMORY_OBJECTS) > 0 &&
+ sysconf(_SC_SYNCHRONIZED_IO) > 0 &&
+ sysconf(_SC_TIMERS) > 0;
+ errno = sverrno;
+ if (value)
+ return (200112L);
+ else
+ return (-1);
+#else
+ return (_XOPEN_REALTIME);
+#endif
+ case _SC_XOPEN_REALTIME_THREADS:
+#if _XOPEN_REALTIME_THREADS == 0
+#error "_XOPEN_REALTIME_THREADS"
+#else
+ return (_XOPEN_REALTIME_THREADS);
+#endif
+ case _SC_XOPEN_SHM:
+ sverrno = errno;
+ if (sysctlbyname("kern.ipc.shmmin", &value, &len, NULL,
+ 0) == -1) {
+ errno = sverrno;
+ return (-1);
+ }
+ errno = sverrno;
+ return (1);
+ case _SC_XOPEN_STREAMS:
+ return (_XOPEN_STREAMS);
+ case _SC_XOPEN_UNIX:
+ return (_XOPEN_UNIX);
+#ifdef _XOPEN_VERSION
+ case _SC_XOPEN_VERSION:
+ return (_XOPEN_VERSION);
+#endif
+#ifdef _XOPEN_XCU_VERSION
+ case _SC_XOPEN_XCU_VERSION:
+ return (_XOPEN_XCU_VERSION);
+#endif
+ case _SC_SYMLOOP_MAX:
+ return (MAXSYMLINKS);
+ case _SC_RAW_SOCKETS:
+ return (_POSIX_RAW_SOCKETS);
+ case _SC_IPV6:
+#if _POSIX_IPV6 == 0
+ sverrno = errno;
+ value = socket(PF_INET6, SOCK_DGRAM, 0);
+ errno = sverrno;
+ if (value >= 0) {
+ close(value);
+ return (200112L);
+ } else
+ return (0);
+#else
+ return (_POSIX_IPV6);
+#endif
+
+ case _SC_NPROCESSORS_CONF:
+ case _SC_NPROCESSORS_ONLN:
+ mib[0] = CTL_HW;
+ mib[1] = HW_NCPU;
+ break;
+
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+ return (sysctl(mib, 2, &value, &len, NULL, 0) == -1 ? -1 : value);
+}
--- /dev/null
+--- sysconf.c.orig Sun Nov 17 00:54:29 2002
++++ sysconf.c Wed Apr 14 17:09:36 2004
+@@ -45,6 +45,8 @@
+ #include <sys/sysctl.h>
+ #include <sys/resource.h>
+ #include <sys/socket.h>
++#include <sys/aio.h>
++#include <sys/semaphore.h>
+
+ #include <errno.h>
+ #include <limits.h>
+@@ -53,8 +55,8 @@
+ #include <time.h>
+ #include <unistd.h>
+
+-#include "../stdlib/atexit.h"
+-#include "../stdtime/tzfile.h"
++#include "atexit.h"
++#include "tzfile.h"
+
+ #define _PATH_ZONEINFO TZDIR /* from tzfile.h */
+
+@@ -76,7 +78,7 @@
+ {
+ struct rlimit rl;
+ size_t len;
+- int mib[2], sverrno, value;
++ int mib[3], sverrno, value;
+ long defaultresult;
+ const char *path;
+
+@@ -254,76 +256,94 @@
+ return (_POSIX_TIMERS);
+ #endif
+ case _SC_AIO_LISTIO_MAX:
+- mib[0] = CTL_P1003_1B;
+- mib[1] = CTL_P1003_1B_AIO_LISTIO_MAX;
+- break;
+ case _SC_AIO_MAX:
+- mib[0] = CTL_P1003_1B;
+- mib[1] = CTL_P1003_1B_AIO_MAX;
++ mib[0] = CTL_KERN;;
++ mib[1] = KERN_AIOMAX;
+ break;
++
+ case _SC_AIO_PRIO_DELTA_MAX:
++#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_AIO_PRIO_DELTA_MAX)
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_AIO_PRIO_DELTA_MAX;
+ break;
++#else
++ return (-1);
++#endif
+ case _SC_DELAYTIMER_MAX:
++#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_DELAYTIMER_MAX)
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_DELAYTIMER_MAX;
+ goto yesno;
++#else
++ return (-1);
++#endif
+ case _SC_MQ_OPEN_MAX:
++#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_MQ_OPEN_MAX)
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_MQ_OPEN_MAX;
+ goto yesno;
++#else
++ return (-1);
++#endif
+ case _SC_PAGESIZE:
+ defaultresult = getpagesize();
++#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_PAGESIZE)
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_PAGESIZE;
+ goto yesno;
++#else
++ return defaultresult;
++#endif
+ case _SC_RTSIG_MAX:
++#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_RTSIG_MAX)
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_RTSIG_MAX;
+ goto yesno;
++#else
++ return (-1);
++#endif
+ case _SC_SEM_NSEMS_MAX:
+- mib[0] = CTL_P1003_1B;
+- mib[1] = CTL_P1003_1B_SEM_NSEMS_MAX;
+- goto yesno;
++ mib[0] = CTL_KERN;
++ mib[1] = KERN_SYSV;
++ mib[2] = KSYSV_SEMMNS;
++ return (sysctl(mib, 3, &value, &len, NULL, 0) == -1 ? -1 : value);
++
+ case _SC_SEM_VALUE_MAX:
++#if SEM_VALUE_MAX == 0
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SEM_VALUE_MAX;
+ goto yesno;
++#else
++ return (SEM_VALUE_MAX);
++#endif
+ case _SC_SIGQUEUE_MAX:
++#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_SIGQUEUE_MAX)
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_SIGQUEUE_MAX;
+ goto yesno;
++#else
++ return (-1);
++#endif
+ case _SC_TIMER_MAX:
++#if defined(CTL_P1003_1B) && defined(CTL_P1003_1B_TIMER_MAX)
+ mib[0] = CTL_P1003_1B;
+ mib[1] = CTL_P1003_1B_TIMER_MAX;
++#else
++ return (-1);
++#endif
+
+ yesno: if (sysctl(mib, 2, &value, &len, NULL, 0) == -1)
+ return (-1);
+ if (value == 0)
+ return (defaultresult);
+ return (value);
+-
+ case _SC_2_PBS:
+ case _SC_2_PBS_ACCOUNTING:
+ case _SC_2_PBS_CHECKPOINT:
+ case _SC_2_PBS_LOCATE:
+ case _SC_2_PBS_MESSAGE:
+ case _SC_2_PBS_TRACK:
+-#if _POSIX2_PBS == 0
+-#error "don't know how to determine _SC_2_PBS"
+- /*
+- * This probably requires digging through the filesystem
+- * to see if the appropriate package has been installed.
+- * Since we don't currently support this option at all,
+- * it's not worth the effort to write the code now.
+- * Figuring out which of the sub-options are supported
+- * would be even more difficult, so it's probably easier
+- * to always say ``no''.
+- */
+-#else
+- return (_POSIX2_PBS);
+-#endif
++ return -1;
+ case _SC_ADVISORY_INFO:
+ #if _POSIX_ADVISORY_INFO == 0
+ #error "_POSIX_ADVISORY_INFO"
+@@ -348,18 +368,10 @@
+ #else
+ return (_POSIX_CPUTIME);
+ #endif
+-#ifdef notdef
+ case _SC_FILE_LOCKING:
+- /*
+- * XXX - The standard doesn't tell us how to define
+- * _POSIX_FILE_LOCKING, so we can't answer this one.
+- */
+-#endif
+-#if _POSIX_THREAD_SAFE_FUNCTIONS > -1
+ case _SC_GETGR_R_SIZE_MAX:
+ case _SC_GETPW_R_SIZE_MAX:
+-#error "somebody needs to implement this"
+-#endif
++ return (-1);
+ case _SC_HOST_NAME_MAX:
+ return (MAXHOSTNAMELEN - 1); /* does not include \0 */
+ case _SC_LOGIN_NAME_MAX:
+@@ -370,10 +382,8 @@
+ #else
+ return (_POSIX_MONOTONIC_CLOCK);
+ #endif
+-#if _POSIX_MESSAGE_PASSING > -1
+ case _SC_MQ_PRIO_MAX:
+- return (MQ_PRIO_MAX);
+-#endif
++ return (-1);
+ case _SC_READER_WRITER_LOCKS:
+ return (_POSIX_READER_WRITER_LOCKS);
+ case _SC_REGEXP:
+@@ -413,7 +423,11 @@
+ case _SC_THREAD_STACK_MIN:
+ return (PTHREAD_STACK_MIN);
+ case _SC_THREAD_THREADS_MAX:
++#ifdef PTHREAD_THREADS_MAX
+ return (PTHREAD_THREADS_MAX); /* XXX wrong type! */
++#else
++ return (-1);
++#endif
+ case _SC_TIMEOUTS:
+ return (_POSIX_TIMEOUTS);
+ case _SC_THREADS:
+@@ -493,9 +507,13 @@
+ case _SC_ATEXIT_MAX:
+ return (ATEXIT_SIZE);
+ case _SC_IOV_MAX:
++#ifdef KERN_IOV_MAX
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_IOV_MAX;
+ break;
++#else
++ return (-1);
++#endif
+ case _SC_XOPEN_CRYPT:
+ return (_XOPEN_CRYPT);
+ case _SC_XOPEN_ENH_I18N:
+@@ -568,11 +586,25 @@
+ return (_POSIX_IPV6);
+ #endif
+
++#ifdef _SC_NPROCESSORS_CONF
+ case _SC_NPROCESSORS_CONF:
++#endif
++#ifdef _SC_NPROCESSORS_ONLN
+ case _SC_NPROCESSORS_ONLN:
++#endif
++#if defined(_SC_NPROCESSORS_CONF) || defined(_SC_NPROCESSORS_ONLN)
+ mib[0] = CTL_HW;
+ mib[1] = HW_NCPU;
+ break;
++#endif
++ case _SC_XBS5_ILP32_OFF32:
++ return (_XBS5_ILP32_OFF32);
++ case _SC_XBS5_ILP32_OFFBIG:
++ return (_XBS5_ILP32_OFFBIG);
++ case _SC_XBS5_LP64_OFF64:
++ return (_XBS5_LP64_OFF64);
++ case _SC_XBS5_LPBIG_OFFBIG:
++ return (_XBS5_LPBIG_OFFBIG);
+
+ default:
+ errno = EINVAL;
--- /dev/null
+Index: sysctl.3
+===================================================================
+RCS file: /cvs/root/Libc/gen/FreeBSD/sysctl.3,v
+retrieving revision 1.2
+diff -u -r1.2 sysctl.3
+--- sysctl.3 2003/05/20 22:21:03 1.2
++++ sysctl.3 2003/10/21 18:31:52
+@@ -181,13 +181,21 @@
+ }
+ .Ed
+ .Pp
++Note: Implementation of
++.Fn printkproc
++-- to print whatever data deemed necessary from the large
++.Vt kinfo_proc
++structure (
++.In sysctl.h
++) -- is left as an exercise for the reader.
++.Pp
+ The top level names are defined with a CTL_ prefix in
+ .Aq Pa sys/sysctl.h ,
+ and are as follows.
+ The next and subsequent levels down are found in the include files
+ listed here, and described in separate sections below.
+ .Pp
+-.Bl -column CTLXMACHDEPXXX "Next level namesXXXXXX" -offset indent
++.Bl -column CTLXMACHDEP "Next level names" -offset indent
+ .It Sy "Name Next level names Description"
+ .It "CTL\_DEBUG sys/sysctl.h Debugging"
+ .It "CTL\_VFS sys/mount.h File system"
+@@ -196,7 +204,8 @@
+ .It "CTL\_MACHDEP sys/sysctl.h Machine dependent"
+ .It "CTL\_NET sys/socket.h Networking"
+ .It "CTL\_USER sys/sysctl.h User-level"
+-.It "CTL\_VM vm/vm_param.h Virtual memory"
++.It "CTL\_VM sys/resource.h Virtual memory (struct loadavg)"
++.It "CTL\_VM sys/vmmeter.h Virtual memory (struct vmtotal)"
+ .El
+ .Pp
+ For example, the following retrieves the maximum number of processes allowed
--- /dev/null
+--- usleep.3.orig Tue Oct 28 18:01:58 2003
++++ usleep.3 Tue Oct 28 18:07:33 2003
+@@ -37,7 +37,7 @@
+ .Os
+ .Sh NAME
+ .Nm usleep
+-.Nd suspend process execution for an interval measured in microseconds
++.Nd suspend thread execution for an interval measured in microseconds
+ .Sh LIBRARY
+ .Lb libc
+ .Sh SYNOPSIS
+@@ -47,12 +47,13 @@
+ .Sh DESCRIPTION
+ The
+ .Fn usleep
+-function suspends execution of the calling process until either
++function suspends execution of the calling thread until either
+ .Fa microseconds
+-microseconds have elapsed or a signal is delivered to the process and its
++microseconds have elapsed or a signal is delivered to the thread and its
+ action is to invoke a signal-catching function or to terminate the
+-process.
+-System activity may lengthen the sleep by an indeterminate amount.
++thread or process.
++The actual time slept may be longer, due to system latencies
++and possible limitations in the timer resolution of the hardware.
+ .Pp
+ This function is implemented using
+ .Xr nanosleep 2
# @(#)Makefile.inc 8.6 (Berkeley) 5/4/95
# $FreeBSD: src/lib/libc/gen/Makefile.inc,v 1.80 2001/08/17 22:09:15 dd Exp $
+# machine-dependent gen sources
+.if exists(${.CURDIR}/${MACHINE_ARCH}/gen/Makefile.inc)
+.include "${.CURDIR}/${MACHINE_ARCH}/gen/Makefile.inc"
+.endif
+
# machine-independent gen sources
-.PATH: ${.CURDIR}/${MACHINE_ARCH}/gen ${.CURDIR}/gen
+.PATH: ${.CURDIR}/gen
CFLAGS += -I${.CURDIR}/pthreads
+CFLAGS-crypt.c += -D__APPLE_PR_3509199_COMPAT__
-SRCS += NSSystemDirectories.c OSSystemInfo.c arc4random.c assert.c cache.c \
- confstr.c crypt.c devname.c disklabel.c errlst.c fts.c \
- getloadavg.c getttyent.c getusershell.c getvfsbyname.c isnan.c \
- malloc.c nanosleep.c nlist.c scalable_malloc.c setlogin.c sigsetops.c \
- stack_logging.c strtofflags.c sysconf.c syslog.c uname.c zone.c
+MISRCS += NSSystemDirectories.c OSSystemInfo.c arc4random.c assert.c cache.c \
+ confstr.c crypt.c devname.c disklabel.c errlst.c fts.c ftw.c \
+ getloadavg.c getttyent.c getusershell.c getvfsbyname.c \
+ isinf.c isnan.c \
+ malloc.c nanosleep.c nftw.c nlist.c scalable_malloc.c setlogin.c \
+ sigsetops.c stack_logging.c strtofflags.c syslog.c \
+ uname.c wordexp.c zone.c
.include "Makefile.fbsd_begin"
-FBSDSRCS = _rand48.c alarm.c basename.c clock.c closedir.c ctermid.c \
+FBSDMISRCS = _rand48.c alarm.c basename.c clock.c closedir.c ctermid.c \
daemon.c dirname.c drand48.c erand48.c err.c errno_.c exec.c \
- fmtcheck.c fnmatch.c ftok.c getbsize.c getcap.c getcwd.c gethostname.c \
- getlogin.c getmntinfo.c getpagesize.c getprogname.c isatty.c \
+ fmtcheck.c fmtmsg.c fnmatch.c ftok.c \
+ getbsize.c getcap.c getcwd.c gethostname.c getpeereid.c \
+ getlogin.c getmntinfo.c getpagesize.c getprogname.c glob.c isatty.c \
jrand48.c lcong48.c lockf.c lrand48.c mrand48.c nice.c nrand48.c \
opendir.c pause.c popen.c pselect.c psignal.c raise.c readdir.c \
readpassphrase.c rewinddir.c scandir.c seed48.c seekdir.c \
sethostname.c setmode.c setprogname.c siginterrupt.c siglist.c \
- signal.c sleep.c srand48.c stringlist.c sysctl.c sysctlbyname.c \
- sysctlnametomib.c telldir.c termios.c time.c times.c timezone.c \
+ signal.c sleep.c srand48.c stringlist.c sysconf.c sysctl.c \
+ sysctlbyname.c sysctlnametomib.c \
+ telldir.c termios.c time.c times.c timezone.c \
ttyname.c ttyslot.c ualarm.c ulimit.c unvis.c usleep.c utime.c vis.c \
wait.c wait3.c waitpid.c
-FBSDORIGHDRS = rand48.h telldir.h
+FBSDHDRS = rand48.h telldir.h
.include "Makefile.fbsd_end"
-
-# machine-dependent gen sources
-.if exists(${.CURDIR}/${MACHINE_ARCH}/gen/Makefile.inc)
-.include "${.CURDIR}/${MACHINE_ARCH}/gen/Makefile.inc"
-.endif
-
.if ${LIB} == "c"
-MAN3 += arc4random.3 confstr.3 devname.3 directory.3 fts.3 \
+MAN3 += arc4random.3 confstr.3 crypt.3 devname.3 directory.3 fts.3 ftw.3 \
getdomainname.3 getfsent.3 getgrent.3 getgrouplist.3 getloadavg.3 \
getnetgrent.3 getobjformat.3 getpeereid.3 getpwent.3 getttyent.3 \
- getusershell.3 getvfsbyname.3 glob.3 initgroups.3 isinf.3 \
+ getusershell.3 getvfsbyname.3 initgroups.3 \
malloc.3 nlist.3 pwcache.3 setjmp.3 sigsetops.3 \
- strtofflags.3 sysconf.3 syslog.3 tcgetpgrp.3 tcsendbreak.3 \
- tcsetattr.3 tcsetpgrp.3 tzset.3 uname.3 valloc.3 intro.3
+ strtofflags.3 syslog.3 tcgetpgrp.3 tcsendbreak.3 \
+ tcsetattr.3 tcsetpgrp.3 tzset.3 uname.3 valloc.3 wordexp.3 intro.3
.include "Makefile.fbsd_begin"
FBSDMAN3= alarm.3 basename.3 clock.3 ctermid.3 daemon.3 dirname.3 err.3 exec.3 \
- fmtcheck.3 fnmatch.3 ftok.3 getbsize.3 getcap.3 getcwd.3 \
- gethostname.3 getmntinfo.3 getpagesize.3 getpass.3 getprogname.3 \
+ fmtcheck.3 fmtmsg.3 fnmatch.3 fpclassify.3 ftok.3 \
+ getbsize.3 getcap.3 getcwd.3 \
+ gethostname.3 getmntinfo.3 getpagesize.3 getpass.3 \
+ getpeereid.3 getprogname.3 \
+ glob.3 isgreater.3 \
lockf.3 nice.3 pause.3 popen.3 pselect.3 psignal.3 raise.3 rand48.3 \
- readpassphrase.3 scandir.3 setmode.3 siginterrupt.3 signal.3 sleep.3 \
- stringlist.3 sysctl.3 time.3 times.3 timezone.3 ttyname.3 ualarm.3 \
+ readpassphrase.3 scandir.3 setmode.3 \
+ siginterrupt.3 signal.3 signbit.3 sleep.3 \
+ stringlist.3 sysconf.3 sysctl.3 \
+ time.3 times.3 timezone.3 ttyname.3 ualarm.3 \
ulimit.3 unvis.3 usleep.3 utime.3 vis.3
.include "Makefile.fbsd_end"
MLINKS+=arc4random.3 arc4random_addrandom.3 arc4random.3 arc4random_stir.3
MLINKS+=ctermid.3 ctermid_r.3
+MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3 crypt.3 des_setkey.3 \
+ crypt.3 des_cipher.3
MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \
directory.3 readdir.3 directory.3 readdir_r.3 directory.3 rewinddir.3 \
directory.3 seekdir.3 directory.3 telldir.3
err.3 vwarnx.3 err.3 warnc.3 err.3 warn.3 err.3 warnx.3
MLINKS+=exec.3 execl.3 exec.3 execle.3 exec.3 execlp.3 \
exec.3 execv.3 exec.3 execvp.3
+MLINKS+=fpclassify.3 isfinite.3 fpclassify.3 isinf.3 fpclassify.3 isnan.3 \
+ fpclassify.3 isnormal.3
MLINKS+=fts.3 fts_children.3 fts.3 fts_close.3 fts.3 fts_open.3 \
fts.3 fts_read.3 fts.3 fts_set.3
+MLINKS+=ftw.3 nftw.3
MLINKS+=getcap.3 cgetcap.3 getcap.3 cgetclose.3 getcap.3 cgetent.3 \
getcap.3 cgetfirst.3 getcap.3 cgetmatch.3 getcap.3 cgetnext.3 \
getcap.3 cgetnum.3 getcap.3 cgetset.3 getcap.3 cgetstr.3 \
getttyent.3 setttyent.3
MLINKS+=getusershell.3 endusershell.3 getusershell.3 setusershell.3
MLINKS+=glob.3 globfree.3
-MLINKS+=isinf.3 isnan.3 isinf.3 isnanf.3
+MLINKS+=isgreater.3 isgreaterequal.3 isgreater.3 isless.3 \
+ isgreater.3 islessequal.3 isgreater.3 islessgreater.3 \
+ isgreater.3 isunordered.3
MLINKS+=malloc.3 calloc.3 malloc.3 valloc.3 malloc.3 realloc.3 malloc.3 free.3 \
- malloc.3 malloc_size.3 malloc.3 malloc_good_size.3
+ malloc.3 malloc_size.3 malloc.3 malloc_good_size.3 malloc.3 reallocf.3
MLINKS+=popen.3 pclose.3
MLINKS+=psignal.3 sys_siglist.3 psignal.3 sys_signame.3
MLINKS+=psignal.3 strsignal.3 psignal.3 sys_siglist.3 psignal.3 sys_signame.3
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
free(p);
}
return (tlen + 1);
+
+ case _CS_POSIX_V6_ILP32_OFF32_CFLAGS:
+ case _CS_XBS5_ILP32_OFF32_CFLAGS: /* legacy */
+
+ case _CS_POSIX_V6_ILP32_OFF32_LDFLAGS:
+ case _CS_XBS5_ILP32_OFF32_LDFLAGS: /* legacy */
+
+ case _CS_POSIX_V6_ILP32_OFF32_LIBS:
+ case _CS_XBS5_ILP32_OFF32_LIBS: /* legacy */
+
+ case _CS_XBS5_ILP32_OFF32_LINTFLAGS: /* legacy */
+
+ case _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS:
+ case _CS_XBS5_ILP32_OFFBIG_CFLAGS: /* legacy */
+
+ case _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS:
+ case _CS_XBS5_ILP32_OFFBIG_LDFLAGS: /* legacy */
+
+ case _CS_POSIX_V6_ILP32_OFFBIG_LIBS:
+ case _CS_XBS5_ILP32_OFFBIG_LIBS: /* legacy */
+
+ case _CS_XBS5_ILP32_OFFBIG_LINTFLAGS: /* legacy */
+
+ case _CS_POSIX_V6_LP64_OFF64_CFLAGS:
+ case _CS_XBS5_LP64_OFF64_CFLAGS: /* legacy */
+
+ case _CS_POSIX_V6_LP64_OFF64_LDFLAGS:
+ case _CS_XBS5_LP64_OFF64_LDFLAGS: /* legacy */
+
+ case _CS_POSIX_V6_LP64_OFF64_LIBS:
+ case _CS_XBS5_LP64_OFF64_LIBS: /* legacy */
+
+ case _CS_XBS5_LP64_OFF64_LINTFLAGS: /* legacy */
+
+ case _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS:
+ case _CS_XBS5_LPBIG_OFFBIG_CFLAGS: /* legacy */
+
+ case _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS:
+ case _CS_XBS5_LPBIG_OFFBIG_LDFLAGS: /* legacy */
+
+ case _CS_POSIX_V6_LPBIG_OFFBIG_LIBS:
+ case _CS_XBS5_LPBIG_OFFBIG_LIBS: /* legacy */
+
+ case _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS: /* legacy */
+ /* No special flags... yet */
+ p = "";
+ goto docopy;
+
+ case _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS:
+ if (sizeof(long) >= 8)
+ p = "_POSIX_V6_LP64_OFF64";
+ else
+ p = "_POSIX_V6_ILP32_OFFBIG";
+
+docopy:
+ if (len != 0 && buf != NULL)
+ strlcpy(buf, p, len);
+ return (strlen(p) + 1);
+
default:
errno = EINVAL;
return (0);
--- /dev/null
+.\" $OpenBSD: crypt.3,v 1.5 1996/12/10 09:06:09 deraadt Exp $
+.\"
+.\" FreeSec: libcrypt
+.\"
+.\" Copyright (c) 1994 David Burren
+.\" 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.
+.\" 4. Neither the name of the author nor the names of other contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" 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.
+.\"
+.\" Manual page, using -mandoc macros
+.\"
+.Dd March 9, 1994
+.Dt CRYPT 3
+.Os "FreeSec 1.0"
+.Sh NAME
+.Nm crypt ,
+.Nm setkey ,
+.Nm encrypt ,
+.Nm des_setkey ,
+.Nm des_cipher ,
+.Nd DES encryption
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft char
+.Fn *crypt "const char *key" "const char *setting"
+.Ft void
+.Fn setkey "char *key"
+.Ft void
+.Fn encrypt "char *block" "int flag"
+.Ft int
+.Fn des_setkey "const char *key"
+.Ft int
+.Fn des_cipher "const char *in" "char *out" "long salt" "int count"
+.Sh DESCRIPTION
+The
+.Fn crypt
+function performs password encryption, based on the
+.Tn NBS
+Data Encryption Standard (DES).
+Additional code has been added to deter key search attempts.
+The first argument to
+.Fn crypt
+is a
+.Dv null Ns -terminated
+string, typically a user's typed password.
+The second is in one of two forms:
+if it begins with an underscore (``_'') then an extended format is used
+in interpreting both the key and the setting, as outlined below.
+.Ss Extended crypt:
+.Pp
+The
+.Ar key
+is divided into groups of 8 characters (the last group is null-padded)
+and the low-order 7 bits of each each character (56 bits per group) are
+used to form the DES key as follows:
+the first group of 56 bits becomes the initial DES key.
+For each additional group, the XOR of the encryption of the current DES
+key with itself and the group bits becomes the next DES key.
+.Pp
+The setting is a 9-character array consisting of an underscore followed
+by 4 bytes of iteration count and 4 bytes of salt.
+These are encoded as printable characters, 6 bits per character,
+least significant character first.
+The values 0 to 63 are encoded as ``./0-9A-Za-z''.
+This allows 24 bits for both
+.Fa count
+and
+.Fa salt .
+.Ss "Traditional" crypt:
+.Pp
+The first 8 bytes of the key are null-padded, and the low-order 7 bits of
+each character is used to form the 56-bit
+.Tn DES
+key.
+.Pp
+The setting is a 2-character array of the ASCII-encoded salt.
+Thus only 12 bits of
+.Fa salt
+are used.
+.Fa count
+is set to 25.
+.Ss Algorithm:
+.Pp
+The
+.Fa salt
+introduces disorder in the
+.Tn DES
+algorithm in one of 16777216 or 4096 possible ways
+(ie. with 24 or 12 bits: if bit
+.Em i
+of the
+.Ar salt
+is set, then bits
+.Em i
+and
+.Em i+24
+are swapped in the
+.Tn DES
+E-box output).
+.Pp
+The DES key is used to encrypt a 64-bit constant using
+.Ar count
+iterations of
+.Tn DES .
+The value returned is a
+.Dv null Ns -terminated
+string, 20 or 13 bytes (plus null) in length, consisting of the
+.Ar setting
+followed by the encoded 64-bit encryption.
+.Pp
+The functions,
+.Fn encrypt ,
+.Fn setkey ,
+.Fn des_setkey
+and
+.Fn des_cipher
+provide access to the
+.Tn DES
+algorithm itself.
+.Fn setkey
+is passed a 64-byte array of binary values (numeric 0 or 1).
+A 56-bit key is extracted from this array by dividing the
+array into groups of 8, and ignoring the last bit in each group.
+That bit is reserved for a byte parity check by DES, but is ignored
+by these functions.
+.Pp
+The
+.Fa block
+argument to
+.Fn encrypt
+is also a 64-byte array of binary values.
+If the value of
+.Fa flag
+is 0,
+.Fa block
+is encrypted otherwise it is decrypted.
+The result is returned in the original array
+.Fa block
+after using the key specified by
+.Fn setkey
+to process it.
+.Pp
+The argument to
+.Fn des_setkey
+is a character array of length 8.
+The least significant bit (the parity bit) in each character is ignored,
+and the remaining bits are concatenated to form a 56-bit key.
+The function
+.Fn des_cipher
+encrypts (or decrypts if
+.Fa count
+is negative) the 64-bits stored in the 8 characters at
+.Fa in
+using
+.Xr abs 3
+of
+.Fa count
+iterations of
+.Tn DES
+and stores the 64-bit result in the 8 characters at
+.Fa out
+(which may be the same as
+.Fa in
+).
+The
+.Fa salt
+specifies perturbations to the
+.Tn DES
+E-box output as described above.
+.Pp
+The function
+.Fn crypt
+returns a pointer to the encrypted value on success, and NULL on failure.
+The functions
+.Fn setkey ,
+.Fn encrypt ,
+.Fn des_setkey ,
+and
+.Fn des_cipher
+return 0 on success and 1 on failure.
+.Pp
+The
+.Fn crypt ,
+.Fn setkey
+and
+.Fn des_setkey
+functions all manipulate the same key space.
+.Sh SEE ALSO
+.Xr login 1 ,
+.Xr passwd 1 ,
+.Xr getpass 3 ,
+.Xr passwd 5
+.Sh BUGS
+The
+.Fn crypt
+function returns a pointer to static data, and subsequent calls to
+.Fn crypt
+will modify the same object.
+.Sh HISTORY
+A rotor-based
+.Fn crypt
+function appeared in
+.At v6 .
+The current style
+.Fn crypt
+first appeared in
+.At v7 .
+.Pp
+This library (FreeSec 1.0) was developed outside the United States of America
+as an unencumbered replacement for the U.S.-only libcrypt encryption
+library.
+Programs linked against the
+.Fn crypt
+interface may be exported from the U.S.A. only if they use
+.Fn crypt
+solely for authentication purposes and avoid use of
+the other programmer interfaces listed above. Special care has been taken
+in the library so that programs which only use the
+.Fn crypt
+interface do not pull in the other components.
+.Sh AUTHOR
+David Burren <davidb@werj.com.au>
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*/
+/*
+ * PR-3509199
+ *
+ * encrypt() and setkey() should return void, but were returning int. For
+ * backwards compatibility, define __APPLE_PR_3509199_COMPAT__ to continue
+ * to return int, even though unistd.h declares void. We will need to not
+ * include unistd.h so as to avoid the prototype mismatch.
+ */
+#ifndef __APPLE_PR_3509199_COMPAT__
#include <unistd.h>
+#endif /* __APPLE_PR_3509199_COMPAT__ */
#include <limits.h>
#include <pwd.h>
#include <stdlib.h>
/*
* "setkey" routine (for backwards compatibility)
*/
+#ifdef __APPLE_PR_3509199_COMPAT__
int setkey(key)
+#else /* __APPLE_PR_3509199_COMPAT__ */
+void setkey(key)
+#endif /* __APPLE_PR_3509199_COMPAT__ */
register const char *key;
{
register int i, j, k;
}
keyblock.b[i] = k;
}
+#ifdef __APPLE_PR_3509199_COMPAT__
return (des_setkey((char *)keyblock.b));
+#else /* __APPLE_PR_3509199_COMPAT__ */
+ des_setkey((char *)keyblock.b);
+#endif /* __APPLE_PR_3509199_COMPAT__ */
}
/*
* "encrypt" routine (for backwards compatibility)
*/
+#ifdef __APPLE_PR_3509199_COMPAT__
int encrypt(block, flag)
+#else /* __APPLE_PR_3509199_COMPAT__ */
+void encrypt(block, flag)
+#endif /* __APPLE_PR_3509199_COMPAT__ */
register char *block;
int flag;
{
}
cblock.b[i] = k;
}
+#ifdef __APPLE_PR_3509199_COMPAT__
if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1)))
return (1);
+#else /* __APPLE_PR_3509199_COMPAT__ */
+ (void)des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1));
+#endif /* __APPLE_PR_3509199_COMPAT__ */
for (i = 7; i >= 0; i--) {
k = cblock.b[i];
for (j = 7; j >= 0; j--) {
k >>= 1;
}
}
+#ifdef __APPLE_PR_3509199_COMPAT__
return (0);
+#endif /* __APPLE_PR_3509199_COMPAT__ */
}
#ifdef DEBUG
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
"Permission denied", /* 13 - EACCES */
"Bad address", /* 14 - EFAULT */
"Block device required", /* 15 - ENOTBLK */
- "Device busy", /* 16 - EBUSY */
+ "Resource busy", /* 16 - EBUSY */
"File exists", /* 17 - EEXIST */
"Cross-device link", /* 18 - EXDEV */
"Operation not supported by device", /* 19 - ENODEV */
"No message of desired type", /* 91 - ENOMSG */
"Illegal byte sequence", /* 92 - EILSEQ */
"Attribute not found", /* 93 - ENOATTR */
+ "Bad message", /* 94 - EBADMSG */
+ "EMULTIHOP (Reserved)", /* 95 - EMULTIHOP */
+ "No message available on STREAM", /* 96 - ENODATA */
+ "ENOLINK (Reserved)", /* 97 - ENOLINK */
+ "No STREAM resources", /* 98 - ENOSR */
+ "Not a STREAM", /* 99 - ENOSTR */
+ "Protocol error", /* 100 - EPROTO */
+ "STREAM ioctl timeout", /* 101 - ETIME */
};
const int sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]);
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+.\" $OpenBSD: ftw.3,v 1.4 2003/10/30 18:52:58 jmc Exp $
+.\"
+.\" Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.Dd May 20, 2003
+.Dt FTW 3
+.Os
+.Sh NAME
+.Nm ftw, nftw
+.Nd traverse (walk) a file tree
+.Sh SYNOPSIS
+.Fd #include <ftw.h>
+.Ft int
+.Fo ftw
+.Fa "const char *path"
+.Fa "int (*fn)(const char *, const struct stat *, int)"
+.Fa "int maxfds"
+.Fc
+.Ft int
+.Fo nftw
+.Fa "const char *path"
+.Fa "int (*fn)(const\ char\ *, const\ struct\ stat\ *, int, struct\ FTW\ *)"
+.Fa "int maxfds"
+.Fa "int flags"
+.Fc
+.Sh DESCRIPTION
+.Bf -symbolic
+These functions are provided for compatibility with legacy code.
+New code should use the
+.Xr fts 3
+functions.
+.Ef
+.Pp
+The
+.Fn ftw
+and
+.Fn nftw
+functions traverse (walk) the directory hierarchy rooted in
+.Fa path .
+For each object in the hierarchy, these functions call the function
+pointed to by
+.Fa fn .
+The
+.Fn ftw
+function passes this function a pointer to a NUL-terminated string containing
+the name of the object, a pointer to a stat structure corresponding to the
+object, and an integer flag.
+The
+.Fn nftw
+function passes the aforementioned arguments plus a pointer to a
+.Dv FTW
+structure as defined by
+.Aq Pa ftw.h
+(shown below):
+.Bd -literal
+struct FTW {
+ int base; /* offset of basename into pathname */
+ int level; /* directory depth relative to starting point */
+};
+.Ed
+.Pp
+Possible values for the flag passed to
+.Fa fn
+are:
+.Bl -tag -width FTW_DNR
+.It Dv FTW_F
+A regular file.
+.It Dv FTW_D
+A directory being visited in pre-order.
+.It Dv FTW_DNR
+A directory which cannot be read.
+The directory will not be descended into.
+.It Dv FTW_DP
+A directory being visited in post-order
+.No ( Ns Fn nftw
+only).
+.It Dv FTW_NS
+A file for which no
+.Xr stat 2
+information was available.
+The contents of the stat structure are undefined.
+.It Dv FTW_SL
+A symbolic link.
+.It Dv FTW_SLN
+A symbolic link with a non-existent target
+.No ( Ns Fn nftw
+only).
+.El
+.Pp
+The
+.Fn ftw
+function traverses the tree in pre-order.
+That is, it processes the directory before the directory's contents.
+.Pp
+The
+.Fa maxfds
+argument specifies the maximum number of file descriptors
+to keep open while traversing the tree.
+It has no effect in this implementation.
+.Pp
+The
+.Fn nftw
+function has an additional
+.Fa flags
+argument with the following possible values:
+.Bl -tag -width FTW_MOUNT
+.It Dv FTW_PHYS
+Physical walk, don't follow symbolic links.
+.It Dv FTW_MOUNT
+The walk will not cross a mount point.
+.It FTW_DEPTH
+Process directories in post-order.
+Contents of a directory are visited before the directory itself.
+By default,
+.Fn nftw
+traverses the tree in pre-order.
+.It FTW_CHDIR
+Change to a directory before reading it.
+By default,
+.Fn nftw
+will change its starting directory.
+The current working directory will be restored to its original value before
+.Fn nftw
+returns.
+.El
+.Sh RETURN VALUES
+If the tree was traversed successfully, the
+.Fn ftw
+and
+.Fn nftw
+functions return 0.
+If the function pointed to by
+.Fa fn
+returns a non-zero value,
+.Fn ftw
+and
+.Fn nftw
+will stop processing the tree and return the value from
+.Fa fn .
+Both functions return \-1 if an error is detected.
+.Sh ERRORS
+The
+.Fn ftw
+and
+.Fn nftw
+functions may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr close 2 ,
+.Xr open 2 ,
+.Xr stat 2 ,
+.Xr malloc 3 ,
+.Xr opendir 3
+and
+.Xr readdir 3 .
+If the
+.Dv FGTW_CHDIR
+flag is set, the
+.Fn nftw
+function may fail and set
+.Va errno
+for any of the errors specified for
+.Xr chdir 2 .
+In addition, either function may fail and set
+.Va errno
+as follows:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa maxfds
+argument is less than 1 or greater than
+.Dv OPEN_MAX .
+.El
+.Sh SEE ALSO
+.Xr chdir 2 ,
+.Xr close 2 ,
+.Xr open 2 ,
+.Xr stat 2 ,
+.Xr fts 3 ,
+.Xr malloc 3 ,
+.Xr opendir 3 ,
+.Xr readdir 3
+.Sh STANDARDS
+The
+.Fn ftw
+and
+.Fn nftw
+functions conform to
+.St -p1003.1-2001 .
+.Sh BUGS
+The
+.Fa maxfds
+argument is currently ignored.
--- /dev/null
+/* $OpenBSD: ftw.c,v 1.2 2003/07/21 21:15:32 millert Exp $ */
+
+/*
+ * Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$OpenBSD: ftw.c,v 1.2 2003/07/21 21:15:32 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fts.h>
+#include <ftw.h>
+#include <limits.h>
+
+int
+ftw(const char *path, int (*fn)(const char *, const struct stat *, int),
+ int nfds)
+{
+ const char *paths[2];
+ FTSENT *cur;
+ FTS *ftsp;
+ int fnflag, error, sverrno;
+
+ /* XXX - nfds is currently unused */
+ if (nfds < 1 || nfds > OPEN_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ paths[0] = path;
+ paths[1] = NULL;
+ ftsp = fts_open((char * const *)paths, FTS_COMFOLLOW | FTS_NOCHDIR,
+ NULL);
+ if (ftsp == NULL)
+ return (-1);
+ error = 0;
+ while ((cur = fts_read(ftsp)) != NULL) {
+ switch (cur->fts_info) {
+ case FTS_D:
+ fnflag = FTW_D;
+ break;
+ case FTS_DNR:
+ fnflag = FTW_DNR;
+ break;
+ case FTS_DP:
+ /* we only visit in preorder */
+ continue;
+ case FTS_F:
+ case FTS_DEFAULT:
+ fnflag = FTW_F;
+ break;
+ case FTS_NS:
+ case FTS_NSOK:
+ case FTS_SLNONE:
+ fnflag = FTW_NS;
+ break;
+ case FTS_SL:
+ fnflag = FTW_SL;
+ break;
+ case FTS_DC:
+ errno = ELOOP;
+ /* FALLTHROUGH */
+ default:
+ error = -1;
+ goto done;
+ }
+ error = fn(cur->fts_path, cur->fts_statp, fnflag);
+ if (error != 0)
+ break;
+ }
+done:
+ sverrno = errno;
+ (void) fts_close(ftsp);
+ errno = sverrno;
+ return (error);
+}
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
.Ql * .
.Pp
By default in Mac OS X 10.3 and later all users will have an
-AuthenticationAuthority will contiain the value ``;ShadowHash;''.
+AuthenticationAuthority with the value ``;ShadowHash;''.
These users will have a visible password value of ``********''.
These functions
will have no access to the encrypted password whatsoever.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
+++ /dev/null
-.\" Copyright (c) 1989, 1991, 1993, 1994
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" This code is derived from software contributed to Berkeley by
-.\" Guido van Rossum.
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)glob.3 8.3 (Berkeley) 4/16/94
-.\" $FreeBSD: src/lib/libc/gen/glob.3,v 1.20 2001/10/01 16:08:51 ru Exp $
-.\"
-.Dd April 16, 1994
-.Dt GLOB 3
-.Os
-.Sh NAME
-.Nm glob ,
-.Nm globfree
-.Nd generate pathnames matching a pattern
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In glob.h
-.Ft int
-.Fn glob "const char *pattern" "int flags" "int (*errfunc)(const char *, int)" "glob_t *pglob"
-.Ft void
-.Fn globfree "glob_t *pglob"
-.Sh DESCRIPTION
-The
-.Fn glob
-function
-is a pathname generator that implements the rules for file name pattern
-matching used by the shell.
-.Pp
-The include file
-.Pa glob.h
-defines the structure type
-.Fa glob_t ,
-which contains at least the following fields:
-.Bd -literal
-typedef struct {
- int gl_pathc; /* count of total paths so far */
- int gl_matchc; /* count of paths matching pattern */
- int gl_offs; /* reserved at beginning of gl_pathv */
- int gl_flags; /* returned flags */
- char **gl_pathv; /* list of paths matching pattern */
-} glob_t;
-.Ed
-.Pp
-The argument
-.Fa pattern
-is a pointer to a pathname pattern to be expanded.
-The
-.Fn glob
-argument
-matches all accessible pathnames against the pattern and creates
-a list of the pathnames that match.
-In order to have access to a pathname,
-.Fn glob
-requires search permission on every component of a path except the last
-and read permission on each directory of any filename component of
-.Fa pattern
-that contains any of the special characters
-.Ql * ,
-.Ql ?\&
-or
-.Ql \&[ .
-.Pp
-The
-.Fn glob
-argument
-stores the number of matched pathnames into the
-.Fa gl_pathc
-field, and a pointer to a list of pointers to pathnames into the
-.Fa gl_pathv
-field.
-The first pointer after the last pathname is
-.Dv NULL .
-If the pattern does not match any pathnames, the returned number of
-matched paths is set to zero.
-.Pp
-It is the caller's responsibility to create the structure pointed to by
-.Fa pglob .
-The
-.Fn glob
-function allocates other space as needed, including the memory pointed
-to by
-.Fa gl_pathv .
-.Pp
-The argument
-.Fa flags
-is used to modify the behavior of
-.Fn glob .
-The value of
-.Fa flags
-is the bitwise inclusive
-.Tn OR
-of any of the following
-values defined in
-.Pa glob.h :
-.Bl -tag -width GLOB_ALTDIRFUNC
-.It Dv GLOB_APPEND
-Append pathnames generated to the ones from a previous call (or calls)
-to
-.Fn glob .
-The value of
-.Fa gl_pathc
-will be the total matches found by this call and the previous call(s).
-The pathnames are appended to, not merged with the pathnames returned by
-the previous call(s).
-Between calls, the caller must not change the setting of the
-.Dv GLOB_DOOFFS
-flag, nor change the value of
-.Fa gl_offs
-when
-.Dv GLOB_DOOFFS
-is set, nor (obviously) call
-.Fn globfree
-for
-.Fa pglob .
-.It Dv GLOB_DOOFFS
-Make use of the
-.Fa gl_offs
-field.
-If this flag is set,
-.Fa gl_offs
-is used to specify how many
-.Dv NULL
-pointers to prepend to the beginning
-of the
-.Fa gl_pathv
-field.
-In other words,
-.Fa gl_pathv
-will point to
-.Fa gl_offs
-.Dv NULL
-pointers,
-followed by
-.Fa gl_pathc
-pathname pointers, followed by a
-.Dv NULL
-pointer.
-.It Dv GLOB_ERR
-Causes
-.Fn glob
-to return when it encounters a directory that it cannot open or read.
-Ordinarily,
-.Fn glob
-continues to find matches.
-.It Dv GLOB_MARK
-Each pathname that is a directory that matches
-.Fa pattern
-has a slash
-appended.
-.It Dv GLOB_NOCHECK
-If
-.Fa pattern
-does not match any pathname, then
-.Fn glob
-returns a list
-consisting of only
-.Fa pattern ,
-with the number of total pathnames is set to 1, and the number of matched
-pathnames set to 0.
-If
-.Dv GLOB_QUOTE
-is set, its effect is present in the pattern returned.
-.It Dv GLOB_NOSORT
-By default, the pathnames are sorted in ascending
-.Tn ASCII
-order;
-this flag prevents that sorting (speeding up
-.Fn glob ) .
-.El
-.Pp
-The following values may also be included in
-.Fa flags ,
-however, they are non-standard extensions to
-.St -p1003.2 .
-.Bl -tag -width GLOB_ALTDIRFUNC
-.It Dv GLOB_ALTDIRFUNC
-The following additional fields in the pglob structure have been
-initialized with alternate functions for glob to use to open, read,
-and close directories and to get stat information on names found
-in those directories.
-.Bd -literal
-void *(*gl_opendir)(const char * name);
-struct dirent *(*gl_readdir)(void *);
-void (*gl_closedir)(void *);
-int (*gl_lstat)(const char *name, struct stat *st);
-int (*gl_stat)(const char *name, struct stat *st);
-.Ed
-.Pp
-This extension is provided to allow programs such as
-.Xr restore 8
-to provide globbing from directories stored on tape.
-.It Dv GLOB_BRACE
-Pre-process the pattern string to expand
-.Ql {pat,pat,...}
-strings like
-.Xr csh 1 .
-The pattern
-.Ql {}
-is left unexpanded for historical reasons (and
-.Xr csh 1
-does the same thing to
-ease typing
-of
-.Xr find 1
-patterns).
-.It Dv GLOB_MAGCHAR
-Set by the
-.Fn glob
-function if the pattern included globbing characters.
-See the description of the usage of the
-.Fa gl_matchc
-structure member for more details.
-.It Dv GLOB_NOMAGIC
-Is the same as
-.Dv GLOB_NOCHECK
-but it only appends the
-.Fa pattern
-if it does not contain any of the special characters ``*'', ``?'' or ``[''.
-.Dv GLOB_NOMAGIC
-is provided to simplify implementing the historic
-.Xr csh 1
-globbing behavior and should probably not be used anywhere else.
-.It Dv GLOB_QUOTE
-Use the backslash
-.Pq Ql \e
-character for quoting: every occurrence of
-a backslash followed by a character in the pattern is replaced by that
-character, avoiding any special interpretation of the character.
-.It Dv GLOB_TILDE
-Expand patterns that start with
-.Ql ~
-to user name home directories.
-.It Dv GLOB_LIMIT
-Limit the total number of returned pathnames to the value provided in
-.Fa gl_matchc
-(default
-.Dv ARG_MAX ) .
-This option should be set for programs
-that can be coerced into a denial of service attack
-via patterns that expand to a very large number of matches,
-such as a long string of
-.Ql */../*/.. .
-.El
-.Pp
-If, during the search, a directory is encountered that cannot be opened
-or read and
-.Fa errfunc
-is
-.Pf non- Dv NULL ,
-.Fn glob
-calls
-.Fa \*(lp*errfunc\*(rp Ns ( Fa path , errno ) .
-This may be unintuitive: a pattern like
-.Ql */Makefile
-will try to
-.Xr stat 2
-.Ql foo/Makefile
-even if
-.Ql foo
-is not a directory, resulting in a
-call to
-.Fa errfunc .
-The error routine can suppress this action by testing for
-.Er ENOENT
-and
-.Er ENOTDIR ;
-however, the
-.Dv GLOB_ERR
-flag will still cause an immediate
-return when this happens.
-.Pp
-If
-.Fa errfunc
-returns non-zero,
-.Fn glob
-stops the scan and returns
-.Dv GLOB_ABEND
-after setting
-.Fa gl_pathc
-and
-.Fa gl_pathv
-to reflect any paths already matched.
-This also happens if an error is encountered and
-.Dv GLOB_ERR
-is set in
-.Fa flags ,
-regardless of the return value of
-.Fa errfunc ,
-if called.
-If
-.Dv GLOB_ERR
-is not set and either
-.Fa errfunc
-is
-.Dv NULL
-or
-.Fa errfunc
-returns zero, the error is ignored.
-.Pp
-The
-.Fn globfree
-function frees any space associated with
-.Fa pglob
-from a previous call(s) to
-.Fn glob .
-.Sh RETURN VALUES
-On successful completion,
-.Fn glob
-returns zero.
-In addition the fields of
-.Fa pglob
-contain the values described below:
-.Bl -tag -width GLOB_NOCHECK
-.It Fa gl_pathc
-contains the total number of matched pathnames so far.
-This includes other matches from previous invocations of
-.Fn glob
-if
-.Dv GLOB_APPEND
-was specified.
-.It Fa gl_matchc
-contains the number of matched pathnames in the current invocation of
-.Fn glob .
-.It Fa gl_flags
-contains a copy of the
-.Fa flags
-parameter with the bit
-.Dv GLOB_MAGCHAR
-set if
-.Fa pattern
-contained any of the special characters ``*'', ``?'' or ``['', cleared
-if not.
-.It Fa gl_pathv
-contains a pointer to a
-.Dv NULL Ns -terminated
-list of matched pathnames.
-However, if
-.Fa gl_pathc
-is zero, the contents of
-.Fa gl_pathv
-are undefined.
-.El
-.Pp
-If
-.Fn glob
-terminates due to an error, it sets errno and returns one of the
-following non-zero constants, which are defined in the include
-file
-.Aq Pa glob.h :
-.Bl -tag -width GLOB_NOCHECK
-.It Dv GLOB_NOSPACE
-An attempt to allocate memory failed, or if
-.Fa errno
-was 0
-.Dv GLOB_LIMIT
-was specified in the flags and
-.Fa pglob\->gl_matchc
-or more patterns were matched.
-.It Dv GLOB_ABEND
-The scan was stopped because an error was encountered and either
-.Dv GLOB_ERR
-was set or
-.Fa \*(lp*errfunc\*(rp\*(lp\*(rp
-returned non-zero.
-.El
-.Pp
-The arguments
-.Fa pglob\->gl_pathc
-and
-.Fa pglob\->gl_pathv
-are still set as specified above.
-.Sh EXAMPLES
-A rough equivalent of
-.Ql "ls -l *.c *.h"
-can be obtained with the
-following code:
-.Bd -literal -offset indent
-glob_t g;
-
-g.gl_offs = 2;
-glob("*.c", GLOB_DOOFFS, NULL, &g);
-glob("*.h", GLOB_DOOFFS | GLOB_APPEND, NULL, &g);
-g.gl_pathv[0] = "ls";
-g.gl_pathv[1] = "-l";
-execvp("ls", g.gl_pathv);
-.Ed
-.Sh SEE ALSO
-.Xr sh 1 ,
-.Xr fnmatch 3 ,
-.Xr regexp 3
-.Sh STANDARDS
-The
-.Fn glob
-function is expected to be
-.St -p1003.2
-compatible with the exception
-that the flags
-.Dv GLOB_ALTDIRFUNC ,
-.Dv GLOB_BRACE ,
-.Dv GLOB_LIMIT ,
-.Dv GLOB_MAGCHAR ,
-.Dv GLOB_NOMAGIC ,
-.Dv GLOB_QUOTE ,
-and
-.Dv GLOB_TILDE ,
-and the fields
-.Fa gl_matchc
-and
-.Fa gl_flags
-should not be used by applications striving for strict
-.Tn POSIX
-conformance.
-.Sh HISTORY
-The
-.Fn glob
-and
-.Fn globfree
-functions first appeared in
-.Bx 4.4 .
-.Sh BUGS
-Patterns longer than
-.Dv MAXPATHLEN
-may cause unchecked errors.
-.Pp
-The
-.Fn glob
-argument
-may fail and set errno for any of the errors specified for the
-library routines
-.Xr stat 2 ,
-.Xr closedir 3 ,
-.Xr opendir 3 ,
-.Xr readdir 3 ,
-.Xr malloc 3 ,
-and
-.Xr free 3 .
+++ /dev/null
-.\" Copyright (c) 1991, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)isinf.3 8.2 (Berkeley) 1/29/94
-.\" $FreeBSD: src/lib/libc/gen/isinf.3,v 1.7 2000/10/30 13:23:18 asmodai Exp $
-.\"
-.Dd January 29, 1994
-.Dt ISINF 3
-.Os
-.Sh NAME
-.Nm isinf ,
-.Nm isnan ,
-.Nm isnanf
-.Nd test for infinity or not-a-number
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.Ft int
-.Fn isinf double
-.Ft int
-.Fn isnan double
-.Ft int
-.Fn isnanf float
-.Sh DESCRIPTION
-The
-.Fn isinf
-function
-returns 1 if the number is
-.Dq \\*(If ,
-otherwise 0.
-.Pp
-The
-.Fn isnan
-and
-.Fn isnanf
-functions
-return 1 if the double or float (respectively) is
-.Dq not-a-number ,
-otherwise 0.
-.Sh SEE ALSO
-.Xr math 3
-.Rs
-.%T "IEEE Standard for Binary Floating-Point Arithmetic"
-.%Q ANSI
-.%R Std 754-1985
-.Re
-.Sh BUGS
-Neither the
-.Tn VAX
-nor the Tahoe floating point have distinguished values
-for either infinity or not-a-number.
-These routines always return 0 on those architectures.
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <math.h>
+
+/* 3BSD compatibility function */
+#undef isinf
+int
+isinf(double d)
+{
+ return __isinfd(d);
+}
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_END@
*/
-/* @(#)s_isnan.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: s_isnan.c,v 1.8 1995/05/10 20:47:36 jtc Exp $";
-#endif
-
-/*
- * isnan(x) returns 1 is x is nan, else 0;
- * no branching!
- */
-
-#include <sys/types.h>
-
-typedef union
-{
- double value;
- struct
- {
-#if defined(__BIG_ENDIAN__)
- u_int32_t msw;
- u_int32_t lsw;
-#else
- u_int32_t lsw;
- u_int32_t msw;
-#endif
- } parts;
-} ieee_double_shape_type;
-/* Get two 32 bit ints from a double. */
-
-#define EXTRACT_WORDS(ix0,ix1,d) \
-do { \
- ieee_double_shape_type ew_u; \
- ew_u.value = (d); \
- (ix0) = ew_u.parts.msw; \
- (ix1) = ew_u.parts.lsw; \
-} while (0)
+#include <math.h>
-#ifdef __STDC__
- int isnan(double x)
-#else
- int isnan(x)
- double x;
-#endif
+/* 3BSD compatibility function */
+#undef isnan
+int
+isnan(double d)
{
- int32_t hx,lx;
- EXTRACT_WORDS(hx,lx,x);
- hx &= 0x7fffffff;
- hx |= (u_int32_t)(lx|(-lx))>>31;
- hx = 0x7ff00000 - hx;
- return (int)((u_int32_t)(hx))>>31;
+ return __isnand(d);
}
.Dt MALLOC 3
.Os
.Sh NAME
-.Nm malloc , calloc , valloc , realloc , free , malloc_size , malloc_good_size
+.Nm malloc , calloc , valloc , realloc , reallocf , free , malloc_size , malloc_good_size
.Nd memory allocation
.Sh SYNOPSIS
.In stdlib.h
.Fn valloc "size_t size"
.Ft void *
.Fn realloc "void *ptr" "size_t size"
+.Ft void *
+.Fn reallocf "void *ptr" "size_t size"
.Ft void
.Fn free "void *ptr"
.Ft size_t
.Fn malloc ,
.Fn calloc ,
.Fn valloc ,
+.Fn realloc ,
and
-.Fn realloc
+.Fn reallocf
functions allocate memory.
The allocated memory is aligned such that it can be used for any data type,
including AltiVec-related types.
is still valid.
.Pp
The
+.Fn reallocf
+function is identical to the
+.Fn realloc
+function, except that it
+will free the passed pointer when the requested memory cannot be allocated.
+This is a
+.Fx
+specific API designed to ease the problems with traditional coding styles
+for realloc causing memory leaks in libraries.
+.Pp
+The
.Fn free
function deallocates the memory allocation pointed to by
.Fa ptr .
.Pp
If successful, the
.Fn realloc
-function returns a pointer to allocated memory.
+and
+.Fn reallocf
+functions return a pointer to allocated memory.
If there is an error, it returns a
.Dv NULL
pointer and sets
If set, record all stacks in a manner that is compatible with the
.Nm malloc_history
program.
+.It Ev MallocPreScribble
+If set, fill memory that has been allocated with 0xaa bytes.
+This increases the likelihood that a program making assumptions about the
+contents of freshly allocated memory will fail.
.It Ev MallocScribble
If set, fill memory that has been deallocated with 0x55 bytes.
This increases the likelihood that a program will fail due to accessing memory
.Xr leaks 1 ,
.Xr malloc_history 1 ,
.Xr abort 3
-.Pa /Developer/Documentation/ReleaseNotes/MallocOptions.html
+.Pa /Developer/Documentation/ReleaseNotes/DeveloperTools/MallocOptions.html
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#import <malloc/malloc.h>
#import <fcntl.h>
#include <crt_externs.h>
+#import <pthread_internals.h>
#import "scalable_malloc.h"
#import "stack_logging.h"
#define USE_SLEEP_RATHER_THAN_ABORT 0
-#define MAX_ALLOCATION 0xc0000000 // beyond this, assume a programming error
#define INITIAL_ZONES 8 // After this number, we reallocate for new zones
typedef void (malloc_logger_t)(unsigned type, unsigned arg1, unsigned arg2, unsigned arg3, unsigned result, unsigned num_hot_frames_to_skip);
static int malloc_free_abort = 0; // default is not to abort
-static int logfd = 2; // malloc_printf file descriptor
+static FILE *malloc_debug_file;
#define MALLOC_LOCK() LOCK(_malloc_lock)
#define MALLOC_UNLOCK() UNLOCK(_malloc_lock)
(void)malloc_create_zone(0, 0);
malloc_set_zone_name(malloc_zones[0], "DefaultMallocZone");
LOCK_INIT(_malloc_lock);
- // malloc_printf("Malloc: %d registered zones\n", malloc_num_zones);
- // malloc_printf("malloc: malloc_zones is at %p; malloc_num_zones is at %p\n", (unsigned)&malloc_zones, (unsigned)&malloc_num_zones);
+ // malloc_printf("%d registered zones\n", malloc_num_zones);
+ // malloc_printf("malloc_zones is at %p; malloc_num_zones is at %p\n", (unsigned)&malloc_zones, (unsigned)&malloc_num_zones);
}
static inline malloc_zone_t *
static void
set_flags_from_environment(void) {
const char *flag;
+ int fd;
+
flag = getenv("MallocLogFile");
if (flag) {
- int fd = open(flag, O_WRONLY|O_APPEND|O_CREAT, 0644);
+ fd = open(flag, O_WRONLY|O_APPEND|O_CREAT, 0644);
if (fd >= 0) {
- logfd = fd;
- fcntl(fd, F_SETFD, 0); // clear close-on-exec flag
- } else
- malloc_printf("malloc[%d]: Could not open %s, using stderr\n",
- getpid(), flag);
+ malloc_debug_file = fdopen(fd, "a+");
+ fcntl(fd, F_SETFD, 0); // clear close-on-exec flag XXX why?
+ } else {
+ malloc_printf("Could not open %s, using stderr\n", flag);
+ }
}
if (getenv("MallocGuardEdges")) {
malloc_debug_flags = SCALABLE_MALLOC_ADD_GUARD_PAGES;
- malloc_printf("malloc[%d]: protecting edges\n", getpid());
+ malloc_printf("protecting edges\n");
if (getenv("MallocDoNotProtectPrelude")) {
malloc_debug_flags |= SCALABLE_MALLOC_DONT_PROTECT_PRELUDE;
- malloc_printf("malloc[%d]: ... but not protecting prelude guard page\n", getpid());
+ malloc_printf("... but not protecting prelude guard page\n");
}
if (getenv("MallocDoNotProtectPostlude")) {
malloc_debug_flags |= SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE;
- malloc_printf("malloc[%d]: ... but not protecting postlude guard page\n", getpid());
+ malloc_printf("... but not protecting postlude guard page\n");
}
}
flag = getenv("MallocStackLogging");
malloc_logger = (val) ? (void *)val : stack_logging_log_stack;
stack_logging_enable_logging = 1;
if (malloc_logger == stack_logging_log_stack) {
- malloc_printf("malloc[%d]: recording stacks using standard recorder\n", getpid());
+ malloc_printf("recording stacks using standard recorder\n");
} else {
- malloc_printf("malloc[%d]: recording stacks using recorder %p\n", getpid(), malloc_logger);
+ malloc_printf("recording stacks using recorder %p\n", malloc_logger);
}
- if (stack_logging_dontcompact) malloc_printf("malloc[%d]: stack logging compaction turned off; VM can increase rapidly\n", getpid());
+ if (stack_logging_dontcompact) malloc_printf("stack logging compaction turned off; VM can increase rapidly\n");
}
if (getenv("MallocScribble")) {
malloc_debug_flags |= SCALABLE_MALLOC_DO_SCRIBBLE;
- malloc_printf("malloc[%d]: enabling scribbling to detect mods to free blocks\n", getpid());
+ malloc_printf("enabling scribbling to detect mods to free blocks\n");
}
flag = getenv("MallocCheckHeapStart");
if (flag) {
if (malloc_check_each == 0) malloc_check_each = 1;
if (malloc_check_each == -1) malloc_check_each = 1;
}
- malloc_printf("malloc[%d]: checks heap after %dth operation and each %d operations\n", getpid(), malloc_check_start, malloc_check_each);
+ malloc_printf("checks heap after %dth operation and each %d operations\n", malloc_check_start, malloc_check_each);
flag = getenv("MallocCheckHeapAbort");
if (flag)
malloc_check_abort = strtol(flag, NULL, 0);
if (malloc_check_abort)
- malloc_printf("malloc[%d]: will abort on heap corruption\n",
- getpid());
+ malloc_printf("will abort on heap corruption\n");
else {
flag = getenv("MallocCheckHeapSleep");
if (flag)
malloc_check_sleep = strtol(flag, NULL, 0);
if (malloc_check_sleep > 0)
- malloc_printf("malloc[%d]: will sleep for %d seconds on heap corruption\n",
- getpid(), malloc_check_sleep);
+ malloc_printf("will sleep for %d seconds on heap corruption\n", malloc_check_sleep);
else if (malloc_check_sleep < 0)
- malloc_printf("malloc[%d]: will sleep once for %d seconds on heap corruption\n",
- getpid(), -malloc_check_sleep);
+ malloc_printf("will sleep once for %d seconds on heap corruption\n", -malloc_check_sleep);
else
- malloc_printf("malloc[%d]: no sleep on heap corruption\n",
- getpid());
+ malloc_printf("no sleep on heap corruption\n");
}
}
flag = getenv("MallocBadFreeAbort");
malloc_free_abort = strtol(flag, NULL, 0);
if (getenv("MallocHelp")) {
malloc_printf(
- "malloc[%d]: environment variables that can be set for debug:\n"
+ "environment variables that can be set for debug:\n"
"- MallocLogFile <f> to create/append messages to file <f> instead of stderr\n"
"- MallocGuardEdges to add 2 guard pages for each large block\n"
"- MallocDoNotProtectPrelude to disable protection (when previous flag set)\n"
"- MallocDoNotProtectPostlude to disable protection (when previous flag set)\n"
"- MallocStackLogging to record all stacks. Tools like leaks can then be applied\n"
"- MallocStackLoggingNoCompact to record all stacks. Needed for malloc_history\n"
- "- MallocScribble to detect writing on free blocks: 0x55 is written upon free\n"
+ "- MallocScribble to detect writing on free blocks and missing initializers:\n"
+ " 0x55 is written upon free and 0xaa is written on allocation\n"
"- MallocCheckHeapStart <n> to start checking the heap after <n> operations\n"
"- MallocCheckHeapEach <s> to repeat the checking of the heap after <s> operations\n"
"- MallocCheckHeapSleep <t> to sleep <t> seconds on heap corruption\n"
"- MallocCheckHeapAbort <b> to abort on heap corruption if <b> is non-zero\n"
"- MallocBadFreeAbort <b> to abort on a bad free if <b> is non-zero\n"
- "- MallocHelp - this help!\n", getpid());
+ "- MallocHelp - this help!\n");
}
}
char **p;
char *c;
/* Given that all environment variables start with "Malloc" we optimize by scanning quickly first the environment, therefore avoiding repeated calls to getenv() */
+ malloc_debug_file = stderr;
for (p = env; (c = *p) != NULL; ++p) {
if (!strncmp(c, "Malloc", 6)) {
set_flags_from_environment();
void *
malloc_zone_malloc(malloc_zone_t *zone, size_t size) {
void *ptr;
- if ((unsigned)size >= MAX_ALLOCATION) {
- /* Probably a programming error */
- malloc_printf("*** malloc_zone_malloc[%d]: argument too large: %d\n", getpid(), size);
- return NULL;
- }
if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
internal_check();
}
if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
internal_check();
}
- if (((unsigned)num_items >= MAX_ALLOCATION) || ((unsigned)size >= MAX_ALLOCATION) || ((long long)size * num_items >= (long long) MAX_ALLOCATION)) {
- /* Probably a programming error */
- malloc_printf("*** malloc_zone_calloc[%d]: arguments too large: %d,%d\n", getpid(), num_items, size);
- return NULL;
- }
ptr = zone->calloc(zone, num_items, size);
if (malloc_logger) malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE | MALLOC_LOG_TYPE_CLEARED, (unsigned)zone, num_items * size, 0, (unsigned)ptr, 0);
return ptr;
void *
malloc_zone_valloc(malloc_zone_t *zone, size_t size) {
void *ptr;
- if ((unsigned)size >= MAX_ALLOCATION) {
- /* Probably a programming error */
- malloc_printf("*** malloc_zone_valloc[%d]: argument too large: %d\n", getpid(), size);
- return NULL;
- }
if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
internal_check();
}
}
}
MALLOC_UNLOCK();
- malloc_printf("*** malloc[%d]: malloc_zone_unregister() failed for %p\n", getpid(), z);
+ malloc_printf("*** malloc_zone_unregister() failed for %p\n", z);
}
void
return zone->zone_name;
}
-static char *
-_malloc_append_unsigned(unsigned value, unsigned base, char *head) {
- if (!value) {
- head[0] = '0';
- } else {
- if (value >= base) head = _malloc_append_unsigned(value / base, base, head);
- value = value % base;
- head[0] = (value < 10) ? '0' + value : 'a' + value - 10;
- }
- return head+1;
-}
-
+/*
+ * XXX malloc_printf cannot handle the %ls, %a and %A formats. It must also not
+ * be used for the printing of vectors, or with formats with positional arguments.
+ */
void
-malloc_printf(const char *format, ...) {
- va_list args;
- char buf[1024];
- char *head = buf;
- char ch;
- unsigned *nums;
- va_start(args, format);
-#if LOG_THREAD
- head = _malloc_append_unsigned(((unsigned)&args) >> 12, 16, head);
- *head++ = ' ';
-#endif
- nums = (void *)args;
- while (ch = *format++) {
- if (ch == '%') {
- ch = *format++;
- if (ch == 's') {
- char *str = (char *)(*nums++);
- write(logfd, buf, head - buf);
- head = buf;
- write(logfd, str, strlen(str));
- } else if (ch == 'y') {
- unsigned num = *nums++;
- if (num == 0) {
- *head++ = '0';
- } else if (num >= 10 * 1024 *1024) {
- // use a round number of MB
- head = _malloc_append_unsigned(num >> 20, 10, head);
- *head++ = 'M'; *head++ = 'B';
- } else if (num >= 10 * 1024) {
- // use a round amount of KB
- head = _malloc_append_unsigned(num >> 10, 10, head);
- *head++ = 'K'; *head++ = 'B';
- } else {
- head = _malloc_append_unsigned(num, 10, head);
- *head++ = 'b';
- }
- } else {
- if (ch == 'p') {
- *head++ = '0'; *head++ = 'x';
- }
- head = _malloc_append_unsigned(*nums++, (ch == 'd') ? 10 : 16, head);
- }
- } else {
- *head++ = ch;
- }
+malloc_printf(const char *format, ...)
+{
+ va_list ap;
+
+ if (__is_threaded) {
+ /* XXX somewhat rude 'knowing' that pthread_t is a pointer */
+ fprintf(malloc_debug_file, "%s(%d,%p) malloc: ", getprogname(), getpid(), (void *)pthread_self());
+ } else {
+ fprintf(malloc_debug_file, "%s(%d) malloc: ", getprogname(), getpid());
}
- write(logfd, buf, head - buf); fflush(stderr);
- va_end(args);
+ va_start(ap, format);
+ vfprintf(malloc_debug_file, format, ap);
+ va_end(ap);
}
/********* Generic ANSI callouts ************/
if (zone) {
malloc_zone_free(zone, ptr);
} else {
- malloc_printf("*** malloc[%d]: Deallocation of a pointer not malloced: %p; This could be a double free(), or free() called with the middle of an allocated block; Try setting environment variable MallocHelp to see tools to help debug\n", getpid(), ptr);
+ malloc_printf("*** Deallocation of a pointer not malloced: %p; "
+ "This could be a double free(), or free() called with the middle of an allocated block; "
+ "Try setting environment variable MallocHelp to see tools to help debug\n", ptr);
if (malloc_free_abort)
abort();
}
err = reader(task, remote_malloc_zones, sizeof(void *), (void **)&zones_address_ref);
// printf("Read malloc_zones[%p]=%p\n", remote_malloc_zones, *zones_address_ref);
if (err) {
- malloc_printf("*** malloc[%d]: malloc_get_all_zones: error reading zones_address at %p\n", getpid(), (unsigned)remote_malloc_zones);
+ malloc_printf("*** malloc_get_all_zones: error reading zones_address at %p\n", (unsigned)remote_malloc_zones);
return err;
}
zones_address = *zones_address_ref;
// printf("Reading num_zones at address %p\n", remote_malloc_num_zones);
err = reader(task, remote_malloc_num_zones, sizeof(unsigned), (void **)&num_zones_ref);
if (err) {
- malloc_printf("*** malloc[%d]: malloc_get_all_zones: error reading num_zones at %p\n", getpid(), (unsigned)remote_malloc_num_zones);
+ malloc_printf("*** malloc_get_all_zones: error reading num_zones at %p\n", (unsigned)remote_malloc_num_zones);
return err;
}
num_zones = *num_zones_ref;
// printf("malloc_get_all_zones succesfully found %d zones\n", num_zones);
err = reader(task, zones_address, sizeof(malloc_zone_t *) * num_zones, (void **)addresses);
if (err) {
- malloc_printf("*** malloc[%d]: malloc_get_all_zones: error reading zones at %p\n", getpid(), (unsigned)&zones_address);
+ malloc_printf("*** malloc_get_all_zones: error reading zones at %p\n", (unsigned)&zones_address);
return err;
}
// printf("malloc_get_all_zones succesfully read %d zones\n", num_zones);
static void
DefaultMallocError(int x) {
- malloc_printf("*** malloc[%d]: error %d\n", getpid(), x);
+ malloc_printf("*** error %d\n", x);
#if USE_SLEEP_RATHER_THAN_ABORT
sleep(3600);
#else
}
}
-size_t
-mstats(void) {
- malloc_zone_print(NULL, 0);
- return 1;
+/*
+ * A Glibc-like mstats() interface.
+ *
+ * Note that this interface really isn't very good, as it doesn't understand
+ * that we may have multiple allocators running at once. We just massage
+ * the result from malloc_zone_statistics in any case.
+ */
+struct mstats
+mstats(void)
+{
+ malloc_statistics_t s;
+ struct mstats m;
+
+ malloc_zone_statistics(NULL, &s);
+ m.bytes_total = s.size_allocated;
+ m.chunks_used = s.blocks_in_use;
+ m.bytes_used = s.size_in_use;
+ m.chunks_free = 0;
+ m.bytes_free = m.bytes_total - m.bytes_used; /* isn't this somewhat obvious? */
+
+ return(m);
}
/***************** OBSOLETE ENTRY POINTS ********************/
static boolean_t warned = 0;
if (!warned) {
#if PHASE_OUT_OLD_MALLOC
- malloc_printf("*** malloc[%d]: OBSOLETE: set_malloc_singlethreaded(%d)\n", getpid(), single);
+ malloc_printf("*** OBSOLETE: set_malloc_singlethreaded(%d)\n", single);
#endif
warned = 1;
}
malloc_singlethreaded() {
static boolean_t warned = 0;
if (!warned) {
- malloc_printf("*** malloc[%d]: OBSOLETE: malloc_singlethreaded()\n", getpid());
+ malloc_printf("*** OBSOLETE: malloc_singlethreaded()\n");
warned = 1;
}
}
int
malloc_debug(int level) {
- malloc_printf("*** malloc[%d]: OBSOLETE: malloc_debug()\n", getpid());
+ malloc_printf("*** OBSOLETE: malloc_debug()\n");
return 0;
}
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <errno.h>
#include <sys/time.h>
-#include <mach/message.h>
#include <mach/mach_error.h>
-#include <mach/mach_syscalls.h>
-#include <mach/clock.h>
-#include <mach/clock_types.h>
+#include <mach/mach_time.h>
#include <stdio.h>
-extern mach_port_t clock_port;
-
int
nanosleep(const struct timespec *requested_time, struct timespec *remaining_time) {
kern_return_t ret;
mach_timespec_t remain;
mach_timespec_t current;
+ uint64_t end;
+ static double ratio = 0.0, rratio;
if ((requested_time == NULL) || (requested_time->tv_sec < 0) || (requested_time->tv_nsec > NSEC_PER_SEC)) {
errno = EINVAL;
return -1;
}
- ret = clock_get_time(clock_port, ¤t);
- if (ret != KERN_SUCCESS) {
- fprintf(stderr, "clock_get_time() failed: %s\n", mach_error_string(ret));
- return -1;
+ if (ratio == 0.0) {
+ struct mach_timebase_info info;
+ ret = mach_timebase_info(&info);
+ if (ret != KERN_SUCCESS) {
+ fprintf(stderr, "mach_timebase_info() failed: %s\n", mach_error_string(ret));
+ errno = EAGAIN;
+ return -1;
+ }
+ ratio = (double)info.numer / ((double)info.denom * NSEC_PER_SEC);
+ rratio = (double)info.denom / (double)info.numer;
}
- /* This depends on the layout of a mach_timespec_t and timespec_t being equivalent */
- ret = clock_sleep_trap(clock_port, TIME_RELATIVE, requested_time->tv_sec, requested_time->tv_nsec, &remain);
+
+ /* use rratio to avoid division */
+ end = mach_absolute_time() + (uint64_t)(((double)requested_time->tv_sec * NSEC_PER_SEC + (double)requested_time->tv_nsec) * rratio);
+ ret = mach_wait_until(end);
if (ret != KERN_SUCCESS) {
if (ret == KERN_ABORTED) {
errno = EINTR;
if (remaining_time != NULL) {
- ret = clock_get_time(clock_port, &remain);
- if (ret != KERN_SUCCESS) {
- fprintf(stderr, "clock_get_time() failed: %s\n", mach_error_string(ret));
- return -1;
- }
- ADD_MACH_TIMESPEC(¤t, requested_time);
- SUB_MACH_TIMESPEC(¤t, &remain);
- remaining_time->tv_sec = current.tv_sec;
- remaining_time->tv_nsec = current.tv_nsec;
+ uint64_t now = mach_absolute_time();
+ double delta;
+ if (now > end)
+ now = end;
+ delta = (end - now) * ratio;
+ remaining_time->tv_sec = delta;
+ remaining_time->tv_nsec = NSEC_PER_SEC * (delta - remaining_time->tv_sec);
}
} else {
errno = EINVAL;
--- /dev/null
+/* $OpenBSD: nftw.c,v 1.2 2003/07/21 21:15:32 millert Exp $ */
+
+/*
+ * Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$OpenBSD: nftw.c,v 1.2 2003/07/21 21:15:32 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fts.h>
+#include <ftw.h>
+#include <limits.h>
+
+int
+nftw(const char *path, int (*fn)(const char *, const struct stat *, int,
+ struct FTW *), int nfds, int ftwflags)
+{
+ const char *paths[2];
+ struct FTW ftw;
+ FTSENT *cur;
+ FTS *ftsp;
+ int ftsflags, fnflag, error, postorder, sverrno;
+
+ /* XXX - nfds is currently unused */
+ if (nfds < 1 || nfds > OPEN_MAX) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ ftsflags = FTS_COMFOLLOW;
+ if (!(ftwflags & FTW_CHDIR))
+ ftsflags |= FTS_NOCHDIR;
+ if (ftwflags & FTW_MOUNT)
+ ftsflags |= FTS_XDEV;
+ if (ftwflags & FTW_PHYS)
+ ftsflags |= FTS_PHYSICAL;
+ postorder = (ftwflags & FTW_DEPTH) != 0;
+ paths[0] = path;
+ paths[1] = NULL;
+ ftsp = fts_open((char * const *)paths, ftsflags, NULL);
+ if (ftsp == NULL)
+ return (-1);
+ error = 0;
+ while ((cur = fts_read(ftsp)) != NULL) {
+ switch (cur->fts_info) {
+ case FTS_D:
+ if (postorder)
+ continue;
+ fnflag = FTW_D;
+ break;
+ case FTS_DNR:
+ fnflag = FTW_DNR;
+ break;
+ case FTS_DP:
+ if (!postorder)
+ continue;
+ fnflag = FTW_DP;
+ break;
+ case FTS_F:
+ case FTS_DEFAULT:
+ fnflag = FTW_F;
+ break;
+ case FTS_NS:
+ case FTS_NSOK:
+ fnflag = FTW_NS;
+ break;
+ case FTS_SL:
+ fnflag = FTW_SL;
+ break;
+ case FTS_SLNONE:
+ fnflag = FTW_SLN;
+ break;
+ case FTS_DC:
+ errno = ELOOP;
+ /* FALLTHROUGH */
+ default:
+ error = -1;
+ goto done;
+ }
+ ftw.base = cur->fts_pathlen - cur->fts_namelen;
+ ftw.level = cur->fts_level;
+ error = fn(cur->fts_path, cur->fts_statp, fnflag, &ftw);
+ if (error != 0)
+ break;
+ }
+done:
+ sverrno = errno;
+ (void) fts_close(ftsp);
+ errno = sverrno;
+ return (error);
+}
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
/* Author: Bertrand Serlet, August 1999 */
-#import "scalable_malloc.h"
+#include "scalable_malloc.h"
-#import <pthread_internals.h>
+#include <pthread_internals.h>
-#import <unistd.h>
-#import <libc.h>
+#include <unistd.h>
+#include <libc.h>
#include <mach/vm_statistics.h>
+#include <mach/mach_init.h>
/********************* DEFINITIONS ************************/
#if DEBUG_MALLOC
#warning DEBUG_MALLOC ENABLED
-#define INLINE
-#define CHECK_LOCKED(szone, fun) { \
- if (__is_threaded && TRY_LOCK(szone->lock)) { \
+# define INLINE
+# define CHECK_LOCKED(szone, fun) \
+do { \
+ if (__is_threaded && TRY_LOCK(szone->lock)) { \
malloc_printf("*** lock was not set %p in %s\n", szone->lock, fun); \
- } \
-}
+ } \
+} while (0)
#else
-#define INLINE __inline__
-#define CHECK_LOCKED(szone, fun) {}
+# define INLINE __inline__
+# define CHECK_LOCKED(szone, fun) {}
#endif
-#define PAGE_SIZE_FIXED 1 // flip if the page size becomes variable, one day
-#if PAGE_SIZE_FIXED
+/*
+ * Access to global variables is slow, so optimise our handling of vm_page_size
+ * and vm_page_shift.
+ */
+#define _vm_page_size vm_page_size /* to get to the originals */
+#define _vm_page_shift vm_page_shift
+#define vm_page_size 4096 /* our normal working sizes */
#define vm_page_shift 12
-#else
-static unsigned vm_page_shift = 0; // guaranteed to be intialized by zone creation
-#endif
typedef unsigned short msize_t; // a size in multiples of SHIFT_SMALL_QUANTUM or SHIFT_TINY_QUANTUM
+/*
+ * Note that in the LP64 case, this is 24 bytes, necessitating the 32-byte tiny grain size.
+ */
typedef struct {
- unsigned checksum;
+ uintptr_t checksum;
void *previous;
void *next;
} free_list_t;
typedef struct {
- unsigned address_and_num_pages;
+ uintptr_t address_and_num_pages;
// this type represents both an address and a number of pages
// the low bits are the number of pages; the high bits are the address
// note that the exact number of bits used for depends on the page size
#define CHECK_REGIONS (1 << 31)
-#define CHECKSUM_MAGIC 0x357B
+#ifdef __LP64__
+# define CHECKSUM_MAGIC 0xdeadbeef0badc0de
+#else
+# define CHECKSUM_MAGIC 0x357B
+#endif
#define MAX_RECORDER_BUFFER 256
/********************* DEFINITIONS for tiny ************************/
-#define SHIFT_TINY_QUANTUM 4 // Required for AltiVec
+/*
+ * Memory in the Tiny range is allocated from regions (heaps) pointed to by the szone's tiny_regions
+ * pointer.
+ *
+ * Each region is laid out as a heap (1MB in 32-bit mode, 2MB in 64-bit mode), followed by a header
+ * block. The header block is arranged:
+ *
+ * 0x0
+ * header bits
+ * 0x2000
+ * 0xffffffff pad word
+ * 0x2004
+ * in-use bits
+ * 0x4004
+ * pad word (not written)
+ *
+ * Each bitfield comprises NUM_TINY_BLOCKS bits, and refers to the corresponding TINY_QUANTUM block
+ * within the heap.
+ *
+ * The bitfields are used to encode the state of memory within the heap. The header bit indicates
+ * that the corresponding quantum is the first quantum in a block (either in use or free). The
+ * in-use bit is set for the header if the block has been handed out (allocated). If the header
+ * bit is not set, the in-use bit is invalid.
+ *
+ * The szone maintains an array of 32 freelists, each of which is used to hold free objects
+ * of the corresponding quantum size.
+ *
+ * A free block is laid out as:
+ *
+ * Offset (32-bit mode) (64-bit mode)
+ * 0x0 0x0
+ * checksum
+ * 0x4 0x08
+ * previous
+ * 0x8 0x10
+ * next
+ * 0xc 0x18
+ * size (in quantum counts)
+ * end - 2 end - 2
+ * size (in quantum counts)
+ * end end
+ *
+ * All fields are pointer-sized, except for the size which is an unsigned short.
+ *
+ */
+
+#ifdef __LP64__
+# define SHIFT_TINY_QUANTUM 5 // Required to fit free_list_t
+#else
+# define SHIFT_TINY_QUANTUM 4 // Required for AltiVec
+#endif
#define TINY_QUANTUM (1 << SHIFT_TINY_QUANTUM)
-#define FOLLOWING_TINY_PTR(ptr,msize) (((char *)(ptr)) + ((msize) << SHIFT_TINY_QUANTUM))
+#define FOLLOWING_TINY_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_TINY_QUANTUM))
-#define NUM_TINY_SLOTS 32 // number of slots for free-lists
+#define NUM_TINY_SLOTS 32 // number of slots for free-lists
-#define SHIFT_NUM_TINY_BLOCKS 16
-#define NUM_TINY_BLOCKS (1 << SHIFT_NUM_TINY_BLOCKS)
-#define TINY_BLOCKS_ALIGN (SHIFT_NUM_TINY_BLOCKS + SHIFT_TINY_QUANTUM)
-#define TINY_REGION_SIZE ((NUM_TINY_BLOCKS * TINY_QUANTUM + (NUM_TINY_BLOCKS >> 2) + 8 + (1 << vm_page_shift) - 1) & ~ ((1 << vm_page_shift) - 1)) // enough room for the data, followed by the bit arrays (2-bits per block) plus 2 words of padding as our bitmap operators overflow, plus rounding to the nearest page
+#define SHIFT_NUM_TINY_BLOCKS 16
+#define NUM_TINY_BLOCKS (1 << SHIFT_NUM_TINY_BLOCKS)
+#define TINY_BLOCKS_ALIGN (SHIFT_NUM_TINY_BLOCKS + SHIFT_TINY_QUANTUM)
-#define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[6])
-// At the end of free blocks, we stick the size (for enabling coalescing)
+/*
+ * Enough room for the data, followed by the bit arrays (2-bits per block) plus 2 words of padding
+ * as our bitmap operators overflow, plus rounding to the nearest page.
+ */
+#define TINY_REGION_SIZE ((NUM_TINY_BLOCKS * TINY_QUANTUM + (NUM_TINY_BLOCKS >> 2) + 8 + vm_page_size - 1) & ~ (vm_page_size - 1))
+
+/*
+ * Obtain the size of a free tiny block (in msize_t units).
+ */
+#ifdef __LP64__
+# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[14])
+#else
+# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[6])
+#endif
+/*
+ * The size is also kept at the very end of a free block.
+ */
#define TINY_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1]
+/*
+ * Beginning and end pointers for a region's heap.
+ */
+#define TINY_REGION_ADDRESS(region) ((void *)(region))
+#define TINY_REGION_END(region) (TINY_REGION_ADDRESS(region) + (1 << TINY_BLOCKS_ALIGN))
-#define TINY_REGION_ADDRESS(region) ((region) << TINY_BLOCKS_ALIGN)
-#define TINY_REGION_END(region) (TINY_REGION_ADDRESS(region)+(1 << TINY_BLOCKS_ALIGN))
+/*
+ * Locate the heap base for a pointer known to be within a tiny region.
+ */
+#define TINY_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << TINY_BLOCKS_ALIGN) - 1)))
-typedef unsigned short tiny_region_t;
+/*
+ * Convert between byte and msize units.
+ */
+#define TINY_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_TINY_QUANTUM)
+#define TINY_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_TINY_QUANTUM)
+
+/*
+ * Locate the block header for a pointer known to be within a tiny region.
+ */
+#define TINY_BLOCK_HEADER_FOR_PTR(_p) ((void *)(((((uintptr_t)(_p)) >> TINY_BLOCKS_ALIGN) + 1) << TINY_BLOCKS_ALIGN))
+
+/*
+ * Locate the inuse map for a given block header pointer.
+ */
+#define TINY_INUSE_FOR_HEADER(_h) ((void *)((uintptr_t)(_h) + (NUM_TINY_BLOCKS >> 3) + 4))
+
+/*
+ * Compute the bitmap index for a pointer known to be within a tiny region.
+ */
+#define TINY_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1))
+
+typedef void *tiny_region_t;
-#define INITIAL_NUM_TINY_REGIONS 24 // must be even for szone to be aligned
+#define INITIAL_NUM_TINY_REGIONS 24 // must be even for szone to be aligned
#define TINY_CACHE 1 // This governs a last-free cache of 1 that bypasses the free-list
/********************* DEFINITIONS for small ************************/
-/* We store the meta bits on the side in two bytes, as follows:
-- high order bit SMALL_IS_FREE is set when the block is avail (and starts here)
-- when block size, expressed in SMALL_QUANTUM, is the other 15 bits
-- else 0 signifies this block is in the middle of another block
-*/
+/*
+ * Memory in the Small range is allocated from regions (heaps) pointed to by the szone's small_regions
+ * pointer.
+ *
+ * Each region is laid out as a heap (8MB in 32-bit and 64-bit mode), followed by the metadata array.
+ * The array is arranged as an array of shorts, one for each SMALL_QUANTUM in the heap.
+ *
+ * The MSB of each short is set for the first quantum in a free block. The low 15 bits encode the
+ * block size (in SMALL_QUANTUM units), or are zero if the quantum is not the first in a block.
+ *
+ * The szone maintains an array of 32 freelists, each of which is used to hold free objects
+ * of the corresponding quantum size.
+ *
+ * A free block is laid out as:
+ *
+ * Offset (32-bit mode) (64-bit mode)
+ * 0x0 0x0
+ * checksum
+ * 0x4 0x08
+ * previous
+ * 0x8 0x10
+ * next
+ * 0xc 0x18
+ * size (in quantum counts)
+ * end - 2 end - 2
+ * size (in quantum counts)
+ * end end
+ *
+ * All fields are pointer-sized, except for the size which is an unsigned short.
+ *
+ */
-#define SMALL_IS_FREE (1 << 15)
+#define SMALL_IS_FREE (1 << 15)
#define SHIFT_SMALL_QUANTUM (SHIFT_TINY_QUANTUM + 5) // 9
#define SMALL_QUANTUM (1 << SHIFT_SMALL_QUANTUM) // 512 bytes
-#define FOLLOWING_SMALL_PTR(ptr,msize) (((char *)(ptr)) + ((msize) << SHIFT_SMALL_QUANTUM))
+#define FOLLOWING_SMALL_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_SMALL_QUANTUM))
-#define NUM_SMALL_SLOTS 32 // number of slots for free-lists
+#define NUM_SMALL_SLOTS 32 // number of slots for free-lists
-#define SHIFT_NUM_SMALL_BLOCKS 14 // we can only represent up to 1<<15 for msize; but we chose to stay even below that to avoid the convention msize=0 => msize = (1<<15)
-#define NUM_SMALL_BLOCKS (1 << SHIFT_NUM_SMALL_BLOCKS)
-#define SMALL_BLOCKS_ALIGN (SHIFT_NUM_SMALL_BLOCKS + SHIFT_SMALL_QUANTUM) // 23
+/*
+ * We can only represent up to 1<<15 for msize; but we choose to stay even below that to avoid the
+ * convention msize=0 => msize = (1<<15)
+ */
+#define SHIFT_NUM_SMALL_BLOCKS 14
+#define NUM_SMALL_BLOCKS (1 << SHIFT_NUM_SMALL_BLOCKS)
+#define SMALL_BLOCKS_ALIGN (SHIFT_NUM_SMALL_BLOCKS + SHIFT_SMALL_QUANTUM) // 23
#define SMALL_REGION_SIZE (NUM_SMALL_BLOCKS * SMALL_QUANTUM + NUM_SMALL_BLOCKS * 2) // data + meta data
#define SMALL_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1]
-#define SMALL_REGION_ADDRESS(region) (((unsigned)region) << SMALL_BLOCKS_ALIGN)
-#define SMALL_REGION_END(region) (SMALL_REGION_ADDRESS(region)+(1 << SMALL_BLOCKS_ALIGN))
+/*
+ * Convert between byte and msize units.
+ */
+#define SMALL_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_SMALL_QUANTUM)
+#define SMALL_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_SMALL_QUANTUM)
+
+
+#define SMALL_REGION_ADDRESS(region) ((unsigned char *)region)
+#define SMALL_REGION_END(region) (SMALL_REGION_ADDRESS(region) + (1 << SMALL_BLOCKS_ALIGN))
+
+/*
+ * Locate the heap base for a pointer known to be within a small region.
+ */
+#define SMALL_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << SMALL_BLOCKS_ALIGN) - 1)))
+
+/*
+ * Locate the metadata base for a pointer known to be within a small region.
+ */
+#define SMALL_META_HEADER_FOR_PTR(_p) ((msize_t *)(((((uintptr_t)(_p)) >> SMALL_BLOCKS_ALIGN) + 1) << SMALL_BLOCKS_ALIGN))
+
+/*
+ * Compute the metadata index for a pointer known to be within a small region.
+ */
+#define SMALL_META_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_SMALL_QUANTUM) & (NUM_SMALL_BLOCKS - 1))
+
+/*
+ * Find the metadata word for a pointer known to be within a small region.
+ */
+#define SMALL_METADATA_FOR_PTR(_p) (SMALL_META_HEADER_FOR_PTR(_p) + SMALL_META_INDEX_FOR_PTR(_p))
+
+/*
+ * Determine whether a pointer known to be within a small region points to memory which is free.
+ */
+#define SMALL_PTR_IS_FREE(_p) (*SMALL_METADATA_FOR_PTR(_p) & SMALL_IS_FREE)
-typedef unsigned short small_region_t;
+/*
+ * Extract the msize value for a pointer known to be within a small region.
+ */
+#define SMALL_PTR_SIZE(_p) (*SMALL_METADATA_FOR_PTR(_p) & ~SMALL_IS_FREE)
+
+typedef void * small_region_t;
-#define INITIAL_NUM_SMALL_REGIONS 6 // must be even for szone to be aligned
+#define INITIAL_NUM_SMALL_REGIONS 6 // must be even for szone to be aligned
-#define PROTECT_SMALL 0 // Should be 0: 1 is too slow for normal use
+#define PROTECT_SMALL 0 // Should be 0: 1 is too slow for normal use
#define SMALL_CACHE 1
#if !SMALL_CACHE
// But if the memory is only read, vm_copy() wins over memmove() at 3 or 4 pages (on a G3/300MHz)
// This must be larger than LARGE_THRESHOLD
+/*
+ * Given a large_entry, return the address of the allocated block.
+ */
#define LARGE_ENTRY_ADDRESS(entry) \
- (((entry).address_and_num_pages >> vm_page_shift) << vm_page_shift)
+ (void *)(((entry).address_and_num_pages >> vm_page_shift) << vm_page_shift)
+
+/*
+ * Given a large entry, return the number of pages or bytes in the allocated block.
+ */
#define LARGE_ENTRY_NUM_PAGES(entry) \
- ((entry).address_and_num_pages & ((1 << vm_page_shift) - 1))
+ ((entry).address_and_num_pages & (vm_page_size - 1))
#define LARGE_ENTRY_SIZE(entry) \
(LARGE_ENTRY_NUM_PAGES(entry) << vm_page_shift)
+
+/*
+ * Compare a pointer with a large entry.
+ */
#define LARGE_ENTRY_MATCHES(entry,ptr) \
- (!(((entry).address_and_num_pages - (unsigned)(ptr)) >> vm_page_shift))
-#define LARGE_ENTRY_IS_EMPTY(entry) (!((entry).address_and_num_pages))
+ ((((entry).address_and_num_pages - (uintptr_t)(ptr)) >> vm_page_shift) == 0)
+
+#define LARGE_ENTRY_IS_EMPTY(entry) (((entry).address_and_num_pages) == 0)
typedef compact_range_t large_entry_t;
free_list_t *tiny_free_list[NUM_TINY_SLOTS]; // 31 free lists for 1*TINY_QUANTUM to 31*TINY_QUANTUM plus 1 for larger than 32*SMALL_QUANTUM
size_t tiny_bytes_free_at_end; // the last free region in the last block is treated as a big block in use that is not accounted for
unsigned num_tiny_objects;
- unsigned num_bytes_in_tiny_objects;
+ size_t num_bytes_in_tiny_objects;
/* Regions for small objects */
unsigned num_small_regions;
free_list_t *small_free_list[NUM_SMALL_SLOTS];
size_t small_bytes_free_at_end; // the last free region in the last block is treated as a big block in use that is not accounted for
unsigned num_small_objects;
- unsigned num_bytes_in_small_objects;
+ size_t num_bytes_in_small_objects;
/* large objects: vm_page_shift <= log2(size) < 2 *vm_page_shift */
unsigned num_large_objects_in_use;
unsigned num_large_entries;
large_entry_t *large_entries; // hashed by location; null entries don't count
- unsigned num_bytes_in_large_objects;
+ size_t num_bytes_in_large_objects;
/* huge objects: log2(size) >= 2 *vm_page_shift */
- unsigned char num_huge_entries;
+ unsigned num_huge_entries;
huge_entry_t *huge_entries;
- unsigned num_bytes_in_huge_objects;
+ size_t num_bytes_in_huge_objects;
/* Initial region list */
tiny_region_t initial_tiny_regions[INITIAL_NUM_TINY_REGIONS];
small_region_t initial_small_regions[INITIAL_NUM_SMALL_REGIONS];
} szone_t;
-static void *szone_malloc(szone_t *szone, size_t size);
-static INLINE void *szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested);
-static void szone_free(szone_t *szone, void *ptr);
-static boolean_t szone_check_all(szone_t *szone, const char *function);
-static void szone_print(szone_t *szone, boolean_t verbose);
-static void *small_malloc_from_region_no_lock(szone_t *szone, msize_t msize);
+#if DEBUG_MALLOC || DEBUG_CLIENT
+static void szone_sleep(void);
+#endif
+static void szone_error(szone_t *szone, const char *msg, const void *ptr);
+static void protect(szone_t *szone, void *address, size_t size, unsigned protection, unsigned debug_flags);
+static void *allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label);
+static void deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags);
+static kern_return_t _szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr);
+
+static INLINE void free_list_checksum(szone_t *szone, free_list_t *ptr, const char *msg);
+static INLINE void free_list_set_checksum(szone_t *szone, free_list_t *ptr);
+static unsigned free_list_count(const free_list_t *ptr);
+
+static INLINE msize_t get_tiny_meta_header(const void *ptr, boolean_t *is_free);
+static INLINE void set_tiny_meta_header_in_use(const void *ptr, msize_t msize);
+static INLINE void set_tiny_meta_header_middle(const void *ptr);
+static INLINE void set_tiny_meta_header_free(const void *ptr, msize_t msize);
+static INLINE boolean_t tiny_meta_header_is_free(const void *ptr);
+static INLINE void *tiny_previous_preceding_free(void *ptr, msize_t *prev_msize);
+static INLINE void tiny_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize);
+static INLINE void tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize);
+static INLINE tiny_region_t *tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr);
+static INLINE void tiny_free_no_lock(szone_t *szone, tiny_region_t *region, void *ptr, msize_t msize);
+static void *tiny_malloc_from_region_no_lock(szone_t *szone, msize_t msize);
+static INLINE boolean_t try_realloc_tiny_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size);
+static boolean_t tiny_check_region(szone_t *szone, tiny_region_t *region);
+static kern_return_t tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t region_address, unsigned short num_regions, size_t tiny_bytes_free_at_end, memory_reader_t reader, vm_range_recorder_t recorder);
+static INLINE void *tiny_malloc_from_free_list(szone_t *szone, msize_t msize);
+static INLINE void *tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested);
+static INLINE void free_tiny(szone_t *szone, void *ptr, tiny_region_t *tiny_region);
+static void print_tiny_free_list(szone_t *szone);
+static void print_tiny_region(boolean_t verbose, tiny_region_t region, size_t bytes_at_end);
+static boolean_t tiny_free_list_check(szone_t *szone, grain_t slot);
+
+static INLINE void small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize);
+static INLINE void small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize);
+static INLINE void small_meta_header_set_middle(msize_t *meta_headers, msize_t index);
+static void small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize);
+static void small_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize);
+static INLINE small_region_t *small_region_for_ptr_no_lock(szone_t *szone, const void *ptr);
+static INLINE void small_free_no_lock(szone_t *szone, small_region_t *region, void *ptr, msize_t msize);
+static void *small_malloc_from_region_no_lock(szone_t *szone, msize_t msize);
+static INLINE boolean_t try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size);
+static boolean_t szone_check_small_region(szone_t *szone, small_region_t *region);
+static kern_return_t small_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t region_address, unsigned short num_regions, size_t small_bytes_free_at_end, memory_reader_t reader, vm_range_recorder_t recorder);
+static INLINE void *small_malloc_from_free_list(szone_t *szone, msize_t msize);
+static INLINE void *small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested);
+static INLINE void *small_malloc_cleared_no_lock(szone_t *szone, msize_t msize);
+static INLINE void free_small(szone_t *szone, void *ptr, small_region_t *small_region);
+static void print_small_free_list(szone_t *szone);
+static void print_small_region(szone_t *szone, boolean_t verbose, small_region_t *region, size_t bytes_at_end);
+static boolean_t small_free_list_check(szone_t *szone, grain_t grain);
#if DEBUG_MALLOC
-#define LOG(szone,ptr) \
- (szone->log_address && (((unsigned)szone->log_address == -1) || (szone->log_address == (void *)(ptr))))
+static void large_debug_print(szone_t *szone);
+#endif
+static large_entry_t *large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr);
+static void large_entry_insert_no_lock(szone_t *szone, large_entry_t range);
+static INLINE void large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry);
+static INLINE large_entry_t *large_entries_alloc_no_lock(szone_t *szone, unsigned num);
+static void large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate);
+static void large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate);
+static vm_range_t large_free_no_lock(szone_t *szone, large_entry_t *entry);
+static kern_return_t large_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t large_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder);
+static huge_entry_t *huge_entry_for_pointer_no_lock(szone_t *szone, const void *ptr);
+static boolean_t huge_entry_append(szone_t *szone, huge_entry_t huge);
+static kern_return_t huge_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t huge_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder);
+static void *large_and_huge_malloc(szone_t *szone, unsigned num_pages);
+static INLINE void free_large_or_huge(szone_t *szone, void *ptr);
+static INLINE int try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size);
+
+static void szone_free(szone_t *szone, void *ptr);
+static INLINE void *szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested);
+static void *szone_malloc(szone_t *szone, size_t size);
+static void *szone_calloc(szone_t *szone, size_t num_items, size_t size);
+static void *szone_valloc(szone_t *szone, size_t size);
+static size_t szone_size(szone_t *szone, const void *ptr);
+static void *szone_realloc(szone_t *szone, void *ptr, size_t new_size);
+static unsigned szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count);
+static void szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count);
+static void szone_destroy(szone_t *szone);
+static size_t szone_good_size(szone_t *szone, size_t size);
+
+static boolean_t szone_check_all(szone_t *szone, const char *function);
+static boolean_t szone_check(szone_t *szone);
+static kern_return_t szone_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder);
+static void szone_print(szone_t *szone, boolean_t verbose);
+static void szone_log(malloc_zone_t *zone, void *log_address);
+static void szone_force_lock(szone_t *szone);
+static void szone_force_unlock(szone_t *szone);
+
+static void szone_statistics(szone_t *szone, malloc_statistics_t *stats);
+
+static void *frozen_malloc(szone_t *zone, size_t new_size);
+static void *frozen_calloc(szone_t *zone, size_t num_items, size_t size);
+static void *frozen_valloc(szone_t *zone, size_t new_size);
+static void *frozen_realloc(szone_t *zone, void *ptr, size_t new_size);
+static void frozen_free(szone_t *zone, void *ptr);
+static void frozen_destroy(szone_t *zone);
+
+#if DEBUG_MALLOC
+# define LOG(szone,ptr) \
+ (szone->log_address && (((uintptr_t)szone->log_address == -1) || (szone->log_address == (void *)(ptr))))
#else
-#define LOG(szone,ptr) 0
+# define LOG(szone,ptr) 0
#endif
-#define SZONE_LOCK(szone) { \
- LOCK(szone->lock); \
-}
+#define SZONE_LOCK(szone) \
+ do { \
+ LOCK(szone->lock); \
+ } while (0)
-#define SZONE_UNLOCK(szone) { \
- UNLOCK(szone->lock); \
-}
+#define SZONE_UNLOCK(szone) \
+ do { \
+ UNLOCK(szone->lock); \
+ } while (0)
-#define LOCK_AND_NOTE_LOCKED(szone,locked) { \
- CHECK(szone, __PRETTY_FUNCTION__); \
- locked = 1; SZONE_LOCK(szone); \
-}
+#define LOCK_AND_NOTE_LOCKED(szone,locked) \
+do { \
+ CHECK(szone, __PRETTY_FUNCTION__); \
+ locked = 1; SZONE_LOCK(szone); \
+} while (0)
#if DEBUG_MALLOC || DEBUG_CLIENT
-#define CHECK(szone,fun) \
+# define CHECK(szone,fun) \
if ((szone)->debug_flags & CHECK_REGIONS) szone_check_all(szone, fun)
#else
-#define CHECK(szone,fun) {}
+# define CHECK(szone,fun) do {} while (0)
#endif
/********************* VERY LOW LEVEL UTILITIES ************************/
#if DEBUG_MALLOC || DEBUG_CLIENT
static void
-szone_sleep(void) {
+szone_sleep(void)
+{
+
if (getenv("MallocErrorSleep")) {
- malloc_printf("*** Sleeping to help debug\n");
+ malloc_printf("*** sleeping to help debug\n");
sleep(3600); // to help debug
}
}
#endif
static void
-szone_error(szone_t *szone, const char *msg, const void *ptr) {
+szone_error(szone_t *szone, const char *msg, const void *ptr)
+{
+
if (szone) SZONE_UNLOCK(szone);
if (ptr) {
- malloc_printf("*** malloc[%d]: error for object %p: %s\n", getpid(), ptr, msg);
+ malloc_printf("*** error for object %p: %s\n", ptr, msg);
} else {
- malloc_printf("*** malloc[%d]: error: %s\n", getpid(), msg);
+ malloc_printf("*** error: %s\n", msg);
}
#if DEBUG_MALLOC
szone_print(szone, 1);
}
static void
-protect(szone_t *szone, vm_address_t address, vm_size_t size,
- unsigned protection, unsigned debug_flags) {
+protect(szone_t *szone, void *address, size_t size, unsigned protection, unsigned debug_flags)
+{
kern_return_t err;
+
if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_PRELUDE)) {
- err = vm_protect(mach_task_self(), address - (1 << vm_page_shift), 1 << vm_page_shift,
- 0, protection);
+ err = vm_protect(mach_task_self(), (vm_address_t)(uintptr_t)address - vm_page_size, vm_page_size, 0, protection);
if (err) {
- malloc_printf("*** malloc[%d]: Can't protect(%p) region for "
- "prelude guard page at %p\n", getpid(), protection,
- address - (1 << vm_page_shift));
+ malloc_printf("*** can't protect(%p) region for prelude guard page at %p\n",
+ protection,address - (1 << vm_page_shift));
}
}
if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE)) {
- err = vm_protect(mach_task_self(), (vm_address_t)(address + size), 1 << vm_page_shift, 0, protection);
+ err = vm_protect(mach_task_self(), (vm_address_t)(uintptr_t)address + size, vm_page_size, 0, protection);
if (err) {
- malloc_printf("*** malloc[%d]: Can't protect(%p) region for "
- "postlude guard page at %p\n", getpid(), protection,
- address + size);
+ malloc_printf("*** can't protect(%p) region for postlude guard page at %p\n",
+ protection, address + size);
}
}
}
-static vm_address_t
-allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label) {
+static void *
+allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label)
+{
// align specifies a desired alignment (as a log) or 0 if no alignment requested
kern_return_t err;
- vm_address_t addr;
+ vm_address_t vm_addr;
+ uintptr_t addr, aligned_address;
boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES;
size_t allocation_size = round_page(size);
+ size_t delta;
+
if (align) add_guard_pages = 0; // too cumbersome to deal with that
if (!allocation_size) allocation_size = 1 << vm_page_shift;
if (add_guard_pages) allocation_size += 2 * (1 << vm_page_shift);
- if (align) allocation_size += 1 << align;
- err = vm_allocate(mach_task_self(), &addr, allocation_size, vm_page_label | 1);
+ if (align) allocation_size += (size_t)1 << align;
+ err = vm_allocate(mach_task_self(), &vm_addr, allocation_size, vm_page_label | 1);
if (err) {
- malloc_printf("*** malloc: vm_allocate(size=%d) failed (error code=%d)\n", size, err);
- szone_error(szone, "Can't allocate region", NULL);
+ malloc_printf("*** vm_allocate(size=%lld) failed (error code=%d)\n", (long long)size, err);
+ szone_error(szone, "can't allocate region", NULL);
return NULL;
}
+ addr = (uintptr_t)vm_addr;
if (align) {
- // malloc_printf("In allocate_pages(size=%d(%p), align=%d) -> %p\n", size, size, align, addr);
- vm_address_t aligned_address = (addr + (1 << align) - 1) & ~ ((1 << align) - 1);
+ aligned_address = (addr + ((uintptr_t)1 << align) - 1) & ~ (((uintptr_t)1 << align) - 1);
if (aligned_address != addr) {
- size_t delta = aligned_address - addr;
- err = vm_deallocate(mach_task_self(), addr, delta);
- if (err) malloc_printf("*** malloc: freeing unaligned header failed with %d\n", err);
- // malloc_printf("deallocated unaligned header %p length=%d(%p)\n", addr, delta, delta);
+ delta = aligned_address - addr;
+ err = vm_deallocate(mach_task_self(), (vm_address_t)addr, delta);
+ if (err)
+ malloc_printf("*** freeing unaligned header failed with %d\n", err);
addr = aligned_address;
allocation_size -= delta;
}
if (allocation_size > size) {
- err = vm_deallocate(mach_task_self(), addr+size, allocation_size - size);
- if (err) malloc_printf("*** malloc: freeing unaligned footer failed with %d\n", err);
+ err = vm_deallocate(mach_task_self(), (vm_address_t)addr + size, allocation_size - size);
+ if (err)
+ malloc_printf("*** freeing unaligned footer failed with %d\n", err);
}
}
if (add_guard_pages) {
- addr += 1 << vm_page_shift;
- protect(szone, addr, size, 0, debug_flags);
+ addr += (uintptr_t)1 << vm_page_shift;
+ protect(szone, (void *)addr, size, 0, debug_flags);
}
- return addr;
+ return (void *)addr;
}
static void
-deallocate_pages(szone_t *szone, vm_address_t addr, size_t size, unsigned debug_flags) {
+deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags)
+{
kern_return_t err;
boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES;
+
if (add_guard_pages) {
addr -= 1 << vm_page_shift;
size += 2 * (1 << vm_page_shift);
}
- err = vm_deallocate(mach_task_self(), addr, size);
- if (err) {
- szone_error(szone, "Can't deallocate_pages region", (void *)addr);
- }
+ err = vm_deallocate(mach_task_self(), (vm_address_t)addr, size);
+ if (err && szone)
+ szone_error(szone, "Can't deallocate_pages region", addr);
}
static kern_return_t
-_szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) {
+_szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr)
+{
*ptr = (void *)address;
return 0;
}
static INLINE void
-free_list_checksum(szone_t *szone, free_list_t *ptr, const char *msg) {
- // We always checksum, as testing whether to do it (based on szone->debug_flags) is as fast as doing it
- if (ptr->checksum != (((unsigned)ptr->previous) ^ ((unsigned)ptr->next) ^ CHECKSUM_MAGIC)) {
+free_list_checksum(szone_t *szone, free_list_t *ptr, const char *msg)
+{
+ // We always checksum, as testing whether to do it (based on szone->debug_flags) is as fast as
+ // doing it
+ // XXX not necessarily true for LP64 case
+ if (ptr->checksum != (((uintptr_t)ptr->previous) ^ ((uintptr_t)ptr->next) ^ CHECKSUM_MAGIC)) {
#if DEBUG_MALLOC
- malloc_printf("*** Incorrect checksum: %s\n", msg);
+ malloc_printf("*** incorrect checksum: %s\n", msg);
#endif
- szone_error(szone, "Incorrect checksum for freed object - object was probably modified after being freed; break at szone_error", ptr);
+ szone_error(szone, "incorrect checksum for freed object "
+ "- object was probably modified after being freed, break at szone_error to debug", ptr);
}
}
static INLINE void
-free_list_set_checksum(szone_t *szone, free_list_t *ptr) {
+free_list_set_checksum(szone_t *szone, free_list_t *ptr)
+{
// We always set checksum, as testing whether to do it (based on
// szone->debug_flags) is slower than just doing it
- ptr->checksum = ((unsigned)ptr->previous) ^ ((unsigned)ptr->next) ^ CHECKSUM_MAGIC;
+ // XXX not necessarily true for LP64 case
+ ptr->checksum = ((uintptr_t)ptr->previous) ^ ((uintptr_t)ptr->next) ^ CHECKSUM_MAGIC;
}
static unsigned
-free_list_count(const free_list_t *ptr) {
+free_list_count(const free_list_t *ptr)
+{
unsigned count = 0;
+
while (ptr) {
count++;
-// malloc_printf("%p ", ptr);
ptr = ptr->next;
}
return count;
}
+/* XXX inconsistent use of BITMAP32 and BITARRAY operations could be cleaned up */
+
#define BITMAP32_SET(bitmap,bit) (bitmap |= 1 << (bit))
#define BITMAP32_CLR(bitmap,bit) (bitmap &= ~ (1 << (bit)))
#define BITMAP32_BIT(bitmap,bit) ((bitmap >> (bit)) & 1)
#define BITARRAY_BIT(bits,index) (((bits[index>>3]) >> (index & 7)) & 1)
// Following is for start<8 and end<=start+32
-#define BITARRAY_MCLR_LESS_32(bits,start,end) { \
- unsigned char *_bits = (bits); \
- unsigned _end = (end); \
- switch (_end >> 3) { \
- case 4: _bits[4] &= ~ ((1 << (_end - 32)) - 1); _end = 32; \
+#define BITARRAY_MCLR_LESS_32(bits,start,end) \
+do { \
+ unsigned char *_bits = (bits); \
+ unsigned _end = (end); \
+ switch (_end >> 3) { \
+ case 4: _bits[4] &= ~ ((1 << (_end - 32)) - 1); _end = 32; \
case 3: _bits[3] &= ~ ((1 << (_end - 24)) - 1); _end = 24; \
- case 2: _bits[2] &= ~ ((1 << (_end - 16)) - 1); _end = 16; \
- case 1: _bits[1] &= ~ ((1 << (_end - 8)) - 1); _end = 8; \
+ case 2: _bits[2] &= ~ ((1 << (_end - 16)) - 1); _end = 16; \
+ case 1: _bits[1] &= ~ ((1 << (_end - 8)) - 1); _end = 8; \
case 0: _bits[0] &= ~ ((1 << _end) - (1 << (start))); \
- } \
-}
+ } \
+} while (0)
#if 0 // Simple but slow version
#warning Slow version in effect
-#define BITARRAY_MCLR(bits,index,num) { \
- unsigned _ctr = (num); \
- unsigned _cur = (index); \
- while (_ctr--) {BITARRAY_CLR(bits,_cur); _cur++; } \
-}
+#define BITARRAY_MCLR(bits,index,num) \
+do { \
+ unsigned _ctr = (num); \
+ unsigned _cur = (index); \
+ \
+ while (_ctr--) {BITARRAY_CLR(bits,_cur); _cur++; } \
+} while (0)
#else
// Following is for num <= 32
-#define BITARRAY_MCLR(bits,index,num) { \
- unsigned _index = (index); \
- unsigned char *_rebased = (bits) + (_index >> 3); \
- _index &= 7; \
- BITARRAY_MCLR_LESS_32(_rebased, _index, _index + (num)); \
-}
+#define BITARRAY_MCLR(bits,index,num) \
+do { \
+ unsigned _index = (index); \
+ unsigned char *_rebased = (bits) + (_index >> 3); \
+ \
+ _index &= 7; \
+ BITARRAY_MCLR_LESS_32(_rebased, _index, _index + (num)); \
+} while (0)
#endif
static INLINE msize_t
-get_tiny_meta_header(const void *ptr, boolean_t *is_free) {
+get_tiny_meta_header(const void *ptr, boolean_t *is_free)
+{
// returns msize and is_free
// may return 0 for the msize component (meaning 65536)
- unsigned short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN;
- unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN;
- unsigned char *block_header = (unsigned char *)headers_start;
- msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1);
- unsigned byte_index = index >> 3;
+ unsigned char *block_header;
+ unsigned char *in_use;
+ msize_t index;
+ unsigned byte_index;
+
+ block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
+ index = TINY_INDEX_FOR_PTR(ptr);
+ byte_index = index >> 3;
+
block_header += byte_index;
index &= 7;
*is_free = 0;
- if (!BITMAP32_BIT(*block_header, index)) return 0;
- unsigned char *in_use = block_header + (NUM_TINY_BLOCKS >> 3) + 4;
+ if (!BITMAP32_BIT(*block_header, index))
+ return 0;
+ in_use = TINY_INUSE_FOR_HEADER(block_header);
if (!BITMAP32_BIT(*in_use, index)) {
*is_free = 1;
return TINY_FREE_SIZE(ptr);
}
-#if defined(__BIG_ENDIAN__)
- unsigned *addr = (void *)((unsigned)block_header & ~3);
- unsigned word0 = OSReadSwapInt32(addr, 0);
- unsigned word1 = OSReadSwapInt32(addr, 4);
- unsigned bits = index + (((unsigned)block_header & 3) * 8);
- unsigned word = (word0 >> bits) | (word1 << (32 - bits));
- unsigned result = ffs(word >> 1);
-#if DEBUG_MALLOC
- if (result >= 32) {
- malloc_printf("*** get_tiny_meta_header() invariant broken %p %d\n", ptr, result);
- szone_sleep();
- }
-#endif
+ uint32_t *addr = (uint32_t *)((uintptr_t)block_header & ~3);
+ uint32_t word0 = OSReadLittleInt32(addr, 0) >> index;
+ uint32_t word1 = OSReadLittleInt32(addr, 4) << (8 - index);
+ uint32_t bits = (((uintptr_t)block_header & 3) * 8); // precision loss on LP64 OK here
+ uint32_t word = (word0 >> bits) | (word1 << (24 - bits));
+ uint32_t result = ffs(word >> 1);
return result;
-#else
- unsigned cur = index + 1;
- while (!BITARRAY_BIT(block_header, cur)) cur++; // assumes padding at the zone end
-#if DEBUG_MALLOC
- if (cur - index >= 32) {
- malloc_printf("*** get_tiny_meta_header() invariant broken %p %d %d\n", ptr, index, cur);
- szone_sleep();
- }
-#endif
- return cur - index;
-#endif
}
static INLINE void
-set_tiny_meta_header_in_use(const void *ptr, msize_t msize) {
- unsigned short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN;
- unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN;
- unsigned char *block_header = (unsigned char *)headers_start;
- msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1);
+set_tiny_meta_header_in_use(const void *ptr, msize_t msize)
+{
+ unsigned char *block_header;
+ unsigned char *in_use;
+ msize_t index;
+ unsigned byte_index;
+ msize_t clr_msize;
+ unsigned end_bit;
+
+ block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
+ index = TINY_INDEX_FOR_PTR(ptr);
+ byte_index = index >> 3;
+
#if DEBUG_MALLOC
- if (msize >= 32) malloc_printf("*** set_tiny_meta_header_in_use() invariant broken %p %d\n", ptr, msize);
- if ((unsigned)index + (unsigned)msize > 0x10000) malloc_printf("*** set_tiny_meta_header_in_use() invariant broken (2) %p %d\n", ptr, msize);
+ if (msize >= 32)
+ malloc_printf("set_tiny_meta_header_in_use() invariant broken %p %d\n", ptr, msize);
+ if ((unsigned)index + (unsigned)msize > 0x10000)
+ malloc_printf("set_tiny_meta_header_in_use() invariant broken (2) %p %d\n", ptr, msize);
#endif
- unsigned byte_index = index >> 3;
block_header += byte_index;
index &= 7;
BITMAP32_SET(*block_header, index);
- unsigned char *in_use = block_header + (NUM_TINY_BLOCKS >> 3) + 4;
+ in_use = TINY_INUSE_FOR_HEADER(block_header);
BITMAP32_SET(*in_use, index);
index++;
- msize_t clr_msize = msize-1;
+ clr_msize = msize-1;
if (clr_msize) {
byte_index = index >> 3;
block_header += byte_index; in_use += byte_index;
index &= 7;
- unsigned end_bit = index + clr_msize;
+ end_bit = index + clr_msize;
BITARRAY_MCLR_LESS_32(block_header, index, end_bit);
BITARRAY_MCLR_LESS_32(in_use, index, end_bit);
}
BITARRAY_SET(block_header, index+clr_msize); // we set the block_header bit for the following block to reaffirm next block is a block
#if DEBUG_MALLOC
- boolean_t ff;
- msize_t mf = get_tiny_meta_header(ptr, &ff);
- if (msize != mf) {
- malloc_printf("*** setting header for tiny in_use %p : %d\n", ptr, msize);
- malloc_printf("reading header for tiny %p : %d %d\n", ptr, mf, ff);
+ {
+ boolean_t ff;
+ msize_t mf;
+
+ mf = get_tiny_meta_header(ptr, &ff);
+ if (msize != mf) {
+ malloc_printf("setting header for tiny in_use %p : %d\n", ptr, msize);
+ malloc_printf("reading header for tiny %p : %d %d\n", ptr, mf, ff);
+ }
}
#endif
}
static INLINE void
-set_tiny_meta_header_middle(const void *ptr) {
+set_tiny_meta_header_middle(const void *ptr)
+{
// indicates this block is in the middle of an in use block
- unsigned short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN;
- unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN;
- unsigned char *block_header = (unsigned char *)headers_start;
- unsigned char *in_use = (unsigned char *)(headers_start + (NUM_TINY_BLOCKS >> 3) + 4);
- msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1);
- BITARRAY_CLR(block_header, index); BITARRAY_CLR(in_use, index);
+ unsigned char *block_header;
+ unsigned char *in_use;
+ msize_t index;
+
+ block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
+ in_use = TINY_INUSE_FOR_HEADER(block_header);
+ index = TINY_INDEX_FOR_PTR(ptr);
+
+ BITARRAY_CLR(block_header, index);
+ BITARRAY_CLR(in_use, index);
TINY_FREE_SIZE(ptr) = 0;
}
static INLINE void
-set_tiny_meta_header_free(const void *ptr, msize_t msize) {
+set_tiny_meta_header_free(const void *ptr, msize_t msize)
+{
// !msize is acceptable and means 65536
- unsigned short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN;
- unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN;
- unsigned char *block_header = (unsigned char *)headers_start;
- unsigned char *in_use = (unsigned char *)(headers_start + (NUM_TINY_BLOCKS >> 3) + 4);
- msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1);
+ unsigned char *block_header;
+ unsigned char *in_use;
+ msize_t index;
+
+ block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
+ in_use = TINY_INUSE_FOR_HEADER(block_header);
+ index = TINY_INDEX_FOR_PTR(ptr);
+
#if DEBUG_MALLOC
if ((unsigned)index + (unsigned)msize > 0x10000) {
- malloc_printf("*** setting header for tiny free %p msize too large: %d\n", ptr, msize);
+ malloc_printf("setting header for tiny free %p msize too large: %d\n", ptr, msize);
}
#endif
BITARRAY_SET(block_header, index); BITARRAY_CLR(in_use, index);
boolean_t ff;
msize_t mf = get_tiny_meta_header(ptr, &ff);
if ((msize != mf) || !ff) {
- malloc_printf("*** setting header for tiny free %p : %d\n", ptr, msize);
+ malloc_printf("setting header for tiny free %p : %d\n", ptr, msize);
malloc_printf("reading header for tiny %p : %d %d\n", ptr, mf, ff);
}
#endif
}
static INLINE boolean_t
-tiny_meta_header_is_free(const void *ptr) {
+tiny_meta_header_is_free(const void *ptr)
+{
// returns msize and is_free shifted by 16
// may return 0 for the msize component (meaning 65536)
- unsigned short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN;
- unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN;
- unsigned char *block_header = (unsigned char *)headers_start;
- unsigned char *in_use = (unsigned char *)(headers_start + (NUM_TINY_BLOCKS >> 3) + 4);
- msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1);
- if (!BITARRAY_BIT(block_header, index)) return 0;
+ unsigned char *block_header;
+ unsigned char *in_use;
+ msize_t index;
+
+ block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
+ in_use = TINY_INUSE_FOR_HEADER(block_header);
+ index = TINY_INDEX_FOR_PTR(ptr);
+ if (!BITARRAY_BIT(block_header, index))
+ return 0;
return !BITARRAY_BIT(in_use, index);
}
static INLINE void *
-tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) {
+tiny_previous_preceding_free(void *ptr, msize_t *prev_msize)
+{
// returns the previous block, assuming and verifying it's free
- unsigned short shifted_base = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN;
- unsigned headers_start = (shifted_base + 1) << TINY_BLOCKS_ALIGN;
- unsigned char *block_header = (unsigned char *)headers_start;
- unsigned char *in_use = (unsigned char *)(headers_start + (NUM_TINY_BLOCKS >> 3) + 4);
- msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1);
- if (!index) return NULL;
- msize_t previous_msize = TINY_PREVIOUS_MSIZE(ptr);
- if (previous_msize > index) return NULL;
- msize_t previous_index = index - previous_msize;
- void *previous_ptr = (void *)((shifted_base << TINY_BLOCKS_ALIGN) + (previous_index << SHIFT_TINY_QUANTUM));
- if (TINY_FREE_SIZE(previous_ptr) != previous_msize) return NULL;
- if (!BITARRAY_BIT(block_header, previous_index)) return NULL;
- if (BITARRAY_BIT(in_use, previous_index)) return NULL;
+ unsigned char *block_header;
+ unsigned char *in_use;
+ msize_t index;
+ msize_t previous_msize;
+ msize_t previous_index;
+ void *previous_ptr;
+
+ block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
+ in_use = TINY_INUSE_FOR_HEADER(block_header);
+ index = TINY_INDEX_FOR_PTR(ptr);
+
+ if (!index)
+ return NULL;
+ if ((previous_msize = TINY_PREVIOUS_MSIZE(ptr)) > index)
+ return NULL;
+
+ previous_index = index - previous_msize;
+ previous_ptr = (void *)(TINY_REGION_FOR_PTR(ptr) + TINY_BYTES_FOR_MSIZE(previous_index));
+ if (TINY_FREE_SIZE(previous_ptr) != previous_msize)
+ return NULL;
+
+ if (!BITARRAY_BIT(block_header, previous_index))
+ return NULL;
+ if (BITARRAY_BIT(in_use, previous_index))
+ return NULL;
+
// conservative check did match true check
*prev_msize = previous_msize;
- // malloc_printf("tiny_previous_preceding_free(%p) -> %p,%d\n", ptr, previous_ptr, previous_msize);
return previous_ptr;
}
static INLINE void
-tiny_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) {
+tiny_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize)
+{
// Adds an item to the proper free list
// Also marks the meta-header of the block properly
// Assumes szone has been locked
grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1;
free_list_t *free_ptr = ptr;
free_list_t *free_head = szone->tiny_free_list[slot];
+
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In tiny_free_list_add_ptr(), ptr=%p, msize=%d\n", ptr, msize);
+ malloc_printf("in tiny_free_list_add_ptr(), ptr=%p, msize=%d\n", ptr, msize);
}
if (((unsigned)ptr) & (TINY_QUANTUM - 1)) {
szone_error(szone, "tiny_free_list_add_ptr: Unaligned ptr", ptr);
free_ptr->next = free_head;
free_list_set_checksum(szone, free_ptr);
szone->tiny_free_list[slot] = free_ptr;
- // malloc_printf("Setting head of free list for slot=%d to %p\n", slot, free_ptr);
}
static INLINE void
-tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize) {
+tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize)
+{
// Removes item in the proper free list
// msize could be read, but all callers have it so we pass it in
// Assumes szone has been locked
free_list_t *free_ptr = ptr;
free_list_t *next = free_ptr->next;
free_list_t *previous = free_ptr->previous;
+
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
malloc_printf("In tiny_free_list_remove_ptr(), ptr=%p, msize=%d\n", ptr, msize);
// The block to remove is the head of the free list
#if DEBUG_MALLOC
if (szone->tiny_free_list[slot] != ptr) {
- malloc_printf("ptr=%p slot=%d msize=%d szone->tiny_free_list[slot]=%p\n", ptr, slot, msize, szone->tiny_free_list[slot]);
+ malloc_printf("ptr=%p slot=%d msize=%d szone->tiny_free_list[slot]=%p\n",
+ ptr, slot, msize, szone->tiny_free_list[slot]);
szone_error(szone, "tiny_free_list_remove_ptr: Internal invariant broken (szone->tiny_free_list[slot])", ptr);
return;
}
}
}
+/*
+ * Find the tiny region containing (ptr) (if any).
+ *
+ * We take advantage of the knowledge that tiny regions are always (1 << TINY_BLOCKS_ALIGN) aligned.
+ */
static INLINE tiny_region_t *
-tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) {
- tiny_region_t *region = szone->tiny_regions;
- unsigned num_regions = szone->num_tiny_regions;
- unsigned ptr_shifted = ((unsigned)ptr) >> TINY_BLOCKS_ALIGN;
- while (num_regions--) {
- tiny_region_t this = *region;
- if (ptr_shifted == this) return region;
- region++;
- }
- return NULL;
+tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr)
+{
+ tiny_region_t *region;
+ tiny_region_t rbase;
+ int i;
+
+ /* mask off irrelevant lower bits */
+ rbase = TINY_REGION_FOR_PTR(ptr);
+ /* iterate over allocated regions - XXX not terribly efficient for large number of regions */
+ for (i = szone->num_tiny_regions, region = szone->tiny_regions; i > 0; i--, region++)
+ if (rbase == *region)
+ return(region);
+ return(NULL);
}
static INLINE void
-tiny_free_no_lock(szone_t *szone, tiny_region_t *region, void *ptr, msize_t msize) {
- size_t original_size = msize << SHIFT_TINY_QUANTUM;
+tiny_free_no_lock(szone_t *szone, tiny_region_t *region, void *ptr, msize_t msize)
+{
+ size_t original_size = TINY_BYTES_FOR_MSIZE(msize);
void *next_block = ((char *)ptr + original_size);
+ msize_t previous_msize;
+ void *previous;
+ msize_t next_msize;
+ free_list_t *big_free_block;
+ free_list_t *after_next_block;
+ free_list_t *before_next_block;
+
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
+ malloc_printf("in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
}
if (! msize) {
- malloc_printf("In tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- szone_error(szone, "Trying to free tiny block that is too small", ptr);
+ malloc_printf("in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
+ szone_error(szone, "trying to free tiny block that is too small", ptr);
}
#endif
// We try to coalesce this block with the preceeding one
- msize_t previous_msize;
- void *previous = tiny_previous_preceding_free(ptr, &previous_msize);
+ previous = tiny_previous_preceding_free(ptr, &previous_msize);
if (previous) {
#if DEBUG_MALLOC
if (LOG(szone, ptr) || LOG(szone,previous)) {
- malloc_printf("In tiny_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous);
+ malloc_printf("in tiny_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous);
}
#endif
tiny_free_list_remove_ptr(szone, previous, previous_msize);
msize += previous_msize;
}
// We try to coalesce with the next block
- if (((vm_address_t)next_block < TINY_REGION_END(*region)) && tiny_meta_header_is_free(next_block)) {
+ if ((next_block < TINY_REGION_END(*region)) && tiny_meta_header_is_free(next_block)) {
// The next block is free, we coalesce
- msize_t next_msize = TINY_FREE_SIZE(next_block);
+ next_msize = TINY_FREE_SIZE(next_block);
#if DEBUG_MALLOC
if (LOG(szone, ptr) || LOG(szone, next_block)) {
- malloc_printf("In tiny_free_no_lock(), for ptr=%p, msize=%d coalesced forward=%p next_msize=%d\n", ptr, msize, next_block, next_msize);
+ malloc_printf("in tiny_free_no_lock(), for ptr=%p, msize=%d coalesced forward=%p next_msize=%d\n",
+ ptr, msize, next_block, next_msize);
}
#endif
if (next_msize >= NUM_TINY_SLOTS) {
// we take a short cut here to avoid removing next_block from the slot 31 freelist and then adding ptr back to slot 31
- // malloc_printf("Replacing %p(msize=%d) with %p(msize=%d) in freelist\n", next_block, next_msize, ptr, msize+next_msize);
msize += next_msize;
- free_list_t *big_free_block = (free_list_t *)next_block;
- free_list_t *after_next_block = big_free_block->next;
- free_list_t *before_next_block = big_free_block->previous;
+ big_free_block = (free_list_t *)next_block;
+ after_next_block = big_free_block->next;
+ before_next_block = big_free_block->previous;
free_list_checksum(szone, big_free_block, __PRETTY_FUNCTION__);
if (!before_next_block) {
szone->tiny_free_list[NUM_TINY_SLOTS-1] = ptr;
msize += next_msize;
}
if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize) {
- memset(ptr, 0x55, msize << SHIFT_TINY_QUANTUM);
+ memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize));
}
tiny_free_list_add_ptr(szone, ptr, msize);
tiny_free_ending:
}
static void *
-tiny_malloc_from_region_no_lock(szone_t *szone, msize_t msize) {
+tiny_malloc_from_region_no_lock(szone_t *szone, msize_t msize)
+{
+ tiny_region_t last_region, *new_regions;
+ void *last_block, *ptr, *aligned_address;
+
// Allocates from the last region or a freshly allocated region
// Before anything we transform the tiny_bytes_free_at_end - if any - to a regular free block
if (szone->tiny_bytes_free_at_end) {
- tiny_region_t last_region = szone-> tiny_regions[szone->num_tiny_regions-1];
- void *last_block = (void *)(TINY_REGION_END(last_region) - szone->tiny_bytes_free_at_end);
- tiny_free_list_add_ptr(szone, last_block, szone->tiny_bytes_free_at_end >> SHIFT_TINY_QUANTUM);
+ last_region = szone->tiny_regions[szone->num_tiny_regions-1];
+ last_block = TINY_REGION_END(last_region) - szone->tiny_bytes_free_at_end;
+ tiny_free_list_add_ptr(szone, last_block, TINY_MSIZE_FOR_BYTES(szone->tiny_bytes_free_at_end));
szone->tiny_bytes_free_at_end = 0;
}
- void *ptr;
// time to create a new region
- vm_address_t aligned_address = allocate_pages(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_TINY));
- if (! aligned_address) {
+ aligned_address = allocate_pages(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_TINY));
+ if (!aligned_address) {
// out of memory!
return NULL;
}
- // malloc_printf("Allocated tiny region #%d: %p [%y]\n", szone->num_tiny_regions, aligned_address, TINY_REGION_SIZE);
// We set the padding after block_header to be all 1
- ((unsigned *)(aligned_address + (1 << TINY_BLOCKS_ALIGN) + (NUM_TINY_BLOCKS >> 3)))[0] = ~0;
+ ((uint32_t *)(aligned_address + (1 << TINY_BLOCKS_ALIGN) + (NUM_TINY_BLOCKS >> 3)))[0] = ~0;
if (szone->num_tiny_regions == INITIAL_NUM_TINY_REGIONS) {
- tiny_region_t *new_regions;
- // malloc_printf("=== Growing tiny_regions (%d regions)\n", szone->num_tiny_regions);
+ // XXX logic here fails after initial reallocation of tiny regions is exhausted (approx 4GB of
+ // tiny allocations)
new_regions = small_malloc_from_region_no_lock(szone, 16); // 16 * 512 bytes is plenty of tiny regions (more than 4,000)
if (!new_regions) return NULL;
memcpy(new_regions, szone->tiny_regions, INITIAL_NUM_TINY_REGIONS * sizeof(tiny_region_t));
szone->tiny_regions = new_regions; // we set the pointer after it's all ready to enable enumeration from another thread without locking
}
- szone->tiny_regions[szone->num_tiny_regions] = aligned_address >> TINY_BLOCKS_ALIGN;
+ szone->tiny_regions[szone->num_tiny_regions] = aligned_address;
szone->num_tiny_regions ++; // we set the number after the pointer is all ready to enable enumeration from another thread without taking the lock
- ptr = (void *)aligned_address;
+ ptr = aligned_address;
set_tiny_meta_header_in_use(ptr, msize);
szone->num_tiny_objects++;
- szone->num_bytes_in_tiny_objects += msize << SHIFT_TINY_QUANTUM;
+ szone->num_bytes_in_tiny_objects += TINY_BYTES_FOR_MSIZE(msize);
// We put a header on the last block so that it appears in use (for coalescing, etc...)
- set_tiny_meta_header_in_use(ptr + (msize << SHIFT_TINY_QUANTUM), 1);
- szone->tiny_bytes_free_at_end = (NUM_TINY_BLOCKS - msize) << SHIFT_TINY_QUANTUM;
+ set_tiny_meta_header_in_use(ptr + TINY_BYTES_FOR_MSIZE(msize), 1);
+ szone->tiny_bytes_free_at_end = TINY_BYTES_FOR_MSIZE(NUM_TINY_BLOCKS - msize);
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In tiny_malloc_from_region_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
+ malloc_printf("in tiny_malloc_from_region_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
}
#endif
return ptr;
}
static INLINE boolean_t
-try_realloc_tiny_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) {
+try_realloc_tiny_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size)
+{
// returns 1 on success
- msize_t index = (((unsigned)ptr) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_BLOCKS - 1);
- msize_t old_msize = old_size >> SHIFT_TINY_QUANTUM;
- unsigned next_index = index + old_msize;
- // malloc_printf("try_realloc_tiny_in_place %p %d %d\n", ptr, old_size, new_size);
+ msize_t index;
+ msize_t old_msize;
+ unsigned next_index;
+ void *next_block;
+ boolean_t is_free;
+ msize_t next_msize, coalesced_msize, leftover_msize;
+ void *leftover;
+
+ index = TINY_INDEX_FOR_PTR(ptr);
+ old_msize = TINY_MSIZE_FOR_BYTES(old_size);
+ next_index = index + old_msize;
+
if (next_index >= NUM_TINY_BLOCKS) {
- // malloc_printf("try_realloc_tiny_in_place can't take place at end %p %d %d %d\n", ptr, old_size, new_size, next_index);
return 0;
}
- void *next_block = (char *)ptr + old_size;
+ next_block = (char *)ptr + old_size;
SZONE_LOCK(szone);
- boolean_t is_free = tiny_meta_header_is_free(next_block);
+ is_free = tiny_meta_header_is_free(next_block);
if (!is_free) {
SZONE_UNLOCK(szone);
return 0; // next_block is in use;
}
- msize_t next_msize = TINY_FREE_SIZE(next_block);
- if (old_size + (next_msize >> SHIFT_TINY_QUANTUM) < new_size) {
- // malloc_printf("try_realloc_tiny_in_place can't %p too small %d\n", next_block, next_msize);
+ next_msize = TINY_FREE_SIZE(next_block);
+ if (old_size + TINY_MSIZE_FOR_BYTES(next_msize) < new_size) {
SZONE_UNLOCK(szone);
return 0; // even with next block, not enough
}
tiny_free_list_remove_ptr(szone, next_block, next_msize);
set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards
- msize_t coalesced_msize = (new_size - old_size + TINY_QUANTUM - 1) >> SHIFT_TINY_QUANTUM;
- msize_t leftover_msize = next_msize - coalesced_msize;
- // malloc_printf("Realloc in place for %p; current size=%d next_msize=%d wanted=%d\n", ptr, old_size, next_msize, new_size);
+ coalesced_msize = TINY_MSIZE_FOR_BYTES(new_size - old_size + TINY_QUANTUM - 1);
+ leftover_msize = next_msize - coalesced_msize;
if (leftover_msize) {
- void *leftover = next_block + (coalesced_msize << SHIFT_TINY_QUANTUM);
- // malloc_printf("Leftover in realloc in place %p leftover_msize=%d\n", leftover, leftover_msize);
+ leftover = next_block + TINY_BYTES_FOR_MSIZE(coalesced_msize);
tiny_free_list_add_ptr(szone, leftover, leftover_msize);
}
set_tiny_meta_header_in_use(ptr, old_msize + coalesced_msize);
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In try_realloc_tiny_in_place(), ptr=%p, msize=%d\n", ptr, old_msize + coalesced_msize);
+ malloc_printf("in try_realloc_tiny_in_place(), ptr=%p, msize=%d\n", ptr, old_msize + coalesced_msize);
}
#endif
- szone->num_bytes_in_tiny_objects += coalesced_msize << SHIFT_TINY_QUANTUM;
+ szone->num_bytes_in_tiny_objects += TINY_BYTES_FOR_MSIZE(coalesced_msize);
SZONE_UNLOCK(szone);
CHECK(szone, __PRETTY_FUNCTION__);
- // malloc_printf("Extended ptr %p for realloc old=%d desired=%d new=%d leftover=%d\n", ptr, (unsigned)old_size, (unsigned)new_size, (unsigned)szone_size(szone, ptr), leftover_msize << SHIFT_TINY_QUANTUM);
return 1;
}
static boolean_t
-szone_check_tiny_region(szone_t *szone, tiny_region_t *region) {
- vm_address_t start = TINY_REGION_ADDRESS(*region);
- void *ptr = (void *)start;
- vm_address_t region_end = TINY_REGION_END(*region);
+tiny_check_region(szone_t *szone, tiny_region_t *region)
+{
+ uintptr_t start, ptr, region_end, follower;
boolean_t prev_free = 0;
- if (region == szone->tiny_regions + szone->num_tiny_regions - 1) region_end -= szone->tiny_bytes_free_at_end;
- // malloc_printf("szone_check_tiny_region: szone=%p region=%p start=%p ptr=%p region_end=%p\n", szone, region, start, ptr, region_end);
- while ((vm_address_t)ptr < region_end) {
- boolean_t is_free;
- msize_t msize = get_tiny_meta_header(ptr, &is_free);
- if (is_free && !msize && (ptr == (void *)start)) {
- // the entire region is free
+ boolean_t is_free;
+ msize_t msize;
+ free_list_t *free_head;
+
+ /* establish region limits */
+ start = (uintptr_t)TINY_REGION_ADDRESS(*region);
+ ptr = start;
+ region_end = (uintptr_t)TINY_REGION_END(*region);
+
+ /*
+ * The last region may have a trailing chunk which has not been converted into inuse/freelist
+ * blocks yet.
+ */
+ if (region == szone->tiny_regions + szone->num_tiny_regions - 1)
+ region_end -= szone->tiny_bytes_free_at_end;
+
+
+ /*
+ * Scan blocks within the region.
+ */
+ while (ptr < region_end) {
+ /*
+ * If the first block is free, and its size is 65536 (msize = 0) then the entire region is
+ * free.
+ */
+ msize = get_tiny_meta_header((void *)ptr, &is_free);
+ if (is_free && !msize && (ptr == start)) {
return 1;
}
- // malloc_printf("tiny %p [%d %d]\n", ptr, msize, is_free);
- if (! msize) {
- malloc_printf("*** malloc[%d]: invariant broken for tiny block %p this msize=%d - size is too small\n", getpid(), ptr, msize);
+
+ /*
+ * If the block's size is 65536 (msize = 0) then since we're not the first entry the size is
+ * corrupt.
+ */
+ if (!msize) {
+ malloc_printf("*** invariant broken for tiny block %p this msize=%d - size is too small\n",
+ ptr, msize);
return 0;
}
+
if (!is_free) {
- // this block is in use
+ /*
+ * In use blocks cannot be more than 31 quanta large.
+ */
prev_free = 0;
- if (msize > 31*TINY_QUANTUM) {
- malloc_printf("*** malloc[%d]: invariant broken for %p this tiny msize=%d[%p] - size is too large\n", getpid(), ptr, msize, msize);
+ if (msize > 31 * TINY_QUANTUM) {
+ malloc_printf("*** invariant broken for %p this tiny msize=%d[%p] - size is too large\n",
+ ptr, msize, msize);
return 0;
}
- ptr += msize << SHIFT_TINY_QUANTUM;
+ /* move to next block */
+ ptr += TINY_BYTES_FOR_MSIZE(msize);
} else {
- // free pointer
+ /*
+ * Free blocks must have been coalesced, we cannot have a free block following another
+ * free block.
+ */
if (prev_free) {
- malloc_printf("*** malloc[%d]: invariant broken for free block %p this tiny msize=%d: two free blocks in a row\n", getpid(), ptr, msize);
+ malloc_printf("*** invariant broken for free block %p this tiny msize=%d: two free blocks in a row\n",
+ ptr, msize);
return 0;
}
prev_free = 1;
- free_list_t *free_head = ptr;
+ /*
+ * Check the integrity of this block's entry in its freelist.
+ */
+ free_head = (free_list_t *)ptr;
free_list_checksum(szone, free_head, __PRETTY_FUNCTION__);
if (free_head->previous && !tiny_meta_header_is_free(free_head->previous)) {
- malloc_printf("*** malloc[%d]: invariant broken for %p (previous %p is not a free pointer)\n", getpid(), ptr, free_head->previous);
+ malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n",
+ ptr, free_head->previous);
return 0;
}
if (free_head->next && !tiny_meta_header_is_free(free_head->next)) {
- malloc_printf("*** malloc[%d]: invariant broken for %p (next in free list %p is not a free pointer)\n", getpid(), ptr, free_head->next);
+ malloc_printf("*** invariant broken for %p (next in free list %p is not a free pointer)\n",
+ ptr, free_head->next);
return 0;
}
- void *follower = FOLLOWING_TINY_PTR(ptr, msize);
- if ((follower != (void *)region_end) && (TINY_PREVIOUS_MSIZE(follower) != msize)) {
- malloc_printf("*** malloc[%d]: invariant broken for tiny free %p followed by %p in region [%p-%p] (end marker incorrect) should be %d; in fact %d\n", getpid(), ptr, follower, TINY_REGION_ADDRESS(*region), region_end, msize, TINY_PREVIOUS_MSIZE(follower));
+ /*
+ * Check the free block's trailing size value.
+ */
+ follower = (uintptr_t)FOLLOWING_TINY_PTR(ptr, msize);
+ if ((follower != region_end) && (TINY_PREVIOUS_MSIZE(follower) != msize)) {
+ malloc_printf("*** invariant broken for tiny free %p followed by %p in region [%p-%p] "
+ "(end marker incorrect) should be %d; in fact %d\n",
+ ptr, follower, TINY_REGION_ADDRESS(*region), region_end, msize, TINY_PREVIOUS_MSIZE(follower));
return 0;
}
+ /* move to next block */
ptr = follower;
}
}
- if (ptr != (void *)region_end) {
- malloc_printf("*** malloc[%d]: invariant broken for region end %p - %p\n", getpid(), ptr, region_end);
+ /*
+ * Ensure that we scanned the entire region
+ */
+ if (ptr != region_end) {
+ malloc_printf("*** invariant broken for region end %p - %p\n", ptr, region_end);
return 0;
}
+ /*
+ * Check the trailing block's integrity.
+ */
if (region == szone->tiny_regions + szone->num_tiny_regions - 1) {
if (szone->tiny_bytes_free_at_end) {
- boolean_t is_free;
- msize_t msize = get_tiny_meta_header(ptr, &is_free);
+ msize = get_tiny_meta_header((void *)ptr, &is_free);
if (is_free || (msize != 1)) {
- malloc_printf("*** malloc[%d]: invariant broken for blocker block %p - %d %d\n", getpid(), ptr, msize, is_free);
+ malloc_printf("*** invariant broken for blocker block %p - %d %d\n", ptr, msize, is_free);
}
}
}
}
static kern_return_t
-tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t region_address, unsigned short num_regions, size_t tiny_bytes_free_at_end, memory_reader_t reader, vm_range_recorder_t recorder) {
+tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t region_address, unsigned short num_regions, size_t tiny_bytes_free_at_end, memory_reader_t reader, vm_range_recorder_t recorder)
+{
tiny_region_t *regions;
unsigned index = 0;
vm_range_t buffer[MAX_RECORDER_BUFFER];
unsigned count = 0;
kern_return_t err;
+ tiny_region_t region;
+ vm_range_t range;
+ vm_range_t admin_range;
+ vm_range_t ptr_range;
+ unsigned char *mapped_region;
+ unsigned char *block_header;
+ unsigned char *in_use;
+ unsigned block_index;
+ unsigned block_limit;
+ boolean_t is_free;
+ msize_t msize;
+ void *mapped_ptr;
+ unsigned bit;
+
err = reader(task, region_address, sizeof(tiny_region_t) * num_regions, (void **)®ions);
if (err) return err;
while (index < num_regions) {
// unsigned num_in_use = 0;
// unsigned num_free = 0;
- tiny_region_t region = regions[index];
- vm_range_t range = {TINY_REGION_ADDRESS(region), TINY_REGION_SIZE};
- // malloc_printf("Enumerating tiny ptrs for tiny region starting at %p\n", range.address);
+ region = regions[index];
+ range.address = (vm_address_t)TINY_REGION_ADDRESS(region);
+ range.size = (vm_size_t)TINY_REGION_SIZE;
if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) {
- vm_range_t admin_range = {range.address + (1 << TINY_BLOCKS_ALIGN), range.size - (1 << TINY_BLOCKS_ALIGN)};
+ admin_range.address = range.address + (1 << TINY_BLOCKS_ALIGN);
+ admin_range.size = range.size - (1 << TINY_BLOCKS_ALIGN);
recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1);
}
if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) {
- vm_range_t ptr_range = {range.address, 1 << TINY_BLOCKS_ALIGN};
+ ptr_range.address = range.address;
+ ptr_range.size = 1 << TINY_BLOCKS_ALIGN;
recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1);
}
if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) {
- unsigned char *mapped_region;
err = reader(task, range.address, range.size, (void **)&mapped_region);
- if (err) return err;
- unsigned char *block_header = (unsigned char *)(mapped_region + (1 << TINY_BLOCKS_ALIGN));
- unsigned char *in_use = block_header + (NUM_TINY_BLOCKS >> 3) + 4;
- unsigned block_index = 0;
- unsigned block_limit = NUM_TINY_BLOCKS;
+ if (err)
+ return err;
+ block_header = (unsigned char *)(mapped_region + (1 << TINY_BLOCKS_ALIGN));
+ in_use = block_header + (NUM_TINY_BLOCKS >> 3) + 4;
+ block_index = 0;
+ block_limit = NUM_TINY_BLOCKS;
if (index == num_regions - 1)
- block_limit -= (tiny_bytes_free_at_end >> SHIFT_TINY_QUANTUM);
+ block_limit -= TINY_MSIZE_FOR_BYTES(tiny_bytes_free_at_end);
while (block_index < block_limit) {
- boolean_t is_free = ! BITARRAY_BIT(in_use, block_index);
- msize_t msize;
+ is_free = !BITARRAY_BIT(in_use, block_index);
if (is_free) {
- void *mapped_ptr = mapped_region + (block_index << SHIFT_TINY_QUANTUM);
+ mapped_ptr = mapped_region + TINY_BYTES_FOR_MSIZE(block_index);
msize = TINY_FREE_SIZE(mapped_ptr);
- // printf("free: index=%x mapped=%p true_addr=%p msize=%d\n", block_index, mapped_ptr, (void *)range.address + (block_index << SHIFT_TINY_QUANTUM), msize);
- // num_free++;
- if (!msize) break;
+ if (!msize)
+ break;
} else {
msize = 1;
- unsigned bit = block_index + 1;
- while (! BITARRAY_BIT(block_header, bit)) { bit++; msize ++; }
- // printf("in_use: index=%x true_addr=%p msize=%d\n", block_index, (void *)range.address + (block_index << SHIFT_TINY_QUANTUM), msize);
- // num_in_use++;
- buffer[count].address = range.address + (block_index << SHIFT_TINY_QUANTUM);
- buffer[count].size = msize << SHIFT_TINY_QUANTUM;
+ bit = block_index + 1;
+ while (! BITARRAY_BIT(block_header, bit)) {
+ bit++;
+ msize ++;
+ }
+ buffer[count].address = range.address + TINY_BYTES_FOR_MSIZE(block_index);
+ buffer[count].size = TINY_BYTES_FOR_MSIZE(msize);
count++;
if (count >= MAX_RECORDER_BUFFER) {
recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count);
block_index += msize;
}
}
- // malloc_printf("Found in tiny region %d in_use and %d free\n", num_in_use, num_free);
index++;
}
if (count) {
}
static INLINE void *
-tiny_malloc_from_free_list(szone_t *szone, msize_t msize) {
+tiny_malloc_from_free_list(szone_t *szone, msize_t msize)
+{
// Assumes we've locked the region
- void *ptr;
- msize_t this_msize;
- grain_t slot = msize-1;
- free_list_t **free_list = szone->tiny_free_list;
- free_list_t **the_slot = free_list + slot;
+ free_list_t *ptr;
+ msize_t this_msize;
+ grain_t slot = msize - 1;
+ free_list_t **free_list = szone->tiny_free_list;
+ free_list_t **the_slot = free_list + slot;
+ free_list_t *next;
+ free_list_t **limit;
+ unsigned bitmap;
+ msize_t leftover_msize;
+ free_list_t *leftover_ptr;
+
+ /*
+ * Look for an exact match by checking the freelist for this msize.
+ */
ptr = *the_slot;
if (ptr) {
- free_list_t *next;
- next = ((free_list_t *)ptr)->next;
+ next = ptr->next;
if (next) {
next->previous = NULL;
free_list_set_checksum(szone, next);
*the_slot = next;
this_msize = msize;
#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("In tiny_malloc_from_free_list(), exact match ptr=%p, this_msize=%d\n", ptr, this_msize);
+ if (LOG(szone, ptr)) {
+ malloc_printf("in tiny_malloc_from_free_list(), exact match ptr=%p, this_msize=%d\n", ptr, this_msize);
}
#endif
goto return_tiny_alloc;
}
- // adjust slot based on bitmap
- unsigned bitmap = szone->tiny_bitmap & ~ ((1 << slot) - 1);
- if (! bitmap) goto try_tiny_malloc_from_end;
+
+ /*
+ * Iterate over freelists for larger blocks looking for the next-largest block.
+ */
+ bitmap = szone->tiny_bitmap & ~ ((1 << slot) - 1);
+ if (!bitmap)
+ goto try_tiny_malloc_from_end;
slot = BITMAP32_FFS(bitmap) - 1;
- free_list_t **limit = free_list + NUM_TINY_SLOTS - 1;
+ limit = free_list + NUM_TINY_SLOTS - 1;
free_list += slot;
while (free_list < limit) {
// try bigger grains
ptr = *free_list;
if (ptr) {
- free_list_t *next;
- next = ((free_list_t *)ptr)->next;
+ next = ptr->next;
if (next) {
next->previous = NULL;
free_list_set_checksum(szone, next);
*free_list = next;
this_msize = TINY_FREE_SIZE(ptr);
#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("In tiny_malloc_from_free_list(), bigger grain ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize);
+ if (LOG(szone, ptr)) {
+ malloc_printf("in tiny_malloc_from_free_list(), bigger grain ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize);
}
#endif
goto add_leftover_and_proceed;
// we are now looking at the last slot (31)
ptr = *limit;
if (ptr) {
- free_list_t *next;
this_msize = TINY_FREE_SIZE(ptr);
- next = ((free_list_t *)ptr)->next;
+ next = ptr->next;
if (this_msize - msize >= NUM_TINY_SLOTS) {
// the leftover will go back to the free list, so we optimize by modifying the free list rather than removing the head and then adding back
- // malloc_printf("Allocation from largest tiny slot %p optimized\n", ptr);
- msize_t leftover_msize = this_msize - msize;
- void *leftover_ptr = ptr + (msize << SHIFT_TINY_QUANTUM);
+ leftover_msize = this_msize - msize;
+ leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize));
*limit = leftover_ptr;
if (next) {
next->previous = leftover_ptr;
free_list_set_checksum(szone, next);
}
- ((free_list_t *)leftover_ptr)->next = next;
- ((free_list_t *)leftover_ptr)->previous = NULL;
+ leftover_ptr->next = next;
+ leftover_ptr->previous = NULL;
free_list_set_checksum(szone, leftover_ptr);
set_tiny_meta_header_free(leftover_ptr, leftover_msize);
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In tiny_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize);
+ malloc_printf("in tiny_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize);
}
#endif
this_msize = msize;
}
try_tiny_malloc_from_end:
// Let's see if we can use szone->tiny_bytes_free_at_end
- if (szone->tiny_bytes_free_at_end >= (msize << SHIFT_TINY_QUANTUM)) {
- ptr = (void *)(TINY_REGION_END(szone->tiny_regions[szone->num_tiny_regions-1]) - szone->tiny_bytes_free_at_end);
- szone->tiny_bytes_free_at_end -= msize << SHIFT_TINY_QUANTUM;
+ if (szone->tiny_bytes_free_at_end >= TINY_BYTES_FOR_MSIZE(msize)) {
+ ptr = (free_list_t *)(TINY_REGION_END(szone->tiny_regions[szone->num_tiny_regions-1]) - szone->tiny_bytes_free_at_end);
+ szone->tiny_bytes_free_at_end -= TINY_BYTES_FOR_MSIZE(msize);
if (szone->tiny_bytes_free_at_end) {
// let's add an in use block after ptr to serve as boundary
- set_tiny_meta_header_in_use(ptr + (msize << SHIFT_TINY_QUANTUM), 1);
+ set_tiny_meta_header_in_use((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize), 1);
}
this_msize = msize;
#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("In tiny_malloc_from_free_list(), from end ptr=%p, msize=%d\n", ptr, msize);
+ if (LOG(szone, ptr)) {
+ malloc_printf("in tiny_malloc_from_free_list(), from end ptr=%p, msize=%d\n", ptr, msize);
}
#endif
goto return_tiny_alloc;
}
return NULL;
add_leftover_and_proceed:
- // malloc_printf("For msize=%d found tiny in free_list (slot=%d) this_msize=%d\n", msize, free_list - szone->tiny_free_list, this_msize);
if (!this_msize || (this_msize > msize)) {
- msize_t leftover_msize = this_msize - msize;
- void *leftover_ptr = ptr + (msize << SHIFT_TINY_QUANTUM);
+ leftover_msize = this_msize - msize;
+ leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize));
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In tiny_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize);
+ malloc_printf("in tiny_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize);
}
#endif
tiny_free_list_add_ptr(szone, leftover_ptr, leftover_msize);
}
return_tiny_alloc:
szone->num_tiny_objects++;
- szone->num_bytes_in_tiny_objects += this_msize << SHIFT_TINY_QUANTUM;
+ szone->num_bytes_in_tiny_objects += TINY_BYTES_FOR_MSIZE(this_msize);
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In tiny_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize);
+ malloc_printf("in tiny_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize);
}
#endif
set_tiny_meta_header_in_use(ptr, this_msize);
}
static INLINE void *
-tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) {
+tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested)
+{
boolean_t locked = 0;
void *ptr;
+
#if DEBUG_MALLOC
- if (! msize) {
- szone_error(szone, "Invariant broken (!msize) in allocation (region)", NULL);
+ if (!msize) {
+ szone_error(szone, "invariant broken (!msize) in allocation (region)", NULL);
+ return(NULL);
}
#endif
#if TINY_CACHE
- ptr = (void *)szone->last_tiny_free;
- if ((((unsigned)ptr) & (TINY_QUANTUM - 1)) == msize) {
+ ptr = szone->last_tiny_free;
+ if ((((uintptr_t)ptr) & (TINY_QUANTUM - 1)) == msize) {
// we have a candidate - let's lock to make sure
LOCK_AND_NOTE_LOCKED(szone, locked);
- if (ptr == (void *)szone->last_tiny_free) {
+ if (ptr == szone->last_tiny_free) {
szone->last_tiny_free = NULL;
- // malloc_printf("using last_tiny_free\n");
SZONE_UNLOCK(szone);
CHECK(szone, __PRETTY_FUNCTION__);
- ptr = (void *)((unsigned)ptr & ~ (TINY_QUANTUM - 1));
+ ptr = (void *)((uintptr_t)ptr & ~ (TINY_QUANTUM - 1));
if (cleared_requested) {
- memset(ptr, 0, msize << SHIFT_TINY_QUANTUM);
+ memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize));
}
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In tiny_malloc_should_clear(), tiny cache ptr=%p, msize=%d\n", ptr, msize);
+ malloc_printf("in tiny_malloc_should_clear(), tiny cache ptr=%p, msize=%d\n", ptr, msize);
}
#endif
return ptr;
}
- // malloc_printf("optimistic locking for last_tiny_free failed\n");
}
#endif
// Except in rare occasions where we need to add a new region, we are going to end up locking, so we might as well lock right away to avoid doing unnecessary optimistic probes
if (!locked) LOCK_AND_NOTE_LOCKED(szone, locked);
ptr = tiny_malloc_from_free_list(szone, msize);
- // malloc_printf("tiny_malloc_from_free_list(%d) returned %p\n", msize, ptr);
if (ptr) {
SZONE_UNLOCK(szone);
CHECK(szone, __PRETTY_FUNCTION__);
if (cleared_requested) {
- memset(ptr, 0, msize << SHIFT_TINY_QUANTUM);
+ memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize));
}
return ptr;
}
ptr = tiny_malloc_from_region_no_lock(szone, msize);
- // malloc_printf("tiny_malloc_from_region_no_lock returned %p for msize=%d\n", ptr, msize);
// we don't clear because this freshly allocated space is pristine
SZONE_UNLOCK(szone);
CHECK(szone, __PRETTY_FUNCTION__);
}
static INLINE void
-free_tiny(szone_t *szone, void *ptr, tiny_region_t *tiny_region) {
+free_tiny(szone_t *szone, void *ptr, tiny_region_t *tiny_region)
+{
+ msize_t msize;
+ boolean_t is_free;
+#if TINY_CACHE
+ void *ptr2;
+#endif
+
// ptr is known to be in tiny_region
SZONE_LOCK(szone);
#if TINY_CACHE
- void *ptr2 = szone->last_tiny_free;
- if (ptr == (void *)((unsigned)ptr2 & ~ (TINY_QUANTUM - 1))) {
- szone_error(szone, "Double free", ptr);
+ ptr2 = szone->last_tiny_free;
+ /* check that we don't already have this pointer in the cache */
+ if (ptr == (void *)((uintptr_t)ptr2 & ~ (TINY_QUANTUM - 1))) {
+ szone_error(szone, "double free", ptr);
return;
}
#endif /* TINY_CACHE */
- boolean_t is_free;
- msize_t msize = get_tiny_meta_header(ptr, &is_free);
+ msize = get_tiny_meta_header(ptr, &is_free);
if (is_free) {
- szone_error(szone, "Double free", ptr);
+ szone_error(szone, "double free", ptr);
return;
}
- // malloc_printf("%p[%x]\n", ptr, msize);
#if DEBUG_MALLOC
if (!msize) {
malloc_printf("*** szone_free() block in use is too large: %p\n", ptr);
+ return;
}
#endif
#if TINY_CACHE
if (msize < TINY_QUANTUM) { // to see if the bits fit in the last 4 bits
- szone->last_tiny_free = (void *)(((unsigned)ptr) | msize);
+ szone->last_tiny_free = (void *)(((uintptr_t)ptr) | msize);
if (!ptr2) {
- // malloc_printf("stuffing last_tiny_free\n");
SZONE_UNLOCK(szone);
CHECK(szone, __PRETTY_FUNCTION__);
return;
}
- // malloc_printf("replacing previous last_tiny_free %p with %p\n", ptr2, szone->last_tiny_free);
- msize = (unsigned)ptr2 & (TINY_QUANTUM - 1);
- ptr = (void *)(((unsigned)ptr2) & ~ (TINY_QUANTUM - 1));
+ msize = (uintptr_t)ptr2 & (TINY_QUANTUM - 1);
+ ptr = (void *)(((uintptr_t)ptr2) & ~(TINY_QUANTUM - 1));
tiny_region = tiny_region_for_ptr_no_lock(szone, ptr);
if (!tiny_region) {
- szone_error(szone, "Double free (tiny cache)", ptr);
+ szone_error(szone, "double free (tiny cache)", ptr);
}
}
#endif
}
static void
-print_tiny_free_list(szone_t *szone) {
- grain_t slot = 0;
- malloc_printf("Tiny free sizes: ");
+print_tiny_free_list(szone_t *szone)
+{
+ grain_t slot = 0;
+ free_list_t *ptr;
+
+ malloc_printf("tiny free sizes: ");
while (slot < NUM_TINY_SLOTS) {
- free_list_t *ptr = szone->tiny_free_list[slot];
+ ptr = szone->tiny_free_list[slot];
if (ptr) {
malloc_printf("%s%y[%d]; ", (slot == NUM_TINY_SLOTS-1) ? ">=" : "", (slot+1)*TINY_QUANTUM, free_list_count(ptr));
}
slot++;
}
- malloc_printf("\n");
}
static void
-print_tiny_region(boolean_t verbose, tiny_region_t region, size_t bytes_at_end) {
+print_tiny_region(boolean_t verbose, tiny_region_t region, size_t bytes_at_end)
+{
unsigned counts[1024];
unsigned in_use = 0;
- vm_address_t start = TINY_REGION_ADDRESS(region);
- vm_address_t current = start;
- vm_address_t limit = TINY_REGION_END(region) - bytes_at_end;
+ uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(region);
+ uintptr_t current = start;
+ uintptr_t limit = (uintptr_t)TINY_REGION_END(region) - bytes_at_end;
+ boolean_t is_free;
+ msize_t msize;
+ unsigned ci;
+
memset(counts, 0, 1024 * sizeof(unsigned));
while (current < limit) {
- boolean_t is_free;
- msize_t msize = get_tiny_meta_header((void *)current, &is_free);
- // malloc_printf("%p [%d %d]; ", current, msize, is_free);
+ msize = get_tiny_meta_header((void *)current, &is_free);
if (is_free & !msize && (current == start)) {
// first block is all free
break;
}
if (!msize) {
- malloc_printf("*** Error with %p: msize=%d\n", current, msize);
+ malloc_printf("*** error with %p: msize=%d\n", (void *)current, (unsigned)msize);
break;
}
- if (! is_free) {
+ if (!is_free) {
// block in use
- if (msize > 32) malloc_printf("*** Error at %p msize for in_use is %d\n", current, msize);
- if (msize < 1024) counts[msize]++;
+ if (msize > 32)
+ malloc_printf("*** error at %p msize for in_use is %d\n", (void *)current, msize);
+ if (msize < 1024)
+ counts[msize]++;
in_use++;
}
- current += msize << SHIFT_TINY_QUANTUM;
+ current += TINY_BYTES_FOR_MSIZE(msize);
}
- malloc_printf("Tiny region [%p-%p, %y]\t", start, TINY_REGION_END(region), (int)TINY_REGION_SIZE);
+ malloc_printf("Tiny region [%p-%p, %y]\t", (void *)start, TINY_REGION_END(region), (int)TINY_REGION_SIZE);
malloc_printf("In_use=%d ", in_use);
- if (bytes_at_end) malloc_printf("Untouched=%y ", bytes_at_end);
+ if (bytes_at_end) malloc_printf("untouched=%y ", bytes_at_end);
if (verbose && in_use) {
- unsigned ci = 0;
- malloc_printf("\n\tSizes in use: ");
- while (ci < 1024) {
- if (counts[ci]) {
- malloc_printf("%d[%d] ", ci << SHIFT_TINY_QUANTUM, counts[ci]);
- }
- ci++;
- }
+ malloc_printf("\tSizes in use: ");
+ for (ci = 0; ci < 1024; ci++)
+ if (counts[ci])
+ malloc_printf("%d[%d]", TINY_BYTES_FOR_MSIZE(ci), counts[ci]);
}
malloc_printf("\n");
}
static boolean_t
-tiny_free_list_check(szone_t *szone, grain_t slot) {
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
+tiny_free_list_check(szone_t *szone, grain_t slot)
+{
unsigned count = 0;
free_list_t *ptr = szone->tiny_free_list[slot];
free_list_t *previous = NULL;
+ boolean_t is_free;
+
+ CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
while (ptr) {
free_list_checksum(szone, ptr, __PRETTY_FUNCTION__);
- boolean_t is_free = tiny_meta_header_is_free(ptr);
+ is_free = tiny_meta_header_is_free(ptr);
if (! is_free) {
- malloc_printf("*** malloc[%d]: In-use ptr in free list slot=%d count=%d ptr=%p\n", getpid(), slot, count, ptr);
+ malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr);
return 0;
}
- if (((unsigned)ptr) & (TINY_QUANTUM - 1)) {
- malloc_printf("*** malloc[%d]: Unaligned ptr in free list slot=%d count=%d ptr=%p\n", getpid(), slot, count, ptr);
+ if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) {
+ malloc_printf("*** inaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr);
return 0;
}
if (!tiny_region_for_ptr_no_lock(szone, ptr)) {
- malloc_printf("*** malloc[%d]: Ptr not in szone slot=%d count=%d ptr=%p\n", getpid(), slot, count, ptr);
+ malloc_printf("*** itr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr);
return 0;
}
if (ptr->previous != previous) {
- malloc_printf("*** malloc[%d]: Previous incorrectly set slot=%d count=%d ptr=%p\n", getpid(), slot, count, ptr);
+ malloc_printf("*** irevious incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr);
return 0;
}
previous = ptr;
ptr = ptr->next;
count++;
}
- // malloc_printf("tiny_free_list_check passed\n");
return 1;
}
/********************* SMALL FREE LIST UTILITIES ************************/
-static INLINE msize_t *
-small_meta_headers(const void *ptr) {
- // returns address of meta info
- unsigned short shifted_base = ((unsigned)ptr) >> SMALL_BLOCKS_ALIGN;
- unsigned headers_start = (shifted_base + 1) << SMALL_BLOCKS_ALIGN;
- return (msize_t *)headers_start;
-}
-
-static INLINE msize_t
-small_meta_index(const void *ptr) {
- // returns address of meta info
- return (((unsigned)ptr) >> SHIFT_SMALL_QUANTUM) & (NUM_SMALL_BLOCKS - 1);
-}
-
-static INLINE msize_t *
-small_meta_header(const void *ptr) {
- // returns address of meta info
- msize_t *meta_headers = small_meta_headers(ptr);
- msize_t index = small_meta_index(ptr);
- return meta_headers + index;
-}
-
+/*
+ * Mark a block as free. Only the first quantum of a block is marked thusly,
+ * the remainder are marked "middle".
+ */
static INLINE void
-small_meta_header_set_is_free(msize_t *meta_headers, msize_t index, msize_t msize) {
- // Indicates that the meta_header for index says 'is free'
+small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize)
+{
+
meta_headers[index] = msize | SMALL_IS_FREE;
}
+/*
+ * Mark a block as in use. Only the first quantum of a block is marked thusly,
+ * the remainder are marked "middle".
+ */
static INLINE void
-small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) {
- // Indicates that the meta_header for index says 'in use'
+small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize)
+{
+
meta_headers[index] = msize;
}
+/*
+ * Mark a quantum as being the second or later in a block.
+ */
static INLINE void
-small_meta_header_set_middle(msize_t *meta_headers, msize_t index) {
- // Indicates that the meta_header for index says 'in the middle of a block'
+small_meta_header_set_middle(msize_t *meta_headers, msize_t index)
+{
+
meta_headers[index] = 0;
}
+// Adds an item to the proper free list
+// Also marks the header of the block properly
+// Assumes szone has been locked
static void
-small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) {
- // Adds an item to the proper free list
- // Also marks the header of the block properly
- // Assumes szone has been locked
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
+small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize)
+{
grain_t grain = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1;
free_list_t *free_ptr = ptr;
free_list_t *free_head = szone->small_free_list[grain];
+ void *follower;
+
+ CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In small_free_list_add_ptr(), ptr=%p, msize=%d\n", ptr, msize);
+ malloc_printf("in small_free_list_add_ptr(), ptr=%p, msize=%d\n", ptr, msize);
}
- if (((unsigned)ptr) & (SMALL_QUANTUM - 1)) {
+ if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) {
szone_error(szone, "small_free_list_add_ptr: Unaligned ptr", ptr);
}
#endif
free_list_checksum(szone, free_head, __PRETTY_FUNCTION__);
#if DEBUG_MALLOC
if (free_head->previous) {
- malloc_printf("ptr=%p grain=%d free_head=%p previous=%p\n", ptr, grain, free_head, free_head->previous);
+ malloc_printf("ptr=%p grain=%d free_head=%p previous=%p\n",
+ ptr, grain, free_head, free_head->previous);
szone_error(szone, "small_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr);
}
- if (!(small_meta_header(free_head)[0] & SMALL_IS_FREE)) {
+ if (!SMALL_PTR_IS_FREE(free_head)) {
malloc_printf("ptr=%p grain=%d free_head=%p\n", ptr, grain, free_head);
szone_error(szone, "small_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr);
}
free_ptr->next = free_head;
free_list_set_checksum(szone, free_ptr);
szone->small_free_list[grain] = free_ptr;
- void *follower = ptr + (msize << SHIFT_SMALL_QUANTUM);
+ follower = ptr + SMALL_BYTES_FOR_MSIZE(msize);
SMALL_PREVIOUS_MSIZE(follower) = msize;
}
+// Removes item in the proper free list
+// msize could be read, but all callers have it so we pass it in
+// Assumes szone has been locked
static void
-small_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize) {
- // Removes item in the proper free list
- // msize could be read, but all callers have it so we pass it in
- // Assumes szone has been locked
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
+small_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize)
+{
grain_t grain = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1;
free_list_t *free_ptr = ptr;
free_list_t *next = free_ptr->next;
free_list_t *previous = free_ptr->previous;
+
+ CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In small_free_list_remove_ptr(), ptr=%p, msize=%d\n", ptr, msize);
+ malloc_printf("in small_free_list_remove_ptr(), ptr=%p, msize=%d\n", ptr, msize);
}
#endif
free_list_checksum(szone, free_ptr, __PRETTY_FUNCTION__);
if (!previous) {
#if DEBUG_MALLOC
if (szone->small_free_list[grain] != ptr) {
- malloc_printf("ptr=%p grain=%d msize=%d szone->small_free_list[grain]=%p\n", ptr, grain, msize, szone->small_free_list[grain]);
+ malloc_printf("ptr=%p grain=%d msize=%d szone->small_free_list[grain]=%p\n",
+ ptr, grain, msize, szone->small_free_list[grain]);
szone_error(szone, "small_free_list_remove_ptr: Internal invariant broken (szone->small_free_list[grain])", ptr);
return;
}
}
static INLINE small_region_t *
-small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) {
- small_region_t *region = szone->small_regions;
- unsigned num_regions = szone->num_small_regions;
- unsigned ptr_shifted = ((unsigned)ptr) >> SMALL_BLOCKS_ALIGN;
- while (num_regions--) {
- small_region_t this = *region;
- if (ptr_shifted == this) return region;
- region++;
- }
- return NULL;
+small_region_for_ptr_no_lock(szone_t *szone, const void *ptr)
+{
+ small_region_t *region;
+ small_region_t rbase;
+ int i;
+
+ /* find assumed heap/region base */
+ rbase = SMALL_REGION_FOR_PTR(ptr);
+
+ /* scan existing regions for a match */
+ for (i = szone->num_small_regions, region = szone->small_regions; i > 0; i--, region++)
+ if (rbase == *region)
+ return(region);
+ return(NULL);
}
static INLINE void
-small_free_no_lock(szone_t *szone, small_region_t *region, void *ptr, msize_t msize) {
+small_free_no_lock(szone_t *szone, small_region_t *region, void *ptr, msize_t msize)
+{
+ msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
+ unsigned index = SMALL_META_INDEX_FOR_PTR(ptr);
+ size_t original_size = SMALL_BYTES_FOR_MSIZE(msize);
+ unsigned char *next_block = ((unsigned char *)ptr + original_size);
+ msize_t next_index = index + msize;
+ msize_t previous_msize, next_msize;
+ void *previous;
+
// Assumes locked
CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
- msize_t *meta_headers = small_meta_headers(ptr);
- msize_t index = small_meta_index(ptr);
- size_t original_size = msize << SHIFT_SMALL_QUANTUM;
- void *next_block = ((char *)ptr + original_size);
- msize_t next_index = index + msize;
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
+ malloc_printf("in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
}
if (! msize) {
- malloc_printf("In small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- szone_error(szone, "Trying to free small block that is too small", ptr);
+ malloc_printf("in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
+ szone_error(szone, "trying to free small block that is too small", ptr);
}
- // printf("In small_free_no_lock %p - msize=%d\n", ptr, msize);
#endif
// We try to coalesce this block with the preceeding one
if (index && (SMALL_PREVIOUS_MSIZE(ptr) <= index)) {
- msize_t previous_msize = SMALL_PREVIOUS_MSIZE(ptr);
+ previous_msize = SMALL_PREVIOUS_MSIZE(ptr);
if (meta_headers[index - previous_msize] == (previous_msize | SMALL_IS_FREE)) {
- void *previous = ptr - (previous_msize << SHIFT_SMALL_QUANTUM);
+ previous = ptr - SMALL_BYTES_FOR_MSIZE(previous_msize);
// previous is really to be coalesced
#if DEBUG_MALLOC
if (LOG(szone, ptr) || LOG(szone,previous)) {
- malloc_printf("In small_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous);
+ malloc_printf("in small_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous);
}
#endif
- // malloc_printf("In small_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous);
small_free_list_remove_ptr(szone, previous, previous_msize);
small_meta_header_set_middle(meta_headers, index);
ptr = previous;
}
}
// We try to coalesce with the next block
- if (((vm_address_t)next_block < SMALL_REGION_END(*region)) && (meta_headers[next_index] & SMALL_IS_FREE)) {
+ if ((next_block < SMALL_REGION_END(*region)) && (meta_headers[next_index] & SMALL_IS_FREE)) {
// next block is free, we coalesce
- msize_t next_msize = meta_headers[next_index] & ~ SMALL_IS_FREE;
+ next_msize = meta_headers[next_index] & ~ SMALL_IS_FREE;
#if DEBUG_MALLOC
if (LOG(szone,ptr)) malloc_printf("In small_free_no_lock(), for ptr=%p, msize=%d coalesced next block=%p next_msize=%d\n", ptr, msize, next_block, next_msize);
#endif
- // malloc_printf("In small_free_no_lock(), for ptr=%p, msize=%d coalesced next block=%p next_msize=%d\n", ptr, msize, next_block, next_msize);
small_free_list_remove_ptr(szone, next_block, next_msize);
small_meta_header_set_middle(meta_headers, next_index);
msize += next_msize;
}
if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) {
if (!msize) {
- szone_error(szone, "Incorrect size information - block header was damaged", ptr);
+ szone_error(szone, "incorrect size information - block header was damaged", ptr);
} else {
- memset(ptr, 0x55, (msize << SHIFT_SMALL_QUANTUM));
+ memset(ptr, 0x55, SMALL_BYTES_FOR_MSIZE(msize));
}
}
small_free_list_add_ptr(szone, ptr, msize);
}
static void *
-small_malloc_from_region_no_lock(szone_t *szone, msize_t msize) {
+small_malloc_from_region_no_lock(szone_t *szone, msize_t msize)
+{
+ small_region_t last_region;
+ void *last_block;
+ void *ptr;
+ void *new_address;
+ msize_t *meta_headers;
+ msize_t index ;
+ size_t region_capacity;
+ msize_t new_msize;
+ small_region_t *new_regions;
+ msize_t msize_left;
+
// Allocates from the last region or a freshly allocated region
CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
// Before anything we transform the small_bytes_free_at_end - if any - to a regular free block
if (szone->small_bytes_free_at_end) {
- small_region_t last_region = szone->small_regions[szone->num_small_regions - 1];
- void *last_block = (void *)(SMALL_REGION_END(last_region) - szone->small_bytes_free_at_end);
- small_free_list_add_ptr(szone, last_block, szone->small_bytes_free_at_end >> SHIFT_SMALL_QUANTUM);
- small_meta_header(last_block)[0] = (szone->small_bytes_free_at_end >> SHIFT_SMALL_QUANTUM) | SMALL_IS_FREE;
+ last_region = szone->small_regions[szone->num_small_regions - 1];
+ last_block = (void *)(SMALL_REGION_END(last_region) - szone->small_bytes_free_at_end);
+ small_free_list_add_ptr(szone, last_block, SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end));
+ *SMALL_METADATA_FOR_PTR(last_block) = SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end) | SMALL_IS_FREE;
szone->small_bytes_free_at_end = 0;
}
- void *ptr;
// time to create a new region
- vm_address_t new_address = allocate_pages(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_SMALL));
+ new_address = allocate_pages(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_SMALL));
if (!new_address) {
// out of memory!
return NULL;
}
- ptr = (void *)new_address;
- msize_t *meta_headers = small_meta_headers(ptr);
- msize_t index = 0;
- // malloc_printf("Allocated small region #%d: %p [%y]\n", szone->num_small_regions, new_address, SMALL_REGION_SIZE);
+ ptr = new_address;
+ meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
+ index = 0;
if (szone->num_small_regions == INITIAL_NUM_SMALL_REGIONS) {
// time to grow the number of regions
- unsigned region_capacity = (1 << (32 - SMALL_BLOCKS_ALIGN)) - 20; // that is for sure the maximum number of small regions we can have
- msize_t new_msize = (region_capacity * sizeof(small_region_t) + SMALL_QUANTUM - 1) / SMALL_QUANTUM;
- small_region_t *new_regions = ptr;
- // malloc_printf("Now %d small_regions growing regions %p to %d msize=%d\n", szone->num_small_regions + 1, szone->small_regions, region_capacity, new_msize);
+ region_capacity = (1 << (32 - SMALL_BLOCKS_ALIGN)) - 20; // that is for sure the maximum number of small regions we can have
+ new_msize = (region_capacity * sizeof(small_region_t) + SMALL_QUANTUM - 1) / SMALL_QUANTUM;
+ new_regions = ptr;
small_meta_header_set_in_use(meta_headers, index, new_msize);
szone->num_small_objects++;
- szone->num_bytes_in_small_objects += new_msize << SHIFT_SMALL_QUANTUM;
+ szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(new_msize);
memcpy(new_regions, szone->small_regions, INITIAL_NUM_SMALL_REGIONS * sizeof(small_region_t));
- // We intentionally leak the previous regions pointer to avoid multi-threading crashes if another thread was reading it (unlocked) while we are changing it.
+ // We intentionally leak the previous regions pointer to avoid multi-threading crashes if
+ // another thread was reading it (unlocked) while we are changing it.
szone->small_regions = new_regions; // note we set this pointer after it's all set
- ptr += new_msize << SHIFT_SMALL_QUANTUM;
+ ptr += SMALL_BYTES_FOR_MSIZE(new_msize);
index = new_msize;
- // malloc_printf("Regions is now %p next ptr is %p\n", szone->small_regions, ptr);
}
- szone->small_regions[szone->num_small_regions] = new_address >> SMALL_BLOCKS_ALIGN;
- szone->num_small_regions++; // we bump the number of regions AFTER we have changes the regions pointer to enable finding a small region without taking the lock
- // malloc_printf("Now %d small regions\n", szone->num_small_regions);
- small_meta_header_set_in_use(meta_headers, index, msize);
- msize_t msize_left = NUM_SMALL_BLOCKS - index;
- szone->num_small_objects++;
- szone->num_bytes_in_small_objects += msize << SHIFT_SMALL_QUANTUM;
- // add a big free block
- index += msize; msize_left -= msize;
- meta_headers[index] = msize_left;
- szone->small_bytes_free_at_end = msize_left << SHIFT_SMALL_QUANTUM;
- // malloc_printf("small_bytes_free_at_end set to %d\n", szone-> small_bytes_free_at_end);
- return ptr;
+ szone->small_regions[szone->num_small_regions] = new_address;
+ // we bump the number of regions AFTER we have changes the regions pointer to enable finding a
+ // small region without taking the lock
+ // XXX naive assumption assumes memory ordering coherence between this and other CPUs
+ szone->num_small_regions++;
+ small_meta_header_set_in_use(meta_headers, index, msize);
+ msize_left = NUM_SMALL_BLOCKS - index;
+ szone->num_small_objects++;
+ szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(msize);
+ // add a big free block
+ index += msize; msize_left -= msize;
+ meta_headers[index] = msize_left;
+ szone->small_bytes_free_at_end = SMALL_BYTES_FOR_MSIZE(msize_left);
+ return ptr;
+}
+
+static INLINE boolean_t
+try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size)
+{
+ // returns 1 on success
+ msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
+ unsigned index = SMALL_META_INDEX_FOR_PTR(ptr);
+ msize_t old_msize = SMALL_MSIZE_FOR_BYTES(old_size);
+ msize_t new_msize = SMALL_MSIZE_FOR_BYTES(new_size + SMALL_QUANTUM - 1);
+ void *next_block = (char *)ptr + old_size;
+ unsigned next_index = index + old_msize;
+ msize_t next_msize_and_free;
+ msize_t next_msize;
+ msize_t leftover_msize;
+ void *leftover;
+ unsigned leftover_index;
+
+ if (next_index >= NUM_SMALL_BLOCKS) {
+ return 0;
+ }
+#if DEBUG_MALLOC
+ if ((uintptr_t)next_block & (SMALL_QUANTUM - 1)) {
+ szone_error(szone, "internal invariant broken in realloc(next_block)", next_block);
+ }
+ if (meta_headers[index] != old_msize)
+ malloc_printf("*** try_realloc_small_in_place incorrect old %d %d\n",
+ meta_headers[index], old_msize);
+#endif
+ SZONE_LOCK(szone);
+ /*
+ * Look for a free block immediately afterwards. If it's large enough, we can consume (part of)
+ * it.
+ */
+ next_msize_and_free = meta_headers[next_index];
+ next_msize = next_msize_and_free & ~ SMALL_IS_FREE;
+ if (!(next_msize_and_free & SMALL_IS_FREE) || (old_msize + next_msize < new_msize)) {
+ SZONE_UNLOCK(szone);
+ return 0;
+ }
+ /*
+ * The following block is big enough; pull it from its freelist and chop off enough to satisfy
+ * our needs.
+ */
+ small_free_list_remove_ptr(szone, next_block, next_msize);
+ small_meta_header_set_middle(meta_headers, next_index);
+ leftover_msize = old_msize + next_msize - new_msize;
+ if (leftover_msize) {
+ /* there's some left, so put the remainder back */
+ leftover = (unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(new_msize);
+ small_free_list_add_ptr(szone, leftover, leftover_msize);
+ leftover_index = index + new_msize;
+ small_meta_header_set_is_free(meta_headers, leftover_index, leftover_msize);
+ }
+#if DEBUG_MALLOC
+ if (SMALL_BYTES_FOR_MSIZE(new_msize) >= LARGE_THRESHOLD) {
+ malloc_printf("*** realloc in place for %p exceeded msize=%d\n", new_msize);
+ }
+#endif
+ small_meta_header_set_in_use(meta_headers, index, new_msize);
+#if DEBUG_MALLOC
+ if (LOG(szone,ptr)) {
+ malloc_printf("in szone_realloc(), ptr=%p, msize=%d\n", ptr, *SMALL_METADATA_FOR_PTR(ptr));
+ }
+#endif
+ szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(new_msize - old_msize);
+ SZONE_UNLOCK(szone);
+ CHECK(szone, __PRETTY_FUNCTION__);
+ return 1;
}
static boolean_t
-szone_check_small_region(szone_t *szone, small_region_t *region) {
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
- void *ptr = (void *)SMALL_REGION_ADDRESS(*region);
- msize_t *meta_headers = small_meta_headers(ptr);
- vm_address_t region_end = SMALL_REGION_END(*region);
+szone_check_small_region(szone_t *szone, small_region_t *region)
+{
+ unsigned char *ptr = SMALL_REGION_ADDRESS(*region);
+ msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
+ unsigned char *region_end = SMALL_REGION_END(*region);
msize_t prev_free = 0;
+ unsigned index;
+ msize_t msize_and_free;
+ msize_t msize;
+ free_list_t *free_head;
+ msize_t *follower;
+
+ CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
if (region == szone->small_regions + szone->num_small_regions - 1) region_end -= szone->small_bytes_free_at_end;
- while ((vm_address_t)ptr < region_end) {
- msize_t index = small_meta_index(ptr);
- msize_t msize_and_free = meta_headers[index];
- if (! (msize_and_free & SMALL_IS_FREE)) {
+ while (ptr < region_end) {
+ index = SMALL_META_INDEX_FOR_PTR(ptr);
+ msize_and_free = meta_headers[index];
+ if (!(msize_and_free & SMALL_IS_FREE)) {
// block is in use
- msize_t msize = msize_and_free;
+ msize = msize_and_free;
if (!msize) {
- malloc_printf("*** malloc[%d]: invariant broken: null msize ptr=%p region#=%d num_small_regions=%d end=%p\n", getpid(), ptr, region - szone->small_regions, szone->num_small_regions, (void *)region_end);
+ malloc_printf("*** invariant broken: null msize ptr=%p region#=%d num_small_regions=%d end=%p\n",
+ ptr, region - szone->small_regions, szone->num_small_regions, (void *)region_end);
return 0;
}
if (msize > (LARGE_THRESHOLD / SMALL_QUANTUM)) {
- malloc_printf("*** malloc[%d]: invariant broken for %p this small msize=%d - size is too large\n", getpid(), ptr, msize_and_free);
+ malloc_printf("*** invariant broken for %p this small msize=%d - size is too large\n",
+ ptr, msize_and_free);
return 0;
}
- ptr += msize << SHIFT_SMALL_QUANTUM;
+ ptr += SMALL_BYTES_FOR_MSIZE(msize);
prev_free = 0;
} else {
// free pointer
- msize_t msize = msize_and_free & ~ SMALL_IS_FREE;
- free_list_t *free_head = ptr;
- msize_t *follower = (void *)FOLLOWING_SMALL_PTR(ptr, msize);
- if (! msize) {
- malloc_printf("*** malloc[%d]: invariant broken for free block %p this msize=%d\n", getpid(), ptr, msize);
+ msize = msize_and_free & ~ SMALL_IS_FREE;
+ free_head = (free_list_t *)ptr;
+ follower = (msize_t *)FOLLOWING_SMALL_PTR(ptr, msize);
+ if (!msize) {
+ malloc_printf("*** invariant broken for free block %p this msize=%d\n", ptr, msize);
return 0;
}
if (prev_free) {
- malloc_printf("*** malloc[%d]: invariant broken for %p (2 free in a row)\n", getpid(), ptr);
+ malloc_printf("*** invariant broken for %p (2 free in a row)\n", ptr);
return 0;
}
free_list_checksum(szone, free_head, __PRETTY_FUNCTION__);
- if (free_head->previous && !(small_meta_header(free_head->previous)[0] & SMALL_IS_FREE)) {
- malloc_printf("*** malloc[%d]: invariant broken for %p (previous %p is not a free pointer)\n", getpid(), ptr, free_head->previous);
+ if (free_head->previous && !SMALL_PTR_IS_FREE(free_head->previous)) {
+ malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n",
+ ptr, free_head->previous);
return 0;
}
- if (free_head->next && !(small_meta_header(free_head->next)[0] & SMALL_IS_FREE)) {
- malloc_printf("*** malloc[%d]: invariant broken for %p (next is not a free pointer)\n", getpid(), ptr);
+ if (free_head->next && !SMALL_PTR_IS_FREE(free_head->next)) {
+ malloc_printf("*** invariant broken for %p (next is not a free pointer)\n", ptr);
return 0;
}
if (SMALL_PREVIOUS_MSIZE(follower) != msize) {
- malloc_printf("*** malloc[%d]: invariant broken for small free %p followed by %p in region [%p-%p] (end marker incorrect) should be %d; in fact %d\n", getpid(), ptr, follower, SMALL_REGION_ADDRESS(*region), region_end, msize, SMALL_PREVIOUS_MSIZE(follower));
+ malloc_printf("*** invariant broken for small free %p followed by %p in region [%p-%p] "
+ "(end marker incorrect) should be %d; in fact %d\n",
+ ptr, follower, SMALL_REGION_ADDRESS(*region), region_end, msize, SMALL_PREVIOUS_MSIZE(follower));
return 0;
}
- ptr = follower;
+ ptr = (unsigned char *)follower;
prev_free = SMALL_IS_FREE;
}
}
}
static kern_return_t
-small_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t region_address, unsigned short num_regions, size_t small_bytes_free_at_end, memory_reader_t reader, vm_range_recorder_t recorder) {
+small_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t region_address, unsigned short num_regions, size_t small_bytes_free_at_end, memory_reader_t reader, vm_range_recorder_t recorder)
+{
small_region_t *regions;
unsigned index = 0;
vm_range_t buffer[MAX_RECORDER_BUFFER];
unsigned count = 0;
kern_return_t err;
+ small_region_t region;
+ vm_range_t range;
+ vm_range_t admin_range;
+ vm_range_t ptr_range;
+ unsigned char *mapped_region;
+ msize_t *block_header;
+ unsigned block_index;
+ unsigned block_limit;
+ msize_t msize_and_free;
+ msize_t msize;
+
err = reader(task, region_address, sizeof(small_region_t) * num_regions, (void **)®ions);
if (err) return err;
while (index < num_regions) {
- small_region_t region = regions[index];
- vm_range_t range = {SMALL_REGION_ADDRESS(region), SMALL_REGION_SIZE};
- // malloc_printf("Enumerating small ptrs for Region starting at %p\n", range.address);
+ region = regions[index];
+ range.address = (vm_address_t)SMALL_REGION_ADDRESS(region);
+ range.size = SMALL_REGION_SIZE;
if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) {
- vm_range_t admin_range = {range.address + (1 << SMALL_BLOCKS_ALIGN), range.size - (1 << SMALL_BLOCKS_ALIGN)};
+ admin_range.address = range.address + (1 << SMALL_BLOCKS_ALIGN);
+ admin_range.size = range.size - (1 << SMALL_BLOCKS_ALIGN);
recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1);
}
if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) {
- vm_range_t ptr_range = {range.address, 1 << SMALL_BLOCKS_ALIGN};
+ ptr_range.address = range.address;
+ ptr_range.size = 1 << SMALL_BLOCKS_ALIGN;
recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1);
}
if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) {
- unsigned char *mapped_region;
err = reader(task, range.address, range.size, (void **)&mapped_region);
if (err) return err;
- msize_t *block_header = (msize_t *)(mapped_region + (1 << SMALL_BLOCKS_ALIGN));
- unsigned block_index = 0;
- unsigned block_limit = NUM_SMALL_BLOCKS;
+ block_header = (msize_t *)(mapped_region + (1 << SMALL_BLOCKS_ALIGN));
+ block_index = 0;
+ block_limit = NUM_SMALL_BLOCKS;
if (index == num_regions - 1)
- block_limit -= (small_bytes_free_at_end >> SHIFT_SMALL_QUANTUM);
+ block_limit -= SMALL_MSIZE_FOR_BYTES(small_bytes_free_at_end);
while (block_index < block_limit) {
- msize_t msize_and_free = block_header[block_index];
- msize_t msize = msize_and_free & ~ SMALL_IS_FREE;
+ msize_and_free = block_header[block_index];
+ msize = msize_and_free & ~ SMALL_IS_FREE;
if (! (msize_and_free & SMALL_IS_FREE)) {
// Block in use
- buffer[count].address = range.address + (block_index << SHIFT_SMALL_QUANTUM);
- buffer[count].size = msize << SHIFT_SMALL_QUANTUM;
+ buffer[count].address = range.address + SMALL_BYTES_FOR_MSIZE(block_index);
+ buffer[count].size = SMALL_BYTES_FOR_MSIZE(msize);
count++;
if (count >= MAX_RECORDER_BUFFER) {
recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count);
}
block_index += msize;
}
- // malloc_printf("End small region - count=%d\n", count);
}
index++;
}
}
static INLINE void *
-small_malloc_from_free_list(szone_t *szone, msize_t msize) {
- // Assumes locked
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
+small_malloc_from_free_list(szone_t *szone, msize_t msize)
+{
grain_t grain = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1;
unsigned bitmap = szone->small_bitmap & ~ ((1 << grain) - 1);
void *ptr;
msize_t this_msize;
+ free_list_t **free_list;
+ free_list_t **limit;
+ free_list_t *next;
+ msize_t leftover_msize;
+ void *leftover_ptr;
+ msize_t *meta_headers;
+ unsigned leftover_index;
+
+ // Assumes locked
+ CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
+
if (!bitmap) goto try_small_from_end;
grain = BITMAP32_FFS(bitmap) - 1;
// first try the small grains
- free_list_t **free_list;
- free_list_t **limit = szone->small_free_list + NUM_SMALL_SLOTS - 1;
+ limit = szone->small_free_list + NUM_SMALL_SLOTS - 1;
free_list = szone->small_free_list + grain;
while (free_list < limit) {
// try bigger grains
ptr = *free_list;
if (ptr) {
- free_list_t *next;
next = ((free_list_t *)ptr)->next;
if (next) {
next->previous = NULL;
free_list_set_checksum(szone, next);
}
*free_list = next;
- this_msize = small_meta_header(ptr)[0] & ~ SMALL_IS_FREE;
- // malloc_printf("small_malloc_from_free_list: allocated from free list\n");
+ this_msize = SMALL_PTR_SIZE(ptr);
goto add_leftover_and_proceed;
}
free_list++;
// We now check the large grains for one that is big enough
ptr = *free_list;
while (ptr) {
- this_msize = small_meta_header(ptr)[0] & ~ SMALL_IS_FREE;
+ this_msize = SMALL_PTR_SIZE(ptr);
if (this_msize >= msize) {
- // malloc_printf("small_malloc_from_free_list: allocated from last free list\n");
small_free_list_remove_ptr(szone, ptr, this_msize);
goto add_leftover_and_proceed;
}
}
try_small_from_end:
// Let's see if we can use szone->small_bytes_free_at_end
- // malloc_printf("Found nothing in free list small_bytes_free_at_end=%y\n", szone-> small_bytes_free_at_end);
- if (szone->small_bytes_free_at_end >= (msize << SHIFT_SMALL_QUANTUM)) {
+ if (szone->small_bytes_free_at_end >= SMALL_BYTES_FOR_MSIZE(msize)) {
ptr = (void *)(SMALL_REGION_END(szone->small_regions[szone->num_small_regions-1]) - szone->small_bytes_free_at_end);
- szone->small_bytes_free_at_end -= msize << SHIFT_SMALL_QUANTUM;
+ szone->small_bytes_free_at_end -= SMALL_BYTES_FOR_MSIZE(msize);
if (szone->small_bytes_free_at_end) {
// let's mark this block as in use to serve as boundary
- small_meta_header(ptr + (msize << SHIFT_SMALL_QUANTUM))[0] = szone->small_bytes_free_at_end >> SHIFT_SMALL_QUANTUM;
+ *SMALL_METADATA_FOR_PTR(ptr + SMALL_BYTES_FOR_MSIZE(msize)) = SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end);
}
this_msize = msize;
goto return_small_alloc;
return NULL;
add_leftover_and_proceed:
if (this_msize > msize) {
- msize_t leftover_msize = this_msize - msize;
- void *leftover_ptr = ptr + (msize << SHIFT_SMALL_QUANTUM);
+ leftover_msize = this_msize - msize;
+ leftover_ptr = ptr + SMALL_BYTES_FOR_MSIZE(msize);
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In small_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize);
+ malloc_printf("in small_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize);
}
#endif
small_free_list_add_ptr(szone, leftover_ptr, leftover_msize);
- msize_t *meta_headers = small_meta_headers(leftover_ptr);
- msize_t leftover_index = small_meta_index(leftover_ptr);
+ meta_headers = SMALL_META_HEADER_FOR_PTR(leftover_ptr);
+ leftover_index = SMALL_META_INDEX_FOR_PTR(leftover_ptr);
small_meta_header_set_is_free(meta_headers, leftover_index, leftover_msize);
this_msize = msize;
}
return_small_alloc:
szone->num_small_objects++;
- szone->num_bytes_in_small_objects += this_msize << SHIFT_SMALL_QUANTUM;
+ szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(this_msize);
#if DEBUG_MALLOC
if (LOG(szone,ptr)) {
- malloc_printf("In small_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize);
+ malloc_printf("in small_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize);
}
#endif
- small_meta_header(ptr)[0] = this_msize;
+ *SMALL_METADATA_FOR_PTR(ptr) = this_msize;
return ptr;
}
static INLINE void *
-small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) {
+small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested)
+{
boolean_t locked = 0;
+#if SMALL_CACHE
void *ptr;
+#endif
+
#if SMALL_CACHE
ptr = (void *)szone->last_small_free;
- if ((((unsigned)ptr) & (SMALL_QUANTUM - 1)) == msize) {
+ if ((((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) == msize) {
// we have a candidate - let's lock to make sure
LOCK_AND_NOTE_LOCKED(szone, locked);
if (ptr == (void *)szone->last_small_free) {
szone->last_small_free = NULL;
- // malloc_printf("using last_small_free\n");
SZONE_UNLOCK(szone);
CHECK(szone, __PRETTY_FUNCTION__);
- ptr = (void *)((unsigned)ptr & ~ (SMALL_QUANTUM - 1));
+ ptr = (void *)((uintptr_t)ptr & ~ (SMALL_QUANTUM - 1));
if (cleared_requested) {
- memset(ptr, 0, msize << SHIFT_SMALL_QUANTUM);
+ memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize));
}
return ptr;
}
- // malloc_printf("optimistic locking for last_small_free failed\n");
}
#endif
- // Except in rare occasions where we need to add a new region, we are going to end up locking, so we might as well lock right away to avoid doing unnecessary optimistic probes
+ // Except in rare occasions where we need to add a new region, we are going to end up locking,
+ // so we might as well lock right away to avoid doing unnecessary optimistic probes
if (!locked) LOCK_AND_NOTE_LOCKED(szone, locked);
ptr = small_malloc_from_free_list(szone, msize);
if (ptr) {
SZONE_UNLOCK(szone);
CHECK(szone, __PRETTY_FUNCTION__);
if (cleared_requested) {
- memset(ptr, 0, msize << SHIFT_SMALL_QUANTUM);
+ memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize));
}
return ptr;
}
return ptr;
}
+// tries to allocate a small, cleared block
static INLINE void *
-small_malloc_cleared_no_lock(szone_t *szone, msize_t msize) {
- // tries to allocate a small, cleared block
+small_malloc_cleared_no_lock(szone_t *szone, msize_t msize)
+{
+ void *ptr;
+
// Assumes already locked
CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
- void *ptr;
ptr = small_malloc_from_free_list(szone, msize);
if (ptr) {
- memset(ptr, 0, msize << SHIFT_SMALL_QUANTUM);
+ memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize));
return ptr;
} else {
ptr = small_malloc_from_region_no_lock(szone, msize);
}
static INLINE void
-free_small(szone_t *szone, void *ptr, small_region_t *small_region) {
- // ptr is known to be in small_region
+free_small(szone_t *szone, void *ptr, small_region_t *small_region)
+{
msize_t msize_and_free;
- msize_and_free = small_meta_header(ptr)[0];
+#if SMALL_CACHE
+ void *ptr2;
+#endif
+
+ // ptr is known to be in small_region
+ msize_and_free = *SMALL_METADATA_FOR_PTR(ptr);
if (msize_and_free & SMALL_IS_FREE) {
szone_error(szone, "Object already freed being freed", ptr);
return;
}
CHECK(szone, __PRETTY_FUNCTION__);
- // malloc_printf("%p[%x]\n", ptr, msize_and_free);
SZONE_LOCK(szone);
#if SMALL_CACHE
- void *ptr2 = szone->last_small_free;
- szone->last_small_free = (void *)(((unsigned)ptr) | msize_and_free);
+ ptr2 = szone->last_small_free;
+ szone->last_small_free = (void *)(((uintptr_t)ptr) | msize_and_free);
if (!ptr2) {
- // malloc_printf("stuffing last_small_free\n");
SZONE_UNLOCK(szone);
CHECK(szone, __PRETTY_FUNCTION__);
return;
}
- // malloc_printf("replacing previous last_small_free %p with %p\n", ptr2, szone->last_small_free);
- msize_and_free = (unsigned)ptr2 & (SMALL_QUANTUM - 1);
- ptr = (void *)(((unsigned)ptr2) & ~ (SMALL_QUANTUM - 1));
+ msize_and_free = (uintptr_t)ptr2 & (SMALL_QUANTUM - 1);
+ ptr = (void *)(((uintptr_t)ptr2) & ~ (SMALL_QUANTUM - 1));
small_region = small_region_for_ptr_no_lock(szone, ptr);
if (!small_region) {
- szone_error(szone, "Double free (small cache)", ptr);
+ szone_error(szone, "double free (small cache)", ptr);
+ return;
}
#endif
small_free_no_lock(szone, small_region, ptr, msize_and_free);
}
static void
-print_small_free_list(szone_t *szone) {
+print_small_free_list(szone_t *szone)
+{
grain_t grain = 0;
- malloc_printf("Small free sizes: ");
+ free_list_t *ptr;
+
+ malloc_printf("small free sizes: ");
while (grain < NUM_SMALL_SLOTS) {
- free_list_t *ptr = szone->small_free_list[grain];
+ ptr = szone->small_free_list[grain];
if (ptr) {
malloc_printf("%s%y[%d]; ", (grain == NUM_SMALL_SLOTS-1) ? ">=" : "", (grain + 1) * SMALL_QUANTUM, free_list_count(ptr));
}
}
static void
-print_small_region(szone_t *szone, boolean_t verbose, small_region_t *region, size_t bytes_at_end) {
- unsigned counts[1024];
- unsigned in_use = 0;
- vm_address_t start = SMALL_REGION_ADDRESS(*region);
- vm_address_t limit = SMALL_REGION_END(*region) - bytes_at_end;
+print_small_region(szone_t *szone, boolean_t verbose, small_region_t *region, size_t bytes_at_end)
+{
+ unsigned counts[1024];
+ unsigned in_use = 0;
+ void *start = SMALL_REGION_ADDRESS(*region);
+ void *limit = SMALL_REGION_END(*region) - bytes_at_end;
+ msize_t msize_and_free;
+ msize_t msize;
+ unsigned ci;
+
memset(counts, 0, 1024 * sizeof(unsigned));
while (start < limit) {
- msize_t msize_and_free = small_meta_header((void *)start)[0];
- msize_t msize = msize_and_free & ~ SMALL_IS_FREE;
+ msize_and_free = *SMALL_METADATA_FOR_PTR(start);
+ msize = msize_and_free & ~ SMALL_IS_FREE;
if (!(msize_and_free & SMALL_IS_FREE)) {
// block in use
- if (msize < 1024) counts[msize]++;
+ if (msize < 1024)
+ counts[msize]++;
in_use++;
}
- start += msize << SHIFT_SMALL_QUANTUM;
+ start += SMALL_BYTES_FOR_MSIZE(msize);
}
- malloc_printf("Small region [%p-%p, %y]\tIn_use=%d ", SMALL_REGION_ADDRESS(*region), SMALL_REGION_END(*region), (int)SMALL_REGION_SIZE, in_use);
- if (bytes_at_end) malloc_printf("Untouched=%y ", bytes_at_end);
+ malloc_printf("Small region [%p-%p, %y]\tIn_use=%d ",
+ SMALL_REGION_ADDRESS(*region), SMALL_REGION_END(*region), (int)SMALL_REGION_SIZE, in_use);
+ if (bytes_at_end)
+ malloc_printf("Untouched=%y ", bytes_at_end);
if (verbose && in_use) {
- unsigned ci = 0;
malloc_printf("\n\tSizes in use: ");
- while (ci < 1024) {
- if (counts[ci]) {
- malloc_printf("%d[%d] ", ci << SHIFT_SMALL_QUANTUM, counts[ci]);
- }
- ci++;
- }
+ for (ci = 0; ci < 1024; ci++)
+ if (counts[ci])
+ malloc_printf("%d[%d] ", SMALL_BYTES_FOR_MSIZE(ci), counts[ci]);
}
malloc_printf("\n");
}
static boolean_t
-small_free_list_check(szone_t *szone, grain_t grain) {
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
+small_free_list_check(szone_t *szone, grain_t grain)
+{
unsigned count = 0;
free_list_t *ptr = szone->small_free_list[grain];
free_list_t *previous = NULL;
+ msize_t msize_and_free;
+
+ CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
while (ptr) {
- msize_t msize_and_free = small_meta_header(ptr)[0];
+ msize_and_free = *SMALL_METADATA_FOR_PTR(ptr);
count++;
if (!(msize_and_free & SMALL_IS_FREE)) {
- malloc_printf("*** malloc[%d]: In-use ptr in free list grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr);
+ malloc_printf("*** in-use ptr in free list grain=%d count=%d ptr=%p\n", grain, count, ptr);
return 0;
}
- if (((unsigned)ptr) & (SMALL_QUANTUM - 1)) {
- malloc_printf("*** malloc[%d]: Unaligned ptr in free list grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr);
+ if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) {
+ malloc_printf("*** unaligned ptr in free list grain=%d count=%d ptr=%p\n", grain, count, ptr);
return 0;
}
if (!small_region_for_ptr_no_lock(szone, ptr)) {
- malloc_printf("*** malloc[%d]: Ptr not in szone grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr);
+ malloc_printf("*** ptr not in szone grain=%d count=%d ptr=%p\n", grain, count, ptr);
return 0;
}
free_list_checksum(szone, ptr, __PRETTY_FUNCTION__);
if (ptr->previous != previous) {
- malloc_printf("*** malloc[%d]: Previous incorrectly set grain=%d count=%d ptr=%p\n", getpid(), grain, count, ptr);
+ malloc_printf("*** previous incorrectly set grain=%d count=%d ptr=%p\n", grain, count, ptr);
return 0;
}
previous = ptr;
#if DEBUG_MALLOC
static void
-large_debug_print(szone_t *szone) {
- unsigned num_large_entries = szone->num_large_entries;
- unsigned index = num_large_entries;
- while (index--) {
- large_entry_t *range = szone->large_entries + index;
- large_entry_t entry = *range;
- if (!LARGE_ENTRY_IS_EMPTY(entry)) {
- malloc_printf("%d: %p(%y); ", index, LARGE_ENTRY_ADDRESS(entry), LARGE_ENTRY_SIZE(entry));
- }
- }
+large_debug_print(szone_t *szone)
+{
+ unsigned num_large_entries = szone->num_large_entries;
+ unsigned index = num_large_entries;
+ large_entry_t *range;
+
+ for (index = 0, range = szone->large_entries; index < szone->num_large_entries; index++, range++)
+ if (!LARGE_ENTRY_IS_EMPTY(*range))
+ malloc_printf("%d: %p(%y); ", index, LARGE_ENTRY_ADDRESS(*range), LARGE_ENTRY_SIZE(*range));
+
malloc_printf("\n");
}
#endif
+/*
+ * Scan the hash ring looking for an entry for the given pointer.
+ */
static large_entry_t *
-large_entry_for_pointer_no_lock(szone_t *szone,
- const void *ptr) {
- // result only valid during a lock
- unsigned num_large_entries = szone->num_large_entries;
- unsigned hash_index;
- unsigned index;
- if (!num_large_entries) return NULL;
- hash_index = ((unsigned)ptr >> vm_page_shift) % num_large_entries;
+large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr)
+{
+ // result only valid with lock held
+ unsigned num_large_entries = szone->num_large_entries;
+ unsigned hash_index;
+ unsigned index;
+ large_entry_t *range;
+
+ if (!num_large_entries)
+ return NULL;
+ hash_index = ((uintptr_t)ptr >> vm_page_shift) % num_large_entries;
index = hash_index;
do {
- large_entry_t *range = szone->large_entries + index;
- large_entry_t entry = *range;
- if (LARGE_ENTRY_MATCHES(entry, ptr)) return range;
- if (LARGE_ENTRY_IS_EMPTY(entry)) return NULL; // end of chain
- index++; if (index == num_large_entries) index = 0;
+ range = szone->large_entries + index;
+ if (LARGE_ENTRY_MATCHES(*range, ptr))
+ return range;
+ if (LARGE_ENTRY_IS_EMPTY(*range))
+ return NULL; // end of chain
+ index++;
+ if (index == num_large_entries)
+ index = 0;
} while (index != hash_index);
return NULL;
}
static void
-large_entry_insert_no_lock(szone_t *szone, large_entry_t range) {
- unsigned num_large_entries = szone->num_large_entries;
- unsigned hash_index = (range.address_and_num_pages >> vm_page_shift)
- % num_large_entries;
- unsigned index = hash_index;
-// malloc_printf("Before insertion of %p\n", LARGE_ENTRY_ADDRESS(range));
+large_entry_insert_no_lock(szone_t *szone, large_entry_t range)
+{
+ unsigned num_large_entries = szone->num_large_entries;
+ unsigned hash_index = (range.address_and_num_pages >> vm_page_shift) % num_large_entries;
+ unsigned index = hash_index;
+ large_entry_t *entry;
+
do {
- large_entry_t *entry = szone->large_entries + index;
+ entry = szone->large_entries + index;
if (LARGE_ENTRY_IS_EMPTY(*entry)) {
*entry = range;
return; // end of chain
}
- index++; if (index == num_large_entries) index = 0;
+ index++;
+ if (index == num_large_entries)
+ index = 0;
} while (index != hash_index);
}
static INLINE void
-large_entries_rehash_after_entry_no_lock(szone_t *szone,
- large_entry_t *entry) {
- unsigned num_large_entries = szone->num_large_entries;
- unsigned hash_index = entry - szone->large_entries;
- unsigned index = hash_index;
+large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry)
+{
+ unsigned num_large_entries = szone->num_large_entries;
+ unsigned hash_index = entry - szone->large_entries;
+ unsigned index = hash_index;
+ large_entry_t range;
+
do {
- large_entry_t range;
- index++; if (index == num_large_entries) index = 0;
+ index++;
+ if (index == num_large_entries)
+ index = 0;
range = szone->large_entries[index];
- if (LARGE_ENTRY_IS_EMPTY(range)) return;
+ if (LARGE_ENTRY_IS_EMPTY(range))
+ return;
szone->large_entries[index].address_and_num_pages = 0;
large_entry_insert_no_lock(szone, range); // this will reinsert in the
// proper place
}
static INLINE large_entry_t *
-large_entries_alloc_no_lock(szone_t *szone,
- unsigned num) {
+large_entries_alloc_no_lock(szone_t *szone, unsigned num)
+{
size_t size = num * sizeof(large_entry_t);
boolean_t is_vm_allocation = size >= LARGE_THRESHOLD;
+
if (is_vm_allocation) {
// Note that we allocate memory (via a system call) under a spin lock
// That is certainly evil, however it's very rare in the lifetime of a process
// The alternative would slow down the normal case
return (void *)allocate_pages(szone, round_page(size), 0, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC_LARGE));
} else {
- return small_malloc_cleared_no_lock(szone, (size + SMALL_QUANTUM - 1) >> SHIFT_SMALL_QUANTUM);
+ return small_malloc_cleared_no_lock(szone, SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1));
}
}
static void
-large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate) {
+large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate)
+{
// returns range to deallocate
- size_t size = num * sizeof(large_entry_t);
- boolean_t is_vm_allocation = size >= LARGE_THRESHOLD;
- // malloc_printf("In large_entries_free_no_lock %d %d\n", num, is_vm_allocation);
+ size_t size = num * sizeof(large_entry_t);
+ boolean_t is_vm_allocation = size >= LARGE_THRESHOLD;
+ small_region_t *region;
+ msize_t msize_and_free;
+
if (is_vm_allocation) {
range_to_deallocate->address = (vm_address_t)entries;
range_to_deallocate->size = round_page(size);
} else {
range_to_deallocate->size = 0;
- small_region_t *region = small_region_for_ptr_no_lock(szone, entries);
- msize_t msize_and_free = small_meta_header(entries)[0];
+ region = small_region_for_ptr_no_lock(szone, entries);
+ msize_and_free = *SMALL_METADATA_FOR_PTR(entries);
if (msize_and_free & SMALL_IS_FREE) {
- szone_error(szone, "Object already freed being freed", entries);
+ szone_error(szone, "object already freed being freed", entries);
return;
}
small_free_no_lock(szone, region, entries, msize_and_free);
}
static void
-large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate) {
+large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate)
+{
// sets range_to_deallocate
unsigned old_num_entries = szone->num_large_entries;
large_entry_t *old_entries = szone->large_entries;
- unsigned new_num_entries = (old_num_entries) ? old_num_entries
- * 2 + 1 : 63; // always an odd number for good hashing
+ unsigned new_num_entries = (old_num_entries) ? old_num_entries * 2 + 1 : 63; // always an odd number for good hashing
large_entry_t *new_entries = large_entries_alloc_no_lock(szone, new_num_entries);
unsigned index = old_num_entries;
+ large_entry_t oldRange;
+
szone->num_large_entries = new_num_entries;
szone->large_entries = new_entries;
- // malloc_printf("_grow_large_entries old_num_entries=%d new_num_entries=%d %p\n", old_num_entries, new_num_entries, old_entries);
+
+ /* rehash entries into the new list */
while (index--) {
- large_entry_t oldRange = old_entries[index];
+ oldRange = old_entries[index];
if (!LARGE_ENTRY_IS_EMPTY(oldRange)) {
large_entry_insert_no_lock(szone, oldRange);
}
}
}
+// frees the specific entry in the size table
+// returns a range to truly deallocate
static vm_range_t
-large_free_no_lock(szone_t *szone, large_entry_t *entry) {
- // frees the specific entry in the size table
- // returns a range to truly deallocate
+large_free_no_lock(szone_t *szone, large_entry_t *entry)
+{
vm_range_t range;
- range.address = LARGE_ENTRY_ADDRESS(*entry);
- range.size = LARGE_ENTRY_SIZE(*entry);
- szone->num_large_objects_in_use --;
+
+ range.address = (vm_address_t)LARGE_ENTRY_ADDRESS(*entry);
+ range.size = (vm_size_t)LARGE_ENTRY_SIZE(*entry);
+ szone->num_large_objects_in_use--;
szone->num_bytes_in_large_objects -= range.size;
if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) {
- protect(szone, range.address, range.size, VM_PROT_READ | VM_PROT_WRITE,
- szone->debug_flags);
- range.address -= 1 << vm_page_shift;
- range.size += 2 * (1 << vm_page_shift);
- }
-// malloc_printf("Entry is %p=%d; cache is %p ; found=%p\n", entry,
-// entry-szone->large_entries, szone->large_entries,
-// large_entry_for_pointer_no_lock(szone, (void *)range.address));
+ protect(szone, (void *)range.address, range.size, VM_PROT_READ | VM_PROT_WRITE, szone->debug_flags);
+ range.address -= vm_page_size;
+ range.size += 2 * vm_page_size;
+ }
entry->address_and_num_pages = 0;
large_entries_rehash_after_entry_no_lock(szone, entry);
#if DEBUG_MALLOC
if (large_entry_for_pointer_no_lock(szone, (void *)range.address)) {
- malloc_printf("*** malloc[%d]: Freed entry %p still in use; "
- "num_large_entries=%d\n", getpid(), range.address,
- szone->num_large_entries);
+ malloc_printf("*** freed entry %p still in use; num_large_entries=%d\n",
+ range.address, szone->num_large_entries);
large_debug_print(szone);
szone_sleep();
}
return range;
}
-static INLINE boolean_t
-try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) {
- // returns 1 on success
- msize_t *meta_headers = small_meta_headers(ptr);
- msize_t index = small_meta_index(ptr);
- msize_t old_msize = old_size >> SHIFT_SMALL_QUANTUM;
- msize_t new_msize = (new_size + SMALL_QUANTUM - 1) >> SHIFT_SMALL_QUANTUM;
- void *next_block = (char *)ptr + old_size;
- msize_t next_index = index + old_msize;
- if (next_index >= NUM_SMALL_BLOCKS) {
- // malloc_printf("try_realloc_small_in_place can't take place at end %p %d %d %d\n", ptr, old_size, new_size, next_index);
- return 0;
- }
-#if DEBUG_MALLOC
- if ((vm_address_t)next_block & (SMALL_QUANTUM - 1)) {
- szone_error(szone, "Internal invariant broken in realloc(next_block)", next_block);
- }
- if (meta_headers[index] != old_msize) malloc_printf("*** try_realloc_small_in_place incorrect old %d %d\n", meta_headers[index], old_msize);
-#endif
- SZONE_LOCK(szone);
- // If the next block is free, we coalesce
- msize_t next_msize_and_free;
- msize_t next_msize;
- next_msize_and_free = meta_headers[next_index];
- next_msize = next_msize_and_free & ~ SMALL_IS_FREE;
- if (!(next_msize_and_free & SMALL_IS_FREE) || (old_msize + next_msize < new_msize)) {
- SZONE_UNLOCK(szone);
- return 0;
- }
- // malloc_printf("Small realloc in place for %p; current msize=%db(%d) next=%p next_msize=%d wanted=%db(%d)\n", ptr, old_size, meta_headers[index], next_block, next_msize, new_size, new_msize);
- small_free_list_remove_ptr(szone, next_block, next_msize);
- small_meta_header_set_middle(meta_headers, next_index);
- msize_t leftover_msize = old_msize + next_msize - new_msize;
- if (leftover_msize) {
- void *leftover = ptr + (new_msize << SHIFT_SMALL_QUANTUM);
- // malloc_printf("Leftover in realloc in place %p msize=%d\n", leftover, leftover_msize);
- small_free_list_add_ptr(szone, leftover, leftover_msize);
- msize_t leftover_index = index + new_msize;
- small_meta_header_set_is_free(meta_headers, leftover_index, leftover_msize);
- }
-#if DEBUG_MALLOC
- if ((new_msize << SHIFT_SMALL_QUANTUM) >= LARGE_THRESHOLD) {
- malloc_printf("*** Realloc in place for %p exceeded msize=%d\n", new_msize);
- }
-#endif
- small_meta_header_set_in_use(meta_headers, index, new_msize);
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("In szone_realloc(), ptr=%p, msize=%d\n", ptr, small_meta_header(ptr)[0]);
- }
-#endif
- szone->num_bytes_in_small_objects += (new_msize - old_msize) << SHIFT_SMALL_QUANTUM;
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
-// malloc_printf("Extended ptr %p for realloc old=%d desired=%d new=%d "
-// "leftover=%d\n", ptr, (unsigned)old_size, (unsigned)new_size,
-// (unsigned)szone_size(szone, ptr), leftover_msize << SHIFT_SMALL_QUANTUM);
- return 1;
-}
-
static kern_return_t
-large_in_use_enumerator(task_t task, void *context,
- unsigned type_mask, vm_address_t large_entries_address, unsigned num_entries,
- memory_reader_t reader, vm_range_recorder_t recorder) {
+large_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t large_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder)
+{
unsigned index = 0;
vm_range_t buffer[MAX_RECORDER_BUFFER];
unsigned count = 0;
large_entry_t *entries;
kern_return_t err;
- err = reader(task, large_entries_address,
- sizeof(large_entry_t) * num_entries, (void **)&entries);
- if (err) return err;
+ vm_range_t range;
+ large_entry_t entry;
+
+ err = reader(task, large_entries_address, sizeof(large_entry_t) * num_entries, (void **)&entries);
+ if (err)
+ return err;
index = num_entries;
- if ((type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE)
- && (num_entries * sizeof(large_entry_t) >= LARGE_THRESHOLD)) {
- vm_range_t range;
+ if ((type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) &&
+ (num_entries * sizeof(large_entry_t) >= LARGE_THRESHOLD)) {
range.address = large_entries_address;
range.size = round_page(num_entries * sizeof(large_entry_t));
recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &range, 1);
}
- if (type_mask & (MALLOC_PTR_IN_USE_RANGE_TYPE
- | MALLOC_PTR_REGION_RANGE_TYPE))
- while (index--) {
- large_entry_t entry = entries[index];
- if (!LARGE_ENTRY_IS_EMPTY(entry)) {
- vm_range_t range;
- range.address = LARGE_ENTRY_ADDRESS(entry);
- range.size = LARGE_ENTRY_SIZE(entry);
- buffer[count++] = range;
- if (count >= MAX_RECORDER_BUFFER) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE
- | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count);
- count = 0;
+ if (type_mask & (MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE))
+ while (index--) {
+ entry = entries[index];
+ if (!LARGE_ENTRY_IS_EMPTY(entry)) {
+ range.address = (vm_address_t)LARGE_ENTRY_ADDRESS(entry);
+ range.size = (vm_size_t)LARGE_ENTRY_SIZE(entry);
+ buffer[count++] = range;
+ if (count >= MAX_RECORDER_BUFFER) {
+ recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count);
+ count = 0;
+ }
}
}
- }
if (count) {
recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE
| MALLOC_PTR_REGION_RANGE_TYPE, buffer, count);
/********************* HUGE ENTRY UTILITIES ************************/
static huge_entry_t *
-huge_entry_for_pointer_no_lock(szone_t *szone,
- const void *ptr) {
- unsigned index = szone->num_huge_entries;
- while (index--) {
- huge_entry_t *huge = szone->huge_entries + index;
- if (huge->address == (vm_address_t)ptr) return huge;
+huge_entry_for_pointer_no_lock(szone_t *szone, const void *ptr)
+{
+ unsigned index;
+ huge_entry_t *huge;
+
+ for (index = szone->num_huge_entries, huge = szone->huge_entries;
+ index > 0;
+ index--, huge++) {
+
+ if ((void *)huge->address == ptr)
+ return huge;
}
return NULL;
}
static boolean_t
-huge_entry_append(szone_t *szone, huge_entry_t huge) {
+huge_entry_append(szone_t *szone, huge_entry_t huge)
+{
+ huge_entry_t *new_huge_entries = NULL, *old_huge_entries;
+ unsigned num_huge_entries;
+
// We do a little dance with locking because doing allocation (even in the
// default szone) may cause something to get freed in this szone, with a
// deadlock
// Returns 1 on success
- huge_entry_t *new_huge_entries = NULL;
SZONE_LOCK(szone);
- while (1) {
- unsigned num_huge_entries;
+ for (;;) {
num_huge_entries = szone->num_huge_entries;
SZONE_UNLOCK(szone);
-// malloc_printf("In huge_entry_append currentEntries=%d\n", num_huge_entries);
- if (new_huge_entries) szone_free(szone, new_huge_entries);
+ /* check for counter wrap */
+ if ((num_huge_entries + 1) < num_huge_entries)
+ return 0;
+ /* stale allocation from last time around the loop? */
+ if (new_huge_entries)
+ szone_free(szone, new_huge_entries);
new_huge_entries = szone_malloc(szone, (num_huge_entries + 1) * sizeof(huge_entry_t));
- if (new_huge_entries == NULL) return 0;
+ if (new_huge_entries == NULL)
+ return 0;
SZONE_LOCK(szone);
if (num_huge_entries == szone->num_huge_entries) {
// No change - our malloc still applies
- huge_entry_t *old_huge_entries = szone->huge_entries;
+ old_huge_entries = szone->huge_entries;
if (num_huge_entries) {
memcpy(new_huge_entries, old_huge_entries, num_huge_entries * sizeof(huge_entry_t));
}
szone->huge_entries = new_huge_entries;
SZONE_UNLOCK(szone);
szone_free(szone, old_huge_entries);
-// malloc_printf("Done huge_entry_append now=%d\n", szone->num_huge_entries);
return 1;
}
// try again!
}
static kern_return_t
-huge_in_use_enumerator(task_t task, void *context,
- unsigned type_mask, vm_address_t huge_entries_address, unsigned num_entries,
- memory_reader_t reader, vm_range_recorder_t recorder) {
+huge_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t huge_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder)
+{
huge_entry_t *entries;
kern_return_t err;
- err = reader(task, huge_entries_address, sizeof(huge_entry_t) * num_entries,
- (void **)&entries);
- if (err) return err;
- if (num_entries) {
- recorder(task, context,
- MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, entries,
- num_entries);
- }
+
+ err = reader(task, huge_entries_address, sizeof(huge_entry_t) * num_entries, (void **)&entries);
+ if (err)
+ return err;
+ if (num_entries)
+ recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, entries, num_entries);
+
return 0;
}
static void *
-large_and_huge_malloc(szone_t *szone, unsigned num_pages) {
- vm_address_t addr = 0;
+large_and_huge_malloc(szone_t *szone, unsigned num_pages)
+{
+ void *addr;
vm_range_t range_to_deallocate;
- if (!num_pages) num_pages = 1; // minimal allocation size for this szone
-// malloc_printf("In large_and_huge_malloc for %y\n", num_pages * (1 << vm_page_shift));
+ huge_entry_t huge_entry;
+ size_t size;
+ large_entry_t large_entry;
+
+ if (!num_pages)
+ num_pages = 1; // minimal allocation size for this szone
+ size = (size_t)num_pages << vm_page_shift;
range_to_deallocate.size = 0;
if (num_pages >= (1 << vm_page_shift)) {
- huge_entry_t huge;
- huge.size = num_pages << vm_page_shift;
- addr = allocate_pages(szone, huge.size, 0, szone->debug_flags, VM_MAKE_TAG(VM_MEMORY_MALLOC_HUGE));
- if (!addr) return NULL;
- huge.address = addr;
- if (! huge_entry_append(szone, huge)) return NULL;
+ addr = allocate_pages(szone, size, 0, szone->debug_flags, VM_MAKE_TAG(VM_MEMORY_MALLOC_HUGE));
+ if (addr == NULL)
+ return NULL;
+ huge_entry.size = size;
+ huge_entry.address = (vm_address_t)addr;
+ if (!huge_entry_append(szone, huge_entry))
+ return NULL; // we are leaking the allocation here
SZONE_LOCK(szone);
- szone->num_bytes_in_huge_objects += huge.size;
+ szone->num_bytes_in_huge_objects += size;
} else {
- vm_size_t size = num_pages << vm_page_shift;
- large_entry_t entry;
+
addr = allocate_pages(szone, size, 0, szone->debug_flags, VM_MAKE_TAG(VM_MEMORY_MALLOC_LARGE));
#if DEBUG_MALLOC
- if (LOG(szone, addr)) malloc_printf("In szone_malloc true large allocation at %p for %y\n", (void *)addr, size);
+ if (LOG(szone, addr))
+ malloc_printf("in szone_malloc true large allocation at %p for %y\n", (void *)addr, size);
#endif
SZONE_LOCK(szone);
- if (!addr) {
+ if (addr == NULL) {
SZONE_UNLOCK(szone);
return NULL;
}
#if DEBUG_MALLOC
- if (large_entry_for_pointer_no_lock(szone, (void *)addr)) {
- malloc_printf("Freshly allocated is already in use: %p\n", addr);
+ if (large_entry_for_pointer_no_lock(szone, addr)) {
+ malloc_printf("freshly allocated is already in use: %p\n", addr);
large_debug_print(szone);
szone_sleep();
}
if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) {
// density of hash table too high; grow table
// we do that under lock to avoid a race
- // malloc_printf("In szone_malloc growing hash table current=%d\n", szone->num_large_entries);
large_entries_grow_no_lock(szone, &range_to_deallocate);
}
-// malloc_printf("Inserting large entry (%p, %y)\n", addr, num_pages * (1 << vm_page_shift));
- entry.address_and_num_pages = addr | num_pages;
+ large_entry.address_and_num_pages = (uintptr_t)addr | num_pages;
#if DEBUG_MALLOC
- if (large_entry_for_pointer_no_lock(szone, (void *)addr)) {
- malloc_printf("Entry about to be added already in use: %p\n",
- addr);
+ if (large_entry_for_pointer_no_lock(szone, addr)) {
+ malloc_printf("entry about to be added already in use: %p\n", addr);
large_debug_print(szone);
szone_sleep();
}
#endif
- large_entry_insert_no_lock(szone, entry);
+ large_entry_insert_no_lock(szone, large_entry);
#if DEBUG_MALLOC
if (!large_entry_for_pointer_no_lock(szone, (void *)addr)) {
- malloc_printf("Can't find entry just added\n");
+ malloc_printf("can't find entry just added\n");
large_debug_print(szone);
szone_sleep();
}
#endif
-// malloc_printf("Inserted large entry (%p, %d pages)\n", addr,
-// num_pages);
szone->num_large_objects_in_use ++;
szone->num_bytes_in_large_objects += size;
}
SZONE_UNLOCK(szone);
if (range_to_deallocate.size) {
- deallocate_pages(szone, range_to_deallocate.address, range_to_deallocate.size, 0); // we deallocate outside the lock
- // malloc_printf("Deallocated large entries %d\n", range_to_deallocate.size);
+ deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); // we deallocate outside the lock
}
return (void *)addr;
}
static INLINE void
-free_large_or_huge(szone_t *szone, void *ptr) {
+free_large_or_huge(szone_t *szone, void *ptr)
+{
// We have established ptr is page-aligned and not tiny nor small
large_entry_t *entry;
vm_range_t vm_range_to_deallocate;
huge_entry_t *huge;
+
SZONE_LOCK(szone);
entry = large_entry_for_pointer_no_lock(szone, ptr);
if (entry) {
-// malloc_printf("Ready for deallocation [%p-%y]\n", LARGE_ENTRY_ADDRESS(*entry), LARGE_ENTRY_SIZE(*entry));
vm_range_to_deallocate = large_free_no_lock(szone, entry);
#if DEBUG_MALLOC
if (large_entry_for_pointer_no_lock(szone, ptr)) {
- malloc_printf("*** malloc[%d]: Just after freeing %p still in use num_large_entries=%d\n", getpid(), ptr, szone->num_large_entries);
+ malloc_printf("*** just after freeing %p still in use num_large_entries=%d\n", ptr, szone->num_large_entries);
large_debug_print(szone);
szone_sleep();
}
} else if ((huge = huge_entry_for_pointer_no_lock(szone, ptr))) {
vm_range_to_deallocate = *huge;
*huge = szone->huge_entries[--szone->num_huge_entries]; // last entry fills that spot
- szone->num_bytes_in_huge_objects -= vm_range_to_deallocate.size;
+ szone->num_bytes_in_huge_objects -= (size_t)vm_range_to_deallocate.size;
} else {
#if DEBUG_MALLOC
large_debug_print(szone);
#endif
- szone_error(szone, "Pointer being freed was not allocated", ptr);
+ szone_error(szone, "pointer being freed was not allocated", ptr);
return;
}
SZONE_UNLOCK(szone); // we release the lock asap
CHECK(szone, __PRETTY_FUNCTION__);
// we deallocate_pages, including guard pages
if (vm_range_to_deallocate.address) {
-// malloc_printf("About to deallocate %p size %y\n", vm_range_to_deallocate.address, vm_range_to_deallocate.size);
#if DEBUG_MALLOC
- if (large_entry_for_pointer_no_lock(szone,
- (void *)vm_range_to_deallocate.address)) {
- malloc_printf("*** malloc[%d]: Invariant broken: %p still in use num_large_entries=%d\n", getpid(), vm_range_to_deallocate.address, szone->num_large_entries);
+ if (large_entry_for_pointer_no_lock(szone, (void *)vm_range_to_deallocate.address)) {
+ malloc_printf("*** invariant broken: %p still in use num_large_entries=%d\n", vm_range_to_deallocate.address, szone->num_large_entries);
large_debug_print(szone);
szone_sleep();
}
#endif
- deallocate_pages(szone, vm_range_to_deallocate.address, vm_range_to_deallocate.size, 0);
+ deallocate_pages(szone, (void *)vm_range_to_deallocate.address, (size_t)vm_range_to_deallocate.size, 0);
}
}
static INLINE int
-try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) {
+try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size)
+{
vm_address_t addr = (vm_address_t)ptr + old_size;
- large_entry_t *entry;
+ large_entry_t *large_entry, saved_entry;
+ huge_entry_t *huge_entry, huge;
kern_return_t err;
+
#if DEBUG_MALLOC
if (old_size != ((old_size >> vm_page_shift) << vm_page_shift)) {
malloc_printf("*** old_size is %d\n", old_size);
}
#endif
-// malloc_printf("=== Trying (1) to extend %p from %d to %d\n", ptr, old_size, new_size);
SZONE_LOCK(szone);
- entry = large_entry_for_pointer_no_lock(szone, (void *)addr);
+ large_entry = large_entry_for_pointer_no_lock(szone, (void *)addr);
SZONE_UNLOCK(szone);
- if (entry) {
- return 0; // large pointer already exist in table - extension is not going to work
+ if (large_entry) {
+ return 0; // large pointer already exists in table - extension is not going to work
}
new_size = round_page(new_size);
-// malloc_printf("=== Trying (2) to extend %p from %d to %d\n", ptr, old_size, new_size);
/*
* Ask for allocation at a specific address, and mark as realloc
* to request coalescing with previous realloc'ed extensions.
* Note: this logic is predicated on the understanding that an allocated
* block can never really shrink, so that the new size will always be
* larger than the old size.
+ *
+ * Note: the use of 1 << vm_page_shift here has to do with the subdivision
+ * of the bits in the large_entry_t, and not the size of a page (directly).
*/
if ((new_size >> vm_page_shift) < (1 << vm_page_shift)) {
/* extend existing large entry */
- entry = large_entry_for_pointer_no_lock(szone, ptr);
- if (!entry) {
+ large_entry = large_entry_for_pointer_no_lock(szone, ptr);
+ if (!large_entry) {
szone_error(szone, "large entry reallocated is not properly in table", ptr);
/* XXX will cause fault on next reference to entry */
}
- entry->address_and_num_pages = (vm_address_t)ptr | (new_size >> vm_page_shift);
+ large_entry->address_and_num_pages = (uintptr_t)ptr | (new_size >> vm_page_shift);
szone->num_bytes_in_large_objects += new_size - old_size;
} else if ((old_size >> vm_page_shift) >= (1 << vm_page_shift)) {
/* extend existing huge entry */
- huge_entry_t *huge_entry = huge_entry_for_pointer_no_lock(szone, ptr);
+ huge_entry = huge_entry_for_pointer_no_lock(szone, ptr);
if (!huge_entry) {
szone_error(szone, "huge entry reallocated is not properly in table", ptr);
/* XXX will cause fault on next reference to huge_entry */
szone->num_bytes_in_huge_objects += new_size - old_size;
} else {
/* need to convert large entry to huge entry */
- huge_entry_t huge;
/* release large entry, note we still have the VM allocation */
- entry = large_entry_for_pointer_no_lock(szone, ptr);
- large_entry_t saved_entry = *entry; // in case we need to put it back
- large_free_no_lock(szone, entry);
+ large_entry = large_entry_for_pointer_no_lock(szone, ptr);
+ saved_entry = *large_entry; // in case we need to put it back
+ large_free_no_lock(szone, large_entry);
szone->num_bytes_in_large_objects -= old_size;
/* and get a huge entry */
// we leak memory (the extra space appended) but data structures are correct
large_entry_insert_no_lock(szone, saved_entry); // this will reinsert the large entry
}
-// malloc_printf("=== Successfully reallocated at end of %p from %d to %d\n", ptr, old_size, new_size);
SZONE_UNLOCK(szone); // we release the lock asap
return 1;
}
/********************* Zone call backs ************************/
static void
-szone_free(szone_t *szone, void *ptr) {
- // malloc_printf("szone_free(%p)\n", ptr);
+szone_free(szone_t *szone, void *ptr)
+{
+ tiny_region_t *tiny_region;
+ small_region_t *small_region;
+
#if DEBUG_MALLOC
- if (LOG(szone, ptr)) malloc_printf("In szone_free with %p\n", ptr);
+ if (LOG(szone, ptr))
+ malloc_printf("in szone_free with %p\n", ptr);
#endif
- if (!ptr) return;
- if ((vm_address_t)ptr & (TINY_QUANTUM - 1)) {
+ if (!ptr)
+ return;
+ /*
+ * Try to free to a tiny region.
+ */
+ if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) {
szone_error(szone, "Non-aligned pointer being freed", ptr);
return;
}
- // try a tiny pointer
- tiny_region_t *tiny_region = tiny_region_for_ptr_no_lock(szone, ptr);
- if (tiny_region) {
+ if ((tiny_region = tiny_region_for_ptr_no_lock(szone, ptr)) != NULL) {
free_tiny(szone, ptr, tiny_region);
return;
}
- if ((vm_address_t)ptr & (SMALL_QUANTUM - 1)) {
+
+ /*
+ * Try to free to a small region.
+ */
+ if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) {
szone_error(szone, "Non-aligned pointer being freed (2)", ptr);
return;
}
- // try a small pointer
- small_region_t *small_region = small_region_for_ptr_no_lock(szone, ptr);
- if (small_region) {
+ if ((small_region = small_region_for_ptr_no_lock(szone, ptr)) != NULL) {
free_small(szone, ptr, small_region);
return;
}
- if (((unsigned)ptr) & ((1 << vm_page_shift) - 1)) {
- szone_error(szone, "Non-page-aligned, non-allocated pointer being freed", ptr);
+
+ /* check that it's a legal large/huge allocation */
+ if ((uintptr_t)ptr & (vm_page_size - 1)) {
+ szone_error(szone, "non-page-aligned, non-allocated pointer being freed", ptr);
return;
}
free_large_or_huge(szone, ptr);
}
static INLINE void *
-szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested) {
+szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested)
+{
void *ptr;
+ msize_t msize;
+ unsigned num_pages;
+
if (size <= 31*TINY_QUANTUM) {
// think tiny
- msize_t msize = (size + TINY_QUANTUM - 1) >> SHIFT_TINY_QUANTUM;
- if (! msize) msize = 1;
+ msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1);
+ if (!msize)
+ msize = 1;
ptr = tiny_malloc_should_clear(szone, msize, cleared_requested);
} else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (size < LARGE_THRESHOLD)) {
// think small
- msize_t msize = (size + SMALL_QUANTUM - 1) >> SHIFT_SMALL_QUANTUM;
+ msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1);
if (! msize) msize = 1;
ptr = small_malloc_should_clear(szone, msize, cleared_requested);
} else {
- unsigned num_pages;
+ // large or huge
num_pages = round_page(size) >> vm_page_shift;
ptr = large_and_huge_malloc(szone, num_pages);
}
#if DEBUG_MALLOC
- if (LOG(szone, ptr)) malloc_printf("szone_malloc returned %p\n", ptr);
+ if (LOG(szone, ptr))
+ malloc_printf("szone_malloc returned %p\n", ptr);
#endif
+ /*
+ * If requested, scribble on allocated memory.
+ */
+ if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && ptr && !cleared_requested && size)
+ memset(ptr, 0xaa, size);
+
return ptr;
}
static void *
szone_malloc(szone_t *szone, size_t size) {
- // malloc_printf("szone_malloc(%d)\n", size);
- void *ptr = szone_malloc_should_clear(szone, size, 0);
- // malloc_printf("szone_malloc(%d) -> %p %d\n", size, ptr, malloc_size(ptr));
- return ptr;
+ return szone_malloc_should_clear(szone, size, 0);
}
static void *
-szone_calloc(szone_t *szone, size_t num_items, size_t size) {
- // malloc_printf("szone_calloc(%d,%d)\n", num_items, size);
- void *ptr = szone_malloc_should_clear(szone, num_items * size, 1);
- // malloc_printf("szone_calloc(%d,%d) -> %p\n", num_items, size, ptr);
- return ptr;
+szone_calloc(szone_t *szone, size_t num_items, size_t size)
+{
+ return szone_malloc_should_clear(szone, num_items * size, 1);
}
static void *
-szone_valloc(szone_t *szone, size_t size) {
+szone_valloc(szone_t *szone, size_t size)
+{
void *ptr;
unsigned num_pages;
+
num_pages = round_page(size) >> vm_page_shift;
ptr = large_and_huge_malloc(szone, num_pages);
#if DEBUG_MALLOC
- if (LOG(szone, ptr)) malloc_printf("szone_valloc returned %p\n", ptr);
+ if (LOG(szone, ptr))
+ malloc_printf("szone_valloc returned %p\n", ptr);
#endif
return ptr;
}
static size_t
-szone_size(szone_t *szone, const void *ptr) {
+szone_size(szone_t *szone, const void *ptr)
+{
size_t size = 0;
+ boolean_t is_free;
+ msize_t msize, msize_and_free;
large_entry_t *entry;
huge_entry_t *huge;
- // malloc_printf("szone_size(%p)\n", ptr);
- if (!ptr) return 0;
+
+ if (!ptr)
+ return 0;
#if DEBUG_MALLOC
if (LOG(szone, ptr)) {
- malloc_printf("In szone_size for %p (szone=%p)\n", ptr, szone);
- }
-#endif
- if ((vm_address_t)ptr & (TINY_QUANTUM - 1)) return 0;
- // Try tiny
- tiny_region_t *tiny_region = tiny_region_for_ptr_no_lock(szone, ptr);
- if (tiny_region) {
- // this is indeed a valid pointer
- boolean_t is_free;
- msize_t msize = get_tiny_meta_header(ptr, &is_free);
- return (is_free) ? 0 : msize << SHIFT_TINY_QUANTUM;
- }
- if ((vm_address_t)ptr & (SMALL_QUANTUM - 1)) return 0;
- // Try a small
- small_region_t *small_region = small_region_for_ptr_no_lock(szone, ptr);
- if (small_region) {
- // this is indeed a valid pointer
- msize_t msize_and_free = small_meta_header(ptr)[0];
- return (msize_and_free & SMALL_IS_FREE) ? 0 : msize_and_free << SHIFT_SMALL_QUANTUM;
- }
- if (((unsigned)ptr) & ((1 << vm_page_shift) - 1)) {
- // malloc_printf("Object %p not found in szone_size\n", ptr);
+ malloc_printf("in szone_size for %p (szone=%p)\n", ptr, szone);
+ }
+#endif
+
+ /*
+ * Look for it in a tiny region.
+ */
+ if ((uintptr_t)ptr & (TINY_QUANTUM - 1))
+ return 0;
+ if (tiny_region_for_ptr_no_lock(szone, ptr)) {
+ msize = get_tiny_meta_header(ptr, &is_free);
+ return (is_free) ? 0 : TINY_BYTES_FOR_MSIZE(msize);
+ }
+
+ /*
+ * Look for it in a small region.
+ */
+ if ((uintptr_t)ptr & (SMALL_QUANTUM - 1))
return 0;
+ if (small_region_for_ptr_no_lock(szone, ptr)) {
+ msize_and_free = *SMALL_METADATA_FOR_PTR(ptr);
+ return (msize_and_free & SMALL_IS_FREE) ? 0 : SMALL_BYTES_FOR_MSIZE(msize_and_free);
}
+
+ /*
+ * If not page-aligned, it cannot have come from a large or huge allocation.
+ */
+ if ((uintptr_t)ptr & (vm_page_size - 1))
+ return(0);
+
+ /*
+ * Look for it in a large or huge entry.
+ */
SZONE_LOCK(szone);
entry = large_entry_for_pointer_no_lock(szone, ptr);
if (entry) {
size = huge->size;
}
SZONE_UNLOCK(szone);
- // malloc_printf("szone_size for large/huge %p returned %d\n", ptr, (unsigned)size);
#if DEBUG_MALLOC
if (LOG(szone, ptr)) {
malloc_printf("szone_size for %p returned %d\n", ptr, (unsigned)size);
}
static void *
-szone_realloc(szone_t *szone, void *ptr, size_t new_size) {
- size_t old_size = 0;
+szone_realloc(szone_t *szone, void *ptr, size_t new_size)
+{
+ size_t old_size;
void *new_ptr;
- // malloc_printf("szone_realloc(%p,%d)\n", ptr, new_size);
+
#if DEBUG_MALLOC
if (LOG(szone, ptr)) {
- malloc_printf("In szone_realloc for %p, %d\n", ptr, (unsigned)new_size);
+ malloc_printf("in szone_realloc for %p, %d\n", ptr, (unsigned)new_size);
}
#endif
if (!ptr) {
ptr = szone_malloc(szone, new_size);
- // malloc_printf("szone_realloc(%p,%d) -> %p\n", ptr, new_size, ptr);
return ptr;
}
old_size = szone_size(szone, ptr);
if (!old_size) {
- szone_error(szone, "Pointer being reallocated was not allocated", ptr);
+ szone_error(szone, "pointer being reallocated was not allocated", ptr);
return NULL;
}
/* we never shrink an allocation */
- if (old_size >= new_size) return ptr;
+ if (old_size >= new_size)
+ return ptr;
+
+ /*
+ * If the old and new sizes both suit the tiny allocator, try to reallocate in-place.
+ */
if ((new_size + TINY_QUANTUM - 1) <= 31 * TINY_QUANTUM) {
- // We now try to realloc in place
if (try_realloc_tiny_in_place(szone, ptr, old_size, new_size)) {
- // malloc_printf("szone_realloc(%p,%d) -> %p\n", ptr, new_size, ptr);
return ptr;
}
- } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && ((new_size + SMALL_QUANTUM - 1) < LARGE_THRESHOLD) && (old_size > 31 * TINY_QUANTUM)) {
- // We now try to realloc in place
+
+ /*
+ * If the old and new sizes both suit the small allocator, and we're not protecting the
+ * small allocations, try to reallocate in-place.
+ */
+ } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) &&
+ ((new_size + SMALL_QUANTUM - 1) < LARGE_THRESHOLD) &&
+ (old_size > 31 * TINY_QUANTUM)) {
if (try_realloc_small_in_place(szone, ptr, old_size, new_size)) {
- // malloc_printf("szone_realloc(%p,%d) small in place -> %p\n", ptr, new_size, ptr);
return ptr;
}
+
+ /*
+ * If the allocation's a large or huge allocation, try to reallocate in-place there.
+ */
} else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (old_size > LARGE_THRESHOLD)) {
if (try_realloc_large_or_huge_in_place(szone, ptr, old_size, new_size)) {
return ptr;
}
}
+
+ /*
+ * Can't reallocate in place for whatever reason; allocate a new buffer and copy.
+ */
new_ptr = szone_malloc(szone, new_size);
- if (new_ptr == NULL) return NULL;
- if ((old_size > VM_COPY_THRESHOLD) && (new_size > VM_COPY_THRESHOLD)) {
- // we know everything is page-aligned try vm_copy
- kern_return_t err = 0;
- err = vm_copy(mach_task_self(), (vm_address_t)ptr, old_size, (vm_address_t)new_ptr);
- if (err) {
- szone_error(szone, "Can't vm_copy region", ptr);
- }
- } else {
+ if (new_ptr == NULL)
+ return NULL;
+
+ /*
+ * If the allocation's large enough, try to copy using VM. If that fails, or
+ * if it's too small, just copy by hand.
+ */
+ if ((old_size < VM_COPY_THRESHOLD) ||
+ vm_copy(mach_task_self(), (vm_address_t)ptr, old_size, (vm_address_t)new_ptr))
memcpy(new_ptr, ptr, old_size);
- }
szone_free(szone, ptr);
+
#if DEBUG_MALLOC
if (LOG(szone, ptr)) {
malloc_printf("szone_realloc returned %p for %d\n", new_ptr, (unsigned)new_size);
}
#endif
- // malloc_printf("szone_realloc(%p,%d) -> %p\n", ptr, new_size, new_ptr);
return new_ptr;
}
-unsigned
-szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) {
- // given a size, returns pointers capable of holding that size
- // returns the number of pointers allocated
- // may return 0 - this function will do best attempts, but just that
- // malloc_printf("In szone_batch_malloc(%d, %d)\n", size, count);
- if (size > 31*TINY_QUANTUM) return 0; // only bother implementing this for tiny
- msize_t msize = (size + TINY_QUANTUM - 1) >> SHIFT_TINY_QUANTUM;
- if (! msize) msize = 1;
- size_t chunk_size = msize << SHIFT_TINY_QUANTUM;
- unsigned found = 0;
+// given a size, returns pointers capable of holding that size
+// returns the number of pointers allocated
+// may return 0 - this function will do best attempts, but just that
+static unsigned
+szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count)
+{
+ msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1);
+ size_t chunk_size = TINY_BYTES_FOR_MSIZE(msize);
+ free_list_t **free_list = szone->tiny_free_list + msize - 1;
+ free_list_t *ptr = *free_list;
+ unsigned found = 0;
+
+ if (size > 31*TINY_QUANTUM)
+ return 0; // only bother implementing this for tiny
+ if (!msize)
+ msize = 1;
CHECK(szone, __PRETTY_FUNCTION__);
SZONE_LOCK(szone); // might as well lock right here to avoid concurrency issues
- free_list_t **free_list = szone->tiny_free_list + msize - 1;
- free_list_t *ptr = *free_list;
while (found < count) {
- if (!ptr) break;
- *results++ = ptr; found++;
+ if (!ptr)
+ break;
+ *results++ = ptr;
+ found++;
set_tiny_meta_header_in_use(ptr, msize);
- ptr = ((free_list_t *)ptr)->next;
+ ptr = ptr->next;
}
if (ptr) {
- ((free_list_t *)ptr)->previous = NULL;
- free_list_set_checksum(szone, (free_list_t *)ptr);
+ ptr->previous = NULL;
+ free_list_set_checksum(szone, ptr);
}
- *free_list = (void *)ptr;
+ *free_list = ptr;
+
// Note that we could allocate from the free lists for larger msize
// But that may un-necessarily fragment - so we might as well let the client do that
// We could also allocate from szone->tiny_bytes_free_at_end
szone->num_tiny_objects += found;
szone->num_bytes_in_tiny_objects += chunk_size * found;
SZONE_UNLOCK(szone);
- // malloc_printf("In szone_batch_malloc(%d, %d) -> %d\n", size, count, found);
return found;
}
-void
-szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count) {
+static void
+szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count)
+{
+ unsigned cc = 0;
+ void *ptr;
+ tiny_region_t *tiny_region;
+ boolean_t is_free;
+ msize_t msize;
+
// frees all the pointers in to_be_freed
// note that to_be_freed may be overwritten during the process
- if (!count) return;
- // malloc_printf("Freeing %d items\n", count);
- unsigned cc = 0;
+ if (!count)
+ return;
CHECK(szone, __PRETTY_FUNCTION__);
SZONE_LOCK(szone);
while (cc < count) {
- void *ptr = to_be_freed[cc];
- tiny_region_t *tiny_region = tiny_region_for_ptr_no_lock(szone, ptr);
+ ptr = to_be_freed[cc];
+ /* XXX this really slows us down */
+ tiny_region = tiny_region_for_ptr_no_lock(szone, ptr);
if (tiny_region) {
// this is a tiny pointer
- boolean_t is_free;
- msize_t msize = get_tiny_meta_header(ptr, &is_free);
- if (is_free) break; // a double free; let the standard free deal with it
+ msize = get_tiny_meta_header(ptr, &is_free);
+ if (is_free)
+ break; // a double free; let the standard free deal with it
tiny_free_no_lock(szone, tiny_region, ptr, msize);
to_be_freed[cc] = NULL;
}
SZONE_UNLOCK(szone);
CHECK(szone, __PRETTY_FUNCTION__);
while (count--) {
- void *ptr = to_be_freed[count];
- // malloc_printf("Freeing item at %d: %p\n", count, ptr);
- if (ptr) szone_free(szone, ptr);
+ ptr = to_be_freed[count];
+ if (ptr)
+ szone_free(szone, ptr);
}
}
static void
-szone_destroy(szone_t *szone) {
- unsigned index;
+szone_destroy(szone_t *szone)
+{
+ unsigned index;
small_region_t pended_region = 0;
+ large_entry_t *large;
+ vm_range_t range_to_deallocate;
+ huge_entry_t *huge;
+ tiny_region_t tiny_region;
+ small_region_t small_region;
+
+ /* destroy large entries */
index = szone->num_large_entries;
while (index--) {
- large_entry_t *entry = szone->large_entries + index;
- if (!LARGE_ENTRY_IS_EMPTY(*entry)) {
- large_entry_t range;
- range = *entry;
+ large = szone->large_entries + index;
+ if (!LARGE_ENTRY_IS_EMPTY(*large)) {
// we deallocate_pages, including guard pages
- deallocate_pages(szone, LARGE_ENTRY_ADDRESS(range), LARGE_ENTRY_SIZE(range), szone->debug_flags);
+ deallocate_pages(szone, (void *)LARGE_ENTRY_ADDRESS(*large), LARGE_ENTRY_SIZE(*large), szone->debug_flags);
}
}
if (szone->num_large_entries * sizeof(large_entry_t) >= LARGE_THRESHOLD) {
- vm_range_t range_to_deallocate;
- large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate); // we do not free in the small chunk case
- if (range_to_deallocate.size) deallocate_pages(szone, range_to_deallocate.address, range_to_deallocate.size, 0);
-
+ // we do not free in the small chunk case
+ large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate);
+ if (range_to_deallocate.size)
+ deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0);
}
+
+ /* destroy huge entries */
index = szone->num_huge_entries;
while (index--) {
- huge_entry_t *huge = szone->huge_entries + index;
- deallocate_pages(szone, huge->address, huge->size, szone->debug_flags);
+ huge = szone->huge_entries + index;
+ deallocate_pages(szone, (void *)huge->address, huge->size, szone->debug_flags);
}
- // the tiny regions
+
+ /* destroy tiny regions */
index = szone->num_tiny_regions;
while (index--) {
- tiny_region_t tiny_region = szone->tiny_regions[index];
- vm_size_t size_allocated = ((TINY_REGION_SIZE + (1 << vm_page_shift) - 1) >> vm_page_shift) << vm_page_shift;
- deallocate_pages(szone, TINY_REGION_ADDRESS(tiny_region), size_allocated, 0);
+ tiny_region = szone->tiny_regions[index];
+ deallocate_pages(szone, TINY_REGION_ADDRESS(tiny_region), TINY_REGION_SIZE, 0);
}
- // and now we free regions, with regions[0] as the last one (the final harakiri)
+ /* destroy small regions; region 0 must go last as it contains the szone */
index = szone->num_small_regions;
while (index--) {
- small_region_t region = szone->small_regions[index];
- if (index > 0
- && (void *)szone->small_regions >= (void *)(SMALL_REGION_ADDRESS(region))
- && (void *)szone->small_regions < (void *)(SMALL_REGION_END(region))) {
- // Pend deallocation of this region, since the region
- // bookkeeping array is in it.
- pended_region = region;
+ small_region = szone->small_regions[index];
+ /*
+ * If we've allocated more than the basic set of small regions, avoid destroying the
+ * region that contains the array.
+ */
+ if ((index > 0) &&
+ (SMALL_REGION_FOR_PTR(szone->small_regions) == SMALL_REGION_ADDRESS(small_region))) {
+ pended_region = small_region;
} else {
- deallocate_pages(szone, SMALL_REGION_ADDRESS(region), SMALL_REGION_SIZE, 0);
+ deallocate_pages(szone, (void *)SMALL_REGION_ADDRESS(small_region), SMALL_REGION_SIZE, 0);
}
}
- if (pended_region) {
- deallocate_pages(szone, SMALL_REGION_ADDRESS(pended_region), SMALL_REGION_SIZE, 0);
- }
+ if (pended_region)
+ deallocate_pages(NULL, (void *)SMALL_REGION_ADDRESS(pended_region), SMALL_REGION_SIZE, 0);
}
static size_t
-szone_good_size(szone_t *szone, size_t size) {
+szone_good_size(szone_t *szone, size_t size)
+{
+ msize_t msize;
+ unsigned num_pages;
+
if (size <= 31 * TINY_QUANTUM) {
// think tiny
- msize_t msize = (size + TINY_QUANTUM - 1) >> SHIFT_TINY_QUANTUM;
+ msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1);
if (! msize) msize = 1;
- return msize << SHIFT_TINY_QUANTUM;
+ return TINY_BYTES_FOR_MSIZE(msize << SHIFT_TINY_QUANTUM);
}
if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (size < LARGE_THRESHOLD)) {
// think small
- msize_t msize = (size + SMALL_QUANTUM - 1) >> SHIFT_SMALL_QUANTUM;
+ msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1);
if (! msize) msize = 1;
- return msize << SHIFT_SMALL_QUANTUM;
+ return SMALL_BYTES_FOR_MSIZE(msize);
} else {
- unsigned num_pages;
num_pages = round_page(size) >> vm_page_shift;
- if (!num_pages) num_pages = 1; // minimal allocation size for this
+ if (!num_pages)
+ num_pages = 1; // minimal allocation size for this
return num_pages << vm_page_shift;
}
}
unsigned szone_check_modulo = 1;
static boolean_t
-szone_check_all(szone_t *szone, const char *function) {
- unsigned index = 0;
+szone_check_all(szone_t *szone, const char *function)
+{
+ int index;
+ tiny_region_t *tiny;
+ small_region_t *small;
+
SZONE_LOCK(szone);
CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
- while (index < szone->num_tiny_regions) {
- tiny_region_t *region = szone->tiny_regions + index++;
- if (! szone_check_tiny_region(szone, region)) {
+
+ /* check tiny regions - chould check region count */
+ for (index = szone->num_tiny_regions - 1, tiny = szone->tiny_regions;
+ index >= 0;
+ index--, tiny++) {
+ if (!tiny_check_region(szone, tiny)) {
SZONE_UNLOCK(szone);
szone->debug_flags &= ~ CHECK_REGIONS;
- malloc_printf("*** malloc[%d]: Tiny region %d incorrect szone_check_all(%s) counter=%d\n", getpid(), index-1, function, szone_check_counter);
- szone_error(szone, "Check: tiny region incorrect", NULL);
+ malloc_printf("*** tiny region %d incorrect szone_check_all(%s) counter=%d\n",
+ szone->num_tiny_regions - index, function, szone_check_counter);
+ szone_error(szone, "check: tiny region incorrect", NULL);
return 0;
}
}
- index = 0;
- while (index < NUM_TINY_SLOTS) {
- if (! tiny_free_list_check(szone, index)) {
+ for (index = NUM_TINY_SLOTS - 1; index >= 0; index--) {
+ if (!tiny_free_list_check(szone, index)) {
SZONE_UNLOCK(szone);
szone->debug_flags &= ~ CHECK_REGIONS;
- malloc_printf("*** malloc[%d]: Tiny free list incorrect (slot=%d) szone_check_all(%s) counter=%d\n", getpid(), index, function, szone_check_counter);
- szone_error(szone, "Check: tiny free list incorrect", NULL);
+ malloc_printf("*** tiny free list incorrect (slot=%d) szone_check_all(%s) counter=%d\n",
+ index, function, szone_check_counter);
+ szone_error(szone, "check: tiny free list incorrect", NULL);
return 0;
}
- index++;
}
- index = 0; while (index < szone->num_small_regions) {
- small_region_t *region = szone->small_regions + index++;
- if (! szone_check_small_region(szone, region)) {
+ /* check small regions - could check region count */
+ for (index = szone->num_small_regions - 1, small = szone->small_regions;
+ index >= 0;
+ index--, small++) {
+ if (!szone_check_small_region(szone, small)) {
SZONE_UNLOCK(szone);
szone->debug_flags &= ~ CHECK_REGIONS;
- malloc_printf("*** malloc[%d]: Small region %d incorrect szone_check_all(%s) counter=%d\n", getpid(), index-1, function, szone_check_counter);
- szone_error(szone, "Check: small region incorrect", NULL);
+ malloc_printf("*** small region %d incorrect szone_check_all(%s) counter=%d\n",
+ szone->num_small_regions, index, function, szone_check_counter);
+ szone_error(szone, "check: small region incorrect", NULL);
return 0;
}
}
- index = 0;
- while (index < NUM_SMALL_SLOTS) {
- if (! small_free_list_check(szone, index)) {
+ for (index = NUM_SMALL_SLOTS - 1; index >= 0; index--) {
+ if (!small_free_list_check(szone, index)) {
SZONE_UNLOCK(szone);
szone->debug_flags &= ~ CHECK_REGIONS;
- malloc_printf("*** malloc[%d]: Small free list incorrect (grain=%d) szone_check_all(%s) counter=%d\n", getpid(), index, function, szone_check_counter);
- szone_error(szone, "Check: small free list incorrect", NULL);
+ malloc_printf("*** small free list incorrect (grain=%d) szone_check_all(%s) counter=%d\n", index, function, szone_check_counter);
+ szone_error(szone, "check: small free list incorrect", NULL);
return 0;
}
- index++;
}
SZONE_UNLOCK(szone);
// szone_print(szone, 1);
}
static boolean_t
-szone_check(szone_t *szone) {
- if (! (++szone_check_counter % 10000)) {
- malloc_printf("At szone_check counter=%d\n", szone_check_counter);
- }
- if (szone_check_counter < szone_check_start) return 1;
- if (szone_check_counter % szone_check_modulo) return 1;
+szone_check(szone_t *szone)
+{
+
+ if ((++szone_check_counter % 10000) == 0)
+ malloc_printf("at szone_check counter=%d\n", szone_check_counter);
+ if (szone_check_counter < szone_check_start)
+ return 1;
+ if (szone_check_counter % szone_check_modulo)
+ return 1;
return szone_check_all(szone, "");
}
static kern_return_t
-szone_ptr_in_use_enumerator(task_t task, void *context,
- unsigned type_mask, vm_address_t zone_address, memory_reader_t reader,
- vm_range_recorder_t recorder) {
+szone_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder)
+{
szone_t *szone;
kern_return_t err;
+
if (!reader) reader = _szone_default_reader;
-// malloc_printf("Enumerator for zone %p\n", zone_address);
err = reader(task, zone_address, sizeof(szone_t), (void **)&szone);
if (err) return err;
-// malloc_printf("Tiny ptrs enumeration for zone %p\n", zone_address);
err = tiny_in_use_enumerator(task, context, type_mask,
(vm_address_t)szone->tiny_regions, szone->num_tiny_regions, szone->tiny_bytes_free_at_end , reader, recorder);
if (err) return err;
-// malloc_printf("Small ptrs enumeration for zone %p\n", zone_address);
err = small_in_use_enumerator(task, context, type_mask,
(vm_address_t)szone->small_regions, szone->num_small_regions, szone->small_bytes_free_at_end , reader, recorder);
if (err) return err;
-// malloc_printf("Large ptrs enumeration for zone %p\n", zone_address);
err = large_in_use_enumerator(task, context, type_mask,
(vm_address_t)szone->large_entries, szone->num_large_entries, reader,
recorder);
if (err) return err;
-// malloc_printf("Huge ptrs enumeration for zone %p\n", zone_address);
err = huge_in_use_enumerator(task, context, type_mask,
(vm_address_t)szone->huge_entries, szone->num_huge_entries, reader,
recorder);
// Following method is deprecated: use scalable_zone_statistics instead
void
-scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count) {
+scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count)
+{
szone_t *szone = (void *)zone;
unsigned info[13];
+
// We do not lock to facilitate debug
info[4] = szone->num_tiny_objects;
info[5] = szone->num_bytes_in_tiny_objects;
}
static void
-szone_print(szone_t *szone, boolean_t verbose) {
- unsigned info[13];
- unsigned index = 0;
+szone_print(szone_t *szone, boolean_t verbose)
+{
+ unsigned info[13];
+ unsigned index = 0;
+ tiny_region_t *region;
+
SZONE_LOCK(szone);
scalable_zone_info((void *)szone, info, 13);
- malloc_printf("Scalable zone %p: inUse=%d(%y) touched=%y allocated=%y flags=%d\n", szone, info[0], info[1], info[2], info[3], info[12]);
- malloc_printf("\ttiny=%d(%y) small=%d(%y) large=%d(%y) huge=%d(%y)\n", info[4], info[5], info[6], info[7], info[8], info[9], info[10], info[11]);
+ malloc_printf("Scalable zone %p: inUse=%d(%y) touched=%y allocated=%y flags=%d\n",
+ szone, info[0], info[1], info[2], info[3], info[12]);
+ malloc_printf("\ttiny=%d(%y) small=%d(%y) large=%d(%y) huge=%d(%y)\n",
+ info[4], info[5], info[6], info[7], info[8], info[9], info[10], info[11]);
// tiny
malloc_printf("%d tiny regions: \n", szone->num_tiny_regions);
while (index < szone->num_tiny_regions) {
- tiny_region_t *region = szone->tiny_regions + index;
+ region = szone->tiny_regions + index;
print_tiny_region(verbose, *region, (index == szone->num_tiny_regions - 1) ? szone->tiny_bytes_free_at_end : 0);
index++;
}
malloc_printf("%d small regions: \n", szone->num_small_regions);
index = 0;
while (index < szone->num_small_regions) {
- small_region_t *region = szone->small_regions + index;
+ region = szone->small_regions + index;
print_small_region(szone, verbose, region, (index == szone->num_small_regions - 1) ? szone->small_bytes_free_at_end : 0);
index++;
}
- if (verbose) print_small_free_list(szone);
+ if (verbose)
+ print_small_free_list(szone);
SZONE_UNLOCK(szone);
}
static void
-szone_log(malloc_zone_t *zone, void *log_address) {
- szone_t *szone = (void *)zone;
+szone_log(malloc_zone_t *zone, void *log_address)
+{
+ szone_t *szone = (szone_t *)zone;
+
szone->log_address = log_address;
}
static void
-szone_force_lock(szone_t *szone) {
-// malloc_printf("szone_force_lock\n");
+szone_force_lock(szone_t *szone)
+{
SZONE_LOCK(szone);
}
static void
-szone_force_unlock(szone_t *szone) {
-// malloc_printf("szone_force_unlock\n");
+szone_force_unlock(szone_t *szone)
+{
SZONE_UNLOCK(szone);
}
boolean_t
-scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone) {
- szone_t *szone = (void *)zone;
+scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone)
+{
+ szone_t *szone = (szone_t *)zone;
+
switch (subzone) {
case 0:
stats->blocks_in_use = szone->num_tiny_objects;
}
static void
-szone_statistics(szone_t *szone, malloc_statistics_t *stats) {
- stats->blocks_in_use = szone->num_tiny_objects + szone->num_small_objects + szone->num_large_objects_in_use + szone->num_huge_entries;
- size_t big_and_huge = szone->num_bytes_in_large_objects + szone->num_bytes_in_huge_objects;
+szone_statistics(szone_t *szone, malloc_statistics_t *stats)
+{
+ size_t big_and_huge;
+
+ stats->blocks_in_use =
+ szone->num_tiny_objects +
+ szone->num_small_objects +
+ szone->num_large_objects_in_use +
+ szone->num_huge_entries;
+ big_and_huge = szone->num_bytes_in_large_objects + szone->num_bytes_in_huge_objects;
stats->size_in_use = szone->num_bytes_in_tiny_objects + szone->num_bytes_in_small_objects + big_and_huge;
- stats->max_size_in_use = stats->size_allocated = szone->num_tiny_regions * TINY_REGION_SIZE + szone->num_small_regions * SMALL_REGION_SIZE + big_and_huge ;
+ stats->max_size_in_use = stats->size_allocated =
+ szone->num_tiny_regions * TINY_REGION_SIZE +
+ szone->num_small_regions * SMALL_REGION_SIZE +
+ big_and_huge ;
+
// Now we account for the untouched areas
stats->max_size_in_use -= szone->tiny_bytes_free_at_end;
stats->max_size_in_use -= szone->small_bytes_free_at_end;
}; // marked as const to spare the DATA section
malloc_zone_t *
-create_scalable_zone(size_t initial_size, unsigned debug_flags) {
+create_scalable_zone(size_t initial_size, unsigned debug_flags)
+{
szone_t *szone;
- vm_address_t addr;
size_t msize;
- size_t msize_used = 0;
- // malloc_printf("=== create_scalable_zone(%d,%d) - %s\n", initial_size, debug_flags, (DEBUG_MALLOC) ? "**** DEBUG" : "");
-#if PAGE_SIZE_FIXED
- if ((1 << vm_page_shift) == vm_page_size) {
- // malloc_printf("vm_page_shift validated to be %d\n", vm_page_shift);
- } else {
- malloc_printf("*** vm_page_shift incorrectly set to %d\n", vm_page_shift);
+ size_t msize_used;
+ msize_t free_msize;
+
+ /*
+ * Sanity-check our build-time assumptions about the size of a page.
+ * Since we have sized various things assuming the default page size,
+ * attempting to determine it dynamically is not useful.
+ */
+ if ((vm_page_size != _vm_page_size) || (vm_page_shift != _vm_page_shift)) {
+ malloc_printf("*** FATAL ERROR - machine page size does not match our assumptions.\n");
exit(-1);
}
-#else
- if (!vm_page_shift) {
- unsigned page;
- vm_page_shift = 12; // the minimal for page sizes
- page = 1 << vm_page_shift;
- while (page != vm_page_size) { page += page; vm_page_shift++;};
- }
-#endif
- addr = allocate_pages(NULL, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC));
- if (!addr) return NULL;
- szone = (void *)addr;
- msize = (sizeof(szone_t) + SMALL_QUANTUM - 1) >> SHIFT_SMALL_QUANTUM;
- // malloc_printf("sizeof(szone_t)=%d msize for 1st block=%d; wasted %d bytes\n", sizeof(szone_t), msize, (msize << SHIFT_SMALL_QUANTUM) - sizeof(szone_t));
- small_meta_header(szone)[0] = msize;
+
+ /* get memory for the zone */
+ szone = allocate_pages(NULL, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, 0, VM_MAKE_TAG(VM_MEMORY_MALLOC));
+ if (!szone)
+ return NULL;
+ /* set up the szone structure */
szone->tiny_regions = szone->initial_tiny_regions;
szone->small_regions = szone->initial_small_regions;
- msize_used += msize; szone->num_small_objects++;
+ msize_used = msize; szone->num_small_objects++;
szone->basic_zone.version = 3;
szone->basic_zone.size = (void *)szone_size;
szone->basic_zone.malloc = (void *)szone_malloc;
szone->basic_zone.batch_malloc = (void *)szone_batch_malloc;
szone->basic_zone.batch_free = (void *)szone_batch_free;
szone->basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect;
+ szone->debug_flags = debug_flags;
+
+ /* as the szone is allocated out of the first tiny, region, reflect that allocation */
+ szone->small_regions[0] = szone;
+ szone->num_small_regions = 1;
+ msize = SMALL_MSIZE_FOR_BYTES(sizeof(szone_t) + SMALL_QUANTUM - 1);
+ free_msize = NUM_SMALL_BLOCKS - msize;
+ *SMALL_METADATA_FOR_PTR(szone) = msize;
+ *(SMALL_METADATA_FOR_PTR(szone) + msize) = free_msize;
+ szone->small_bytes_free_at_end = SMALL_BYTES_FOR_MSIZE(free_msize);
+
LOCK_INIT(szone->lock);
#if 0
#warning CHECK_REGIONS enabled
#warning LOG enabled
szone->log_address = ~0;
#endif
- szone->debug_flags = debug_flags;
- szone->small_regions[0] = addr >> SMALL_BLOCKS_ALIGN;
- szone->num_small_regions = 1;
- msize_t free_msize = NUM_SMALL_BLOCKS - msize;
- small_meta_header(szone)[msize] = free_msize;
- szone->small_bytes_free_at_end = free_msize << SHIFT_SMALL_QUANTUM;
CHECK(szone, __PRETTY_FUNCTION__);
-#if 0
- write(1, "Malloc szone created\n", 23);
-#endif
return (malloc_zone_t *)szone;
}
* malloc does not store flags in front of large page-aligned allocations.
* 3) Original szone-based freezedrying code.
* 4) Fresher malloc with tiny zone
+ * 5) 32/64bit compatible malloc
*
* No version backward compatibility is provided, but the version number does
* make it possible for malloc_jumpstart() to return an error if the application
* was freezedried with an older version of malloc.
*/
-#define MALLOC_FREEZEDRY_VERSION 4
+#define MALLOC_FREEZEDRY_VERSION 5
typedef struct {
unsigned version;
} malloc_frozen;
static void *
-frozen_malloc(szone_t *zone, size_t new_size) {
+frozen_malloc(szone_t *zone, size_t new_size)
+{
return malloc(new_size);
}
static void *
-frozen_calloc(szone_t *zone, size_t num_items, size_t size) {
+frozen_calloc(szone_t *zone, size_t num_items, size_t size)
+{
return calloc(num_items, size);
}
static void *
-frozen_valloc(szone_t *zone, size_t new_size) {
+frozen_valloc(szone_t *zone, size_t new_size)
+{
return valloc(new_size);
}
static void *
-frozen_realloc(szone_t *zone, void *ptr, size_t new_size) {
+frozen_realloc(szone_t *zone, void *ptr, size_t new_size)
+{
size_t old_size = szone_size(zone, ptr);
void *new_ptr;
+
if (new_size <= old_size) {
return ptr;
}
}
static void
-frozen_free(szone_t *zone, void *ptr) {
+frozen_free(szone_t *zone, void *ptr)
+{
}
static void
-frozen_destroy(szone_t *zone) {
+frozen_destroy(szone_t *zone)
+{
}
/********* Pseudo-private API for emacs unexec ************/
* returns 0 (error) if any non-szone zones are encountered.
*/
-int
-malloc_freezedry(void) {
+uintptr_t
+malloc_freezedry(void)
+{
extern unsigned malloc_num_zones;
extern malloc_zone_t **malloc_zones;
malloc_frozen *data;
data->nszones = malloc_num_zones;
data->szones = (szone_t *) calloc(malloc_num_zones, sizeof(szone_t));
- /* Fill in the array of szone structures. They are copied rather than
+ /*
+ * Fill in the array of szone structures. They are copied rather than
* referenced, since the originals are likely to be clobbered during malloc
- * initialization. */
+ * initialization.
+ */
for (i = 0; i < malloc_num_zones; i++) {
if (strcmp(malloc_zones[i]->zone_name, "DefaultMallocZone")) {
/* Unknown zone type. */
memcpy(&data->szones[i], malloc_zones[i], sizeof(szone_t));
}
- return (int) data;
+ return((uintptr_t)data);
}
int
-malloc_jumpstart(int cookie) {
- malloc_frozen *data = (malloc_frozen *) cookie;
+malloc_jumpstart(uintptr_t cookie)
+{
+ malloc_frozen *data = (malloc_frozen *)cookie;
unsigned i;
if (data->version != MALLOC_FREEZEDRY_VERSION) {
return 0;
}
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
void *address;
if (vm_allocate(mach_task_self(), (vm_address_t *)&address, bytes,
VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)| TRUE)) {
- malloc_printf("malloc[%d]: Out of memory while stack logging\n", getpid());
+ malloc_printf("*** out of memory while stack logging\n");
abort();
}
return (void *)address;
/*************** Recording stack ***********/
static void *first_frame_address(void) {
-#if 0
+#if defined(__i386__)
return __builtin_frame_address(1);
-#elif defined(__ppc__)
+#elif defined(__ppc__) || defined(__ppc64__)
void *addr;
#warning __builtin_frame_address IS BROKEN IN BEAKER: RADAR #2340421
__asm__ volatile("mr %0, r1" : "=r" (addr));
void *ret;
#if defined(__MACH__) && defined(__i386__)
__asm__ volatile("movl (%1),%0" : "=r" (ret) : "r" (addr));
-#elif defined(__MACH__) && defined(__ppc__)
+#elif defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))
__asm__ volatile("lwz %0,0x0(%1)" : "=r" (ret) : "b" (addr));
#elif defined(__hpux__)
__asm__ volatile("ldw 0x0(%1),%0" : "=r" (ret) : "r" (addr));
#if defined(__i386__) || defined (__m68k__)
#define FP_LINK_OFFSET 1
-#elif defined(__ppc__)
+#elif defined(__ppc__) || defined(__ppc64__)
#define FP_LINK_OFFSET 2
#elif defined(__hppa__)
#define FP_LINK_OFFSET -5
buffer[*nb] = *((vm_address_t *)fp_link);
(*nb)++;
addr2 = next_frame_address(addr);
-#if defined(__ppc__)
+#if defined(__ppc__) || defined(__ppc64__)
if ((unsigned)addr2 <= (unsigned)addr) break; // catch bozo frames
#endif
addr = addr2;
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* @APPLE_LICENSE_HEADER_END@
*/
-#import <malloc.h>
+#import <malloc/malloc.h>
#define stack_logging_type_free 0
#define stack_logging_type_generic 1 /* anything that is not allocation/deallocation */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
+++ /dev/null
-.\" Copyright (c) 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)sysconf.3 8.3 (Berkeley) 4/19/94
-.\" $FreeBSD: src/lib/libc/gen/sysconf.3,v 1.16 2001/10/01 16:08:51 ru Exp $
-.\"
-.Dd June 18, 2001
-.Dt SYSCONF 3
-.Os
-.Sh NAME
-.Nm sysconf
-.Nd get configurable system variables
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In unistd.h
-.Ft long
-.Fn sysconf "int name"
-.Sh DESCRIPTION
-This interface is defined by
-.St -p1003.1-88 .
-A far more complete interface is available using
-.Xr sysctl 3 .
-.Pp
-The
-.Fn sysconf
-function provides a method for applications to determine the current
-value of a configurable system limit or option variable.
-The
-.Fa name
-argument specifies the system variable to be queried.
-Symbolic constants for each name value are found in the include file
-.Aq Pa unistd.h .
-Shell programmers who need access to these parameters should use the
-.Xr getconf 1
-utility.
-.Pp
-The available values are as follows:
-.Pp
-.Bl -tag -width 6n
-.Pp
-.It Li _SC_ARG_MAX
-The maximum bytes of argument to
-.Xr execve 2 .
-.It Li _SC_CHILD_MAX
-The maximum number of simultaneous processes per user id.
-.It Li _SC_CLK_TCK
-The frequency of the statistics clock in ticks per second.
-.It Li _SC_IOV_MAX
-The maximum number of elements in the I/O vector used by
-.Xr readv 2 ,
-.Xr writev 2 ,
-.Xr recvmsg 2 ,
-and
-.Xr sendmsg 2 .
-.It Li _SC_NGROUPS_MAX
-The maximum number of supplemental groups.
-.It Li _SC_OPEN_MAX
-The maximum number of open files per user id.
-.It Li _SC_PAGESIZE
-The memory page size of the system expressed in bytes.
-This is the fundamental unit of memory management of the operating system.
-.It Li _SC_STREAM_MAX
-The minimum maximum number of streams that a process may have open
-at any one time.
-.It Li _SC_TZNAME_MAX
-The minimum maximum number of types supported for the name of a
-timezone.
-.It Li _SC_JOB_CONTROL
-Return 1 if job control is available on this system, otherwise \-1.
-.It Li _SC_SAVED_IDS
-Returns 1 if saved set-group and saved set-user ID is available,
-otherwise \-1.
-.It Li _SC_VERSION
-The version of
-.St -p1003.1
-with which the system
-attempts to comply.
-.It Li _SC_BC_BASE_MAX
-The maximum ibase/obase values in the
-.Xr bc 1
-utility.
-.It Li _SC_BC_DIM_MAX
-The maximum array size in the
-.Xr bc 1
-utility.
-.It Li _SC_BC_SCALE_MAX
-The maximum scale value in the
-.Xr bc 1
-utility.
-.It Li _SC_BC_STRING_MAX
-The maximum string length in the
-.Xr bc 1
-utility.
-.It Li _SC_COLL_WEIGHTS_MAX
-The maximum number of weights that can be assigned to any entry of
-the LC_COLLATE order keyword in the locale definition file.
-.It Li _SC_EXPR_NEST_MAX
-The maximum number of expressions that can be nested within
-parenthesis by the
-.Xr expr 1
-utility.
-.It Li _SC_LINE_MAX
-The maximum length in bytes of a text-processing utility's input
-line.
-.It Li _SC_RE_DUP_MAX
-The maximum number of repeated occurrences of a regular expression
-permitted when using interval notation.
-.It Li _SC_2_VERSION
-The version of
-.St -p1003.2
-with which the system attempts to comply.
-.It Li _SC_2_C_BIND
-Return 1 if the system's C-language development facilities support the
-C-Language Bindings Option, otherwise \-1.
-.It Li _SC_2_C_DEV
-Return 1 if the system supports the C-Language Development Utilities Option,
-otherwise \-1.
-.It Li _SC_2_CHAR_TERM
-Return 1 if the system supports at least one terminal type capable of
-all operations described in
-.St -p1003.2 ,
-otherwise \-1.
-.It Li _SC_2_FORT_DEV
-Return 1 if the system supports the FORTRAN Development Utilities Option,
-otherwise \-1.
-.It Li _SC_2_FORT_RUN
-Return 1 if the system supports the FORTRAN Runtime Utilities Option,
-otherwise \-1.
-.It Li _SC_2_LOCALEDEF
-Return 1 if the system supports the creation of locales, otherwise \-1.
-.It Li _SC_2_SW_DEV
-Return 1 if the system supports the Software Development Utilities Option,
-otherwise \-1.
-.It Li _SC_2_UPE
-Return 1 if the system supports the User Portability Utilities Option,
-otherwise \-1.
-.El
-.Sh RETURN VALUES
-If the call to
-.Fn sysconf
-is not successful, \-1 is returned and
-.Va errno
-is set appropriately.
-Otherwise, if the variable is associated with functionality that is not
-supported, \-1 is returned and
-.Va errno
-is not modified.
-Otherwise, the current variable value is returned.
-.Sh ERRORS
-The
-.Fn sysconf
-function may fail and set
-.Va errno
-for any of the errors specified for the library function
-.Xr sysctl 3 .
-In addition, the following error may be reported:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The value of the
-.Fa name
-argument is invalid.
-.El
-.Sh SEE ALSO
-.Xr getconf 1 ,
-.Xr pathconf 2 ,
-.Xr confstr 3 ,
-.Xr sysctl 3
-.Sh BUGS
-The value for _SC_STREAM_MAX is a minimum maximum, and required to be
-the same as ANSI C's FOPEN_MAX, so the returned value is a ridiculously
-small and misleading number.
-.Sh STANDARDS
-Except for the fact that values returned by
-.Fn sysconf
-may change over the lifetime of the calling process,
-this function conforms to
-.St -p1003.1-88 .
-.Sh HISTORY
-The
-.Fn sysconf
-function first appeared in
-.Bx 4.4 .
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Sean Eric Fagan of Cygnus Support.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#include <errno.h>
-#include <unistd.h>
-
-/*
- * sysconf --
- * get configurable system variables.
- *
- * XXX
- * POSIX 1003.1 (ISO/IEC 9945-1, 4.8.1.3) states that the variable values
- * not change during the lifetime of the calling process. This would seem
- * to require that any change to system limits kill all running processes.
- * A workaround might be to cache the values when they are first retrieved
- * and then simply return the cached value on subsequent calls. This is
- * less useful than returning up-to-date values, however.
- */
-long
-sysconf(name)
- int name;
-{
- struct rlimit rl;
- size_t len;
- int mib[2], value;
-
- len = sizeof(value);
-
- switch (name) {
-/* 1003.1 */
- case _SC_ARG_MAX:
- mib[0] = CTL_KERN;
- mib[1] = KERN_ARGMAX;
- break;
- case _SC_CHILD_MAX:
- return (getrlimit(RLIMIT_NPROC, &rl) ? -1 : rl.rlim_cur);
- case _SC_CLK_TCK:
- return (CLK_TCK);
- case _SC_JOB_CONTROL:
- mib[0] = CTL_KERN;
- mib[1] = KERN_JOB_CONTROL;
- goto yesno;
- case _SC_NGROUPS_MAX:
- mib[0] = CTL_KERN;
- mib[1] = KERN_NGROUPS;
- break;
- case _SC_OPEN_MAX:
- return (getrlimit(RLIMIT_NOFILE, &rl) ? -1 : rl.rlim_cur);
- case _SC_STREAM_MAX:
- mib[0] = CTL_USER;
- mib[1] = USER_STREAM_MAX;
- break;
- case _SC_TZNAME_MAX:
- mib[0] = CTL_USER;
- mib[1] = USER_TZNAME_MAX;
- break;
- case _SC_SAVED_IDS:
- mib[0] = CTL_KERN;
- mib[1] = KERN_SAVED_IDS;
- goto yesno;
- case _SC_VERSION:
- mib[0] = CTL_KERN;
- mib[1] = KERN_POSIX1;
- break;
-
-/* 1003.2 */
- case _SC_BC_BASE_MAX:
- mib[0] = CTL_USER;
- mib[1] = USER_BC_BASE_MAX;
- break;
- case _SC_BC_DIM_MAX:
- mib[0] = CTL_USER;
- mib[1] = USER_BC_DIM_MAX;
- break;
- case _SC_BC_SCALE_MAX:
- mib[0] = CTL_USER;
- mib[1] = USER_BC_SCALE_MAX;
- break;
- case _SC_BC_STRING_MAX:
- mib[0] = CTL_USER;
- mib[1] = USER_BC_STRING_MAX;
- break;
- case _SC_COLL_WEIGHTS_MAX:
- mib[0] = CTL_USER;
- mib[1] = USER_COLL_WEIGHTS_MAX;
- break;
- case _SC_EXPR_NEST_MAX:
- mib[0] = CTL_USER;
- mib[1] = USER_EXPR_NEST_MAX;
- break;
- case _SC_LINE_MAX:
- mib[0] = CTL_USER;
- mib[1] = USER_LINE_MAX;
- break;
- case _SC_PAGESIZE:
- mib[0] = CTL_HW;
- mib[1] = HW_PAGESIZE;
- break;
- case _SC_RE_DUP_MAX:
- mib[0] = CTL_USER;
- mib[1] = USER_RE_DUP_MAX;
- break;
- case _SC_2_VERSION:
- mib[0] = CTL_USER;
- mib[1] = USER_POSIX2_VERSION;
- break;
- case _SC_2_C_BIND:
- mib[0] = CTL_USER;
- mib[1] = USER_POSIX2_C_BIND;
- goto yesno;
- case _SC_2_C_DEV:
- mib[0] = CTL_USER;
- mib[1] = USER_POSIX2_C_DEV;
- goto yesno;
- case _SC_2_CHAR_TERM:
- mib[0] = CTL_USER;
- mib[1] = USER_POSIX2_CHAR_TERM;
- goto yesno;
- case _SC_2_FORT_DEV:
- mib[0] = CTL_USER;
- mib[1] = USER_POSIX2_FORT_DEV;
- goto yesno;
- case _SC_2_FORT_RUN:
- mib[0] = CTL_USER;
- mib[1] = USER_POSIX2_FORT_RUN;
- goto yesno;
- case _SC_2_LOCALEDEF:
- mib[0] = CTL_USER;
- mib[1] = USER_POSIX2_LOCALEDEF;
- goto yesno;
- case _SC_2_SW_DEV:
- mib[0] = CTL_USER;
- mib[1] = USER_POSIX2_SW_DEV;
- goto yesno;
- case _SC_2_UPE:
- mib[0] = CTL_USER;
- mib[1] = USER_POSIX2_UPE;
-yesno: if (sysctl(mib, 2, &value, &len, NULL, 0) == -1)
- return (-1);
- if (value == 0)
- return (-1);
- return (value);
- break;
- default:
- errno = EINVAL;
- return (-1);
- }
- return (sysctl(mib, 2, &value, &len, NULL, 0) == -1 ? -1 : value);
-}
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+.\"
+.\" Copyright (c) 2002 Tim J. Robbins
+.\" 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.
+.\"
+.\" $FreeBSD: src/lib/libc/gen/wordexp.3,v 1.6 2003/09/08 19:57:14 ru Exp $
+.\"
+.Dd December 27, 2002
+.Dt WORDEXP 3
+.Os
+.Sh NAME
+.Nm wordexp
+.Nd "perform shell-style word expansions"
+.Sh SYNOPSIS
+.In wordexp.h
+.Ft int
+.Fn wordexp "const char * restrict words" "wordexp_t * restrict we" "int flags"
+.Ft void
+.Fn wordfree "wordexp_t *we"
+.Sh DESCRIPTION
+The
+.Fn wordexp
+function performs shell-style word expansion on
+.Fa words
+and places the list of words into the
+.Va we_wordv
+member of
+.Fa we ,
+and the number of words into
+.Va we_wordc .
+.Pp
+The
+.Fa flags
+argument (see
+.Sx BUGS )
+is the bitwise inclusive OR of any of the following constants:
+.Bl -tag -width ".Dv WRDE_SHOWERR"
+.It Dv WRDE_APPEND
+Append the words to those generated by a previous call to
+.Fn wordexp .
+.It Dv WRDE_DOOFS
+As many
+.Dv NULL
+pointers as are specified by the
+.Va we_offs
+member of
+.Fa we
+are added to the front of
+.Va we_wordv .
+.It Dv WRDE_NOCMD
+Disallow command substitution in
+.Fa words .
+See the note in
+.Sx BUGS
+before using this.
+.It Dv WRDE_REUSE
+The
+.Fa we
+argument was passed to a previous successful call to
+.Fn wordexp
+but has not been passed to
+.Fn wordfree .
+The implementation may reuse the space allocated to it.
+.It Dv WRDE_SHOWERR
+Do not redirect shell error messages to
+.Pa /dev/null .
+.It Dv WRDE_UNDEF
+Report error on an attempt to expand an undefined shell variable.
+.El
+.Pp
+The
+.Vt wordexp_t
+structure is defined in
+.In wordexp.h
+as:
+.Bd -literal -offset indent
+typedef struct {
+ size_t we_wordc; /* count of words matched */
+ char **we_wordv; /* pointer to list of words */
+ size_t we_offs; /* slots to reserve in we_wordv */
+} wordexp_t;
+.Ed
+.Pp
+The
+.Fn wordfree
+function frees the memory allocated by
+.Fn wordexp .
+.Sh RETURN VALUES
+The
+.Fn wordexp
+function returns zero if successful, otherwise it returns one of the following
+error codes:
+.Bl -tag -width ".Dv WRDE_NOSPACE"
+.It Dv WRDE_BADCHAR
+The
+.Fa words
+argument contains one of the following unquoted characters:
+.Aq newline ,
+.Ql | ,
+.Ql & ,
+.Ql \&; ,
+.Ql < ,
+.Ql > ,
+.Ql \&( ,
+.Ql \&) ,
+.Ql { ,
+.Ql } .
+.It Dv WRDE_BADVAL
+An attempt was made to expand an undefined shell variable and
+.Dv WRDE_UNDEF
+is set in
+.Fa flags .
+.It Dv WRDE_CMDSUB
+An attempt was made to use command substitution and
+.Dv WRDE_NOCMD
+is set in
+.Fa flags .
+.It Dv WRDE_NOSPACE
+Not enough memory to store the result.
+.It Dv WRDE_SYNTAX
+Shell syntax error in
+.Fa words .
+.El
+.Pp
+The
+.Fn wordfree
+function returns no value.
+.Sh EXAMPLES
+Invoke the editor on all
+.Pa .c
+files in the current directory
+and
+.Pa /etc/motd
+(error checking omitted):
+.Bd -literal -offset indent
+wordexp_t we;
+
+wordexp("${EDITOR:-vi} *.c /etc/motd", &we, 0);
+execvp(we->we_wordv[0], we->we_wordv);
+.Ed
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr fnmatch 3 ,
+.Xr glob 3 ,
+.Xr popen 3 ,
+.Xr system 3
+.Sh BUGS
+This version of
+.Fn workexp
+ignores the value of the
+.Fa flags
+argument.
+.Sh COPYRIGHT
+Copyright 1995-2002 University Corporation for Atmospheric Research/Unidata
+.Pp
+Portions of this software were developed by the Unidata Program at the
+University Corporation for Atmospheric Research.
--- /dev/null
+/*
+ * Copyright 1994, University Corporation for Atmospheric Research
+ * See ../COPYRIGHT file for copying and redistribution conditions.
+ */
+/*
+ * Reproduction of ../COPYRIGHT file:
+ *
+ *********************************************************************
+
+Copyright 1995-2002 University Corporation for Atmospheric Research/Unidata
+
+Portions of this software were developed by the Unidata Program at the
+University Corporation for Atmospheric Research.
+
+Access and use of this software shall impose the following obligations
+and understandings on the user. The user is granted the right, without
+any fee or cost, to use, copy, modify, alter, enhance and distribute
+this software, and any derivative works thereof, and its supporting
+documentation for any purpose whatsoever, provided that this entire
+notice appears in all copies of the software, derivative works and
+supporting documentation. Further, UCAR requests that the user credit
+UCAR/Unidata in any publications that result from the use of this
+software or in any product that includes this software. The names UCAR
+and/or Unidata, however, may not be used in any advertising or publicity
+to endorse or promote any products or commercial entity unless specific
+written permission is obtained from UCAR/Unidata. The user also
+understands that UCAR/Unidata is not obligated to provide the user with
+any support, consulting, training or assistance of any kind with regard
+to the use, operation and performance of this software nor to provide
+the user with any updates, revisions, new versions or "bug fixes."
+
+THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "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 UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ *********************************************************************
+ */
+
+/* $Id: wordexp.c,v 1.13 2002/12/26 16:46:46 steve Exp $ */
+
+#if 0
+#include "ldmconfig.h"
+#endif
+
+/*
+ * Hack to provide POSIX 1003.2-1992 _interface_.
+ * NOT fully functional
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "wordexp.h"
+
+
+
+/*
+ * Translate return value from wordexp() into a string
+ */
+const char *
+s_wrde_err(int wrde_err)
+{
+ switch(wrde_err) {
+ case 0: return "No Error";
+ case WRDE_BADCHAR: return "WRDE_BADCHAR";
+ case WRDE_BADVAL: return "WRDE_BADVAL";
+ case WRDE_CMDSUB: return "WRDE_CMDSUB";
+ case WRDE_NOSPACE: return "WRDE_NOSPACE";
+ case WRDE_SYNTAX: return "WRDE_SYNTAX";
+ }
+ /* default */
+ return "Unknown Error";
+}
+
+
+/*ARGSUSED*/
+int
+wordexp(const char *words, wordexp_t *pwordexp, int flags)
+{
+ const char *ccp;
+ char **argv;
+ const char *buf;
+ size_t argc;
+ enum states {ARGSTART, IN_QUOTE, NOT_IN_QUOTE, DONE};
+ enum classes {EOS, SPACE, QUOTE, OTHER};
+ int state = ARGSTART;
+ char *argbuf;
+ const char *sp;
+ char *dp;
+ int status = 0;
+
+ /* devour leading white space */
+ for(ccp = words; *ccp != 0 && isspace(*ccp); )
+ ccp++;
+ /* skip comments */
+ if(*ccp == '#')
+ {
+ pwordexp->we_wordc = 0;
+ pwordexp->we_wordv = NULL;
+ return 0;
+ }
+
+/* If every other character was a space ... */
+#define MAXNARGS(str) ((strlen(str) +1)/2 +1)
+ argv = (char **)calloc(MAXNARGS(ccp), sizeof(char *));
+ if(argv == NULL)
+ return WRDE_NOSPACE;
+
+ buf = ccp;
+
+ argbuf = malloc(strlen(words)+1); /* where each arg is built */
+ if (argbuf == NULL)
+ {
+ free(argv);
+ return WRDE_NOSPACE;
+ }
+
+ sp = buf;
+ dp = argbuf;
+ argc = 0;
+ while(state != DONE)
+ {
+ int class;
+
+ if (*sp == 0)
+ class = EOS;
+ else if (isspace(*sp))
+ class = SPACE;
+ else if (*sp == '"')
+ class = QUOTE;
+ else
+ class = OTHER;
+ switch (state) {
+ case ARGSTART:
+ switch(class) {
+ case EOS:
+ state = DONE;
+ break;
+ case SPACE:
+ sp++;
+ break;
+ case QUOTE:
+ sp++;
+ state = IN_QUOTE;
+ break;
+ case OTHER:
+ *dp++ = *sp++;
+ state = NOT_IN_QUOTE;
+ break;
+ }
+ break;
+ case IN_QUOTE:
+ switch(class) {
+ case EOS: /* unmatched quote */
+ state = DONE;
+ status = WRDE_SYNTAX;
+ break;
+ case QUOTE:
+ sp++;
+ state = NOT_IN_QUOTE;
+ break;
+ case SPACE:
+ case OTHER:
+ *dp++ = *sp++;
+ break;
+ }
+ break;
+ case NOT_IN_QUOTE:
+ switch(class) {
+ case EOS:
+ *dp = 0;
+ dp = argbuf;
+ argv[argc++] = strdup(argbuf);
+ state = DONE;
+ break;
+ case SPACE:
+ *dp = 0;
+ dp = argbuf;
+ argv[argc++] = strdup(argbuf);
+ sp++;
+ state = ARGSTART;
+ break;
+ case QUOTE:
+ sp++;
+ state = IN_QUOTE;
+ break;
+ case OTHER:
+ *dp++ = *sp++;
+ break;
+ }
+ break;
+ }
+ }
+ argv[argc] = NULL;
+
+ pwordexp->we_wordc = argc;
+ pwordexp->we_wordv = argv;
+
+ free(argbuf);
+
+ return status;
+}
+
+
+void
+wordfree(wordexp_t *pwordexp)
+{
+ if(pwordexp == NULL || pwordexp->we_wordv == NULL)
+ return;
+ if(*pwordexp->we_wordv)
+ free(*pwordexp->we_wordv);
+ free(pwordexp->we_wordv);
+}
+
+
+#if TEST
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main(int argc, char *argv[])
+{
+ char strbuf[1024];
+ wordexp_t wrdexp;
+ int status;
+ char **cpp;
+
+ while(fgets(strbuf, sizeof(strbuf), stdin) != NULL)
+ {
+ {
+ char *cp = strrchr(strbuf,'\n');
+ if(cp)
+ *cp = 0;
+ }
+ fprintf(stdout, "\t%s\n", strbuf);
+ status = wordexp(strbuf, &wrdexp, WRDE_SHOWERR);
+ if(status)
+ {
+ fprintf(stderr, "wordexp: %s\n", s_wrde_err(status));
+ continue;
+ }
+ /* else */
+ fprintf(stdout, "\t%d:\n", wrdexp.we_wordc);
+ for(cpp = wrdexp.we_wordv;
+ cpp < &wrdexp.we_wordv[wrdexp.we_wordc]; cpp++)
+ {
+ fprintf(stdout, "\t\t%s\n", *cpp);
+ }
+ wordfree(&wrdexp);
+
+ }
+ exit(EXIT_SUCCESS);
+}
+
+#endif /* TEST */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
NXZone *NXZoneFromPtr(void *ptr) {
NXZone *zone = malloc_zone_from_ptr(ptr);
if (!zone) {
- fprintf(stderr, "*** malloc[%d]: NXZoneFromPtr() did not find any zone for %p; returning default\n", getpid(), ptr);
+ malloc_printf("*** NXZoneFromPtr() did not find any zone for %p; returning default\n", ptr);
zone = NX_NOZONE;
}
return zone;
}
void NXAddRegion(void *start, size_t size, malloc_zone_t *zone) {
- fprintf(stderr, "*** malloc[%d]: OBSOLETE: NXAddRegion()\n", getpid());
+ malloc_printf("*** OBSOLETE: NXAddRegion()\n");
}
void NXRemoveRegion(void *start) {
- fprintf(stderr, "*** malloc[%d]: OBSOLETE: NXRemoveRegion()\n", getpid());
+ malloc_printf("*** OBSOLETE: NXRemoveRegion()\n");
}
void NXZonePtrInfo(void *ptr) {
void NXMergeZone(malloc_zone_t *z) {
static char warned = 0;
if (!warned) {
- fprintf(stderr, "*** malloc[%d]: NXMergeZone() now obsolete, does nothing\n", getpid());
+ malloc_printf("*** NXMergeZone() now obsolete, does nothing\n");
warned = 1;
}
}
boolean_t NXProtectZone(malloc_zone_t *zone, int protection) {
- fprintf(stderr, "*** malloc[%d]: NXProtectZone() is obsolete\n", getpid());
+ malloc_printf("*** NXProtectZone() is obsolete\n");
return 0;
}
// We can not remove this one as it is still used by IndexingKit
static char warned = 0;
if (!warned) {
- fprintf(stderr, "*** malloc[%d]: NXCreateChildZone() now obsolete, has been defined to create new zone\n", getpid());
+ malloc_printf("*** NXCreateChildZone() now obsolete, has been defined to create new zone\n");
warned = 1;
}
return NXCreateZone(startsize, granularity, canfree);
}
void _NXMallocDumpFrees(void) {
- fprintf(stderr, "*** malloc[%d]: OBSOLETE: _NXMallocDumpFrees()\n", getpid());
+ malloc_printf("*** OBSOLETE: _NXMallocDumpFrees()\n");
}
# gmon sources
.PATH: ${.CURDIR}/gmon
-SRCS+= gmon.c
+MISRCS+= gmon.c
#.if ${LIB} == "c"
#MAN+= moncontrol.3
gmon.po:
${CC} -O -pipe -arch ${MACHINE_ARCH} -Wmost -g -fno-common \
-no-cpp-precomp -force_cpusubtype_ALL -I${.CURDIR}/include \
- -I${.CURDIR}/include/objc -c ${.CURDIR}/gmon/gmon.c -o gmon.po
+ -I${.CURDIR}/include/objc \
+ ${PRIVINC} \
+ -c ${.CURDIR}/gmon/gmon.c -o gmon.po
#gmon.po: gmon.o
# cp gmon.o gmon.po
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
p->profrate = getprofhz();
o = highpc - lowpc;
if((monsize - sizeof(struct gmonhdr)) < o)
+/* POSSIBLE BUG, if "(float) (monsize - sizeof(struct gmonhdr))/ o)" is zero
+ * then m->scale will be set to zero and the add_profil() call will disable
+ * profiling */
m->scale = ((float) (monsize - sizeof(struct gmonhdr))/ o) *
SCALE_1_TO_1;
else
p->lpc = (unsigned long)m->lowpc;
p->hpc = (unsigned long)m->highpc;
p->ncnt = m->ssiz;
+ p->version = GMONVERSION;
+ p->profrate = getprofhz();
}
if(m->froms != NULL)
memset(m->froms, '\0', m->textsize / HASHFRACTION);
-SRCS+= bcopy.s \
- bzero.s \
- ecvt.c \
+.PATH: ${.CURDIR}/i386/gen
+MDSRCS+= ecvt.c \
icacheinval.s \
- isinf.c \
mcount.s \
- memcpy.s \
- memmove.s \
setjmperr.c
+++ /dev/null
-/*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Call the comm page routines
- */
-
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-
-#include <architecture/i386/asm_help.h>
-
- TEXT
- ALIGN
-
-#if defined(MEMCOPY)
-LEAF(_memcpy,0)
- movl $(_COMM_PAGE_MEMCPY), %eax
- jmpl %eax
-#elif defined(MEMMOVE)
-LEAF(_memmove,0)
- movl $(_COMM_PAGE_MEMMOVE), %eax
- jmpl %eax
-#else
-LEAF(_bcopy,0)
- movl $(_COMM_PAGE_BCOPY), %eax
- jmpl %eax
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Call the comm page routine
- */
-
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-
-#include <architecture/i386/asm_help.h>
-
- TEXT
- ALIGN
-
-LEAF(_bzero,0)
- movl $(_COMM_PAGE_BZERO), %eax
- jmpl %eax
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1987 NeXT, INC.
- */
-
-struct words {
-#if defined(__BIG_ENDIAN__)
- unsigned int hi;
- unsigned int lo;
-#else
- unsigned int lo;
- unsigned int hi;
-#endif
-};
-
-union double_words {
- double d;
- struct words w;
-};
-
-/*
- * isinf -- returns 1 if positive IEEE infinity, -1 if negative
- * IEEE infinity, 0 otherwise.
- */
-int
-isinf(d)
-double d;
-{
- union double_words dw;
- dw.d = d;
- if (dw.w.hi == 0x7ff00000)
- return(1);
- if (dw.w.hi == 0xfff00000)
- return(-1);
- return(0);
-}
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
- *
- * File: libc/i386/ansi/memcpy.c
- * Author: Bruce Martin, NeXT Computer, Inc.
- *
- * HISTORY
- * 24-Nov-92 Derek B Clegg (dclegg@next.com)
- * Created for m98k.
- */
-#define MEMCOPY
-#include "bcopy.s"
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
- *
- * File: libc/i386/ansi/memmove.c
- * Author: Bruce Martin, NeXT Computer, Inc.
- *
- * HISTORY
- * 24-Nov-92 Derek B Clegg (dclegg@next.com)
- * Created for m98k.
- */
-#define MEMMOVE
-#include "bcopy.s"
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-SRCS += mach_absolute_time.c
+.PATH: ${.CURDIR}/i386/mach
+MDSRCS += mach_absolute_time.c
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <stdint.h>
#include <mach/clock.h>
#include <mach/mach_time.h>
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
extern mach_port_t clock_port;
-inline static uint64_t
-fast_get_nano_from_abs(int scale)
-{
- uint64_t value;
- asm (
- "rdtsc \n\t"
- "movl %%edx,%%esi \n\t"
- "mull %%ecx \n\t"
- "movl %%edx,%%edi \n\t"
- "movl %%esi,%%eax \n\t"
- "mull %%ecx \n\t"
- "xorl %%ecx,%%ecx \n\t"
- "addl %%edi,%%eax \n\t"
- "adcl %%ecx,%%edx "
- : "=A"(value) : "c"(scale) : "%esi", "%edi");
- return value;
-}
+#define COMM_PAGE_VERSION \
+ (*((short *) _COMM_PAGE_VERSION))
+
+#define COMM_PAGE_NANOTIME() \
+ (((uint64_t (*)()) _COMM_PAGE_NANOTIME)())
uint64_t
mach_absolute_time(void) {
- static int scale = 0;
-
- if (__builtin_expect(scale == 0, 0)) {
- mach_timebase_info_data_t info;
- mach_timebase_info(&info);
- scale = info.numer;
- }
- if (__builtin_expect(scale == 1, 0)) {
+ if (__builtin_expect(COMM_PAGE_VERSION == 1, 0)) {
mach_timespec_t now;
(void)clock_get_time(clock_port, &now);
return (uint64_t)now.tv_sec * NSEC_PER_SEC + now.tv_nsec;
}
- return fast_get_nano_from_abs(scale);
+ return COMM_PAGE_NANOTIME();
}
#endif
+.PATH: ${.CURDIR}/i386/pthreads
MDSRCS += \
init_cpu_capabilities.c \
get_cpu_capabilities.s \
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#
#
#
-#MDSRCS += \
-# strcmp.s
-
-
-
+.PATH: ${.CURDIR}/i386/string
+MDSRCS += bcopy.s \
+ bzero.s \
+ memcpy.s \
+ memmove.s \
+ strcmp.s
--- /dev/null
+/*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Call the comm page routines
+ */
+
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+
+#include <architecture/i386/asm_help.h>
+
+ TEXT
+ ALIGN
+
+#if defined(MEMCOPY)
+LEAF(_memcpy,0)
+ movl $(_COMM_PAGE_MEMCPY), %eax
+ jmpl %eax
+#elif defined(MEMMOVE)
+LEAF(_memmove,0)
+ movl $(_COMM_PAGE_MEMMOVE), %eax
+ jmpl %eax
+#else
+LEAF(_bcopy,0)
+ movl $(_COMM_PAGE_BCOPY), %eax
+ jmpl %eax
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Call the comm page routine
+ */
+
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+
+#include <architecture/i386/asm_help.h>
+
+ TEXT
+ ALIGN
+
+LEAF(_bzero,0)
+ movl $(_COMM_PAGE_BZERO), %eax
+ jmpl %eax
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
+ *
+ * File: libc/i386/ansi/memcpy.c
+ * Author: Bruce Martin, NeXT Computer, Inc.
+ *
+ * HISTORY
+ * 24-Nov-92 Derek B Clegg (dclegg@next.com)
+ * Created for m98k.
+ */
+#define MEMCOPY
+#include "bcopy.s"
--- /dev/null
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
+ *
+ * File: libc/i386/ansi/memmove.c
+ * Author: Bruce Martin, NeXT Computer, Inc.
+ *
+ * HISTORY
+ * 24-Nov-92 Derek B Clegg (dclegg@next.com)
+ * Created for m98k.
+ */
+#define MEMMOVE
+#include "bcopy.s"
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-SRCS+= ATPgetreq.s \
+.PATH: ${.CURDIR}/i386/sys
+MDSRCS+= ATPgetreq.s \
ATPgetrsp.s \
ATPsndreq.s \
ATPsndrsp.s \
audit.s \
auditctl.s \
auditon.s \
+ auditsvc.s \
bind.s \
cerror.s \
chdir.s \
fchmod.s \
fchown.s \
fcntl.s \
+ fgetxattr.s \
fhopen.s \
+ flistxattr.s \
flock.s \
fork.s \
fpathconf.s \
+ fremovexattr.s \
fsctl.s \
+ fsetxattr.s \
fstat.s \
fstatfs.s \
fstatv.s \
getgroups.s \
getitimer.s \
getpeername.s \
+ getpgid.s \
getpgrp.s \
getpid.s \
getppid.s \
getpriority.s \
getrlimit.s \
getrusage.s \
- getpgid.s \
getsid.s \
getsockname.s \
getsockopt.s \
getuid.s \
+ getxattr.s \
ioctl.s \
issetugid.s \
kevent.s \
kqueue_from_portset_np.s \
kqueue_portset_np.s \
ktrace.s \
+ lchown.s \
link.s \
lio_listio.s \
listen.s \
+ listxattr.s \
load_shared_file.s \
lseek.s \
lstat.s \
open.s \
pathconf.s \
pipe.s \
- pread.s \
posix_madvise.s \
+ pread.s \
profil.s \
- pwrite.s \
- ptrace.s \
pthread_sigmask.s \
+ ptrace.s \
+ pwrite.s \
quota.s \
quotactl.s \
read.s \
reboot.s \
recvfrom.s \
recvmsg.s \
+ removexattr.s \
rename.s \
reset_shared_file.s \
revoke.s \
setsockopt.s \
settimeofday.s \
setuid.s \
+ setxattr.s \
shmat.s \
shmctl.s \
shmdt.s \
wait4.s \
write.s \
writev.s
+
+.for _src in fhopen.s getfh.s nfsclnt.s
+CFLAGS-${_src} += -DNFSCLIENT
+.endfor
+
+CFLAGS-nfssvc.s += -DNFSSERVER
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* Created.
*/
-#define KERNEL_PRIVATE 1
/*
* Headers
*/
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+UNIX_SYSCALL(auditsvc, 2)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+UNIX_SYSCALL(fgetxattr, 5)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+UNIX_SYSCALL(flistxattr, 4)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+UNIX_SYSCALL(fremovexattr, 3)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+UNIX_SYSCALL(fsetxattr, 5)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*/
#include "SYS.h"
-PSEUDO(getegid, getgid, 0)
- movl %edx, %eax
- ret // egid = getegid();
+UNIX_SYSCALL(getegid, 0)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*/
#include "SYS.h"
-PSEUDO(geteuid, getuid, 0)
- movl %edx, %eax
- ret // euid = geteuid();
+UNIX_SYSCALL(geteuid, 0)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*/
#include "SYS.h"
-PSEUDO(getppid, getpid, 0)
- movl %edx, %eax
- ret // ppid = getppid();
+UNIX_SYSCALL(getppid,0)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+UNIX_SYSCALL(getxattr, 5)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+UNIX_SYSCALL(lchown, 3)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+UNIX_SYSCALL(listxattr, 4)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+UNIX_SYSCALL(removexattr, 3)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+UNIX_SYSCALL(setxattr, 5)
+ ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*/
#include "SYS.h"
-UNIX_SYSCALL(utimes, 1)
+UNIX_SYSCALL(utimes, 2)
ret
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
.include "${.CURDIR}/include/arpa/Makefile.inc"
+.include "${.CURDIR}/include/libkern/Makefile.inc"
.include "${.CURDIR}/include/protocols/Makefile.inc"
.include "${.CURDIR}/include/malloc/Makefile.inc"
.include "${.CURDIR}/include/objc/Makefile.inc"
+.include "${.CURDIR}/include/sys/Makefile.inc"
-# waiting for 2852915 to be reviewed/approved
-# alloca.h
INC_INSTHDRS += NSSystemDirectories.h \
+ _types.h \
+ aio.h \
alloca.h \
ar.h \
asm.h \
bitstring.h \
c.h \
+ cpio.h \
crt_externs.h \
ctype.h \
db.h \
err.h \
errno.h \
fcntl.h \
+ fmtmsg.h \
fnmatch.h \
fsproperties.h \
fstab.h \
fts.h \
+ ftw.h \
getopt.h \
glob.h \
grp.h \
utmp.h \
vis.h \
wchar.h \
- wctype.h
+ wctype.h \
+ wordexp.h
+
+.PATH: ${.CURDIR}/include
+MAN3 += sysexits.3
INC_INSTHDRS := ${INC_INSTHDRS:S/^/${.CURDIR}\/include\//}
INSTHDRS += ${INC_INSTHDRS}
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 1999-2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef __TYPES_H_
+#define __TYPES_H_
+
+#include <sys/_types.h>
+#include <machine/ansi.h>
+
+/*
+ * XXX - This block will eventually be relocated into sys/_types.h (or
+ * into a header it calls. It is here temporarily to work can proceed
+ * on the Libc part
+ */
+#ifndef __OSX_NULL
+#ifdef __GNUG__
+#define __OSX_NULL __null
+#else /* ! __GNUG__ */
+#ifndef __cplusplus
+#define __OSX_NULL ((void *)0)
+#else /* __cplusplus */
+#define __OSX_NULL 0
+#endif /* ! __cplusplus */
+#endif /* __GNUG__ */
+
+// XXX - renaming from sys/_types.h
+typedef __mode_t __osx_mode_t;
+typedef __off_t __osx_off_t;
+typedef __size_t __osx_size_t;
+typedef __pid_t __osx_pid_t;
+typedef __gid_t __osx_gid_t;
+#endif /* XXX - ! __OSX_NULL */
+
+typedef _BSD_CT_RUNE_T_ __osx_ct_rune_t;
+typedef _BSD_MBSTATE_T_ __osx_mbstate_t;
+typedef int __osx_nl_item;
+#ifdef _BSD_PTRDIFF_T_
+typedef _BSD_PTRDIFF_T_ __osx_ptrdiff_t;
+#endif /* _BSD_PTRDIFF_T_ */
+typedef _BSD_RUNE_T_ __osx_rune_t;
+#ifdef __WCHAR_TYPE__
+typedef __WCHAR_TYPE__ __osx_wchar_t;
+#else /* ! __WCHAR_TYPE__ */
+typedef _BSD_WCHAR_T_ __osx_wchar_t;
+#endif /* __WCHAR_TYPE__ */
+typedef int __osx_wctrans_t;
+typedef unsigned long __osx_wctype_t;
+typedef _BSD_WINT_T_ __osx_wint_t;
+
+#ifdef __WCHAR_MAX__
+#define __OSX_WCHAR_MAX __WCHAR_MAX__
+#else /* ! __WCHAR_MAX__ */
+#define __OSX_WCHAR_MAX (sizeof(__osx_wchar_t) == 2 ? 0xffff : 0x7fffffff)
+#endif /* __WCHAR_MAX__ */
+
+#define __OSX_WCHAR_MIN (sizeof(__osx_wchar_t) == 2 ? 0 : 0x80000000)
+#define __OSX_WEOF ((__osx_wint_t)-1)
+
+#endif /* __TYPES_H_ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/* Copyright (c) 1983, 1989
* The Regents of the University of California. All rights reserved.
*
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*
* @OSF_COPYRIGHT@
*/
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * 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.
+ *
+ * $FreeBSD: src/include/cpio.h,v 1.1 2002/08/01 07:18:38 mike Exp $
+ */
+
+#ifndef _CPIO_H_
+#define _CPIO_H_
+
+#define C_ISSOCK 0140000 /* Socket. */
+#define C_ISLNK 0120000 /* Symbolic link. */
+#define C_ISCTG 0110000 /* Reserved. */
+#define C_ISREG 0100000 /* Regular file. */
+#define C_ISBLK 0060000 /* Block special. */
+#define C_ISDIR 0040000 /* Directory. */
+#define C_ISCHR 0020000 /* Character special. */
+#define C_ISFIFO 0010000 /* FIFO. */
+#define C_ISUID 0004000 /* Set user ID. */
+#define C_ISGID 0002000 /* Set group ID. */
+#define C_ISVTX 0001000 /* On directories, restricted deletion flag. */
+#define C_IRUSR 0000400 /* Read by owner. */
+#define C_IWUSR 0000200 /* Write by owner. */
+#define C_IXUSR 0000100 /* Execute by owner. */
+#define C_IRGRP 0000040 /* Read by group. */
+#define C_IWGRP 0000020 /* Write by group. */
+#define C_IXGRP 0000010 /* Execute by group. */
+#define C_IROTH 0000004 /* Read by others. */
+#define C_IWOTH 0000002 /* Write by others. */
+#define C_IXOTH 0000001 /* Execute by others. */
+
+#define MAGIC "070707"
+
+#endif /* _CPIO_H_ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
__BEGIN_DECLS
int isalnum(int);
int isalpha(int);
+int isblank(int);
int iscntrl(int);
int isdigit(int);
int isgraph(int);
int toupper(int);
#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+int _tolower(int);
+int _toupper(int);
int digittoint(int);
int isascii(int);
-int isblank(int);
int ishexnumber(int);
int isideogram(int);
int isnumber(int);
#define isalnum(c) __istype((c), (_CTYPE_A|_CTYPE_D))
#define isalpha(c) __istype((c), _CTYPE_A)
+#define isblank(c) __istype((c), _CTYPE_B)
#define iscntrl(c) __istype((c), _CTYPE_C)
#define isdigit(c) __isctype((c), _CTYPE_D) /* ANSI -- locale independent */
#define isgraph(c) __istype((c), _CTYPE_G)
#define toupper(c) __toupper(c)
#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+#define _tolower(c) __tolower(c)
+#define _toupper(c) __toupper(c)
#define digittoint(c) __maskrune((c), 0xFF)
-#define isascii(c) ((c & ~0x7F) == 0)
-#define isblank(c) __istype((c), _CTYPE_B)
+#define isascii(c) (((c) & ~0x7F) == 0)
#define ishexnumber(c) __istype((c), _CTYPE_X)
#define isideogram(c) __istype((c), _CTYPE_I)
#define isnumber(c) __istype((c), _CTYPE_D)
static __inline int
__maskrune(_BSD_CT_RUNE_T_ _c, unsigned long _f)
{
+#ifdef USE_ASCII
+ return _CurrentRuneLocale->runetype[_c && 0xff] & _f;
+#else /* USE_ASCII */
return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype(_c) :
_CurrentRuneLocale->runetype[_c]) & _f;
+#endif /* USE_ASCII */
}
static __inline int
static __inline _BSD_CT_RUNE_T_
__isctype(_BSD_CT_RUNE_T_ _c, unsigned long _f)
{
+#ifdef USE_ASCII
+ return !!(_DefaultRuneLocale.runetype[_c & 0xff] & _f);
+#else /* USE_ASCII */
return (_c < 0 || _c >= _CACHED_RUNES) ? 0 :
!!(_DefaultRuneLocale.runetype[_c] & _f);
+#endif /* USE_ASCII */
}
static __inline _BSD_CT_RUNE_T_
__toupper(_BSD_CT_RUNE_T_ _c)
{
+#ifdef USE_ASCII
+ return _CurrentRuneLocale->mapupper[_c & 0xff];
+#else /* USE_ASCII */
return (_c < 0 || _c >= _CACHED_RUNES) ? ___toupper(_c) :
_CurrentRuneLocale->mapupper[_c];
+#endif /* USE_ASCII */
}
static __inline _BSD_CT_RUNE_T_
__tolower(_BSD_CT_RUNE_T_ _c)
{
+#ifdef USE_ASCII
+ return _CurrentRuneLocale->maplower[_c & 0xff];
+#else /* USE_ASCII */
return (_c < 0 || _c >= _CACHED_RUNES) ? ___tolower(_c) :
_CurrentRuneLocale->maplower[_c];
+#endif /* USE_ASCII */
}
#else /* not using inlines */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* The kernel defines the format of directory entries returned by
* the getdirentries(2) system call.
*/
-#include <sys/types.h>
+#include <_types.h>
#include <sys/dirent.h>
#ifdef _POSIX_SOURCE
typedef void * DIR;
#else
-
-#define d_ino d_fileno /* backward compatibility */
+#include <sys/types.h>
/* definitions for library routines operating on directories. */
#define DIRBLKSIZ 1024
#define __DTF_READALL 0x0008 /* everything has been read */
#ifndef NULL
-#define NULL 0
-#endif
+#define NULL __OSX_NULL
+#endif /* ! NULL */
-#endif /* _POSIX_SOURCE */
+#endif /* ! _POSIX_SOURCE */
#ifndef KERNEL
#include <sys/cdefs.h>
__BEGIN_DECLS
+#ifndef _POSIX_SOURCE
+int alphasort(const void *, const void *);
+#endif /* not POSIX */
+int closedir(DIR *);
+#ifndef _POSIX_SOURCE
+int getdirentries(int, char *, int, long *);
+#endif /* not POSIX */
DIR *opendir(const char *);
+#ifndef _POSIX_SOURCE
+DIR *__opendir2(const char *, int);
+#endif /* not POSIX */
struct dirent *readdir(DIR *);
+int readdir_r(DIR *, struct dirent *, struct dirent **);
void rewinddir(DIR *);
-int closedir(DIR *);
#ifndef _POSIX_SOURCE
-DIR *__opendir2(const char *, int);
-long telldir(DIR *);
-void seekdir(DIR *, long);
int scandir(const char *, struct dirent ***,
int (*)(struct dirent *), int (*)(const void *, const void *));
-int alphasort(const void *, const void *);
-int getdirentries(int, char *, int, long *);
-int readdir_r(DIR *, struct dirent *, struct dirent **);
#endif /* not POSIX */
+void seekdir(DIR *, long);
+long telldir(DIR *);
__END_DECLS
#endif /* !KERNEL */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * 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.
+ *
+ * $FreeBSD: src/include/fmtmsg.h,v 1.2 2002/08/05 16:37:05 mike Exp $
+ */
+
+#ifndef _FMTMSG_H_
+#define _FMTMSG_H_
+
+/* Source of condition is... */
+#define MM_HARD 0x0001 /* ...hardware. */
+#define MM_SOFT 0x0002 /* ...software. */
+#define MM_FIRM 0x0004 /* ...fireware. */
+
+/* Condition detected by... */
+#define MM_APPL 0x0010 /* ...application. */
+#define MM_UTIL 0x0020 /* ...utility. */
+#define MM_OPSYS 0x0040 /* ...operating system. */
+
+/* Display on... */
+#define MM_PRINT 0x0100 /* ...standard error. */
+#define MM_CONSOLE 0x0200 /* ...system console. */
+
+#define MM_RECOVER 0x1000 /* Recoverable error. */
+#define MM_NRECOV 0x2000 /* Non-recoverable error. */
+
+/* Severity levels. */
+#define MM_NOSEV 0 /* No severity level provided. */
+#define MM_HALT 1 /* Error causing application to halt. */
+#define MM_ERROR 2 /* Non-fault fault. */
+#define MM_WARNING 3 /* Unusual non-error condition. */
+#define MM_INFO 4 /* Informative message. */
+
+/* Null options. */
+#define MM_NULLLBL (char *)0
+#define MM_NULLSEV 0
+#define MM_NULLMC 0L
+#define MM_NULLTXT (char *)0
+#define MM_NULLACT (char *)0
+#define MM_NULLTAG (char *)0
+
+/* Return values. */
+#define MM_OK 0 /* Success. */
+#define MM_NOMSG 1 /* Failed to output to stderr. */
+#define MM_NOCON 2 /* Failed to output to console. */
+#define MM_NOTOK 3 /* Failed to output anything. */
+
+int fmtmsg(long, const char *, int, const char *, const char *,
+ const char *);
+
+#endif /* !_FMTMSG_H_ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
#define FNM_PERIOD 0x04 /* Period must be matched by period. */
+#define FNM_NOSYS (-1) /* Reserved */
+
#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
#define FNM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */
#define FNM_CASEFOLD 0x10 /* Case insensitive search. */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/* $OpenBSD: ftw.h,v 1.1 2003/07/21 21:13:18 millert Exp $ */
+
+/*
+ * Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#ifndef _FTW_H
+#define _FTW_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/*
+ * Valid flags for the 3rd argument to the function that is passed as the
+ * second argument to ftw(3) and nftw(3). Say it three times fast!
+ */
+#define FTW_F 0 /* File. */
+#define FTW_D 1 /* Directory. */
+#define FTW_DNR 2 /* Directory without read permission. */
+#define FTW_DP 3 /* Directory with subdirectories visited. */
+#define FTW_NS 4 /* Unknown type; stat() failed. */
+#define FTW_SL 5 /* Symbolic link. */
+#define FTW_SLN 6 /* Sym link that names a nonexistent file. */
+
+/*
+ * Flags for use as the 4th argument to nftw(3). These may be ORed together.
+ */
+#define FTW_PHYS 0x01 /* Physical walk, don't follow sym links. */
+#define FTW_MOUNT 0x02 /* The walk does not cross a mount point. */
+#define FTW_DEPTH 0x04 /* Subdirs visited before the dir itself. */
+#define FTW_CHDIR 0x08 /* Change to a directory before reading it. */
+
+struct FTW {
+ int base;
+ int level;
+};
+
+__BEGIN_DECLS
+int ftw(const char *, int (*)(const char *, const struct stat *, int), int);
+int nftw(const char *, int (*)(const char *, const struct stat *, int,
+ struct FTW *), int, int);
+__END_DECLS
+
+#endif /* !_FTW_H */
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
-
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
-/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
* SUCH DAMAGE.
*
* @(#)glob.h 8.1 (Berkeley) 6/2/93
+ * $FreeBSD: /repoman/r/ncvs/src/include/glob.h,v 1.7 2002/07/17 04:58:09 mikeh Exp $
*/
#ifndef _GLOB_H_
#define _GLOB_H_
#include <sys/cdefs.h>
+#include <_types.h>
+
+#ifndef _BSD_SIZE_T_DEFINED_
+#define _BSD_SIZE_T_DEFINED_
+typedef __osx_size_t size_t;
+#endif
struct stat;
typedef struct {
- int gl_pathc; /* Count of total paths so far. */
+ size_t gl_pathc; /* Count of total paths so far. */
int gl_matchc; /* Count of paths matching pattern. */
- int gl_offs; /* Reserved at beginning of gl_pathv. */
+ size_t gl_offs; /* Reserved at beginning of gl_pathv. */
int gl_flags; /* Copy of flags parameter to glob. */
char **gl_pathv; /* List of paths matching pattern. */
/* Copy of errfunc parameter to glob. */
* and lstat(2).
*/
void (*gl_closedir)(void *);
- struct dirent *(*gl_readdir)(void *);
+ struct dirent *(*gl_readdir)(void *);
void *(*gl_opendir)(const char *);
int (*gl_lstat)(const char *, struct stat *);
int (*gl_stat)(const char *, struct stat *);
} glob_t;
+/* Believed to have been introduced in 1003.2-1992 */
#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
#define GLOB_ERR 0x0004 /* Return on error. */
#define GLOB_MARK 0x0008 /* Append / to matching directories. */
#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */
#define GLOB_NOSORT 0x0020 /* Don't sort. */
+#define GLOB_NOESCAPE 0x2000 /* Disable backslash escaping. */
+
+/* Error values returned by glob(3) */
+#define GLOB_NOSPACE (-1) /* Malloc call failed. */
+#define GLOB_ABORTED (-2) /* Unignored error. */
+#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK was not set. */
+#define GLOB_NOSYS (-4) /* Obsolete: source comptability only. */
#ifndef _POSIX_SOURCE
#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
-#endif
+#define GLOB_LIMIT 0x1000 /* limit number of returned paths */
-#define GLOB_NOSPACE (-1) /* Malloc call failed. */
-#define GLOB_ABEND (-2) /* Unignored error. */
+/* source compatibility, these are the old names */
+#define GLOB_MAXPATH GLOB_LIMIT
+#define GLOB_ABEND GLOB_ABORTED
+#endif /* ! _POSIX_SOURCE */
__BEGIN_DECLS
-int glob(const char *, int, int (*)(const char *, int), glob_t *);
+int glob(const char * __restrict, int,
+ int (* __restrict)(const char *, int), glob_t * __restrict);
void globfree(glob_t *);
__END_DECLS
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#ifndef _GRP_H_
#define _GRP_H_
+#include <sys/_types.h>
+
+#ifndef _GID_T_DECLARED
+typedef __gid_t gid_t; /* [XBD] */
+#define _GID_T_DECLARED
+#endif
+
+/*
+ * Although the definition of size_t is not mandated by [TSF], the function
+ * prototypes defined by [TSF] for the thread reentrant functions include
+ * it as a type for their 4th arguments, so we define it here.
+ */
+#ifndef _BSD_SIZE_T_DEFINED_
+#define _BSD_SIZE_T_DEFINED_
+typedef __size_t size_t; /* [???] */
+#endif
+
#ifndef _POSIX_SOURCE
#define _PATH_GROUP "/etc/group"
#endif
struct group {
- char *gr_name; /* group name */
- char *gr_passwd; /* group password */
- gid_t gr_gid; /* group id */
- char **gr_mem; /* group members */
+ char *gr_name; /* [XBD] group name */
+ char *gr_passwd; /* [???] group password */
+ gid_t gr_gid; /* [XBD] group id */
+ char **gr_mem; /* [XBD] group members */
};
#include <sys/cdefs.h>
__BEGIN_DECLS
+/* [XBD] */
struct group *getgrgid(gid_t);
struct group *getgrnam(const char *);
+/* [TSF] */
int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
int getgrnam_r(const char *, struct group *, char *, size_t, struct group **);
-#ifndef _POSIX_SOURCE
+/* [XSI] */
struct group *getgrent(void);
+int setgrent(void);
+void endgrent(void);
+
+#ifndef _POSIX_SOURCE
#ifndef _XOPEN_SOURCE
char *group_from_gid(gid_t, int);
#endif
-int setgrent(void);
-void endgrent(void);
void setgrfile(const char *);
int setgroupent(int);
#endif
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*-
* Copyright (c) 1998 Alex Nash
* All rights reserved.
#ifndef _ISO646_H_
#define _ISO646_H_
+#ifndef __cplusplus
#define and &&
#define and_eq &=
#define bitand &
#define or_eq |=
#define xor ^
#define xor_eq ^=
+#endif /* ! __cplusplus */
#endif /* !_ISO646_H_ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*-
* Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
#define _LANGINFO_H_
#include <sys/cdefs.h>
-#include <sys/types.h>
+#include <_types.h>
#ifndef _NL_ITEM_DECLARED
-typedef int nl_item;
+typedef __osx_nl_item nl_item;
#define _NL_ITEM_DECLARED
#endif
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <stdarg.h>
#endif
+#include <sys/param.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/resource.h>
-#include <sys/param.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/stat.h>
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/* $OpenBSD: libgen.h,v 1.4 1999/05/28 22:00:22 espie Exp $ */
/* $FreeBSD: src/include/libgen.h,v 1.1.2.1 2000/11/12 18:01:51 adrian Exp $ */
char *basename(const char *);
char *dirname(const char *);
-#if 0
-char *regcmp(const char *, ...);
-char *regex(const char *, const char *, ...);
-
-extern char *__loc1;
-#endif
__END_DECLS
--- /dev/null
+LIBKERN_INSTHDRS += OSAtomic.h
+
+LIBKERN_INSTHDRS := ${LIBKERN_INSTHDRS:S/^/${.CURDIR}\/include\/libkern\//}
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _OSATOMIC_H_
+#define _OSATOMIC_H_
+
+#include <stddef.h>
+#include <sys/cdefs.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+/* These are the preferred versions of the atomic and synchronization operations.
+ * Their implementation is customized at boot time for the platform, including
+ * late-breaking errata fixes as necessary. They are thread safe.
+ *
+ * WARNING: all addresses passed to these functions must be "naturally aligned", ie
+ * int32_t's must be 32-bit aligned (low 2 bits of address zero), and int64_t's
+ * must be 64-bit aligned (low 3 bits of address zero.)
+ */
+__BEGIN_DECLS
+
+/* Arithmetic functions. They do not incorporate memory barriers and thus cannot
+ * be used by themselves to synchronize shared memory. They return the new value.
+ * The "or", "and", and "xor" operations are layered on top of compare-and-swap.
+ */
+int32_t OSAtomicAdd32( int32_t theAmount, int32_t *theValue );
+inline static
+int32_t OSAtomicIncrement32( int32_t *theValue ) { return OSAtomicAdd32( 1, theValue); }
+inline static
+int32_t OSAtomicDecrement32( int32_t *theValue ) { return OSAtomicAdd32( -1, theValue); }
+int32_t OSAtomicOr32( uint32_t theMask, uint32_t *theValue );
+int32_t OSAtomicAnd32( uint32_t theMask, uint32_t *theValue );
+int32_t OSAtomicXor32( uint32_t theMask, uint32_t *theValue );
+#if defined(__ppc64__) || defined(__i386__)
+int64_t OSAtomicAdd64( int64_t theAmount, int64_t *theValue );
+inline static
+int64_t OSAtomicIncrement64( int64_t *theValue ) { return OSAtomicAdd64( 1, theValue); }
+inline static
+int64_t OSAtomicDecrement64( int64_t *theValue ) { return OSAtomicAdd64( -1, theValue); }
+#endif /* defined(__ppc64__) || defined(__i386__) */
+
+/* Compare and swap. They do not incorporate memory barriers and thus cannot be used
+ * by themselved to synchronize shared memory. They return true if the swap occured.
+ */
+bool OSAtomicCompareAndSwap32( int32_t oldValue, int32_t newValue, int32_t *theValue );
+#if defined(__ppc64__) || defined(__i386__)
+bool OSAtomicCompareAndSwap64( int64_t oldValue, int64_t newValue, int64_t *theValue );
+#endif /* defined(__ppc64__) || defined(__i386__) */
+
+/* Test and set. They do not incorporate memory barriers and thus cannot be used by
+ * themselves to synchronize shared memory. They return the original value of the bit.
+ * They operate on bit (0x80>>(n&7)) in byte ((char*)theAddress + (n>>3)). They are
+ * layered on top of the compare-and-swap operation.
+ */
+bool OSAtomicTestAndSet( uint32_t n, void *theAddress );
+bool OSAtomicTestAndClear( uint32_t n, void *theAddress );
+
+/* FILO queue and dequeue. These use memory barriers as required to synchronize access to
+ * the queued/dequeued structure. The "inOffset" field is the offset within the structure
+ * of the link field. "inList" is the list head; it is not a struct. The queue is a singly
+ * linked list with a zero terminator.
+ */
+void * OSAtomicDequeue( void ** inList, size_t inOffset);
+void OSAtomicEnqueue( void ** inList, void * inNewLink, size_t inOffset);
+
+/* Spinlocks. These use memory barriers as required to synchronize access to shared
+ * memory protected by the lock. The lock operation spins, but employs various strategies
+ * to back off if the lock is held, making it immune to most priority-inversion livelocks.
+ * The try operation immediately returns false if the lock was held, true if it took the
+ * lock. The convention is that unlocked is zero, locked is nonzero.
+ */
+#define OS_SPINLOCK_INIT 0
+
+typedef int32_t OSSpinLock;
+
+bool OSSpinLockTry( OSSpinLock *lock );
+void OSSpinLockLock( OSSpinLock *lock );
+void OSSpinLockUnlock( OSSpinLock *lock );
+
+/* Memory barrier. This strictly orders memory accesses in a weakly ordered model such
+ * as PPC. All loads and stores executed in sequential program order before the barrier
+ * will complete with respect to the coherence mechanism, before any load or store
+ * executed after the barrier. Used with an atomic operation, the barrier can be used to
+ * create custom synchronization protocols, as an alternative to the spinlock or queue/
+ * dequeue operations. Note that this barrier does not order uncached loads and stores.
+ * On a uniprocessor, the barrier is typically a nop.
+ */
+void OSMemoryBarrier( void );
+
+__END_DECLS
+
+#endif /* _OSATOMIC_H_ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
};
#ifndef NULL
-#define NULL 0
-#endif
+#ifdef __GNUG__
+#define NULL __null
+#else /* ! __GNUG__ */
+#ifndef __cplusplus
+#define NULL ((void *)0)
+#else /* __cplusplus */
+#define NULL 0
+#endif /* ! __cplusplus */
+#endif /* __GNUG__ */
+#endif /* ! NULL */
#define LC_ALL 0
#define LC_COLLATE 1
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
typedef struct _malloc_zone_t {
/* Only zone implementors should depend on the layout of this structure;
Regular callers should use the access functions below */
- unsigned version;
- void *reserved2;
+ void *reserved1; /* RESERVED FOR CFAllocator DO NOT USE */
+ void *reserved2; /* RESERVED FOR CFAllocator DO NOT USE */
size_t (*size)(struct _malloc_zone_t *zone, const void *ptr); /* returns the size of a block or 0 if not in this zone; must be fast, especially for negative answers */
void *(*malloc)(struct _malloc_zone_t *zone, size_t size);
void *(*calloc)(struct _malloc_zone_t *zone, size_t num_items, size_t size); /* same as malloc, but block returned is set to zero */
void (*batch_free)(struct _malloc_zone_t *zone, void **to_be_freed, unsigned num_to_be_freed); /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process */
struct malloc_introspection_t *introspect;
- void *reserved5;
+ unsigned version;
} malloc_zone_t;
/********* Creation and destruction ************/
If address==0 nothing is logged;
If address==-1 all activity is logged;
Else only the activity regarding address is logged */
+
+struct mstats {
+ size_t bytes_total;
+ size_t chunks_used;
+ size_t bytes_used;
+ size_t chunks_free;
+ size_t bytes_free;
+};
+
+extern struct mstats mstats(void);
+
__END_DECLS
#endif /* _MALLOC_MALLOC_H_ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*-
* Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
* All rights reserved.
#define _MONETARY_H_
#include <sys/cdefs.h>
-#include <sys/types.h>
+#include <_types.h>
+
+#ifndef _BSD_SIZE_T_DEFINED_
+#define _BSD_SIZE_T_DEFINED_
+typedef __osx_size_t size_t;
+#endif
+
+#ifndef _BSD_SSIZE_T_DEFINED_
+#define _BSD_SSIZE_T_DEFINED_
+typedef __osx_ssize_t ssize_t;
+#endif
__BEGIN_DECLS
ssize_t strfmon(char *, size_t, const char *, ...);
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#ifndef _NDBM_H_
#define _NDBM_H_
-#include <db.h>
+#include <sys/cdefs.h>
+#include <_types.h>
+
+#ifndef _MODE_T_DECLARED
+typedef __osx_mode_t mode_t;
+#define _MODE_T_DECLARED
+#endif
+#ifndef _BSD_SIZE_T_DEFINED_
+#define _BSD_SIZE_T_DEFINED_
+typedef __osx_size_t size_t;
+#endif
+
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
/* Map dbm interface onto db(3). */
+#include <fcntl.h>
#define DBM_RDONLY O_RDONLY
+#endif
/* Flags to dbm_store(). */
#define DBM_INSERT 0
#define DBM_REPLACE 1
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
/*
* The db(3) support for ndbm(3) always appends this suffix to the
* file name to avoid overwriting the user's original database.
*/
#define DBM_SUFFIX ".db"
+#endif
typedef struct {
- char *dptr;
- int dsize;
+ void *dptr;
+ size_t dsize;
} datum;
-typedef DB DBM;
+typedef struct __db DBM;
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
#define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE
+#endif
__BEGIN_DECLS
-void dbm_close(DBM *);
int dbm_clearerr( DBM *);
+void dbm_close(DBM *);
int dbm_delete(DBM *, datum);
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+int dbm_dirfno(DBM *);
+#endif
int dbm_error( DBM *);
datum dbm_fetch(DBM *, datum);
datum dbm_firstkey(DBM *);
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
long dbm_forder(DBM *, datum);
+#endif
datum dbm_nextkey(DBM *);
-DBM *dbm_open(const char *, int, int);
+DBM *dbm_open(const char *, int, mode_t);
int dbm_store(DBM *, datum, datum, int);
-int dbm_dirfno(DBM *);
__END_DECLS
#endif /* !_NDBM_H_ */
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/* $FreeBSD: src/include/nl_types.h,v 1.7 1999/08/27 23:44:51 peter Exp $ */
/***********************************************************
#ifndef _NL_TYPES_H_
#define _NL_TYPES_H_
#include <sys/cdefs.h>
+#include <_types.h>
#define NL_SETD 0
#define NL_CAT_LOCALE 1
-typedef int nl_item;
+#ifndef _NL_ITEM_DECLARED
+typedef __osx_nl_item nl_item;
+#define _NL_ITEM_DECLARED
+#endif
+
typedef void *nl_catd;
__BEGIN_DECLS
-extern nl_catd catopen(__const char *, int);
-extern char *catgets(nl_catd, int, int, __const char *);
+extern nl_catd catopen(const char *, int);
+extern char *catgets(nl_catd, int, int, const char *);
extern int catclose(nl_catd);
__END_DECLS
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#ifndef _PWD_H_
#define _PWD_H_
-#include <sys/types.h>
+#include <_types.h>
+
+#ifndef _GID_T_DECLARED
+typedef __osx_gid_t gid_t;
+#define _GID_T_DECLARED
+#endif
+
+#ifndef _BSD_SIZE_T_DEFINED_
+#define _BSD_SIZE_T_DEFINED_
+typedef __osx_size_t size_t;
+#endif
+
+#ifndef _BSD_TIME_T_DEFINED_
+#define _BSD_TIME_T_DEFINED_
+typedef __osx_time_t time_t;
+#endif
+
+#ifndef _UID_T_DECLARED
+typedef __osx_uid_t uid_t;
+#define _UID_T_DECLARED
+#endif
#ifndef _POSIX_SOURCE
+#define _PATH_PWD "/etc"
#define _PATH_PASSWD "/etc/passwd"
+#define _PASSWD "passwd"
#define _PATH_MASTERPASSWD "/etc/master.passwd"
#define _PATH_MASTERPASSWD_LOCK "/etc/ptmp"
+#define _MASTERPASSWD "master.passwd"
#define _PATH_MP_DB "/etc/pwd.db"
+#define _MP_DB "pwd.db"
#define _PATH_SMP_DB "/etc/spwd.db"
+#define _SMP_DB "spwd.db"
#define _PATH_PWD_MKDB "/usr/sbin/pwd_mkdb"
struct passwd *getpwnam(const char *);
int getpwuid_r(uid_t, struct passwd *, char *, size_t, struct passwd **);
int getpwnam_r(const char *, struct passwd *, char *, size_t, struct passwd **);
-#ifndef _POSIX_SOURCE
struct passwd *getpwent(void);
-#ifndef _XOPEN_SOURCE
+#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
int setpassent(int);
char *user_from_uid(uid_t, int);
#endif
int setpwent(void);
void endpwent(void);
-#endif
__END_DECLS
#endif /* !_PWD_H_ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/* $OpenBSD: /usr/local/www/cvsroot/OpenBSD/src/include/readpassphrase.h,v 1.2 2002/02/16 21:27:17 millert Exp $ */
/* $FreeBSD: /repoman/r/ncvs/src/include/readpassphrase.h,v 1.2 2002/03/08 20:52:52 green Exp $ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#define _REGEX_H_
#include <sys/cdefs.h>
+#include <sys/_types.h>
/* types */
-typedef off_t regoff_t;
+typedef __off_t regoff_t;
+
+#ifndef _BSD_SIZE_T_DEFINED_
+#define _BSD_SIZE_T_DEFINED_
+typedef __size_t size_t;
+#endif
typedef struct {
int re_magic;
size_t re_nsub; /* number of parenthesized subexpressions */
- __const char *re_endp; /* end pointer for REG_PEND */
+ const char *re_endp; /* end pointer for REG_PEND */
struct re_guts *re_g; /* none of your business :-) */
} regex_t;
} regmatch_t;
/* regcomp() flags */
+#ifndef _POSIX_SOURCE
#define REG_BASIC 0000
+#endif /* !_POSIX_SOURCE */
#define REG_EXTENDED 0001
#define REG_ICASE 0002
#define REG_NOSUB 0004
#define REG_NEWLINE 0010
+#ifndef _POSIX_SOURCE
#define REG_NOSPEC 0020
#define REG_PEND 0040
#define REG_DUMP 0200
+#endif /* !_POSIX_SOURCE */
/* regerror() flags */
+#define REG_ENOSYS (-1) /* Reserved */
#define REG_NOMATCH 1
#define REG_BADPAT 2
#define REG_ECOLLATE 3
#define REG_ERANGE 11
#define REG_ESPACE 12
#define REG_BADRPT 13
+#ifndef _POSIX_SOURCE
#define REG_EMPTY 14
#define REG_ASSERT 15
#define REG_INVARG 16
#define REG_ATOI 255 /* convert name to number (!) */
#define REG_ITOA 0400 /* convert number to name (!) */
+#endif /* !_POSIX_SOURCE */
/* regexec() flags */
#define REG_NOTBOL 00001
#define REG_NOTEOL 00002
+#ifndef _POSIX_SOURCE
#define REG_STARTEND 00004
#define REG_TRACE 00400 /* tracing of execution */
#define REG_LARGE 01000 /* force large representation */
#define REG_BACKR 02000 /* force use of backref code */
+#endif /* !_POSIX_SOURCE */
__BEGIN_DECLS
-int regcomp(regex_t *, const char *, int);
-size_t regerror(int, const regex_t *, char *, size_t);
-int regexec(const regex_t *,
- const char *, size_t, regmatch_t [], int);
+int regcomp(regex_t * __restrict, const char * __restrict, int);
+size_t regerror(int, const regex_t * __restrict, char * __restrict, size_t);
+int regexec(const regex_t * __restrict,
+ const char * __restrict, size_t, regmatch_t [ __restrict], int);
void regfree(regex_t *);
__END_DECLS
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
#define _RUNETYPE_H_
#include <sys/cdefs.h>
-#include <machine/ansi.h>
+#include <_types.h>
#ifndef _BSD_SIZE_T_DEFINED_
#define _BSD_SIZE_T_DEFINED_
-typedef _BSD_SIZE_T_ size_t;
+typedef __osx_size_t size_t;
#endif
#ifndef _BSD_CT_RUNE_T_DEFINED_
#define _BSD_CT_RUNE_T_DEFINED_
-typedef _BSD_CT_RUNE_T_ ct_rune_t;
+typedef __osx_ct_rune_t ct_rune_t;
#endif
#ifndef _BSD_RUNE_T_DEFINED_
#define _BSD_RUNE_T_DEFINED_
-typedef _BSD_RUNE_T_ rune_t;
+typedef __osx_rune_t rune_t;
#endif
#ifndef __cplusplus
#ifndef _BSD_WCHAR_T_DEFINED_
#define _BSD_WCHAR_T_DEFINED_
-#ifdef __WCHAR_TYPE__
-typedef __WCHAR_TYPE__ wchar_t;
-#else /* ! __WCHAR_TYPE__ */
-typedef _BSD_WCHAR_T_ wchar_t;
-#endif /* __WCHAR_TYPE__ */
+typedef __osx_wchar_t wchar_t;
#endif /* _BSD_WCHAR_T_DEFINED_ */
#endif /* __cplusplus */
#ifndef _BSD_WINT_T_DEFINED_
#define _BSD_WINT_T_DEFINED_
-typedef _BSD_WINT_T_ wint_t;
+typedef __osx_wint_t wint_t;
#endif
#define _CACHED_RUNES (1 <<8 ) /* Must be a power of 2 */
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*-
* Written by J.T. Conklin <jtc@netbsd.org>
* Public domain.
#define _SEARCH_H_
#include <sys/cdefs.h>
-#include <sys/types.h>
+#include <_types.h>
+
+#ifndef _BSD_SIZE_T_DEFINED_
+#define _BSD_SIZE_T_DEFINED_
+typedef __osx_size_t size_t;
+#endif
typedef struct entry {
char *key;
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#ifndef _USER_SIGNAL_H
#define _USER_SIGNAL_H
-#include <sys/types.h>
+#include <_types.h>
#include <sys/cdefs.h>
#include <sys/signal.h>
+#ifndef _PTHREAD_T_DECLARED
+typedef __osx_pthread_t pthread_t;
+#define _PTHREAD_T_DECLARED
+#endif
+
#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
extern __const char *__const sys_signame[NSIG];
extern __const char *__const sys_siglist[NSIG];
__BEGIN_DECLS
int raise(int);
+__END_DECLS
+
#ifndef _ANSI_SOURCE
+__BEGIN_DECLS
+void (*bsd_signal(int, void (*)(int)))(int);
int kill(pid_t, int);
-int sigaction(int, const struct sigaction *, struct sigaction *);
+int killpg(pid_t, int);
+int pthread_kill(pthread_t, int);
+int pthread_sigmask(int, const sigset_t *, sigset_t *);
+int sigaction(int, const struct sigaction * __restrict,
+ struct sigaction * __restrict);
int sigaddset(sigset_t *, int);
-int sigaltstack(const struct sigaltstack *, struct sigaltstack *);
+int sigaltstack(const stack_t * __restrict, stack_t * __restrict);
int sigdelset(sigset_t *, int);
int sigemptyset(sigset_t *);
int sigfillset(sigset_t *);
+int sighold(int);
+int sigignore(int);
+int siginterrupt(int, int);
int sigismember(const sigset_t *, int);
+int sigpause(int);
int sigpending(sigset_t *);
-int sigprocmask(int, const sigset_t *, sigset_t *);
+int sigprocmask(int, const sigset_t * __restrict, sigset_t * __restrict);
+int sigrelse(int);
int sigsuspend(const sigset_t *);
-int sigwait(const sigset_t *, int *);
+int sigwait(const sigset_t * __restrict, int * __restrict);
#ifndef _POSIX_SOURCE
-int killpg(pid_t, int);
+void psignal(unsigned int, const char *);
int sigblock(int);
-int siginterrupt(int, int);
-int sighold(int);
-int sigrelse(int);
-int sigpause(int);
int sigreturn(struct sigcontext *);
int sigsetmask(int);
int sigvec(int, struct sigvec *, struct sigvec *);
-void psignal(unsigned int, const char *);
-
#endif /* !_POSIX_SOURCE */
-#endif /* !_ANSI_SOURCE */
__END_DECLS
/* List definitions after function declarations, or Reiser cpp gets upset. */
#define sigemptyset(set) (*(set) = 0, 0)
#define sigfillset(set) (*(set) = ~(sigset_t)0, 0)
#define sigismember(set, signo) ((*(set) & (1 << ((signo) - 1))) != 0)
+#endif /* !_ANSI_SOURCE */
#endif /* !_USER_SIGNAL_H */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#ifndef __STDDEF_H__
#define __STDDEF_H__
-#include <machine/types.h>
-#include <machine/ansi.h>
+#include <_types.h>
-typedef _BSD_PTRDIFF_T_ ptrdiff_t;
+#ifndef _PTRDIFF_T_DECLARED
+typedef __osx_ptrdiff_t ptrdiff_t;
+#define _PTRDIFF_T_DECLARED
+#endif
#ifndef _BSD_SIZE_T_DEFINED_
#define _BSD_SIZE_T_DEFINED_
-typedef _BSD_SIZE_T_ size_t;
-#endif
-
-#ifndef _BSD_CT_RUNE_T_DEFINED_
-#define _BSD_CT_RUNE_T_DEFINED_
-typedef _BSD_CT_RUNE_T_ ct_rune_t;
-#endif
-
-#ifndef _BSD_RUNE_T_DEFINED_
-#define _BSD_RUNE_T_DEFINED_
-typedef _BSD_RUNE_T_ rune_t;
+typedef __osx_size_t size_t;
#endif
#ifndef __cplusplus
#ifndef _BSD_WCHAR_T_DEFINED_
#define _BSD_WCHAR_T_DEFINED_
-#ifdef __WCHAR_TYPE__
-typedef __WCHAR_TYPE__ wchar_t;
-#else /* ! __WCHAR_TYPE__ */
-typedef _BSD_WCHAR_T_ wchar_t;
-#endif /* __WCHAR_TYPE__ */
+typedef __osx_wchar_t wchar_t;
#endif /* _BSD_WCHAR_T_DEFINED_ */
#endif /* __cplusplus */
-#ifndef _BSD_WINT_T_DEFINED_
-#define _BSD_WINT_T_DEFINED_
-typedef _BSD_WINT_T_ wint_t;
-#endif
+#ifndef NULL
+#define NULL __OSX_NULL
+#endif /* ! NULL */
-#ifndef NULL
-#define NULL 0
+#ifndef __offsetof /* Deprecated: for source compatability only */
+#define __offsetof(type, field) ((size_t)(&((type *)0)->field))
#endif
-
-#define offsetof(type, member) __offsetof(type, member)
+#define offsetof(type, field) ((size_t)(&((type *)0)->field))
#endif /* __STDDEF_H__ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#ifndef _STDIO_H_
#define _STDIO_H_
-#if !defined(_ANSI_SOURCE) && !defined(__STRICT_ANSI__)
-#include <sys/types.h>
-#endif
-
+#include <_types.h>
#include <sys/cdefs.h>
-#include <machine/ansi.h>
+#ifndef _POSIX_SOURCE
+#include <stdarg.h>
+#else /* _POSIX_SOURCE */
+/* set __need___va_list to only define __gnuc_va_list */
+#define __need___va_list
+#include <stdarg.h>
+#ifdef __GNUC_VA_LIST
+#ifndef _VA_LIST_DEFINED
+#define _VA_LIST_DEFINED
+typedef __gnuc_va_list va_list;
+#endif /* _VA_LIST_DEFINED */
+#endif /* __GNUC_VA_LIST */
+#endif /* _POSIX_SOURCE */
+
#ifndef _BSD_SIZE_T_DEFINED_
#define _BSD_SIZE_T_DEFINED_
-typedef _BSD_SIZE_T_ size_t;
+typedef __osx_size_t size_t;
#endif
#ifndef NULL
-#define NULL 0
-#endif
+#define NULL __OSX_NULL
+#endif /* ! NULL */
#if !defined(_ANSI_SOURCE) && !defined(__STRICT_ANSI__)
-typedef off_t fpos_t;
+typedef __osx_off_t fpos_t;
#else
-#include <machine/types.h>
-typedef int64_t fpos_t;
+typedef __int64_t fpos_t;
#endif
#define _FSTDIO /* Define for new stdio with functions. */
#define SEEK_END 2 /* set file offset to EOF plus offset */
#endif
-#define stdin (&__sF[0])
-#define stdout (&__sF[1])
-#define stderr (&__sF[2])
+#define stdin (&__sF[0])
+#define stdout (&__sF[1])
+#define stderr (&__sF[2])
/*
* Functions defined in ANSI C standard.
int ferror(FILE *);
int fflush(FILE *);
int fgetc(FILE *);
-int fgetpos(FILE *, fpos_t *);
-char *fgets(char *, int, FILE *);
-FILE *fopen(const char *, const char *);
-int fprintf(FILE *, const char *, ...);
+int fgetpos(FILE * __restrict, fpos_t *);
+char *fgets(char * __restrict, int, FILE *);
+FILE *fopen(const char * __restrict, const char * __restrict);
+int fprintf(FILE * __restrict, const char * __restrict, ...);
int fputc(int, FILE *);
-int fputs(const char *, FILE *);
-size_t fread(void *, size_t, size_t, FILE *);
-FILE *freopen(const char *, const char *, FILE *);
-int fscanf(FILE *, const char *, ...);
+int fputs(const char * __restrict, FILE * __restrict);
+size_t fread(void * __restrict, size_t, size_t, FILE * __restrict);
+FILE *freopen(const char * __restrict, const char * __restrict,
+ FILE * __restrict);
+int fscanf(FILE * __restrict, const char * __restrict, ...);
int fseek(FILE *, long, int);
int fsetpos(FILE *, const fpos_t *);
long ftell(FILE *);
-size_t fwrite(const void *, size_t, size_t, FILE *);
+size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict);
int getc(FILE *);
int getchar(void);
char *gets(char *);
extern __const char *__const sys_errlist[];
#endif
void perror(const char *);
-int printf(const char *, ...);
+int printf(const char * __restrict, ...);
int putc(int, FILE *);
int putchar(int);
int puts(const char *);
int remove(const char *);
int rename (const char *, const char *);
void rewind(FILE *);
-int scanf(const char *, ...);
-void setbuf(FILE *, char *);
-int setvbuf(FILE *, char *, int, size_t);
-int sprintf(char *, const char *, ...);
-int sscanf(const char *, const char *, ...);
+int scanf(const char * __restrict, ...);
+void setbuf(FILE * __restrict, char * __restrict);
+int setvbuf(FILE * __restrict, char * __restrict, int, size_t);
+int sprintf(char * __restrict, const char * __restrict, ...);
+int sscanf(const char * __restrict, const char * __restrict, ...);
FILE *tmpfile(void);
char *tmpnam(char *);
int ungetc(int, FILE *);
-int vfprintf(FILE *, const char *, _BSD_VA_LIST_);
-int vprintf(const char *, _BSD_VA_LIST_);
-int vsprintf(char *, const char *, _BSD_VA_LIST_);
+int vfprintf(FILE * __restrict, const char * __restrict, va_list);
+int vprintf(const char * __restrict, va_list);
+int vsprintf(char * __restrict, const char * __restrict, va_list);
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
int asprintf(char **, const char *, ...);
-int vasprintf(char **, const char *, _BSD_VA_LIST_);
+int vasprintf(char **, const char *, va_list);
+#endif
__END_DECLS
/*
__BEGIN_DECLS
char *ctermid(char *);
+#ifndef _POSIX_SOURCE
char *ctermid_r(char *);
+#endif /* not POSIX */
FILE *fdopen(int, const char *);
-int fileno(FILE *);
-__END_DECLS
-#endif /* not ANSI */
-
-/*
- * Routines that are purely local.
- */
-#if !defined (_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
+#ifndef _POSIX_SOURCE
char *fgetln(FILE *, size_t *);
+#endif /* not POSIX */
+int fileno(FILE *);
void flockfile(FILE *);
+#ifndef _POSIX_SOURCE
__const char
*fmtcheck(const char *, const char *);
int fpurge(FILE *);
+#endif /* not POSIX */
int fseeko(FILE *, fpos_t, int);
fpos_t ftello(FILE *);
int ftrylockfile(FILE *);
void funlockfile(FILE *);
int getc_unlocked(FILE *);
int getchar_unlocked(void);
+#ifndef _POSIX_SOURCE
int getw(FILE *);
+#endif /* not POSIX */
int pclose(FILE *);
FILE *popen(const char *, const char *);
int putc_unlocked(int, FILE *);
int putchar_unlocked(int);
+#ifndef _POSIX_SOURCE
int putw(int, FILE *);
void setbuffer(FILE *, char *, int);
int setlinebuf(FILE *);
+#endif /* not POSIX */
+int snprintf(char * __restrict, size_t, const char * __restrict, ...);
char *tempnam(const char *, const char *);
-int snprintf(char *, size_t, const char *, ...);
-int vfscanf(FILE *, const char *, _BSD_VA_LIST_);
-int vsnprintf(char *, size_t, const char *, _BSD_VA_LIST_);
-int vscanf(const char *, _BSD_VA_LIST_);
-int vsscanf(const char *, const char *, _BSD_VA_LIST_);
+int vfscanf(FILE * __restrict, const char * __restrict, va_list);
+int vscanf(const char * __restrict, va_list);
+int vsnprintf(char * __restrict, size_t, const char * __restrict, va_list);
+int vsscanf(const char * __restrict, const char * __restrict, va_list);
+#ifndef _POSIX_SOURCE
FILE *zopen(const char *, const char *, int);
+#endif /* not POSIX */
__END_DECLS
/*
* Stdio function-access interface.
*/
+#ifndef _POSIX_SOURCE
__BEGIN_DECLS
FILE *funopen(const void *,
int (*)(void *, char *, int),
__END_DECLS
#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
-#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
+#endif /* not POSIX */
+#endif /* not ANSI */
/*
* Functions internal to the implementation.
*/
__BEGIN_DECLS
int __srget(FILE *);
-int __svfscanf(FILE *, const char *, _BSD_VA_LIST_);
+int __svfscanf(FILE *, const char *, va_list);
int __swbuf(int, FILE *);
__END_DECLS
#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
#define __sfileno(p) ((p)->_file)
+#ifndef _ANSI_SOURCE
+#ifndef _POSIX_SOURCE
#define feof_unlocked(p) __sfeof(p)
#define ferror_unlocked(p) __sferror(p)
#define clearerr_unlocked(p) __sclearerr(p)
-
-#ifndef _ANSI_SOURCE
#define fileno_unlocked(p) __sfileno(p)
-#endif
+#endif /* not POSIX */
#ifndef lint
#define getc_unlocked(fp) __sgetc(fp)
#define getchar_unlocked() getc_unlocked(stdin)
#define putchar_unlocked(x) putc_unlocked(x, stdout)
+#endif /* not ANSI */
+
#endif /* _STDIO_H_ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
} ldiv_t;
#ifndef NULL
-#define NULL 0
-#endif
+#ifdef __GNUG__
+#define NULL __null
+#else /* ! __GNUG__ */
+#ifndef __cplusplus
+#define NULL ((void *)0)
+#else /* __cplusplus */
+#define NULL 0
+#endif /* ! __cplusplus */
+#endif /* __GNUG__ */
+#endif /* ! NULL */
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
#ifndef _STRHASH_H_INCLUDE
#define _STRHASH_H_INCLUDE
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
typedef _BSD_SIZE_T_ size_t;
#endif
-#ifndef NULL
-#define NULL 0
-#endif
+#ifndef NULL
+#ifdef __GNUG__
+#define NULL __null
+#else /* ! __GNUG__ */
+#ifndef __cplusplus
+#define NULL ((void *)0)
+#else /* __cplusplus */
+#define NULL 0
+#endif /* ! __cplusplus */
+#endif /* __GNUG__ */
+#endif /* ! NULL */
#include <sys/cdefs.h>
void *memcpy(void *, const void *, size_t);
void *memmove(void *, const void *, size_t);
void *memset(void *, int, size_t);
+#ifndef _POSIX_SOURCE
char *stpcpy(char *, const char *);
char *strcasestr(const char *, const char *);
+#endif /* !_POSIX_SOURCE */
char *strcat(char *, const char *);
char *strchr(const char *, int);
int strcmp(const char *, const char *);
char *strncat(char *, const char *, size_t);
int strncmp(const char *, const char *, size_t);
char *strncpy(char *, const char *, size_t);
+#ifndef _POSIX_SOURCE
char *strnstr(const char *, const char *, size_t);
+#endif /* !_POSIX_SOURCE */
char *strpbrk(const char *, const char *);
char *strrchr(const char *, int);
size_t strspn(const char *, const char *);
/* Nonstandard routines */
#ifndef _ANSI_SOURCE
+void *memccpy(void *, const void *, int, size_t);
+char *strtok_r(char *, const char *, char **);
+char *strdup(const char *);
+#ifndef _POSIX_SOURCE
int bcmp(const void *, const void *, size_t);
void bcopy(const void *, void *, size_t);
void bzero(void *, size_t);
int ffs(int);
char *index(const char *, int);
-void *memccpy(void *, const void *, int, size_t);
char *rindex(const char *, int);
int strcasecmp(const char *, const char *);
-char *strdup(const char *);
size_t strlcat(char *, const char *, size_t);
size_t strlcpy(char *, const char *, size_t);
void strmode(int, char *);
int strncasecmp(const char *, const char *, size_t);
char *strsep(char **, const char *);
char *strsignal(int sig);
-char *strtok_r(char *, const char *, char **);
void swab(const void *, void *, size_t);
-#endif
+#endif /* !_POSIX_SOURCE */
+#endif /* !_ANSI_SOURCE */
__END_DECLS
#endif /* _STRING_H_ */
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/* $NetBSD: stringlist.h,v 1.2 1997/01/17 06:11:36 lukem Exp $ */
/*
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+SYS_INSTHDRS += statvfs.h
+
+SYS_INSTHDRS := ${SYS_INSTHDRS:S/^/${.CURDIR}\/include\/sys\//}
--- /dev/null
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * sys/statvfs.h
+ */
+#ifndef _SYS_STATVFS_H_
+#define _SYS_STATVFS_H_
+
+#include <sys/cdefs.h>
+
+/* Following types need to be defined in <sys/types.h> as well */
+typedef unsigned int fsblkcnt_t;
+typedef unsigned int fsfilcnt_t;
+
+/* Following structure is used as a statvfs/fstatvfs function parameter */
+struct statvfs {
+ unsigned long f_bsize; /* File system block size */
+ unsigned long f_frsize; /* Fundamental file system block size */
+ fsblkcnt_t f_blocks; /* Blocks on FS in units of f_frsize*/
+ fsblkcnt_t f_bfree; /* Free blocks */
+ fsblkcnt_t f_bavail; /* Blocks available to non-root */
+ fsfilcnt_t f_files; /* Total inodes */
+ fsfilcnt_t f_ffree; /* Free inodes */
+ fsfilcnt_t f_favail; /* Free inodes for non-root */
+ unsigned long f_fsid; /* Filesystem ID */
+ unsigned long f_flag; /* Bit mask of values */
+ unsigned long f_namemax; /* Max file name length */
+};
+
+/* Defined bits for f_flag field value */
+#define ST_RDONLY 0x00000001 /* Read-only file system */
+#define ST_NOSUID 0x00000002 /* Does not honor setuid/setgid */
+
+__BEGIN_DECLS
+int fstatvfs(int, struct statvfs *);
+int statvfs(const char * __restrict, struct statvfs * __restrict);
+__END_DECLS
+
+#endif /* _SYS_STATVFS_H_ */
--- /dev/null
+.\"
+.\" Copyright (c) 1996 Joerg Wunsch
+.\"
+.\" 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 DEVELOPERS ``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 DEVELOPERS 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.
+.\"
+.\" $FreeBSD: /repoman/r/ncvs/src/share/man/man3/sysexits.3,v 1.12 2003/09/10 19:24:34 ru Exp $
+.\"
+.\" "
+.Dd March 31, 1996
+.Os
+.Dt SYSEXITS 3
+.Sh NAME
+.Nm sysexits
+.Nd preferable exit codes for programs
+.Sh SYNOPSIS
+.In sysexits.h
+.Sh DESCRIPTION
+According to
+.Xr style 9 ,
+it is not a good practice to call
+.Xr exit 3
+with arbitrary values to indicate a failure condition when ending
+a program. Instead, the pre-defined exit codes from
+.Nm
+should be used, so the caller of the process can get a rough
+estimation about the failure class without looking up the source code.
+.Pp
+The successful exit is always indicated by a status of 0, or
+.Sy EX_OK .
+Error numbers begin at
+.Sy EX__BASE
+to reduce the possibility of clashing with other exit statuses that
+random programs may already return. The meaning of the codes is
+approximately as follows:
+.Bl -tag -width "EX_UNAVAILABLEXX(XX)"
+.It Sy EX_USAGE Pq 64
+The command was used incorrectly, e.g., with the wrong number of
+arguments, a bad flag, a bad syntax in a parameter, or whatever.
+.It Sy EX_DATAERR Pq 65
+The input data was incorrect in some way. This should only be used
+for user's data and not system files.
+.It Sy EX_NOINPUT Pq 66
+An input file (not a system file) did not exist or was not readable.
+This could also include errors like
+.Dq \&No message
+to a mailer (if it cared to catch it).
+.It Sy EX_NOUSER Pq 67
+The user specified did not exist. This might be used for mail
+addresses or remote logins.
+.It Sy EX_NOHOST Pq 68
+The host specified did not exist. This is used in mail addresses or
+network requests.
+.It Sy EX_UNAVAILABLE Pq 69
+A service is unavailable. This can occur if a support program or file
+does not exist. This can also be used as a catchall message when
+something you wanted to do doesn't work, but you don't know why.
+.It Sy EX_SOFTWARE Pq 70
+An internal software error has been detected. This should be limited
+to non-operating system related errors as possible.
+.It Sy EX_OSERR Pq 71
+An operating system error has been detected. This is intended to be
+used for such things as
+.Dq cannot fork ,
+.Dq cannot create pipe ,
+or the like. It includes things like getuid returning a user that
+does not exist in the passwd file.
+.It Sy EX_OSFILE Pq 72
+Some system file (e.g.,
+.Pa /etc/passwd ,
+.Pa /var/run/utmp ,
+etc.) does not exist, cannot be opened, or has some sort of error
+(e.g., syntax error).
+.It Sy EX_CANTCREAT Pq 73
+A (user specified) output file cannot be created.
+.It Sy EX_IOERR Pq 74
+An error occurred while doing I/O on some file.
+.It Sy EX_TEMPFAIL Pq 75
+Temporary failure, indicating something that is not really an error.
+In sendmail, this means that a mailer (e.g.) could not create a
+connection, and the request should be reattempted later.
+.It Sy EX_PROTOCOL Pq 76
+The remote system returned something that was
+.Dq not possible
+during a protocol exchange.
+.It Sy EX_NOPERM Pq 77
+You did not have sufficient permission to perform the operation. This
+is not intended for file system problems, which should use
+.Sy EX_NOINPUT
+or
+.Sy EX_CANTCREAT ,
+but rather for higher level permissions.
+.It Sy EX_CONFIG Pq 78
+Something was found in an unconfigured or misconfigured state.
+.El
+.Pp
+The numerical values corresponding to the symbolical ones are given in
+parenthesis for easy reference.
+.Sh SEE ALSO
+.Xr exit 3 ,
+.Xr style 9
+.Sh HISTORY
+The
+.Nm
+file appeared somewhere after
+.Bx 4.3 .
+.Sh AUTHORS
+This man page has been written by
+.An J\(:org Wunsch
+after the comments in
+.In sysexits.h .
+.Sh BUGS
+The choice of an appropriate exit value is often ambiguous.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_END@
*/
+#ifndef __TERMIOS_H__
+#define __TERMIOS_H__
+
+#include <sys/cdefs.h>
#include <sys/termios.h>
+#include <_types.h>
+
+#ifndef _PID_T_DECLARED
+typedef __osx_pid_t pid_t;
+#define _PID_T_DECLARED
+#endif
+
+__BEGIN_DECLS
+pid_t tcgetsid(int);
+__END_DECLS
+#endif /* __TERMIOS_H__ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <machine/ansi.h>
-#ifndef NULL
-#define NULL 0
-#endif
+#ifndef NULL
+#ifdef __GNUG__
+#define NULL __null
+#else /* ! __GNUG__ */
+#ifndef __cplusplus
+#define NULL ((void *)0)
+#else /* __cplusplus */
+#define NULL 0
+#endif /* ! __cplusplus */
+#endif /* __GNUG__ */
+#endif /* ! NULL */
#ifndef _BSD_CLOCK_T_DEFINED_
#define _BSD_CLOCK_T_DEFINED_
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+/*-
+ * Copyright (c) 2002 Kyle Martin <mkm@ieee.org>
+ * All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
+ * 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.
+ *
+ * $FreeBSD: src/include/ulimit.h,v 1.4 2003/01/08 01:18:13 tjr Exp $
*/
-#ifndef _ULIMIT_H
-#define _ULIMIT_H
-#define UL_GETFSIZE 1
-#define UL_SETFSIZE 2
+#ifndef _ULIMIT_H_
+#define _ULIMIT_H_
#include <sys/cdefs.h>
+#define UL_GETFSIZE 1
+#define UL_SETFSIZE 2
+
__BEGIN_DECLS
-long int ulimit(int, ...);
+long ulimit(int, ...);
__END_DECLS
-#endif /* _ULIMIT_H */
+#endif /* !_ULIMIT_H_ */
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <sys/cdefs.h>
#include <sys/types.h>
-#include <sys/unistd.h>
+#include <sys/unistd.h> /* XXX needs to go away */
+
#define STDIN_FILENO 0 /* standard input file descriptor */
#define STDOUT_FILENO 1 /* standard output file descriptor */
#define STDERR_FILENO 2 /* standard error file descriptor */
#ifndef NULL
-#define NULL 0 /* null pointer constant */
+#ifdef __GNUG__
+#define NULL __null
+#else /* ! __GNUG__ */
+#ifndef __cplusplus
+#define NULL ((void *)0)
+#else /* __cplusplus */
+#define NULL 0
+#endif /* ! __cplusplus */
+#endif /* __GNUG__ */
+#endif /* ! NULL */
+
+#ifdef _POSIX_VERSION /* XXX <sys/unistd.h> */
+#undef _POSIX_VERSION
+#endif
+#ifdef _POSIX2_VERSION /* XXX <sys/unistd.h> */
+#undef _POSIX2_VERSION
+#endif
+#ifdef _POSIX_CHOWN_RESTRICTED /* XXX <sys/unistd.h> */
+#undef _POSIX_CHOWN_RESTRICTED
#endif
+#ifdef _POSIX_NO_TRUNC /* XXX <sys/unistd.h> */
+#undef _POSIX_NO_TRUNC
+#endif
+
+/* Version test macros */
+#define _POSIX_VERSION 200112L
+#define _POSIX2_VERSION 200112L
+
+#define _XOPEN_VERSION 600 /* [XSI] */
+#define _XOPEN_XCU_VERSION 4 /* Older standard */
+
+
+/* Please keep this list in the same order as the applicable standard */
+#define _POSIX_ADVISORY_INFO (-1) /* [ADV] */
+#define _POSIX_ASYNCHRONOUS_IO 200112L /* [AIO] */
+#define _POSIX_BARRIERS (-1) /* [BAR] */
+#define _POSIX_CHOWN_RESTRICTED 200112L
+#define _POSIX_CLOCK_SELECTION (-1) /* [CS] */
+#define _POSIX_CPUTIME (-1) /* [CPT] */
+#define _POSIX_FSYNC 200112L /* [FSC] */
+#define _POSIX_IPV6 200112L
+#define _POSIX_JOB_CONTROL 200112L
+#define _POSIX_MAPPED_FILES 200112L /* [MF] */
+#define _POSIX_MEMLOCK 200112L /* [ML] */
+#define _POSIX_MEMLOCK_RANGE 200112L /* [MR] */
+#define _POSIX_MEMORY_PROTECTION 200112L /* [MPR] */
+#define _POSIX_MESSAGE_PASSING (-1) /* [MSG] */
+#define _POSIX_MONOTONIC_CLOCK (-1) /* [MON] */
+#define _POSIX_NO_TRUNC 200112L
+#define _POSIX_PRIORITIZED_IO (-1) /* [PIO] */
+#define _POSIX_PRIORITY_SCHEDULING (-1) /* [PS] */
+#define _POSIX_RAW_SOCKETS 200112L /* [RS] */
+#define _POSIX_READER_WRITER_LOCKS 200112L /* [THR] */
+#define _POSIX_REALTIME_SIGNALS (-1) /* [RTS] */
+#define _POSIX_REGEXP 200112L
+#define _POSIX_SAVED_IDS (-1) /* XXX required */
+#define _POSIX_SEMAPHORES 200112L /* [SEM] */
+#define _POSIX_SHARED_MEMORY_OBJECTS 200112L /* [SHM] */
+#define _POSIX_SHELL 200112L
+#define _POSIX_SPAWN (-1) /* [SPN] */
+#define _POSIX_SPIN_LOCKS (-1) /* [SPI] */
+#define _POSIX_SPORADIC_SERVER (-1) /* [SS] */
+#define _POSIX_SYNCHRONIZED_IO 200112L /* [SIO] */
+#define _POSIX_THREAD_ATTR_STACKADDR 200112L /* [TSA] */
+#define _POSIX_THREAD_ATTR_STACKSIZE 200112L /* [TSS] */
+#define _POSIX_THREAD_CPUTIME (-1) /* [TCT] */
+#define _POSIX_THREAD_PRIO_INHERIT (-1) /* [TPI] */
+#define _POSIX_THREAD_PRIO_PROTECT (-1) /* [TPP] */
+#define _POSIX_THREAD_PRIORITY_SCHEDULING (-1) /* [TPS] */
+#define _POSIX_THREAD_PROCESS_SHARED 200112L /* [TSH] */
+#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L /* [TSF] */
+#define _POSIX_THREAD_SPORADIC_SERVER (-1) /* [TSP] */
+#define _POSIX_THREADS 200112L /* [THR] */
+#define _POSIX_TIMEOUTS (-1) /* [TMO] */
+#define _POSIX_TIMERS (-1) /* [TMR] */
+#define _POSIX_TRACE (-1) /* [TRC] */
+#define _POSIX_TRACE_EVENT_FILTER (-1) /* [TEF] */
+#define _POSIX_TRACE_INHERIT (-1) /* [TRI] */
+#define _POSIX_TRACE_LOG (-1) /* [TRL] */
+#define _POSIX_TYPED_MEMORY_OBJECTS (-1) /* [TYM] */
+#ifndef _POSIX_VDISABLE
+#define _POSIX_VDISABLE 0xff /* same as sys/termios.h */
+#endif /* _POSIX_VDISABLE */
+
+#define _POSIX2_C_BIND 200112L
+#define _POSIX2_C_DEV (-1) /* c99 command */
+#define _POSIX2_CHAR_TERM 200112L
+#define _POSIX2_FORT_DEV (-1) /* fort77 command */
+#define _POSIX2_FORT_RUN 200112L
+#define _POSIX2_LOCALEDEF (-1) /* localedef command */
+#define _POSIX2_PBS (-1)
+#define _POSIX2_PBS_ACCOUNTING (-1)
+#define _POSIX2_PBS_CHECKPOINT (-1)
+#define _POSIX2_PBS_LOCATE (-1)
+#define _POSIX2_PBS_MESSAGE (-1)
+#define _POSIX2_PBS_TRACK (-1)
+#define _POSIX2_SW_DEV 200112L
+#define _POSIX2_UPE 200112L /* XXXX no fc, newgrp, tabs */
+
+#define _V6_ILP32_OFF32 (-1)
+#define _V6_ILP32_OFFBIG 0
+#define _V6_LP64_OFF64 0
+#define _V6_LPBIG_OFFBIG (-1)
+
+#define _XBS5_ILP32_OFF32 _V6_ILP32_OFF32 /* legacy */
+#define _XBS5_ILP32_OFFBIG _V6_ILP32_OFFBIG /* legacy */
+#define _XBS5_LP64_OFF64 _V6_LP64_OFF64 /* legacy */
+#define _XBS5_LPBIG_OFFBIG _V6_LPBIG_OFFBIG /* legacy */
+
+#define _XOPEN_CRYPT (1)
+#define _XOPEN_ENH_I18N (1) /* XXX required */
+#define _XOPEN_LEGACY (-1) /* no ftime gcvt, wcswcs */
+#define _XOPEN_REALTIME (-1) /* no q'ed signals, mq_* */
+#define _XOPEN_REALTIME_THREADS (-1) /* no posix_spawn, et. al. */
+#define _XOPEN_SHM (1)
+#define _XOPEN_STREAMS (-1)
+#define _XOPEN_UNIX (1)
-#define _POSIX_THREADS /* We support pthreads */
#ifndef _POSIX_SOURCE
#define F_ULOCK 0 /* unlock locked section */
#endif
/* configurable system variables */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLK_TCK 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-#define _SC_BC_BASE_MAX 9
-#define _SC_BC_DIM_MAX 10
-#define _SC_BC_SCALE_MAX 11
-#define _SC_BC_STRING_MAX 12
-#define _SC_COLL_WEIGHTS_MAX 13
-#define _SC_EXPR_NEST_MAX 14
-#define _SC_LINE_MAX 15
-#define _SC_RE_DUP_MAX 16
-#define _SC_2_VERSION 17
-#define _SC_2_C_BIND 18
-#define _SC_2_C_DEV 19
-#define _SC_2_CHAR_TERM 20
-#define _SC_2_FORT_DEV 21
-#define _SC_2_FORT_RUN 22
-#define _SC_2_LOCALEDEF 23
-#define _SC_2_SW_DEV 24
-#define _SC_2_UPE 25
-#define _SC_STREAM_MAX 26
-#define _SC_TZNAME_MAX 27
-/* POSIX.1B sysconf options for async IO*/
-#define _SC_ASYNCHRONOUS_IO 28
-#define _SC_PAGESIZE 29
-#define _SC_AIO_LISTIO_MAX 42
-#define _SC_AIO_MAX 43
-#define _SC_AIO_PRIO_DELTA_MAX 44
+#define _SC_ARG_MAX 1
+#define _SC_CHILD_MAX 2
+#define _SC_CLK_TCK 3
+#define _SC_NGROUPS_MAX 4
+#define _SC_OPEN_MAX 5
+#define _SC_JOB_CONTROL 6
+#define _SC_SAVED_IDS 7
+#define _SC_VERSION 8
+#define _SC_BC_BASE_MAX 9
+#define _SC_BC_DIM_MAX 10
+#define _SC_BC_SCALE_MAX 11
+#define _SC_BC_STRING_MAX 12
+#define _SC_COLL_WEIGHTS_MAX 13
+#define _SC_EXPR_NEST_MAX 14
+#define _SC_LINE_MAX 15
+#define _SC_RE_DUP_MAX 16
+#define _SC_2_VERSION 17
+#define _SC_2_C_BIND 18
+#define _SC_2_C_DEV 19
+#define _SC_2_CHAR_TERM 20
+#define _SC_2_FORT_DEV 21
+#define _SC_2_FORT_RUN 22
+#define _SC_2_LOCALEDEF 23
+#define _SC_2_SW_DEV 24
+#define _SC_2_UPE 25
+#define _SC_STREAM_MAX 26
+#define _SC_TZNAME_MAX 27
+#define _SC_ASYNCHRONOUS_IO 28
+#define _SC_PAGESIZE 29
+#define _SC_MEMLOCK 30
+#define _SC_MEMLOCK_RANGE 31
+#define _SC_MEMORY_PROTECTION 32
+#define _SC_MESSAGE_PASSING 33
+#define _SC_PRIORITIZED_IO 34
+#define _SC_PRIORITY_SCHEDULING 35
+#define _SC_REALTIME_SIGNALS 36
+#define _SC_SEMAPHORES 37
+#define _SC_FSYNC 38
+#define _SC_SHARED_MEMORY_OBJECTS 39
+#define _SC_SYNCHRONIZED_IO 40
+#define _SC_TIMERS 41
+#define _SC_AIO_LISTIO_MAX 42
+#define _SC_AIO_MAX 43
+#define _SC_AIO_PRIO_DELTA_MAX 44
+#define _SC_DELAYTIMER_MAX 45
+#define _SC_MQ_OPEN_MAX 46
+#define _SC_MAPPED_FILES 47 /* swap _SC_PAGESIZE vs. BSD */
+#define _SC_RTSIG_MAX 48
+#define _SC_SEM_NSEMS_MAX 49
+#define _SC_SEM_VALUE_MAX 50
+#define _SC_SIGQUEUE_MAX 51
+#define _SC_TIMER_MAX 52
+#define _SC_2_PBS 59
+#define _SC_2_PBS_ACCOUNTING 60
+#define _SC_2_PBS_CHECKPOINT 61
+#define _SC_2_PBS_LOCATE 62
+#define _SC_2_PBS_MESSAGE 63
+#define _SC_2_PBS_TRACK 64
+#define _SC_ADVISORY_INFO 65
+#define _SC_BARRIERS 66
+#define _SC_CLOCK_SELECTION 67
+#define _SC_CPUTIME 68
+#define _SC_FILE_LOCKING 69
+#define _SC_GETGR_R_SIZE_MAX 70
+#define _SC_GETPW_R_SIZE_MAX 71
+#define _SC_HOST_NAME_MAX 72
+#define _SC_LOGIN_NAME_MAX 73
+#define _SC_MONOTONIC_CLOCK 74
+#define _SC_MQ_PRIO_MAX 75
+#define _SC_READER_WRITER_LOCKS 76
+#define _SC_REGEXP 77
+#define _SC_SHELL 78
+#define _SC_SPAWN 79
+#define _SC_SPIN_LOCKS 80
+#define _SC_SPORADIC_SERVER 81
+#define _SC_THREAD_ATTR_STACKADDR 82
+#define _SC_THREAD_ATTR_STACKSIZE 83
+#define _SC_THREAD_CPUTIME 84
+#define _SC_THREAD_DESTRUCTOR_ITERATIONS 85
+#define _SC_THREAD_KEYS_MAX 86
+#define _SC_THREAD_PRIO_INHERIT 87
+#define _SC_THREAD_PRIO_PROTECT 88
+#define _SC_THREAD_PRIORITY_SCHEDULING 89
+#define _SC_THREAD_PROCESS_SHARED 90
+#define _SC_THREAD_SAFE_FUNCTIONS 91
+#define _SC_THREAD_SPORADIC_SERVER 92
+#define _SC_THREAD_STACK_MIN 93
+#define _SC_THREAD_THREADS_MAX 94
+#define _SC_TIMEOUTS 95
+#define _SC_THREADS 96
+#define _SC_TRACE 97
+#define _SC_TRACE_EVENT_FILTER 98
+#define _SC_TRACE_INHERIT 99
+#define _SC_TRACE_LOG 100
+#define _SC_TTY_NAME_MAX 101
+#define _SC_TYPED_MEMORY_OBJECTS 102
+#define _SC_V6_ILP32_OFF32 103
+#define _SC_V6_ILP32_OFFBIG 104
+#define _SC_V6_LP64_OFF64 105
+#define _SC_V6_LPBIG_OFFBIG 106
+#define _SC_IPV6 118
+#define _SC_RAW_SOCKETS 119
+#define _SC_SYMLOOP_MAX 120
+#define _SC_ATEXIT_MAX 107
+#define _SC_IOV_MAX 56
+#define _SC_PAGE_SIZE _SC_PAGESIZE
+#define _SC_XOPEN_CRYPT 108
+#define _SC_XOPEN_ENH_I18N 109
+#define _SC_XOPEN_LEGACY 110
+#define _SC_XOPEN_REALTIME 111
+#define _SC_XOPEN_REALTIME_THREADS 112
+#define _SC_XOPEN_SHM 113
+#define _SC_XOPEN_STREAMS (-1) /* 114 - Not supported */
+#define _SC_XOPEN_UNIX 115
+#define _SC_XOPEN_VERSION 116
+#define _SC_XOPEN_XCU_VERSION 121
+#define _SC_XBS5_ILP32_OFF32 122
+#define _SC_XBS5_ILP32_OFFBIG 123
+#define _SC_XBS5_LP64_OFF64 124
+#define _SC_XBS5_LPBIG_OFFBIG 125
+
+#ifndef _CS_PATH /* XXX temporary #ifdef'ed for <sys/unistd.h> */
+#define _CS_PATH 1
+#endif
+#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS 2
+#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS 3
+#define _CS_POSIX_V6_ILP32_OFF32_LIBS 4
+#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS 5
+#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS 6
+#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS 7
+#define _CS_POSIX_V6_LP64_OFF64_CFLAGS 8
+#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS 9
+#define _CS_POSIX_V6_LP64_OFF64_LIBS 10
+#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS 11
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS 12
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS 13
+#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 14
+
+/* reserved for compatibility with Issue 5 */
+#define _CS_XBS5_ILP32_OFF32_CFLAGS 20
+#define _CS_XBS5_ILP32_OFF32_LDFLAGS 21
+#define _CS_XBS5_ILP32_OFF32_LIBS 22
+#define _CS_XBS5_ILP32_OFF32_LINTFLAGS 23
+#define _CS_XBS5_ILP32_OFFBIG_CFLAGS 24
+#define _CS_XBS5_ILP32_OFFBIG_LDFLAGS 25
+#define _CS_XBS5_ILP32_OFFBIG_LIBS 26
+#define _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 27
+#define _CS_XBS5_LP64_OFF64_CFLAGS 28
+#define _CS_XBS5_LP64_OFF64_LDFLAGS 29
+#define _CS_XBS5_LP64_OFF64_LIBS 30
+#define _CS_XBS5_LP64_OFF64_LINTFLAGS 31
+#define _CS_XBS5_LPBIG_OFFBIG_CFLAGS 32
+#define _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 33
+#define _CS_XBS5_LPBIG_OFFBIG_LIBS 34
+#define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 35
+
__BEGIN_DECLS
pid_t getppid(void);
uid_t getuid(void);
int isatty(int);
+int lchown(const char *, uid_t, gid_t);
int link(const char *, const char *);
off_t lseek(int, off_t, int);
long pathconf(const char *, int);
char *brk(const char *);
int chroot(const char *);
char *crypt(const char *, const char *);
-int des_cipher(const char *, char *, long, int);
-int des_setkey(const char *key);
-int encrypt(char *, int);
+void encrypt(char *, int);
void endusershell(void);
int fchdir(int);
int fchown(int, int, int);
mode_t getmode(const void *, mode_t);
int getpagesize(void) __pure2;
char *getpass(const char *);
+int getpeereid(int, uid_t *, gid_t *);
int getpgid(pid_t _pid);
int getsid(pid_t _pid);
char *getusershell(void);
int setgroups(int, const gid_t *);
void sethostid(long);
int sethostname(const char *, int);
-int setkey(const char *);
+void setkey(const char *);
int setlogin(const char *);
void *setmode(const char *);
int setpgrp(pid_t pid, pid_t pgrp); /* obsoleted by setpgid() */
int getsubopt(char **, char * const *, char **);
/* HFS & HFS Plus semantics system calls go here */
+#ifdef __LP64__
+int getattrlist(const char*,void*,void*,size_t,unsigned int);
+int setattrlist(const char*,void*,void*,size_t,unsigned int);
+int exchangedata(const char*,const char*,unsigned int);
+int checkuseraccess(const char*,uid_t,gid_t*,int,int,unsigned int);
+int getdirentriesattr(int,void*,void*,size_t,unsigned int*,unsigned int*,unsigned int*,unsigned int);
+int searchfs(const char*,void*,void*,unsigned int,unsigned int,void*);
+
+int fsctl(const char *,unsigned int,void*,unsigned int);
+#else /* __LP64__ */
int getattrlist(const char*,void*,void*,size_t,unsigned long);
int setattrlist(const char*,void*,void*,size_t,unsigned long);
int exchangedata(const char*,const char*,unsigned long);
int searchfs(const char*,void*,void*,unsigned long,unsigned long,void*);
int fsctl(const char *,unsigned long,void*,unsigned long);
-
+#endif /* __LP64__ */
#endif /* !_POSIX_SOURCE */
__END_DECLS
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*-
* Copyright (c)1999 Citrus Project,
* All rights reserved.
#define _WCHAR_H_
#include <sys/cdefs.h>
-#include <sys/types.h>
+#include <_types.h>
#include <stdarg.h>
+#include <stdio.h>
+#include <time.h>
#ifndef NULL
-#define NULL 0
-#endif
+#define NULL __OSX_NULL
+#endif /* ! NULL */
#ifndef _BSD_SIZE_T_DEFINED_
#define _BSD_SIZE_T_DEFINED_
-typedef _BSD_SIZE_T_ size_t;
+typedef __osx_size_t size_t;
#endif
#ifndef _BSD_MBSTATE_T_DEFINED_
#define _BSD_MBSTATE_T_DEFINED_
-typedef _BSD_MBSTATE_T_ mbstate_t;
+typedef __osx_mbstate_t mbstate_t;
#endif
#ifndef _BSD_CT_RUNE_T_DEFINED_
#define _BSD_CT_RUNE_T_DEFINED_
-typedef _BSD_CT_RUNE_T_ ct_rune_t;
+typedef __osx_ct_rune_t ct_rune_t;
#endif
#ifndef _BSD_RUNE_T_DEFINED_
#define _BSD_RUNE_T_DEFINED_
-typedef _BSD_RUNE_T_ rune_t;
+typedef __osx_rune_t rune_t;
#endif
#ifndef __cplusplus
#ifndef _BSD_WCHAR_T_DEFINED_
#define _BSD_WCHAR_T_DEFINED_
-#ifdef __WCHAR_TYPE__
-typedef __WCHAR_TYPE__ wchar_t;
-#else /* ! __WCHAR_TYPE__ */
-typedef _BSD_WCHAR_T_ wchar_t;
-#endif /* __WCHAR_TYPE__ */
+typedef __osx_wchar_t wchar_t;
#endif /* _BSD_WCHAR_T_DEFINED_ */
#endif /* __cplusplus */
+#ifndef _WCTYPE_T_DEFINED_
+#define _WCTYPE_T_DEFINED_
+typedef __osx_wctype_t wctype_t;
+#endif
+
#ifndef _BSD_WINT_T_DEFINED_
#define _BSD_WINT_T_DEFINED_
-typedef _BSD_WINT_T_ wint_t;
+typedef __osx_wint_t wint_t;
#endif
#ifndef WEOF
-#define WEOF ((wint_t)-1)
+#define WEOF __OSX_WEOF
#endif
#ifndef WCHAR_MIN
-#define WCHAR_MIN 0
+#define WCHAR_MIN __OSX_WCHAR_MIN
#endif
#ifndef WCHAR_MAX
-#ifdef __WCHAR_MAX__
-#define WCHAR_MAX __WCHAR_MAX__
-#else /* ! __WCHAR_MAX__ */
-#define WCHAR_MAX 0x7fffffff
-#endif /* __WCHAR_MAX__ */
+#define WCHAR_MAX __OSX_WCHAR_MAX
#endif
-struct __sFILE;
-struct tm;
-
__BEGIN_DECLS
wint_t btowc(int);
-wint_t fgetwc(struct __sFILE *);
-wchar_t *fgetws(wchar_t * __restrict, int, struct __sFILE * __restrict);
-wint_t fputwc(wchar_t, struct __sFILE *);
-int fputws(const wchar_t * __restrict, struct __sFILE * __restrict);
-int fwide(struct __sFILE *, int);
-int fwprintf(struct __sFILE * __restrict, const wchar_t * __restrict, ...);
-int fwscanf(struct __sFILE * __restrict, const wchar_t * __restrict, ...);
-wint_t getwc(struct __sFILE *);
+wint_t fgetwc(FILE *);
+wchar_t *fgetws(wchar_t * __restrict, int, FILE * __restrict);
+wint_t fputwc(wchar_t, FILE *);
+int fputws(const wchar_t * __restrict, FILE * __restrict);
+int fwide(FILE *, int);
+int fwprintf(FILE * __restrict, const wchar_t * __restrict, ...);
+int fwscanf(FILE * __restrict, const wchar_t * __restrict, ...);
+wint_t getwc(FILE *);
wint_t getwchar(void);
+int iswalnum(wint_t);
+int iswalpha(wint_t);
+int iswcntrl(wint_t);
+int iswctype(wint_t, wctype_t);
+int iswdigit(wint_t);
+int iswgraph(wint_t);
+int iswlower(wint_t);
+int iswprint(wint_t);
+int iswpunct(wint_t);
+int iswspace(wint_t);
+int iswupper(wint_t);
+int iswxdigit(wint_t);
size_t mbrlen(const char * __restrict, size_t, mbstate_t * __restrict);
size_t mbrtowc(wchar_t * __restrict, const char * __restrict, size_t,
mbstate_t * __restrict);
int mbsinit(const mbstate_t *);
size_t mbsrtowcs(wchar_t * __restrict, const char ** __restrict, size_t,
mbstate_t * __restrict);
-wint_t putwc(wchar_t, struct __sFILE *);
+wint_t putwc(wchar_t, FILE *);
wint_t putwchar(wchar_t);
int swprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict,
...);
int swscanf(const wchar_t * __restrict, const wchar_t * __restrict, ...);
-wint_t ungetwc(wint_t, struct __sFILE *);
-int vfwprintf(struct __sFILE * __restrict, const wchar_t * __restrict,
+wint_t towlower(wint_t);
+wint_t towupper(wint_t);
+wint_t ungetwc(wint_t, FILE *);
+int vfwprintf(FILE * __restrict, const wchar_t * __restrict,
_BSD_VA_LIST_);
int vswprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict,
_BSD_VA_LIST_);
long wcstol(const wchar_t * __restrict, wchar_t ** __restrict, int);
unsigned long
wcstoul(const wchar_t * __restrict, wchar_t ** __restrict, int);
+wctype_t
+ wctype(const char *);
wchar_t *wmemchr(const wchar_t *, wchar_t, size_t);
int wmemcmp(const wchar_t *, const wchar_t *, size_t);
wchar_t *wmemcpy(wchar_t * __restrict, const wchar_t * __restrict, size_t);
int wscanf(const wchar_t * __restrict, ...);
#if !defined(_ANSI_SOURCE)
-int vfwscanf(struct __sFILE * __restrict, const wchar_t * __restrict,
+int vfwscanf(FILE * __restrict, const wchar_t * __restrict,
_BSD_VA_LIST_);
int vswscanf(const wchar_t * __restrict, const wchar_t * __restrict,
_BSD_VA_LIST_);
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
/*-
* Copyright (c)1999 Citrus Project,
* All rights reserved.
#define _WCTYPE_H_
#include <sys/cdefs.h>
-#include <sys/types.h>
-
+#include <_types.h>
#include <ctype.h>
#ifndef _BSD_CT_RUNE_T_DEFINED_
#define _BSD_CT_RUNE_T_DEFINED_
-typedef _BSD_CT_RUNE_T_ ct_rune_t;
+typedef __osx_ct_rune_t ct_rune_t;
#endif
#ifndef _BSD_RUNE_T_DEFINED_
#define _BSD_RUNE_T_DEFINED_
-typedef _BSD_RUNE_T_ rune_t;
+typedef __osx_rune_t rune_t;
#endif
#ifndef __cplusplus
#ifndef _BSD_WCHAR_T_DEFINED_
#define _BSD_WCHAR_T_DEFINED_
-#ifdef __WCHAR_TYPE__
-typedef __WCHAR_TYPE__ wchar_t;
-#else /* ! __WCHAR_TYPE__ */
-typedef _BSD_WCHAR_T_ wchar_t;
-#endif /* __WCHAR_TYPE__ */
+typedef __osx_wchar_t wchar_t;
#endif /* _BSD_WCHAR_T_DEFINED_ */
#endif /* __cplusplus */
#ifndef _BSD_WINT_T_DEFINED_
#define _BSD_WINT_T_DEFINED_
-typedef _BSD_WINT_T_ wint_t;
+typedef __osx_wint_t wint_t;
#endif
-#ifndef _WCTRANS_T
-typedef int wctrans_t;
-#define _WCTRANS_T
+#ifndef _WCTRANS_T_DEFINED_
+#define _WCTRANS_T_DEFINED_
+typedef __osx_wctrans_t wctrans_t;
#endif
-#ifndef _WCTYPE_T
-typedef unsigned long wctype_t;
-#define _WCTYPE_T
+#ifndef _WCTYPE_T_DEFINED_
+#define _WCTYPE_T_DEFINED_
+typedef __osx_wctype_t wctype_t;
#endif
#ifndef WEOF
-#define WEOF ((wint_t)-1)
+#define WEOF __OSX_WEOF
#endif
__BEGIN_DECLS
--- /dev/null
+/*
+ * Copyright 1994, University Corporation for Atmospheric Research
+ * See ../COPYRIGHT file for copying and redistribution conditions.
+ */
+/*
+ * Reproduction of ../COPYRIGHT file:
+ *
+ *********************************************************************
+
+Copyright 1995-2002 University Corporation for Atmospheric Research/Unidata
+
+Portions of this software were developed by the Unidata Program at the
+University Corporation for Atmospheric Research.
+
+Access and use of this software shall impose the following obligations
+and understandings on the user. The user is granted the right, without
+any fee or cost, to use, copy, modify, alter, enhance and distribute
+this software, and any derivative works thereof, and its supporting
+documentation for any purpose whatsoever, provided that this entire
+notice appears in all copies of the software, derivative works and
+supporting documentation. Further, UCAR requests that the user credit
+UCAR/Unidata in any publications that result from the use of this
+software or in any product that includes this software. The names UCAR
+and/or Unidata, however, may not be used in any advertising or publicity
+to endorse or promote any products or commercial entity unless specific
+written permission is obtained from UCAR/Unidata. The user also
+understands that UCAR/Unidata is not obligated to provide the user with
+any support, consulting, training or assistance of any kind with regard
+to the use, operation and performance of this software nor to provide
+the user with any updates, revisions, new versions or "bug fixes."
+
+THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "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 UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
+INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ *********************************************************************
+ *
+ */
+
+/* $Id: wordexp.h,v 1.2 2004/04/15 23:35:49 emoy Exp $ */
+#ifndef _WORDEXP_H
+#define _WORDEXP_H
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+#ifndef _BSD_SIZE_T_DEFINED_
+#define _BSD_SIZE_T_DEFINED_
+typedef __size_t size_t;
+#endif
+
+typedef struct {
+ size_t we_wordc;
+ char **we_wordv;
+ size_t we_offs;
+} wordexp_t;
+
+/* wordexp() flags Argument */
+#define WRDE_APPEND 0x01
+#define WRDE_DOOFFS 0x02
+#define WRDE_NOCMD 0x04
+#define WRDE_REUSE 0x08
+#define WRDE_SHOWERR 0x10
+#define WRDE_UNDEF 0x20
+
+/*
+ * wordexp() Return Values
+ */
+/* required */
+#define WRDE_BADCHAR 1
+#define WRDE_BADVAL 2
+#define WRDE_CMDSUB 3
+#define WRDE_NOSPACE 4
+#define WRDE_NOYS 5
+#define WRDE_SYNTAX 6
+
+
+__BEGIN_DECLS
+int wordexp(const char *words, wordexp_t *pwordexp, int flags);
+void wordfree(wordexp_t *pwordexp);
+__END_DECLS
+
+#endif /* _WORDEXP_H */
.PATH: ${.CURDIR}/${MACHINE_ARCH}/internat ${.CURDIR}/internat
-SRCS += NXCType.c NXIsCntrl.c NXIsPrint.c NXIsXDigit.c _NXToLower.c \
+MISRCS += NXCType.c NXIsCntrl.c NXIsPrint.c NXIsXDigit.c _NXToLower.c \
NXIsAlNum.c NXIsDigit.c NXIsPunct.c NXToAscii.c _NXToUpper.c \
NXIsAlpha.c NXIsGraph.c NXIsSpace.c NXToLower.c \
NXIsAscii.c NXIsLower.c NXIsUpper.c NXToUpper.c
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
.PATH: ${.CURDIR}/${MACHINE_ARCH}/locale ${.CURDIR}/locale
.include "Makefile.fbsd_begin"
-FBSDSRCS= big5.c btowc.c collate.c collcmp.c euc.c fix_grouping.c frune.c \
+FBSDMISRCS= big5.c btowc.c collate.c collcmp.c euc.c fix_grouping.c frune.c \
isctype.c iswctype.c \
ldpart.c lmessages.c lmonetary.c lnumeric.c localeconv.c mblen.c \
mbrlen.c \
wcstombs.c \
wcstoul.c wcstoull.c wcstoumax.c wctob.c wctomb.c wctrans.c wctype.c \
wcwidth.c
-FBSDORIGHDRS= collate.h ldpart.h lmessages.h lmonetary.h lnumeric.h setlocale.h
+FBSDHDRS= collate.h ldpart.h lmessages.h lmonetary.h lnumeric.h setlocale.h
.include "Makefile.fbsd_end"
# Begin hack for 3333969
-CFLAGS += -D__APPLE_PR_3333969_HACK__
-
-SRCS += lconv.c
+MISRCS += lconv.c
+CFLAGS-lconv.c += -D__APPLE_PR_3333969_HACK__
# End hack for 3333969
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-.PATH: ${.CURDIR}/${MACHINE_ARCH}/mach ${.CURDIR}/mach
-
-.include "${.CURDIR}/mach/headers/Makefile.inc"
-.include "${.CURDIR}/mach/servers/Makefile.inc"
-
-# machine-dependent mach sources
+# machine-dependent mach sources
.if exists(${.CURDIR}/${MACHINE_ARCH}/mach/Makefile.inc)
.include "${.CURDIR}/${MACHINE_ARCH}/mach/Makefile.inc"
.endif
+.PATH: ${.CURDIR}/mach
+
+.include "${.CURDIR}/mach/headers/Makefile.inc"
+.include "${.CURDIR}/mach/servers/Makefile.inc"
+
MD_MIGDEFS += task.defs \
thread_act.defs
lock_set.defs \
mach_port.defs \
mach_host.defs \
+ mach_vm.defs \
processor.defs \
processor_set.defs \
vm_map.defs
# These files are generated from the .defs files
MIGSRCS = ${MIGDEFS:.defs=User.c} ${MD_MIGDEFS:.defs=User.c}
-SRCS += ${MIGSRCS} \
+MISRCS += ${MIGSRCS} \
bootstrap_ports.c \
clock_sleep.c \
error_codes.c \
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*/
extern vm_size_t vm_page_size;
+extern vm_size_t vm_page_mask;
+extern int vm_page_shift;
#define trunc_page(x) ((x) & (~(vm_page_size - 1)))
#define round_page(x) trunc_page((x) + (vm_page_size - 1))
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <mach/i386/task.h>
#elif defined(__ppc__)
#include <mach/ppc/task.h>
+#elif defined(__ppc64__)
+#include <mach/ppc64/task.h>
#else
#error unknown architecture
#endif
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <mach/i386/thread_act.h>
#elif defined(__ppc__)
#include <mach/ppc/thread_act.h>
+#elif defined(__ppc64__)
+#include <mach/ppc64/thread_act.h>
#else
#error unknown architecture
#endif
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
__private_extern__ kern_return_t _host_mach_msg_trap_return_;
vm_size_t vm_page_size;
+vm_size_t vm_page_mask;
+int vm_page_shift;
/*
* Forward internal declarations for automatic mach_init during
* Cache some other valuable system constants
*/
+#if defined(__ppc64__) /* NGK hack for now */
+ vm_page_size = 4096;
+#else
(void)host_page_size(host, &vm_page_size);
+#endif
+ vm_page_mask = vm_page_size - 1;
+ if (vm_page_size == 0) {
+ /* guard against unlikely craziness */
+ vm_page_shift = 0;
+ } else {
+ /*
+ * Unfortunately there's no kernel interface to get the
+ * vm_page_shift, but it's easy enough to calculate.
+ */
+ for (vm_page_shift = 0;
+ (vm_page_size & (1 << vm_page_shift)) == 0;
+ vm_page_shift++)
+ continue;
+ }
mach_port_deallocate(mach_task_self_, host);
/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
if (kr != KERN_SUCCESS)
return;
- kr = mach_ports_lookup(mach_task_self(), &ports,
- &ports_count);
- if ((kr != KERN_SUCCESS) ||
- (ports_count < MACH_PORTS_SLOTS_USED))
- return;
-
- name_server_port = ports[NAME_SERVER_SLOT];
- environment_port = ports[ENVIRONMENT_SLOT];
- service_port = ports[SERVICE_SLOT];
-
- /* get rid of out-of-line data so brk has a chance of working */
-
- (void) vm_deallocate(mach_task_self(),
- (vm_offset_t) ports,
- (vm_size_t) (ports_count * sizeof *ports));
-
/* Get the clock service port for nanosleep */
host = mach_host_self();
kr = host_get_clock_service(host, SYSTEM_CLOCK, &clock_port);
if (kr != KERN_SUCCESS) {
abort();
}
+
+ /*
+ * Find the options service ports.
+ * XXX - Don't need these on Darwin, should go away.
+ */
+ kr = mach_ports_lookup(mach_task_self(), &ports,
+ &ports_count);
+ if (kr == KERN_SUCCESS) {
+ if (ports_count >= MACH_PORTS_SLOTS_USED) {
+ name_server_port = ports[NAME_SERVER_SLOT];
+ environment_port = ports[ENVIRONMENT_SLOT];
+ service_port = ports[SERVICE_SLOT];
+ }
+
+ /* get rid of out-of-line data */
+ (void) vm_deallocate(mach_task_self(),
+ (vm_offset_t) ports,
+ (vm_size_t) (ports_count * sizeof *ports));
+ }
}
#ifdef notdef
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include <mach/mach_vm.defs>
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
SRVHDRS := ${SRVHDRS:S/^/${.CURDIR}\/mach\/servers\//}
SRVHDRS += ${SRVMIGHDRS}
-SRCS+= ${SRVMIGDEFS:S/.defs$/User.defs/}
+MISRCS+= ${SRVMIGDEFS:S/.defs$/User.defs/}
CLEANFILES += ${SRVMIGHDRS} ${SRVMIGHDRS:S/.h$/User.c/} \
${SRVMIGHDRS:S/.h$/Server.c/}
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_END@
*/
+#if defined(__LP64__)
+/*
+ * In an LP64 environment, the traditional Mach VM interface names are
+ * really just a second instance of the "wide" Mach VM interfaces.
+ *
+ * The _MACH_VM_PUBLISH_AS_LOCAL_ flag triggers mach_vm.defs to export
+ * the local names instead.
+ */
+#define _MACH_VM_PUBLISH_AS_LOCAL_
+#include <mach/mach_vm.defs>
+#else
#include <mach/vm_map.defs>
+#endif
.PATH: ${.CURDIR}/${MACHINE_ARCH}/net ${.CURDIR}/net
.include "Makefile.fbsd_begin"
-FBSDSRCS= addr2ascii.c ascii2addr.c inet_addr.c inet_lnaof.c \
+FBSDMISRCS= addr2ascii.c ascii2addr.c inet_addr.c inet_lnaof.c \
inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \
inet_netof.c inet_network.c inet_ntoa.c linkaddr.c nsap_addr.c \
recv.c send.c
.include "Makefile.fbsd_end"
-CFLAGS+=-DINET6 -I${.OBJDIR}
+CFLAGS+= -I${.OBJDIR}
# machine-dependent net sources
.if exists(${.CURDIR}/${MACHINE_ARCH}/net/Makefile.inc)
.PATH: ${.CURDIR}/nls
.include "Makefile.fbsd_begin"
-FBSDSRCS= msgcat.c
-FBSDORIGHDRS= msgcat.h
+FBSDMISRCS= msgcat.c
+FBSDHDRS= msgcat.h
.include "Makefile.fbsd_end"
# Install msgcat.h for usage by gencat (in adv_cmds)
-LOCALHDRS+= msgcat.h
+LOCALHDRS+= ${SYMROOT}/msgcat.h
.if ${LIB} == "c"
.include "Makefile.fbsd_begin"
.PATH: ${.CURDIR}/../libc/posix1e
-SRCS+= acl_calc_mask.c \
+MISRCS+= acl_calc_mask.c \
acl_copy.c \
acl_delete.c \
acl_delete_entry.c \
+.PATH: ${.CURDIR}/ppc/gen
+
MDSRCS += \
abs.s \
- bcopy.s \
- bzero.s \
ecvt.c \
ffs.s \
fp.h \
icacheinval.s \
- isinf.c \
mcount.s \
setjmperr.c
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-#undef __APPLE_API_PRIVATE
-
- // These functions have migrated to the comm page.
-
- .text
- .globl _bcopy
- .globl _memcpy
- .globl _memmove
-
- .align 5
-_bcopy: // void bcopy(const void *src, void *dst, size_t len)
- ba _COMM_PAGE_BCOPY
-
- .align 5
-_memcpy: // void* memcpy(void *dst, void *src, size_t len)
-_memmove: // void* memmove(void *dst, const void *src, size_t len)
- ba _COMM_PAGE_MEMCPY
-
+++ /dev/null
-/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-//
-// =============================
-// BZERO and MEMSET FOR Mac OS X
-// =============================
-//
-// We use DCBZ, and therefore are dependent on the cache block size (32.)
-// Bzero and memset need to be in the same file since they are tightly
-// coupled, so we can use bzero for memset of 0 without incurring extra
-// overhead. (The issue is that bzero must preserve r3 for memset.)
-//
-// Registers we use:
-// r3 = original ptr, not changed since memset returns it
-// r4 = count of bytes to set ("rc")
-// r11 = working operand ptr ("rp")
-// r10 = value to set ("rv")
-
-#define rc r4
-#define rp r11
-#define rv r10
-
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-
-#include <architecture/ppc/asm_help.h>
-
- .text
- .align 5
- .globl _bzero
- .globl _memset
-
-// *************
-// * B Z E R O *
-// *************
-
-_bzero: // void bzero(void *b, size_t len);
- ba _COMM_PAGE_BZERO
-
- // store up to 31 trailing bytes
- // rv = value to store (in all 4 bytes)
- // rc = #bytes to store (0..31)
-Ltail:
- andi. r5,rc,16 // bit 27 set in length?
- mtcrf 0x01,rc // low 4 bits of length to cr7
- beq 1f // test bits of length
- stw rv,0(rp)
- stw rv,4(rp)
- stw rv,8(rp)
- stw rv,12(rp)
- addi rp,rp,16
-1:
- bf 28,2f
- stw rv,0(rp)
- stw rv,4(rp)
- addi rp,rp,8
-2:
- bf 29,3f
- stw rv,0(rp)
- addi rp,rp,4
-3:
- bf 30,4f
- sth rv,0(rp)
- addi rp,rp,2
-4:
- bflr 31
- stb rv,0(rp)
- blr
-
-
-// ***************
-// * M E M S E T *
-// ***************
-
- .align 5
-_memset: // void * memset(void *b, int c, size_t len);
- andi. rv,r4,0xFF // copy value to working register, test for 0
- mr rc,r5 // move length to working register
- cmplwi cr1,r5,32 // length < 32 ?
- beqa++ _COMM_PAGE_BZERO
- rlwimi rv,rv,8,16,23 // replicate value to low 2 bytes
- mr rp,r3 // make working copy of operand ptr
- rlwimi rv,rv,16,0,15 // value now in all 4 bytes
- blt cr1,Ltail // length<32, so use common tail routine
- neg r5,rp // start to compute #bytes to align
- andi. r6,r5,0x7 // r6 <- #bytes to align on dw
- beq- Lmemset1 // already aligned
-
- ; align on 8-byte boundary
-
- mtcrf 0x01,r6 // move count to cr7 (faster if only 1 cr)
- sub rc,rc,r6 // adjust length
- bf 31,1f
- stb rv,0(rp)
- addi rp,rp,1
-1:
- bf 30,2f
- sth rv,0(rp)
- addi rp,rp,2
-2:
- bf 29,Lmemset1
- stw rv,0(rp)
- addi rp,rp,4
-
- // loop on 16-byte blocks
-Lmemset1:
- stw rv,0(rp) // store first 8 bytes from rv
- stw rv,4(rp)
- srwi r5,rc,4 // r5 <- #blocks (>=1)
- mtcrf 0x01,rc // leftover length to cr7
- mtctr r5 // set up loop count
- lfd f0,0(rp) // pick up in a fp register
- b 2f // enter loop in middle
- .align 4
-1: // loop on 16-byte blocks
- stfd f0,0(rp)
-2:
- stfd f0,8(rp)
- addi rp,rp,16
- bdnz 1b
-
- // store up to 16 trailing bytes (count in cr7)
-
- bf 28,3f
- stfd f0,0(rp)
- addi rp,rp,8
-3:
- bf 29,4f
- stw rv,0(rp)
- addi rp,rp,4
-4:
- bf 30,5f
- sth rv,0(rp)
- addi rp,rp,2
-5:
- bflr 31
- stb rv,0(rp)
- blr
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/* Copyright (c) 1992, 1997 NeXT Software, Inc. All rights reserved.
- *
- * File: libc/gen/ppc/isinf.c
- * Author: Derek B Clegg, NeXT Software, Inc.
- *
- * HISTORY
-* 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com)
-* Ported to PPC.
- * 11-Nov-92 Derek B Clegg (dclegg@next.com)
- * Created.
- *
- * int isinf(double value);
- *
- * Returns 1 if `value' is equal to positive IEEE infinity, -1 if `value'
- * is equal to negative IEEE infinity, 0 otherwise.
- *
- * An IEEE infinity is a double value with the maximum biased exponent value
- * (2047) and a zero fraction value.
- */
-#import "fp.h"
-
-int
-isinf(double value)
-{
- union dbl d;
-
- d.value = value;
- if (d.u[0] == 0x7FF00000 && d.u[1] == 0)
- return 1;
- if (d.u[0] == 0xFFF00000 && d.u[1] == 0)
- return -1;
- return 0;
-}
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
**
*/
-#include <architecture/ppc/asm_help.h>
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
- .text
- .align 2
- .globl mcount
-mcount:
- mflr r0
- stw r0,8(r1)
- stwu r1,-64(r1)
- mflr r4
- CALL_EXTERN(_moncount)
- addi r1,r1,64
- lwz r0,8(r1)
- mtlr r0
+MI_ENTRY_POINT(mcount)
+ mflr r0
+ stg r0,SF_RETURN(r1)
+ stgu r1,-SF_MINSIZE(r1)
+ mr r4,r0 /* pass our return address as 2nd argument */
+ MI_CALL_EXTERNAL(_moncount)
+ addi r1,r1,SF_MINSIZE
+ lg r0,SF_RETURN(r1)
+ mtlr r0
blr
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-SRCS += mach_absolute_time.s
+.PATH: ${.CURDIR}/ppc/mach
+MDSRCS += mach_absolute_time.s
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
+.PATH: ${.CURDIR}/ppc/pthreads
MDSRCS += \
init_cpu_capabilities.c \
get_cpu_capabilities.s \
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#
# PPC-optimised string functions.
#
+.PATH: ${.CURDIR}/ppc/string
+
MDSRCS += \
+ bcopy.s \
+ bzero.s \
memcmp.s \
strcat.s \
strcmp.s \
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+ // These functions have migrated to the comm page.
+
+ .text
+ .globl _bcopy
+ .globl _memcpy
+ .globl _memmove
+
+ .align 5
+_bcopy: // void bcopy(const void *src, void *dst, size_t len)
+ ba _COMM_PAGE_BCOPY
+
+ .align 5
+_memcpy: // void* memcpy(void *dst, void *src, size_t len)
+_memmove: // void* memmove(void *dst, const void *src, size_t len)
+ ba _COMM_PAGE_MEMCPY
+
--- /dev/null
+/*
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+
+ .text
+ .align 5
+ .globl _bzero
+ .globl _memset
+
+// *************
+// * B Z E R O *
+// *************
+//
+// This function has migrated to the commpage.
+
+_bzero: // void bzero(void *b, size_t len);
+ ba _COMM_PAGE_BZERO
+
+
+// ***************
+// * M E M S E T *
+// ***************
+// Registers we use:
+// r3 = original ptr, not changed since memset returns it
+// r4 = count of bytes to set ("rc")
+// r11 = working operand ptr ("rp")
+// r10 = value to set ("rv")
+
+#define rc r4
+#define rp r11
+#define rv r10
+
+ .align 5
+_memset: // void * memset(void *b, int c, size_t len);
+ andi. rv,r4,0xFF // copy value to working register, test for 0
+ mr rc,r5 // move length to working register
+ cmplgi cr1,r5,32 // length < 32 ?
+ beqa++ _COMM_PAGE_BZERO
+ rlwimi rv,rv,8,16,23 // replicate value to low 2 bytes
+ mr rp,r3 // make working copy of operand ptr
+ rlwimi rv,rv,16,0,15 // value now in all 4 bytes
+ blt cr1,Ltail // length<32, so use common tail routine
+ neg r5,rp // start to compute #bytes to align
+ andi. r6,r5,0x7 // r6 <- #bytes to align on dw
+ beq Lmemset1 // already aligned
+
+ ; align on 8-byte boundary
+
+ mtcrf 0x01,r6 // move count to cr7
+ sub rc,rc,r6 // adjust length
+ bf 31,1f
+ stb rv,0(rp)
+ addi rp,rp,1
+1:
+ bf 30,2f
+ sth rv,0(rp)
+ addi rp,rp,2
+2:
+ bf 29,Lmemset1
+ stw rv,0(rp)
+ addi rp,rp,4
+
+ // loop on 16-byte blocks
+Lmemset1:
+ stw rv,0(rp) // store first 8 bytes from rv
+ stw rv,4(rp)
+ srgi r5,rc,4 // r5 <- #blocks (>=1)
+ mtcrf 0x01,rc // leftover length to cr7
+ mtctr r5 // set up loop count
+ lfd f0,0(rp) // pick up in a fp register
+ b 2f // enter loop in middle
+ .align 4
+1: // loop on 16-byte blocks
+ stfd f0,0(rp)
+2:
+ stfd f0,8(rp)
+ addi rp,rp,16
+ bdnz 1b
+
+ // store up to 16 trailing bytes (count in cr7)
+
+ bf 28,3f
+ stfd f0,0(rp)
+ addi rp,rp,8
+3:
+ bf 29,4f
+ stw rv,0(rp)
+ addi rp,rp,4
+4:
+ bf 30,5f
+ sth rv,0(rp)
+ addi rp,rp,2
+5:
+ bflr 31
+ stb rv,0(rp)
+ blr
+
+ // store up to 31 bytes from rv
+ // rv = value to store (in all 4 bytes)
+ // rc = #bytes to store (0..31)
+Ltail:
+ andi. r5,rc,16 // bit 27 set in length?
+ mtcrf 0x01,rc // low 4 bits of length to cr7
+ beq 1f // test bits of length
+ stw rv,0(rp)
+ stw rv,4(rp)
+ stw rv,8(rp)
+ stw rv,12(rp)
+ addi rp,rp,16
+1:
+ bf 28,2f
+ stw rv,0(rp)
+ stw rv,4(rp)
+ addi rp,rp,8
+2:
+ bf 29,3f
+ stw rv,0(rp)
+ addi rp,rp,4
+3:
+ bf 30,4f
+ sth rv,0(rp)
+ addi rp,rp,2
+4:
+ bflr 31
+ stb rv,0(rp)
+ blr
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <mach/ppc/asm.h>
#undef ASSEMBLER
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+
// *************** ***********
// * M E M C M P * and * B C M P *
// *************** ***********
// finding a difference, we might get a spurious page fault by
// reading bytes past the difference. To avoid this, we never do a "lwz"
// that crosses a page boundary.
+//
+// In 64-bit mode, this routine is doubleword parallel.
.text
.globl EXT(memcmp)
.globl EXT(bcmp)
.align 5
-LEXT(memcmp) // int memcmp(const char *s1,const char *s2,size_t len);
+LEXT(memcmp) // int memcmp(const char *s1,const char *s2,size_t len);
LEXT(bcmp) // int bcmp(const char *s1,const char *s2,size_t len);
- cmplwi cr1,r5,8 // is buffer too short to bother with word compares?
- andi. r0,r3,3 // is LHS word aligned?
+ cmplgi cr1,r5,2*GPR_BYTES // is buffer too short to bother with parallel compares?
+ andi. r0,r3,GPR_BYTES-1 // is LHS aligned?
blt cr1,Lshort // short buffer, so just compare byte-by-byte
beq Laligned // skip if aligned
- subfic r0,r0,4 // r0 <- #bytes to word align LHS
+ subfic r0,r0,GPR_BYTES // r0 <- #bytes to align LHS
mtctr r0 // set up for byte loop
b Lbyteloop
// Handle short buffer or end-of-buffer.
// r3 = LHS ptr (unaligned)
// r4 = RHS ptr (unaligned)
-// r5 = length remaining in buffer (0..7)
+// r5 = length remaining in buffer (0..2*GPR_BYTES-1)
Lshort:
- cmpwi r5,0 // null buffer?
+ cmpgi r5,0 // null buffer?
mtctr r5 // assume not null, and set up for loop
- bne Lshortloop // buffer not null
+ bne Lshortloop // buffer not null
li r3,0 // say "equal"
blr
sub r3,r7,r8 // generate return value
blr
-// We're at a RHS page boundary. Compare 4 bytes in order to cross the
-// page but still keep the LHS ptr word-aligned.
+// We're at a RHS page boundary. Compare GPR_BYTES bytes in order to cross the
+// page but still keep the LHS ptr aligned.
Lcrosspage:
- cmplwi r5,8 // enough bytes left to use word compares?
- li r0,4 // get #bytes to cross RHS page
+ cmplgi r5,2*GPR_BYTES // enough bytes left to use parallel compares?
+ li r0,GPR_BYTES // get #bytes to cross RHS page
blt Lshort // buffer is about to end
- mtctr r0 // set up to compare 4 bytes
+ mtctr r0
b Lbyteloop
// Compare byte-by-byte.
cmpw r7,r8 // compare the bytes
bdnzt eq,Lbyteloop // loop if more to go and bytes are equal
- bne Ldifferent // done if we found differing bytes
+ bne Ldifferent // done if we found differing bytes
-// LHS is now word aligned. Loop over words until end of RHS page or buffer.
-// When we get to the end of the page, we compare 4 bytes, so that we keep
-// the LHS word aligned.
+// LHS is now aligned. Loop over words/doublewords until end of RHS page or buffer.
+// When we get to the end of the page, we compare 4/8 bytes, so that we keep
+// the LHS aligned.
// r3 = LHS ptr (aligned)
// r4 = RHS ptr (unaligned)
-// r5 = length remaining in buffer (>= 4 bytes)
+// r5 = length remaining in buffer (>= GPR_BYTES bytes)
Laligned:
rlwinm r9,r4,0,0xFFF // get RHS offset in page
subfe r8,r5,r5 // * r9 <- min(r0,r5),
and r7,r7,r8 // * using algorithm in Compiler Writer's Guide
add r9,r0,r7 // ***
- srwi. r8,r9,2 // get #words we can compare
- rlwinm r9,r9,0,0,29 // get #bytes we will compare word-parallel
+ srgi. r8,r9,LOG2_GPR_BYTES// get #words/doublewords we can compare
+ clrrgi r9,r9,LOG2_GPR_BYTES// get #bytes we will compare word-parallel
beq-- Lcrosspage // we're at a RHS page boundary
mtctr r8 // set up loop count
sub r5,r5,r9 // decrement length remaining
b Lwordloop
-// Compare a word at a time, until one of two conditions:
+// Compare a word or doubleword at a time, until one of two conditions:
// - a difference is found
// - end of count (ie, end of buffer or RHS page, whichever is first)
// At this point, registers are as follows:
// r3 = LHS ptr (aligned)
// r4 = RHS ptr (unaligned)
// r5 = length remaining in buffer (may be 0)
-// ctr = count of words until end of buffer or RHS page
+// ctr = count of word/doublewords until end of buffer or RHS page
- .align 5 // align inner loop, which is 8 words long
+ .align 5 // align inner loop
Lwordloop:
- lwz r7,0(r3) // r7 <- next 4 LHS bytes
- addi r3,r3,4
- lwz r8,0(r4) // r8 <- next 4 RHS bytes
- addi r4,r4,4
- xor. r11,r7,r8 // compare the words
+ lg r7,0(r3) // r7 <- next aligned LHS word or doubleword
+ addi r3,r3,GPR_BYTES
+ lg r8,0(r4) // r8 <- next unaligned RHS word or doubleword
+ addi r4,r4,GPR_BYTES
+ xor. r11,r7,r8 // compare them
bdnzt eq,Lwordloop // loop if ctr!=0 and cr0_eq
- beq-- Lcrosspage // skip if buffer or page end reached
+ beq Lcrosspage // skip if buffer or page end reached wo difference
// Found differing bytes.
- cntlzw r0,r11 // find 1st difference (r0 = 0..31)
- rlwinm r9,r0,0,0x18 // byte align bit offset (r9 = 0,8,16, or 24)
- addi r0,r9,8 // now, r0 = 8, 16, 24, or 32
+ cntlzg r0,r11 // find 1st difference (r0 = 0..31 or 63)
+ rlwinm r9,r0,0,0x38 // byte align bit offset (r9 = 0,8,16, or 24 etc)
+ addi r0,r9,8 // now, r0 = 8, 16, 24, or 32 etc
+#if defined(__ppc__)
rlwnm r7,r7,r0,24,31 // right justify differing bytes and mask off rest
rlwnm r8,r8,r0,24,31
+#else
+ rldcl r7,r7,r0,56 // right justify differing bytes and mask off rest
+ rldcl r8,r8,r0,56
+#endif
Ldifferent: // bytes in r7 and r8 differ
sub r3,r7,r8 // compute return value
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <mach/ppc/asm.h>
#undef ASSEMBLER
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+
// ***************
// * S T R C A T *
// ***************
// We optimize the move by doing it word parallel. This introduces
// a complication: if we blindly did word load/stores until finding
// a 0, we might get a spurious page fault by touching bytes past it.
-// To avoid this, we never do a "lwz" that crosses a page boundary,
+// To avoid this, we never do a load that crosses a page boundary,
// and never store a byte we don't have to.
//
// The test for 0s relies on the following inobvious but very efficient
// The test maps any non-zero byte to zero, and any zero byte to 0x80,
// with one exception: 0x01 bytes preceeding the first zero are also
// mapped to 0x80.
+//
+// In 64-bit mode, this algorithm is doubleword parallel.
.text
.globl EXT(strcat)
.align 5
-LEXT(strcat) // char* strcat(const char *s, const char *append);
- andi. r0,r3,3 // is dst aligned?
- dcbtst 0,r3 // touch in dst
- lis r6,hi16(0xFEFEFEFF) // start to load magic constants
+LEXT(strcat) // char* strcat(const char *s, const char *append);
+ clrrgi r9,r3,LOG2_GPR_BYTES// align pointer by zeroing right LOG2_GPR_BYTES bits
+ li r10,-1 // get 0xFFs
+ lg r8,0(r9) // get word or doubleword with 1st operand byte
+ rlwinm r11,r3,3,(GPR_BYTES-1)*8 // get starting bit position of operand
+#if defined(__ppc__)
+ lis r6,hi16(0xFEFEFEFF) // start to generate 32-bit magic constants
lis r7,hi16(0x80808080)
- dcbt 0,r4 // touch in source
+ srw r10,r10,r11 // create a mask of 0xFF bytes for operand in r8
ori r6,r6,lo16(0xFEFEFEFF)
ori r7,r7,lo16(0x80808080)
- mr r9,r3 // use r9 for dest ptr (must return r3 intact)
- beq Lword0loop // dest is aligned
- subfic r0,r0,4 // r0 <- #bytes to word align dest
- mtctr r0
-
-// Loop over bytes looking for 0-byte marking end of dest.
-// r4 = source ptr (unalaigned)
-// r6 = 0xFEFEFEFF
-// r7 = 0x80808080
-// r9 = dest ptr (unaligned)
-// ctr = byte count
-
-Lbyte0loop:
- lbz r8,0(r9) // r8 <- next dest byte
- addi r9,r9,1
- cmpwi r8,0 // test for 0
- bdnzf eq,Lbyte0loop // loop until (ctr==0) | (r8==0)
-
- bne Lword0loop // enter word loop if we haven't found the 0-byte
- subi r9,r9,1 // point to 0-byte
- b L0found // start to append the source
-
-// Loop over words looking for 0-byte marking end of dest.
-// r4 = source ptr (unalaigned)
+#else
+ ld r6,_COMM_PAGE_MAGIC_FE(0) // get 0xFEFEFEFE FEFEFEFF from commpage
+ ld r7,_COMM_PAGE_MAGIC_80(0) // get 0x80808080 80808080 from commpage
+ srd r10,r10,r11 // create a mask of 0xFF bytes for operand in r8
+#endif
+ orc r8,r8,r10 // make sure bytes preceeding operand are nonzero
+ b Lword0loopEnter
+
+// Loop over words or doublewords looking for 0-byte marking end of dest.
+// r4 = source ptr (unaligned)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
-// r9 = dest ptr (word aligned)
+// r9 = dest ptr (aligned)
.align 5 // align inner loops for speed
Lword0loop:
- lwz r8,0(r9) // r8 <- next dest word
- addi r9,r9,4
+ lgu r8,GPR_BYTES(r9) // r8 <- next dest word or doubleword
+Lword0loopEnter: // initial entry
add r10,r8,r6 // r10 <- word + 0xFEFEFEFF
andc r12,r7,r8 // r12 <- ~word & 0x80808080
and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte
beq Lword0loop // loop until 0 found
-
- slwi r0,r8,7 // move 0x01 bits (false hits) into 0x80 position
- subi r9,r9,4 // back r9 up to beginning of word
- andc r11,r11,r0 // mask out false hits
- cntlzw r0,r11 // find 0 byte (r0 = 0, 8, 16, or 24)
- srwi r0,r0,3 // now r0 = 0, 1, 2, or 3
- add r9,r9,r0 // now r9 points to the 0-byte in dest
-
-// End of dest found, so we can start appending source.
-// We align the _source_, which allows us to avoid all worries about
-// spurious page faults. Doing so is faster than aligning the dest.
+
+// Now we know one of the bytes in r8 is zero, we just have to figure out which one.
+// We have mapped 0 bytes to 0x80, and nonzero bytes to 0x00, with one exception:
+// 0x01 bytes preceeding the first zero are also mapped to 0x80. So we have to mask
+// out the 0x80s caused by 0x01s before searching for the 0x80 byte. Once the 0 is
+// found, we can start appending source. We align the source, which allows us to
+// avoid worrying about spurious page faults.
// r4 = source ptr (unaligned)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
-// r9 = ptr to 0-byte (unaligned)
+// r8 = word or doubleword with a 0-byte
+// r9 = ptr to the word or doubleword in r8 (aligned)
+// r11 = mapped word or doubleword
-L0found:
- andi. r0,r4,3 // is source aligned?
- beq LwordloopEnter // skip if so
- subfic r0,r0,4 // not aligned, get #bytes to align r4
+ slgi r10,r8,7 // move 0x01 bits (false hits) into 0x80 position
+ andi. r0,r4,GPR_BYTES-1 // is source aligned?
+ andc r11,r11,r10 // mask out false hits
+ cntlzg r10,r11 // find 0 byte (r0 = 0, 8, 16, or 24)
+ subfic r0,r0,GPR_BYTES // get #bytes to align r4
+ srwi r10,r10,3 // now r0 = 0, 1, 2, or 3
+ add r9,r9,r10 // now r9 points to the 0-byte in dest
+ beq LwordloopEnter // skip if source is already aligned
+
mtctr r0 // set up loop
// Loop over bytes.
bne LwordloopEnter // 0-byte not found, so enter word loop
blr // 0-byte found, done
-// Word loop: move a word at a time until 0-byte found.
-// r4 = source ptr (word aligned)
+// Word loop: move a word or doubleword at a time until 0-byte found.
+// r4 = source ptr (aligned)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
// r9 = dest ptr (unaligned)
.align 5 // align inner loop, which is 8 words ling
Lwordloop:
- stw r8,0(r9) // pack word into destination
- addi r9,r9,4
+ stg r8,0(r9) // pack word or doubleword into destination
+ addi r9,r9,GPR_BYTES
LwordloopEnter:
- lwz r8,0(r4) // r8 <- next 4 source bytes
- addi r4,r4,4
+ lg r8,0(r4) // r8 <- next 4 or 8 source bytes
+ addi r4,r4,GPR_BYTES
add r10,r8,r6 // r10 <- word + 0xFEFEFEFF
andc r12,r7,r8 // r12 <- ~word & 0x80808080
and. r0,r10,r12 // r0 <- nonzero iff word has a 0-byte
- beq Lwordloop // loop if ctr!=0 and cr0_eq
+ beq Lwordloop // loop if no 0-byte
// Found a 0-byte. Store last word up to and including the 0, a byte at a time.
-// r8 = last word, known to have a 0-byte
+// r8 = last word or doubleword, known to have a 0-byte
// r9 = dest ptr
Lstorelastbytes:
- srwi. r0,r8,24 // right justify next byte and test for 0
- slwi r8,r8,8 // shift next byte into position
+ srgi. r0,r8,GPR_BYTES*8-8 // shift leftmost byte into bottom so we can "stb"
+ slgi r8,r8,8 // move on to next
stb r0,0(r9) // pack into dest
addi r9,r9,1
bne Lstorelastbytes // loop until 0 stored
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <mach/ppc/asm.h>
#undef ASSEMBLER
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+
// ***************
// * S T R C M P *
// ***************
// The test maps any non-zero byte to zero, and any zero byte to 0x80,
// with one exception: 0x01 bytes preceeding the first zero are also
// mapped to 0x80.
+//
+// In 64-bit mode, the algorithm is doubleword parallel.
.text
.globl EXT(strcmp)
.align 5
-LEXT(strcmp) // int strcmp(const char *s1, const char *s2);
- andi. r0,r3,3 // is LHS aligned?
- dcbt 0,r3 // touch in LHS
- lis r5,hi16(0xFEFEFEFF) // start to load magic constants
+LEXT(strcmp) // int strcmp(const char *s1, const char *s2);
+ andi. r0,r3,GPR_BYTES-1 // is LHS aligned?
+#if defined(__ppc__)
+ lis r5,hi16(0xFEFEFEFF) // start to generate 32-bit magic constants
lis r6,hi16(0x80808080)
- dcbt 0,r4 // touch in RHS
ori r5,r5,lo16(0xFEFEFEFF)
ori r6,r6,lo16(0x80808080)
- subi r3,r3,4 // we use "lwzu" in the inner loops
- subi r4,r4,4
+#else
+ ld r5,_COMM_PAGE_MAGIC_FE(0) // get 0xFEFEFEFE FEFEFEFF from commpage
+ ld r6,_COMM_PAGE_MAGIC_80(0) // get 0x80808080 80808080 from commpage
+#endif
+ subi r3,r3,GPR_BYTES // we use "lgu" in the inner loops
+ subi r4,r4,GPR_BYTES
beq Laligned // LHS is aligned
- subfic r0,r0,4 // r0 <- #bytes to word align LHS
+ subfic r0,r0,GPR_BYTES // r0 <- #bytes to align LHS
mtctr r0
// Loop over bytes.
Lbyteloop:
- lbz r7,4(r3) // r7 <- next LHS byte
+ lbz r7,GPR_BYTES(r3) // r7 <- next LHS byte
addi r3,r3,1
- lbz r8,4(r4) // r8 <- next RHS byte
+ lbz r8,GPR_BYTES(r4) // r8 <- next RHS byte
addi r4,r4,1
cntlzw r9,r7 // is r7 zero?
sub r0,r7,r8 // different?
bne Ldone // done if different or 0
-// LHS is word aligned. If RHS also is, we need not worry about page
-// crossing. Otherwise, we must stop the word loop before page is crossed.
+// LHS is aligned. If RHS also is, we need not worry about page
+// crossing. Otherwise, we must stop the loop before page is crossed.
Laligned:
- andi. r0,r4,3 // is RHS now word aligned too?
- addi r9,r4,4 // restore true address of next RHS byte
+ andi. r0,r4,GPR_BYTES-1 // is RHS now aligned too?
+ addi r9,r4,GPR_BYTES // restore true address of next RHS byte
rlwinm r9,r9,0,0xFFF // get RHS offset in page
- beq Lalignedloop // RHS word aligned, use simple loop
+ beq Lalignedloop // RHS also aligned, use simple loop
subfic r9,r9,4096 // get #bytes left in RHS page
- srwi. r0,r9,2 // get #words left in RHS page
+ srwi. r0,r9,LOG2_GPR_BYTES// get #words or doublewords left in RHS page
mtctr r0 // set up loop count
bne++ Lunalignedloop // at least one word left in RHS page
- li r0,4 // must check 4 bytes, a byte at a time...
- mtctr r0 // ...in order to keep LHS word aligned
+ li r0,GPR_BYTES // must check GPR_BYTES, a byte at a time...
+ mtctr r0 // ...in order to keep LHS aligned
b Lbyteloop // go cross RHS page
-// Unaligned inner loop: compare a word at a time, until one of three conditions:
+// Unaligned inner loop: compare a word or doubleword at a time, until one of
+// three conditions:
// - a difference is found
// - a zero byte is found
// - end of RHS page (we dare not touch next page until we must)
// At this point, registers are as follows:
-// r3 = LHS ptr - 4 (word aligned)
-// r4 = RHS ptr - 4 (not aligned)
+// r3 = LHS ptr - GPR_BYTES (aligned)
+// r4 = RHS ptr - GPR_BYTES (not aligned)
// r5 = 0xFEFEFEFF
// r6 = 0x80808080
-// ctr = whole words left in RHS page
+// ctr = words or doublewords left in RHS page
.align 5 // align inner loop, which is 8 words long
Lunalignedloop:
- lwzu r7,4(r3) // r7 <- next 4 LHS bytes
- lwzu r8,4(r4) // r8 <- next 4 RHS bytes
+ lgu r7,GPR_BYTES(r3) // r7 <- next LHS bytes
+ lgu r8,GPR_BYTES(r4) // r8 <- next RHS bytes
add r10,r7,r5 // r10 <- LHS + 0xFEFEFEFF
andc r12,r6,r7 // r12 <- ~LHS & 0x80808080
xor r11,r7,r8 // r11 <- compare the words
bdnzt eq,Lunalignedloop // loop if ctr!=0 and cr0_eq
bne++ Ldifferent // done if we found a 0 or difference
- li r0,4 // must check 4 bytes, a byte at a time...
+ li r0,GPR_BYTES // must check GPR_BYTES, a byte at a time...
mtctr r0 // ...in order to keep LHS word aligned
b Lbyteloop // cross RHS page, then resume word loop
.align 5 // align inner loop, which is 8 words ling
Lalignedloop:
- lwzu r7,4(r3) // r7 <- next 4 LHS bytes
- lwzu r8,4(r4) // r8 <- next 4 RHS bytes
+ lgu r7,GPR_BYTES(r3) // r7 <- next LHS bytes
+ lgu r8,GPR_BYTES(r4) // r8 <- next RHS bytes
add r10,r7,r5 // r10 <- LHS + 0xFEFEFEFF
andc r12,r6,r7 // r12 <- ~LHS & 0x80808080
xor r11,r7,r8 // r11 <- compare the words
// the 0-byte.
Ldifferent: // r0 == 0-test vector (with 0x01 false hits)
- slwi r9,r7,7 // move 0x01 bits in LHS into position 0x80
+ slgi r9,r7,7 // move 0x01 bits in LHS into position 0x80
andc r0,r0,r9 // mask out the false 0-hits from 0x01 bytes
or r11,r11,r0 // recompute difference vector
- cntlzw r9,r11 // find 1st difference (r9 = 0..31)
- rlwinm r9,r9,0,0x18 // byte align bit offset (now, r9 = 0,8,16, or 24)
- addi r9,r9,8 // now, r9 = 8, 16, 24, or 32
- rlwnm r5,r7,r9,24,31 // right justify differing bytes and mask off rest
- rlwnm r6,r8,r9,24,31
- sub r3,r5,r6 // compute difference (0, +, or -)
- blr
-
-Ldone: // r0 = return value
- mr r3,r0 // return in r3
+ cntlzg r9,r11 // find 1st difference (r9 = 0..31 or 63)
+ rlwinm r9,r9,0,0x38 // byte align bit offset (now, r9 = 0,8,16, or 24 etc)
+ addi r0,r9,8 // now, r0 = 8, 16, 24, or 32
+#if defined(__ppc__)
+ rlwnm r7,r7,r0,24,31 // right justify differing bytes and mask off rest
+ rlwnm r8,r8,r0,24,31
+#else
+ rldcl r7,r7,r0,56 // right justify differing bytes and mask off rest
+ rldcl r8,r8,r0,56
+#endif
+
+Ldone: // differing bytes are in r7 and r8
+ sub r3,r7,r8 // compute difference (0, +, or -)
blr
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <mach/ppc/asm.h>
#undef ASSEMBLER
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+
// ***************
// * S T R C P Y *
// ***************
//
// We align the _source_, which allows us to avoid all worries about
// spurious page faults. Doing so is faster than aligning the dest.
+//
+// In 64-bit mode, the algorithm is doubleword parallel.
.text
.globl EXT(strcpy)
.align 5
-LEXT(strcpy) // char* strcpy(const char *dst, const char *src);
- andi. r0,r4,3 // is source aligned?
- dcbt 0,r4 // touch in source
- lis r6,hi16(0xFEFEFEFF) // start to load magic constants
+LEXT(strcpy) // char* strcpy(const char *dst, const char *src);
+ andi. r0,r4,GPR_BYTES-1 // is source aligned?
+#if defined(__ppc__)
+ lis r6,hi16(0xFEFEFEFF) // start to generate 32-bit magic constants
lis r7,hi16(0x80808080)
- dcbtst 0,r3 // touch in dst
ori r6,r6,lo16(0xFEFEFEFF)
ori r7,r7,lo16(0x80808080)
+#else
+ ld r6,_COMM_PAGE_MAGIC_FE(0) // get 0xFEFEFEFE FEFEFEFF from commpage
+ ld r7,_COMM_PAGE_MAGIC_80(0) // get 0x80808080 80808080 from commpage
+#endif
mr r9,r3 // use r9 for dest ptr (must return r3 intact)
beq LwordloopEnter // source is aligned
- subfic r0,r0,4 // r0 <- #bytes to word align source
+ subfic r0,r0,GPR_BYTES // r0 <- #bytes to align source
mtctr r0
// Loop over bytes.
bne LwordloopEnter // 0-byte not found, so enter word loop
blr // 0-byte found, done
-// Word loop: move a word at a time until 0-byte found.
-// r4 = source ptr (word aligned)
+// Word loop: move a word or doubleword at a time until 0-byte found.
+// r4 = source ptr (aligned)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
// r9 = dest ptr (unaligned)
.align 5 // align inner loop, which is 8 words ling
Lwordloop:
- stw r8,0(r9) // pack word into destination
- addi r9,r9,4
+ stg r8,0(r9) // pack word or doubleword into destination
+ addi r9,r9,GPR_BYTES
LwordloopEnter:
- lwz r8,0(r4) // r8 <- next 4 source bytes
- addi r4,r4,4
+ lg r8,0(r4) // r8 <- next source word or doubleword
+ addi r4,r4,GPR_BYTES
add r10,r8,r6 // r10 <- word + 0xFEFEFEFF
andc r12,r7,r8 // r12 <- ~word & 0x80808080
and. r0,r10,r12 // r0 <- nonzero iff word has a 0-byte
- beq Lwordloop // loop if ctr!=0 and cr0_eq
+ beq Lwordloop // loop if no 0-byte
// Found a 0-byte. Store last word up to and including the 0, a byte at a time.
-// r8 = last word, known to have a 0-byte
+// r8 = last word or doubleword, known to have a 0-byte
// r9 = dest ptr
Lstorelastbytes:
- srwi. r0,r8,24 // right justify next byte and test for 0
- slwi r8,r8,8 // shift next byte into position
+ srgi. r0,r8,GPR_BYTES*8-8 // shift leftmost byte into bottom so we can "stb"
+ slgi r8,r8,8 // move on to next
stb r0,0(r9) // pack into dest
addi r9,r9,1
bne Lstorelastbytes // loop until 0 stored
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <mach/ppc/asm.h>
#undef ASSEMBLER
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+
// *****************
// * S T R L C A T *
// *****************
//
// Note that "count" is the total buffer length, including the length
// of the "dst" string. This is different than strncat().
+//
+// In 64-bit mode, this algorithm is doubleword parallel.
.text
.globl EXT(strlcat)
.align 5
-LEXT(strlcat)
- srwi. r0,r5,2 // get #words to scan
- dcbtst 0,r3 // touch in dst
- lis r6,hi16(0xFEFEFEFF) // start to load magic constants
+LEXT(strlcat) // size_t strlcat(char *dst, const char *src, size_t count);
+ srgi. r0,r5,LOG2_GPR_BYTES// get #words or doublewords to scan
+#if defined(__ppc__)
+ lis r6,hi16(0xFEFEFEFF) // start to generate 32-bit magic constants
lis r7,hi16(0x80808080)
- dcbt 0,r4 // touch in source
ori r6,r6,lo16(0xFEFEFEFF)
ori r7,r7,lo16(0x80808080)
+#else
+ ld r6,_COMM_PAGE_MAGIC_FE(0) // get 0xFEFEFEFE FEFEFEFF from commpage
+ ld r7,_COMM_PAGE_MAGIC_80(0) // get 0x80808080 80808080 from commpage
+#endif
mr r9,r3 // use r9 for dest ptr (r3 remembers dst start)
beq-- L0bytes // buffer length <4
mtctr r0 // set up loop
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
// r9 = dest ptr (unaligned)
-// ctr = #words remaining in buffer
+// ctr = #words or doublewords remaining in buffer
.align 5 // align inner loops for speed
L0words:
- lwz r8,0(r9) // r8 <- next dest word
- addi r9,r9,4
+ lg r8,0(r9) // r8 <- next dest word or doubleword
+ addi r9,r9,GPR_BYTES
add r10,r8,r6 // r10 <- word + 0xFEFEFEFF
andc r12,r7,r8 // r12 <- ~word & 0x80808080
and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte
beq-- L0bytes // skip if 0 not found
- slwi r0,r8,7 // move 0x01 bits (false hits) into 0x80 position
- subi r9,r9,4 // back up r9 to the start of the word
+ slgi r0,r8,7 // move 0x01 bits (false hits) into 0x80 position
+ subi r9,r9,GPR_BYTES // back up r9 to the start of the word
andc r11,r11,r0 // mask out false hits
- cntlzw r0,r11 // find 0 byte (r0 = 0, 8, 16, or 24)
+ cntlzg r0,r11 // find 0 byte (r0 = 0, 8, 16, or 24)
srwi r0,r0,3 // now r0 = 0, 1, 2, or 3
add r9,r9,r0 // now r9 points to the 0-byte in dest
b L0found // start to append source
// r9 = dest ptr (unaligned)
L0bytes:
- andi. r0,r5,3 // get #bytes remaining in buffer
+ andi. r0,r5,GPR_BYTES-1 // get #bytes remaining in buffer
mtctr r0 // set up byte loop
beq-- L0notfound // skip if 0 not found in buffer (error)
L0byteloop:
// r9 = ptr to 0-byte in dest (unaligned)
L0found:
- andi. r0,r4,3 // is source aligned?
+ andi. r0,r4,GPR_BYTES-1 // is source aligned?
add r5,r5,r3 // get ptr to end of buffer
sub r5,r5,r9 // get #bytes remaining in buffer, counting the 0 (r5>0)
beq Laligned // skip if source already word aligned
- subfic r0,r0,4 // not aligned, get #bytes to align r4
+ subfic r0,r0,GPR_BYTES // not aligned, get #bytes to align r4
b Lbyteloop1 // r5!=0, so skip check
// Copy min(r0,r5) bytes, until 0-byte.
// r9 = dest ptr (unaligned)
Lbyteloop:
- cmpwi r5,0 // buffer empty? (note: unsigned)
+ cmpgi r5,0 // buffer empty? (note: length is unsigned)
beq-- Loverrun // buffer filled before end of source reached
Lbyteloop1: // entry when we know r5!=0
lbz r8,0(r4) // r8 <- next source byte
beq cr1,L0stored // byte was 0, so done
bne Lbyteloop // r0!=0, source not yet aligned
-// Source is word aligned. Loop over words until 0-byte found or end
+// Source is aligned. Loop over words or doublewords until 0-byte found or end
// of buffer.
// r3 = original start of buffer
-// r4 = source ptr (word aligned)
+// r4 = source ptr (aligned)
// r5 = length remaining in buffer
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
// r9 = dest ptr (unaligned)
Laligned:
- srwi. r8,r5,2 // get #words in buffer
+ srgi. r8,r5,LOG2_GPR_BYTES// get #words or doublewords in buffer
addi r0,r5,1 // if no words...
beq-- Lbyteloop // ...copy to end of buffer
- mtctr r8 // set up word loop count
- rlwinm r5,r5,0,0x3 // mask buffer length down to leftover bytes
+ mtctr r8 // set up loop count
+ rlwinm r5,r5,0,GPR_BYTES-1 // mask buffer length down to leftover bytes
b LwordloopEnter
-// Inner loop: move a word at a time, until one of two conditions:
+// Inner loop: move a word or doubleword at a time, until one of two conditions:
// - a zero byte is found
// - end of buffer
// At this point, registers are as follows:
// r3 = original start of buffer
-// r4 = source ptr (word aligned)
-// r5 = bytes leftover in buffer (0..3)
+// r4 = source ptr (aligned)
+// r5 = bytes leftover in buffer (0..GPR_BYTES-1)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
// r9 = dest ptr (unaligned)
-// ctr = whole words left in buffer
+// ctr = loop count
.align 5 // align inner loop, which is 8 words long
Lwordloop:
- stw r8,0(r9) // pack word into destination
- addi r9,r9,4
+ stg r8,0(r9) // pack word into destination
+ addi r9,r9,GPR_BYTES
LwordloopEnter:
- lwz r8,0(r4) // r8 <- next 4 source bytes
- addi r4,r4,4
+ lg r8,0(r4) // r8 <- next 4 or 8 source bytes
+ addi r4,r4,GPR_BYTES
add r10,r8,r6 // r10 <- word + 0xFEFEFEFF
andc r12,r7,r8 // r12 <- ~word & 0x80808080
and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte
// r9 = dest ptr (one past 0)
Lstorelastbytes:
- srwi. r0,r8,24 // right justify next byte and test for 0
- slwi r8,r8,8 // shift next byte into position
+ srgi. r0,r8,GPR_BYTES*8-8 // right justify next byte and test for 0
+ slgi r8,r8,8 // shift next byte into position
stb r0,0(r9) // pack into dest
addi r9,r9,1
bne Lstorelastbytes // loop until 0 stored
subi r3,r3,1 // return length
blr
-// 0-byte not found in aligned source words. There are up to 3 leftover source
-// bytes, hopefully the 0-byte is among them.
-// r4 = source ptr (word aligned)
-// r5 = leftover bytes in buffer (0..3)
+// 0-byte not found in aligned source words. There are up to GPR_BYTES-1 leftover
+// source bytes, hopefully the 0-byte is among them.
+// r4 = source ptr (aligned)
+// r5 = leftover bytes in buffer (0..GPR_BYTES-1)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
-// r8 = last full word of source
+// r8 = last full word or doubleword of source
// r9 = dest ptr (unaligned)
Lleftovers:
- stw r8,0(r9) // store last word
- addi r9,r9,4
+ stg r8,0(r9) // store last word
+ addi r9,r9,GPR_BYTES
addi r0,r5,1 // make sure r5 terminates byte loop (not r0)
b Lbyteloop
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <mach/ppc/asm.h>
#undef ASSEMBLER
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+
// *****************
// * S T R L C P Y *
// *****************
// The test maps any non-zero byte to zero, and any zero byte to 0x80,
// with one exception: 0x01 bytes preceeding the first zero are also
// mapped to 0x80.
+//
+// This algorithm is doubleword parallel in 64-bit mode.
.text
.globl EXT(strlcpy)
.align 5
-LEXT(strlcpy)
- andi. r0,r4,3 // is source aligned?
- dcbt 0,r4 // touch in source
- lis r6,hi16(0xFEFEFEFF) // start to load magic constants
+LEXT(strlcpy) // size_t strlcpy(char *dst, const char *src, size_t size);
+ andi. r0,r4,GPR_BYTES-1 // is source aligned?
+#if defined(__ppc__)
+ lis r6,hi16(0xFEFEFEFF) // start to generate 32-bit magic constants
lis r7,hi16(0x80808080)
- dcbtst 0,r3 // touch in dst
ori r6,r6,lo16(0xFEFEFEFF)
ori r7,r7,lo16(0x80808080)
- mr r9,r3 // use r9 for dest ptr (r3 remembers dst start)
+#else
+ ld r6,_COMM_PAGE_MAGIC_FE(0) // get 0xFEFEFEFE FEFEFEFF from commpage
+ ld r7,_COMM_PAGE_MAGIC_80(0) // get 0x80808080 80808080 from commpage
+#endif
+ mr r9,r3 // use r9 for dest ptr (must return r3 intact)
beq Laligned // source is aligned
- subfic r0,r0,4 // r0 <- #bytes to word align source
+ subfic r0,r0,GPR_BYTES // r0 <- #bytes to align source
// Copy min(r0,r5) bytes, until 0-byte found.
// r0 = #bytes we propose to copy (NOTE: must be >0)
beq cr1,L0found // byte was 0
bne Lbyteloop // r0!=0, source not yet aligned
-// Source is word aligned. Loop over words until end of buffer. We align
-// the source, rather than the dest, to avoid getting spurious page faults.
-// r4 = source ptr (word aligned)
+// Source is aligned. Loop over words or doublewords until end of buffer. We
+// align the source, rather than the dest, to avoid getting spurious page faults.
+// r4 = source ptr (aligned)
// r5 = length remaining in buffer
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
// r9 = dest ptr (unaligned)
Laligned:
- srwi. r8,r5,2 // get #words in buffer
+ srgi. r8,r5,LOG2_GPR_BYTES// get #words or doublewords in buffer
addi r0,r5,1 // if no words, compare rest of buffer
- beq Lbyteloop // r8==0, no words
+ beq-- Lbyteloop // r8==0, no words
mtctr r8 // set up word loop count
- rlwinm r5,r5,0,0x3 // mask buffer length down to leftover bytes
+ rlwinm r5,r5,0,GPR_BYTES-1 // mask buffer length down to leftover bytes
b LwordloopEnter
-// Move a word at a time, until one of two conditions:
+// Move a word or doubleword at a time, until one of two conditions:
// - a zero byte is found
// - end of buffer
// At this point, registers are as follows:
-// r4 = source ptr (word aligned)
-// r5 = leftover bytes in buffer (0..3)
+// r4 = source ptr (aligned)
+// r5 = leftover bytes in buffer (0..GPR_BYTES-1)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
// r9 = dest ptr (unaligned)
-// ctr = whole words left in buffer
+// ctr = whole words or doublewords left in buffer
.align 5 // align inner loop, which is 8 words long
Lwordloop:
- stw r8,0(r9) // pack word into destination
- addi r9,r9,4
+ stg r8,0(r9) // pack word or doubleword into destination
+ addi r9,r9,GPR_BYTES
LwordloopEnter:
- lwz r8,0(r4) // r8 <- next 4 source bytes
- addi r4,r4,4
+ lg r8,0(r4) // r8 <- next 4 or 8 source bytes
+ addi r4,r4,GPR_BYTES
add r10,r8,r6 // r10 <- word + 0xFEFEFEFF
andc r12,r7,r8 // r12 <- ~word & 0x80808080
and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte
beq Lleftovers // 0-byte not found in aligned words
// Found a 0-byte. Store last word up to and including the 0, a byte at a time.
-// r8 = last word, known to have a 0-byte
+// r8 = last word or doubleword, known to have a 0-byte
// r9 = dest ptr
Lstorelastbytes:
- srwi. r0,r8,24 // right justify next byte and test for 0
- slwi r8,r8,8 // shift next byte into position
+ srgi. r0,r8,GPR_BYTES*8-8 // right justify next byte and test for 0
+ slgi r8,r8,8 // shift next byte into position
stb r0,0(r9) // pack into dest
addi r9,r9,1
bne Lstorelastbytes // loop until 0 stored
subi r3,r3,1 // don't count the 0
blr // return strlen(src)
-// 0-byte not found in aligned source words. There are up to 3 leftover source
-// bytes, hopefully the 0-byte is among them.
-// r4 = source ptr (word aligned)
-// r5 = leftover bytes in buffer (0..3)
+// 0-byte not found in aligned source words. There are up to GPR_BYTES-1 leftover
+// source bytes, hopefully the 0-byte is among them.
+// r4 = source ptr (aligned)
+// r5 = leftover bytes in buffer (0..GPR_BYTES-1)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
-// r8 = last full word of source
+// r8 = last full word or doubleword of source
// r9 = dest ptr (unaligned)
Lleftovers:
- stw r8,0(r9) // store last word
- addi r9,r9,4
- addi r0,r5,1 // make sure r5 terminate byte loop (not r0)
+ stg r8,0(r9) // store last word or doubleword
+ addi r9,r9,GPR_BYTES
+ addi r0,r5,1 // make sure r5 terminates byte loop (not r0)
b Lbyteloop
// Buffer full but 0-byte not found. Stuff a 0 into last byte of buffer.
/*
- * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_END@
*/
-#define ASSEMBLER
-#include <mach/ppc/asm.h>
-#undef ASSEMBLER
-
-;
-;
-; Strlen, optimized for PPC. The routine we use is 2-3x faster
-; then the simple loop which checks each byte for zero.
-; For 0- and 1-byte strings, the simple routine is faster, but
-; only by a few cycles. The algorithm used was adapted from the
-; Mac OS 9 stdCLib strcopy routine, which was originally
-; written by Gary Davidian. It relies on the following rather
-; inobvious but very efficient test:
-;
-; y = dataWord + 0xFEFEFEFF
-; z = ~dataWord & 0x80808080
-; if ( y & z ) = 0 then all bytes in dataWord are non-zero
-;
-; The test maps any non-zero byte to zeros and any zero byte to 0x80,
-; with one exception: 0x01 bytes preceeding the first zero are also
-; mapped to 0x80.
-;
-;
-; int strlen(ptr)
-;
-;
- .align 5
- .globl EXT(strlen)
-LEXT(strlen)
-
- andi. r4,r3,0x03 ; test alignment first
- mr r9,r3 ; store the original address for later use....
- bne LalignSource ; align the source addr if not already aligned
-Llentry:
- lis r5,hi16(0xFEFEFEFF)
- lis r6,hi16(0x80808080)
- subi r3,r3,0x04 ; pre-decrement r3 for the lwzu
- ori r5,r5,lo16(0xFEFEFEFF) ; r5=0xFEFEFEFF
- ori r6,r6,lo16(0x80808080) ; r6=0x80808080
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
-LLoop:
- lwzu r8,4(r3) ; get the first 4 bytes and increment address
- add r4,r5,r8 ; r4= data + 0xFEFEFEFF
- andc r7,r6,r8 ; r7= ~data & 0x80808080
- and. r4,r4,r7 ; r4= r4 & r7
- beq LLoop ; if r4 is zero, then all bytes are non-zero
+#include <mach/ppc/asm.h>
-; Now we know one of the bytes in r8 is zero,
-; we just have to figure out which one.
-; We have mapped 0 bytes to 0x80, and nonzero bytes to 0x00,
-; with one exception:
-; 0x01 bytes preceeding the first zero are also mapped to 0x80.
-; So we have to mask out the 0x80s caused by 0x01s before
-; counting leading zeroes to get the bytes in last word.
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
- rlwinm r5,r8,7,0,31 ; move 0x01 bits to 0x80 position
- subf r3,r9,r3 ; start to compute string length
- andc r4,r4,r5 ; turn off false hits from 0x0100 worst case
- cntlzw r7,r4 ; now we can count leading 0s
- srwi r7,r7,3 ; convert 0,8,16,24 to 0,1,2,3
- add r3,r3,r7 ; add in nonzero bytes in last word
- blr
-; We must align the source address for two reasons: to avoid spurious page
-; faults, and for speed.
-; r4 = low 2 bits of address (1,2, or 3)
-; r3 = address
-; r9 = original address (still same as r3)
+// Strlen, optimized for PPC. We use an inobvious but very efficient
+// word-parallel test for 0-bytes:
+//
+// y = dataWord + 0xFEFEFEFF
+// z = ~dataWord & 0x80808080
+// if ( y & z ) = 0 then all bytes in dataWord are non-zero
+//
+// The test maps any non-zero byte to zeros and any zero byte to 0x80,
+// with one exception: 0x01 bytes preceeding the first zero are also
+// mapped to 0x80. Using altivec is another possibility, but it turns
+// out that the overhead of maintaining VRSAVE and dealing with edge
+// cases pushes the crossover point out to around 30 bytes... longer
+// the the "typical" operand length.
+//
+// In 64-bit mode, the algorithm is doubleword parallel.
-LalignSource:
- lbz r5,0(r3) ; get the first byte...
- subic. r4,r4,2 ; test for 1, 2 or 3 bytes
- addi r3,r3,1 ; increment address
- addi r6,r9,1 ; now r6==r3
- cmpwi cr1,r5,0 ; zero?
- beq cr1,Lreturn ; if its zero return zero
- bgt Llentry ; address is aligned now if low bits were 3
+ .text
+ .align 5
+ .globl EXT(strlen)
+LEXT(strlen) // int strlen(ptr)
+ clrrgi r9,r3,LOG2_GPR_BYTES// align pointer by zeroing right LOG2_GPR_BYTES bits
+ li r7,-1 // get 0xFFs
+ lg r8,0(r9) // get word or doubleword with 1st operand byte
+ rlwinm r4,r3,3,(GPR_BYTES-1)*8 // get starting bit position of operand
+#if defined(__ppc__)
+ lis r5,hi16(0xFEFEFEFF) // start to generate 32-bit magic constants
+ lis r6,hi16(0x80808080)
+ srw r7,r7,r4 // create a mask of 0xFF bytes for operand in r8
+ ori r5,r5,lo16(0xFEFEFEFF)
+ ori r6,r6,lo16(0x80808080)
+#else
+ ld r5,_COMM_PAGE_MAGIC_FE(0) // get 0xFEFEFEFE FEFEFEFF from commpage
+ ld r6,_COMM_PAGE_MAGIC_80(0) // get 0x80808080 80808080 from commpage
+ srd r7,r7,r4 // create a mask of 0xFF bytes for operand in r8
+#endif
+ orc r8,r8,r7 // make sure bytes preceeding operand are 0xFF
+ b Lloop1 // enter loop
+
+// Loop over words or doublewords.
+// r3 = original address
+// r5 = 0xFEFEFEFE FEFEFEFF
+// r6 = 0x80808080 80808080
+// r9 = address (aligned)
- lbz r5,0(r3) ; get the next byte...
- addi r3,r3,1 ; increment address
- cmpwi cr1,r5,0 ; zero?
- beq cr1,Lreturn ; if its zero return one
- beq Llentry ; addr is aligned now if low bits were 2
+ .align 5
+Lloop:
+ lgu r8,GPR_BYTES(r9) // get next word or doubleword
+Lloop1: // initial entry
+ add r4,r5,r8 // r4 = data + 0xFEFEFEFF
+ andc r7,r6,r8 // r7 = ~data & 0x80808080
+ and. r4,r4,r7 // r4 = r4 & r7
+ beq Lloop // if r4 is zero, then all bytes are non-zero
- lbz r5,0(r3) ; get the next byte...
- addi r3,r3,1 ; increment address
- cmpwi cr1,r5,0 ; zero?
- bne cr1,Llentry ; not zero, continue check (now aligned)
-Lreturn:
- sub r3,r3,r6 ; get string length (0, 1, or 2)
- blr
+// Now we know one of the bytes in r8 is zero, we just have to figure out which one.
+// We have mapped 0 bytes to 0x80, and nonzero bytes to 0x00, with one exception:
+// 0x01 bytes preceeding the first zero are also mapped to 0x80. So we have to mask
+// out the 0x80s caused by 0x01s before searching for the 0x80 byte.
+ slgi r5,r8,7 // move 0x01 bits to 0x80 position
+ sub r3,r9,r3 // start to compute string length
+ andc r4,r4,r5 // turn off false hits from 0x0100 worst case
+ cntlzg r7,r4 // now we can count leading 0s
+ srwi r7,r7,3 // convert 0,8,16,24 to 0,1,2,3, etc
+ add r3,r3,r7 // add in nonzero bytes in last word
+ blr
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <mach/ppc/asm.h>
#undef ASSEMBLER
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+
// *****************
// * S T R N C A T *
// *****************
// Note that "count" refers to the max number of bytes to _append_.
// There is no limit to the number of bytes we will scan looking for
// the end of the "dst" string.
+//
+// In 64-bit mode, this algorithm is doubleword parallel.
.text
.globl EXT(strncat)
.align 5
-LEXT(strncat)
- andi. r0,r3,3 // is dst aligned?
- dcbtst 0,r3 // touch in dst
- lis r6,hi16(0xFEFEFEFF) // start to load magic constants
+LEXT(strncat) // char* strncat(char *dst, const char *src, size_t count);
+ clrrgi r9,r3,LOG2_GPR_BYTES// align pointer by zeroing right LOG2_GPR_BYTES bits
+ li r10,-1 // get 0xFFs
+ lg r8,0(r9) // get word or doubleword with 1st operand byte
+ rlwinm r11,r3,3,(GPR_BYTES-1)*8 // get starting bit position of operand
+#if defined(__ppc__)
+ lis r6,hi16(0xFEFEFEFF) // start to generate 32-bit magic constants
lis r7,hi16(0x80808080)
- dcbt 0,r4 // touch in source
+ srw r10,r10,r11 // create a mask of 0xFF bytes for operand in r8
ori r6,r6,lo16(0xFEFEFEFF)
ori r7,r7,lo16(0x80808080)
- mr r9,r3 // use r9 for dest ptr (must return r3 intact)
- beq Lword0loop // dest is aligned
- subfic r0,r0,4 // r0 <- #bytes to word align dest
- mtctr r0 // set up byte loop
-
-// Loop over bytes looking for 0-byte marking end of dest, until dest is
-// word aligned.
-// r4 = source ptr (unaligned)
-// r5 = count (unchanged so far)
-// r6 = 0xFEFEFEFF
-// r7 = 0x80808080
-// r9 = dest ptr (unaligned)
-// ctr = byte count
-
-Lbyte0loop:
- lbz r8,0(r9) // r8 <- next dest byte
- addi r9,r9,1
- cmpwi r8,0 // test for 0
- bdnzf eq,Lbyte0loop // loop until (ctr==0) | (r8==0)
-
- bne Lword0loop // haven't found 0, so enter word-aligned loop
- andi. r0,r4,3 // is source aligned?
- subi r9,r9,1 // point to the 0-byte we just stored
- beq Laligned // source is already aligned
- subfic r0,r0,4 // r0 <- #bytes to word align source
- b Lbyteloop // must align source
+#else
+ ld r6,_COMM_PAGE_MAGIC_FE(0) // get 0xFEFEFEFE FEFEFEFF from commpage
+ ld r7,_COMM_PAGE_MAGIC_80(0) // get 0x80808080 80808080 from commpage
+ srd r10,r10,r11 // create a mask of 0xFF bytes for operand in r8
+#endif
+ orc r8,r8,r10 // make sure bytes preceeding operand are nonzero
+ b Lword0loopEnter
-// Loop over words looking for 0-byte marking end of dest.
+// Loop over words or doublewords looking for 0-byte marking end of dest.
// r4 = source ptr (unaligned)
// r5 = count (unchanged so far)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
-// r9 = dest ptr (word aligned)
+// r9 = dest ptr (aligned)
.align 5 // align inner loops for speed
Lword0loop:
- lwz r8,0(r9) // r8 <- next dest word
- addi r9,r9,4
+ lgu r8,GPR_BYTES(r9) // r8 <- next dest word or doubleword
+Lword0loopEnter:
add r10,r8,r6 // r10 <- word + 0xFEFEFEFF
andc r12,r7,r8 // r12 <- ~word & 0x80808080
and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte
beq Lword0loop // loop until 0 found
+
+// Now we know one of the bytes in r8 is zero, we just have to figure out which one.
+// We have mapped 0 bytes to 0x80, and nonzero bytes to 0x00, with one exception:
+// 0x01 bytes preceeding the first zero are also mapped to 0x80. So we have to mask
+// out the 0x80s caused by 0x01s before searching for the 0x80 byte. Once the 0 is
+// found, we can start appending source. We align the source, which allows us to
+// avoid worrying about spurious page faults.
+// r4 = source ptr (unaligned)
+// r5 = count (unchanged so far)
+// r6 = 0xFEFEFEFF
+// r7 = 0x80808080
+// r8 = word or doubleword with a 0-byte
+// r9 = ptr to the word or doubleword in r8 (aligned)
+// r11 = mapped word or doubleword
- slwi r10,r8,7 // move 0x01 bits (false hits) into 0x80 position
- andi. r0,r4,3 // is source aligned?
+ slgi r10,r8,7 // move 0x01 bits (false hits) into 0x80 position
+ andi. r0,r4,GPR_BYTES-1 // is source aligned?
andc r11,r11,r10 // mask out false hits
- subi r9,r9,4 // back up r9 to the start of the word
- cntlzw r10,r11 // find 0 byte (r0 = 0, 8, 16, or 24)
+ cntlzg r10,r11 // find 0 byte (r0 = 0, 8, 16, or 24)
+ subfic r0,r0,GPR_BYTES // get #bytes to align r4
srwi r10,r10,3 // now r10 = 0, 1, 2, or 3
add r9,r9,r10 // now r9 points to the 0-byte in dest
beq Laligned // skip if source already aligned
- subfic r0,r0,4 // r0 <- #bytes to word align source
// Copy min(r0,r5) bytes, until 0-byte.
// r0 = #bytes we propose to copy (NOTE: must be >0)
// r9 = dest ptr (unaligned)
Lbyteloop:
- cmpwi r5,0 // buffer empty? (note: unsigned)
+ cmpgi r5,0 // buffer empty? (note: count is unsigned)
beq-- L0notfound // buffer full but 0 not found
lbz r8,0(r4) // r8 <- next source byte
subic. r0,r0,1 // decrement count of bytes to move
beqlr cr1 // byte was 0, so done
bne Lbyteloop // r0!=0, source not yet aligned
-// Source is word aligned. Loop over words until 0-byte found or end
-// of buffer.
-// r4 = source ptr (word aligned)
+// Source is aligned. Loop over words or doublewords until 0-byte found
+// or end of buffer.
+// r4 = source ptr (aligned)
// r5 = length remaining in buffer
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
// r9 = dest ptr (unaligned)
Laligned:
- srwi. r8,r5,2 // get #words in buffer
+ srgi. r8,r5,LOG2_GPR_BYTES// get #words or doublewords in buffer
addi r0,r5,1 // if no words, copy rest of buffer
beq-- Lbyteloop // fewer than 4 bytes in buffer
mtctr r8 // set up word loop count
- rlwinm r5,r5,0,0x3 // mask buffer length down to leftover bytes
+ rlwinm r5,r5,0,GPR_BYTES-1 // mask buffer length down to leftover bytes
b LwordloopEnter
-// Inner loop: move a word at a time, until one of two conditions:
+// Inner loop: move a word or doubleword at a time, until one of two conditions:
// - a zero byte is found
// - end of buffer
// At this point, registers are as follows:
-// r4 = source ptr (word aligned)
-// r5 = bytes leftover in buffer (0..3)
+// r4 = source ptr (aligned)
+// r5 = bytes leftover in buffer (0..GPR_BYTES-1)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
// r9 = dest ptr (unaligned)
-// ctr = whole words left in buffer
+// ctr = whole words or doublewords left in buffer
.align 5 // align inner loop, which is 8 words long
Lwordloop:
- stw r8,0(r9) // pack word into destination
- addi r9,r9,4
+ stg r8,0(r9) // pack word or doubleword into destination
+ addi r9,r9,GPR_BYTES
LwordloopEnter:
- lwz r8,0(r4) // r8 <- next 4 source bytes
- addi r4,r4,4
+ lg r8,0(r4) // r8 <- next GPR_BYTES source bytes
+ addi r4,r4,GPR_BYTES
add r10,r8,r6 // r10 <- word + 0xFEFEFEFF
andc r12,r7,r8 // r12 <- ~word & 0x80808080
and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte
beq-- LcheckLeftovers // skip if 0-byte not found
// Found a 0-byte. Store last word up to and including the 0, a byte at a time.
-// r8 = last word, known to have a 0-byte
+// r8 = last word or doubleword, known to have a 0-byte
// r9 = dest ptr
Lstorelastbytes:
- srwi. r0,r8,24 // right justify next byte and test for 0
- slwi r8,r8,8 // shift next byte into position
+ srgi. r0,r8,GPR_BYTES*8-8 // right justify next byte and test for 0
+ slgi r8,r8,8 // shift next byte into position
stb r0,0(r9) // pack into dest
addi r9,r9,1
bne Lstorelastbytes // loop until 0 stored
blr
// 0-byte not found while appending words to source. There might be up to
-// 3 "leftover" bytes to append, hopefully the 0-byte is in there.
+// GPR_BYTES-1 "leftover" bytes to append, hopefully the 0-byte is in there.
// r4 = source ptr (past word in r8)
-// r5 = bytes leftover in buffer (0..3)
+// r5 = bytes leftover in buffer (0..GPR_BYTES-1)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
-// r8 = last word of source, with no 0-byte
+// r8 = last word or doubleword of source, with no 0-byte
// r9 = dest ptr (unaligned)
LcheckLeftovers:
- stw r8,0(r9) // store last whole word of source
- addi r9,r9,4
+ stg r8,0(r9) // store last whole word or doubleword of source
+ addi r9,r9,GPR_BYTES
addi r0,r5,1 // let r5 (not r0) terminate byte loop
b Lbyteloop // append last few bytes
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <mach/ppc/asm.h>
#undef ASSEMBLER
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+
// *****************
// * S T R N C M P *
// *****************
// The test maps any non-zero byte to zero, and any zero byte to 0x80,
// with one exception: 0x01 bytes preceeding the first zero are also
// mapped to 0x80.
+//
+// This routine is doubleword parallel in 64-bit mode.
.text
.globl EXT(strncmp)
.align 5
-LEXT(strncmp) // int strncmp(const char *s1,const char *s2,size_t len);
- cmplwi cr1,r5,8 // is buffer too short to bother with word compares?
- andi. r0,r3,3 // is LHS aligned?
- dcbt 0,r3 // touch in LHS
- subi r3,r3,4 // we use "lwzu" in the word inner loop
- subi r4,r4,4
+LEXT(strncmp) // int strncmp(const char *s1,const char *s2,size_t len);
+ cmplgi cr1,r5,GPR_BYTES*2 // buffer too short to bother? (WARNING: cr1 is used later)
+ andi. r0,r3,GPR_BYTES-1 // is LHS aligned?
+ subi r3,r3,GPR_BYTES // we use "lgu" in the inner loops
+ subi r4,r4,GPR_BYTES
blt cr1,Lshort // short buffer, just compare a byte at a time
- lis r2,hi16(0xFEFEFEFF) // start to load magic constants
+#if defined(__ppc__)
+ lis r2,hi16(0xFEFEFEFF) // start to generate 32-bit magic constants
lis r6,hi16(0x80808080)
ori r2,r2,lo16(0xFEFEFEFF)
ori r6,r6,lo16(0x80808080)
+#else
+ ld r2,_COMM_PAGE_MAGIC_FE(0) // get 0xFEFEFEFE FEFEFEFF from commpage
+ ld r6,_COMM_PAGE_MAGIC_80(0) // get 0x80808080 80808080 from commpage
+#endif
beq Laligned // LHS is aligned
- subfic r0,r0,4 // r0 <- #bytes to word align LHS
- mtctr r0 // set up for byte loop
- sub r5,r5,r0 // adjust length
+ subfic r0,r0,GPR_BYTES // r0 <- #bytes to align LHS
+ mtctr r0
+ sub r5,r5,r0 // adjust length
b Lbyteloop
// Handle short operands or end-of-buffer.
-// r3 = LHS ptr - 4 (unaligned)
-// r4 = RHS ptr - 4 (unaligned)
-// r5 = length remaining in buffer (0..7)
+// r3 = LHS ptr - GPR_BYTES (unaligned)
+// r4 = RHS ptr - GPR_BYTES (unaligned)
+// r5 = length remaining in buffer (0..GPR_BYTES*2-1)
// cr1 = blt set
Lshort:
- cmpwi r5,0 // buffer null?
+ cmpgi r5,0 // buffer null?
mtctr r5 // assume not null, set up for loop
bne Lbyteloop // buffer not null
li r3,0 // if buffer null, say "equal"
blr
-// We're at a RHS page boundary. Compare 4 bytes in order to cross the page
+// We're at a RHS page boundary. Compare GPR_BYTES bytes in order to cross the page
// but still keep the LHS ptr word-aligned.
// r2 = 0xFEFEFEFF
-// r3 = LHS ptr - 4 (aligned)
-// r4 = RHS ptr - 4 (unaligned)
+// r3 = LHS ptr - GPR_BYTES (aligned)
+// r4 = RHS ptr - GPR_BYTES (unaligned)
// r5 = length remaining in buffer (may be 0)
// r6 = 0x80808080
Lcrosspage:
- cmplwi cr1,r5,8 // not enough left in buffer for word compares?
- li r0,4 // get #bytes to cross RHS page
+ cmplgi cr1,r5,GPR_BYTES*2 // not enough left in buffer for word compares?
+ li r0,GPR_BYTES // get #bytes to cross RHS page
blt cr1,Lshort // buffer is about to end
- mtctr r0 // set up to compare 4 bytes
+ mtctr r0 // set up to compare GPR_BYTES bytes
sub r5,r5,r0 // adjust length
b Lbyteloop
// Compare bytes, until 0-byte or difference found.
// r2 = 0xFEFEFEFF (if cr1 bge)
-// r3 = LHS ptr - 4 (unaligned)
-// r4 = RHS ptr - 4 (unaligned)
+// r3 = LHS ptr - GPR_BYTES (unaligned)
+// r4 = RHS ptr - GPR_BYTES (unaligned)
// r5 = length remaining in buffer (may be 0)
// r6 = 0x80808080 (if cr1 bge)
// cr1 = blt if this is end of buffer
.align 5 // align inner loop, which is 8 words long
Lbyteloop:
- lbz r7,4(r3) // next LHS byte
+ lbz r7,GPR_BYTES(r3) // next LHS byte
addi r3,r3,1
- lbz r8,4(r4) // next RHS byte
+ lbz r8,GPR_BYTES(r4) // next RHS byte
addi r4,r4,1
cmpwi cr0,r7,0 // zero?
cmpw cr7,r7,r8 // equal?
bne Ldifferent // done if bytes differ or are 0
blt cr1,Ldifferent // done if buffer end (ie, if r5==0)
-// LHS is now word aligned. Loop over words until end of RHS page or buffer.
-// When we get to the end of the page, we compare 4 bytes, so that we keep
-// the LHS word aligned.
+// LHS is now aligned. Loop over words or doublewords until end of RHS page
+// or buffer. When we get to the end of the page, we compare GPR_BYTES bytes,
+// so that we keep the LHS aligned.
// r2 = 0xFEFEFEFF
-// r3 = LHS ptr - 4 (aligned)
-// r4 = RHS ptr - 4 (unaligned)
+// r3 = LHS ptr - GPR_BYTES (aligned)
+// r4 = RHS ptr - GPR_BYTES (unaligned)
// r5 = length remaining in buffer (may be 0)
// r6 = 0x80808080
Laligned:
- addi r9,r4,4 // restore true address of next RHS byte
+ addi r9,r4,GPR_BYTES // restore true address of next RHS byte
rlwinm r9,r9,0,0xFFF // get RHS offset in page
subfic r0,r9,4096 // get #bytes left in RHS page
subfc r7,r0,r5 // ***
subfe r8,r5,r5 // * r9 <- min(r0,r5),
and r7,r7,r8 // * using algorithm in Compiler Writer's Guide
add r9,r0,r7 // ***
- srwi. r8,r9,2 // get #words we can compare
- beq-- Lcrosspage // no words so advance to next RHS page
- slwi r9,r8,2 // convert #words to #bytes
+ srgi. r8,r9,LOG2_GPR_BYTES// get #words or doublewords we can compare
+ beq-- Lcrosspage // none so advance to next RHS page
+ slgi r9,r8,LOG2_GPR_BYTES// get #bytes we will be comparing in parallel loop
mtctr r8 // set up loop count
sub r5,r5,r9 // decrement length remaining
b Lwordloop
-// Inner loop: compare a word at a time, until one of three conditions:
+// Inner loop: compare a word or doubleword at a time, until one of three conditions:
// - a difference is found
// - a zero byte is found
// - end of count (ie, end of buffer or RHS page, whichever is first)
// At this point, registers are as follows:
// r2 = 0xFEFEFEFF
-// r3 = LHS ptr - 4 (aligned)
-// r4 = RHS ptr - 4 (unaligned)
+// r3 = LHS ptr - GPR_BYTES (aligned)
+// r4 = RHS ptr - GPR_BYTES (unaligned)
// r5 = length remaining in buffer (may be 0)
// r6 = 0x80808080
-// ctr = count of words until end of buffer or RHS page
+// ctr = count of words or doublewords until end of buffer or RHS page
.align 5 // align inner loop, which is 8 words long
Lwordloop:
- lwzu r7,4(r3) // r7 <- next 4 LHS bytes
- lwzu r8,4(r4) // r8 <- next 4 RHS bytes
+ lgu r7,GPR_BYTES(r3) // r7 <- next 4 or 8 LHS bytes
+ lgu r8,GPR_BYTES(r4) // r8 <- next 4 or 8 RHS bytes
add r10,r7,r2 // r10 <- LHS + 0xFEFEFEFF
andc r12,r6,r7 // r12 <- ~LHS & 0x80808080
xor r11,r7,r8 // r11 <- compare the words
// false hits in the 0-byte test, which consist of 0x01 bytes that preceed
// the 0-byte.
- slwi r0,r7,7 // move 0x01 bits in LHS into position 0x80
+ slgi r0,r7,7 // move 0x01 bits in LHS into position 0x80
andc r9,r9,r0 // mask out the false 0-hits from 0x01 bytes
or r11,r11,r9 // recompute difference vector
- cntlzw r0,r11 // find 1st difference (r0 = 0..31)
- rlwinm r9,r0,0,0x18 // byte align bit offset (r9 = 0,8,16, or 24)
+ cntlzg r0,r11 // find 1st difference (r0 = 0..31 or 63)
+ rlwinm r9,r0,0,0x38 // byte align bit offset (r9 = 0,8,16, or 24)
addi r0,r9,8 // now, r0 = 8, 16, 24, or 32
+#if defined(__ppc__)
rlwnm r7,r7,r0,24,31 // right justify differing bytes and mask off rest
rlwnm r8,r8,r0,24,31
+#else
+ rldcl r7,r7,r0,56 // right justify differing bytes and mask off rest
+ rldcl r8,r8,r0,56
+#endif
Ldifferent: // bytes in r7 and r8 differ or are 0
sub r3,r7,r8 // compute return value
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <mach/ppc/asm.h>
#undef ASSEMBLER
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+
// *****************
// * S T R N C P Y *
// *****************
//
-// char* strncpy(const char *dst, const char *src, size_t len));
+// char* strncpy(const char *dst, const char *src, size_t len);
//
// We optimize the move by doing it word parallel. This introduces
// a complication: if we blindly did word load/stores until finding
// The test maps any non-zero byte to zero, and any zero byte to 0x80,
// with one exception: 0x01 bytes preceeding the first zero are also
// mapped to 0x80.
+//
+// This algorithm is doubleword parallel in 64-bit mode.
.text
.globl EXT(strncpy)
.align 5
-LEXT(strncpy)
- andi. r0,r4,3 // is source aligned?
- dcbt 0,r4 // touch in source
- lis r6,hi16(0xFEFEFEFF) // start to load magic constants
+LEXT(strncpy) // char* strncpy(const char *dst, const char *src, size_t len));
+ andi. r0,r4,GPR_BYTES-1 // is source aligned?
+#if defined(__ppc__)
+ lis r6,hi16(0xFEFEFEFF) // start to generate 32-bit magic constants
lis r7,hi16(0x80808080)
- dcbtst 0,r3 // touch in dst
ori r6,r6,lo16(0xFEFEFEFF)
ori r7,r7,lo16(0x80808080)
+#else
+ ld r6,_COMM_PAGE_MAGIC_FE(0) // get 0xFEFEFEFE FEFEFEFF from commpage
+ ld r7,_COMM_PAGE_MAGIC_80(0) // get 0x80808080 80808080 from commpage
+#endif
mr r9,r3 // use r9 for dest ptr (must return r3 intact)
add r2,r3,r5 // remember where end of buffer is
beq Laligned // source is aligned
- subfic r0,r0,4 // r0 <- #bytes to word align source
+ subfic r0,r0,GPR_BYTES // r0 <- #bytes to align source
// Copy min(r0,r5) bytes, until 0-byte.
// r0 = #bytes we propose to copy (NOTE: must be >0)
// r9 = dest ptr (unaligned)
Lbyteloop:
- cmpwi r5,0 // buffer empty? (note: unsigned)
+ cmpgi r5,0 // buffer empty? (note: length is unsigned)
beqlr-- // buffer full but 0 not found
lbz r8,0(r4) // r8 <- next source byte
subic. r0,r0,1 // decrement count of bytes to move
addi r4,r4,1
subi r5,r5,1 // decrement buffer length remaining
- stb r8,0(r9) // pack into dest
cmpwi cr1,r8,0 // 0-byte?
+ stb r8,0(r9) // pack into dest
addi r9,r9,1
beq cr1,L0found // byte was 0
bne Lbyteloop // r0!=0, source not yet aligned
-// Source is word aligned. Loop over words until end of buffer. Note that we
-// have aligned the source, rather than the dest, in order to avoid spurious
+// Source is aligned. Loop over words or doublewords until end of buffer. Note that
+// we have aligned the source, rather than the dest, in order to avoid spurious
// page faults.
// r2 = ptr to 1st byte not in buffer
-// r4 = source ptr (word aligned)
+// r4 = source ptr (aligned)
// r5 = length remaining in buffer
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
// r9 = dest ptr (unaligned)
Laligned:
- srwi. r8,r5,2 // get #words in buffer
- addi r0,r5,1 // if no words, compare rest of buffer
+ srgi. r8,r5,LOG2_GPR_BYTES// get #words or doublewords in buffer
+ addi r0,r5,1 // if none, compare rest of buffer
beq-- Lbyteloop // r8==0, no words
mtctr r8 // set up word loop count
- rlwinm r5,r5,0,0x3 // mask buffer length down to leftover bytes
- b LwordloopEnter
+ rlwinm r5,r5,0,GPR_BYTES-1 // mask buffer length down to leftover bytes
+ b Lwordloop
-// Move a word at a time, until one of two conditions:
+// Move a word or a doubleword at a time, until one of two conditions:
// - a zero byte is found
// - end of buffer
// At this point, registers are as follows:
// r2 = ptr to 1st byte not in buffer
-// r4 = source ptr (word aligned)
-// r5 = leftover bytes in buffer (0..3)
+// r4 = source ptr (aligned)
+// r5 = leftover bytes in buffer (0..GPR_BYTES-1)
// r6 = 0xFEFEFEFF
// r7 = 0x80808080
// r9 = dest ptr (unaligned)
-// ctr = whole words left in buffer
+// ctr = whole words or doublewords left in buffer
.align 5 // align inner loop, which is 8 words long
Lwordloop:
- stw r8,0(r9) // pack word into destination
- addi r9,r9,4
-LwordloopEnter:
- lwz r8,0(r4) // r8 <- next 4 source bytes
- addi r4,r4,4
+ lg r8,0(r4) // r8 <- next 4 or 8 source bytes
+ addi r9,r9,GPR_BYTES // bump dest addr while we wait for data
+ addi r4,r4,GPR_BYTES
add r10,r8,r6 // r10 <- word + 0xFEFEFEFF
andc r12,r7,r8 // r12 <- ~word & 0x80808080
+ stg r8,-GPR_BYTES(r9) // pack word or doubleword into destination
and. r11,r10,r12 // r11 <- nonzero iff word has a 0-byte
bdnzt eq,Lwordloop // loop if ctr!=0 and cr0_eq
- stw r8,0(r9) // pack in last word
- addi r9,r9,4
addi r0,r5,1 // if no 0-byte found...
beq-- Lbyteloop // ...fill rest of buffer a byte at a time
// Found a 0-byte, point to following byte with r9.
- slwi r0,r8,7 // move 0x01 false hit bits to 0x80 position
+ slgi r0,r8,7 // move 0x01 false hit bits to 0x80 position
andc r11,r11,r0 // mask out false hits
- cntlzw r0,r11 // find the 0-byte (r0 = 0,8,16, or 24)
- srwi r0,r0,3 // now r0 = 0, 1, 2, or 3
- subfic r0,r0,3 // now r0 = 3, 2, 1, or 0
+ cntlzg r0,r11 // find the 0-byte (r0 = 0,8,16, or 24)
+ srwi r0,r0,3 // now r0 = 0, 1, 2, or 3 (0..7 if 64-bit)
+ subfic r0,r0,GPR_BYTES-1 // now r0 = 3, 2, 1, or 0
sub r9,r9,r0 // now r9 points one past the 0-byte
-// Zero rest of buffer, if any. We don't simply branch to bzero or memset, because
-// r3 is set up incorrectly, and there is a fair amt of overhead involved in using them.
-// Instead we use a simpler routine, which will nonetheless be faster unless the number
-// of bytes to 0 is large and we're on a 64-bit machine.
+// Zero rest of buffer, if any. We use the commpage bzero() routine.
// r2 = ptr to 1st byte not in buffer
// r9 = ptr to 1st byte to zero
+//
+// NB: commpage bzero() preserves r10-r12 by contract.
L0found:
- sub r5,r2,r9 // r5 <- #bytes to zero (ie, rest of buffer)
- cmplwi r5,32 // how many?
- neg r8,r9 // start to compute #bytes to align ptr
- li r0,0 // get a 0
- blt Ltail // skip if <32 bytes
- andi. r10,r8,31 // get #bytes to 32-byte align
- sub r5,r5,r10 // adjust buffer length
- srwi r11,r5,5 // get #32-byte chunks
- cmpwi cr1,r11,0 // any chunks?
- mtctr r11 // set up dcbz loop count
- beq 1f // skip if already 32-byte aligned
-
-// 32-byte align. We just store 32 0s, rather than test and use conditional
-// branches.
-
- stw r0,0(r9) // zero next 32 bytes
- stw r0,4(r9)
- stw r0,8(r9)
- stw r0,12(r9)
- stw r0,16(r9)
- stw r0,20(r9)
- stw r0,24(r9)
- stw r0,28(r9)
- add r9,r9,r10 // now r9 is 32-byte aligned
- beq cr1,Ltail // skip if no 32-byte chunks
- b 1f
-
-// Loop doing 32-byte version of DCBZ instruction.
-
- .align 4 // align the inner loop
-1:
- dcbz 0,r9 // zero another 32 bytes
- addi r9,r9,32
- bdnz 1b
-
-// Store trailing bytes.
-// r0 = 0
-// r5 = #bytes to store (<32)
-// r9 = address
-
-Ltail:
- mtcrf 0x02,r5 // remaining byte count to cr6 and cr7
- mtcrf 0x01,r5
- bf 27,2f // 16-byte chunk?
- stw r0,0(r9)
- stw r0,4(r9)
- stw r0,8(r9)
- stw r0,12(r9)
- addi r9,r9,16
-2:
- bf 28,4f // 8-byte chunk?
- stw r0,0(r9)
- stw r0,4(r9)
- addi r9,r9,8
-4:
- bf 29,5f // word?
- stw r0,0(r9)
- addi r9,r9,4
-5:
- bf 30,6f // halfword?
- sth r0,0(r9)
- addi r9,r9,2
-6:
- bflr 31 // byte?
- stb r0,0(r9)
+ mflr r12 // save return
+ mr r11,r3 // save original dest ptr
+ sub r4,r2,r9 // #bytes to zero (ie, rest of buffer)
+ mr r3,r9 // point to 1st byte to zero
+ bla _COMM_PAGE_BZERO
+ mtlr r12 // restore our return
+ mr r3,r11 // restore ptr to original dest
blr
-
-
-
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
-SRCS+= ATPgetreq.s \
+.PATH: ${.CURDIR}/ppc/sys
+MDSRCS+= ATPgetreq.s \
ATPgetrsp.s \
ATPsndreq.s \
ATPsndrsp.s \
ATgetmsg.s \
ATputmsg.s \
ATsocket.s \
+ OSAtomic.s \
_exit.s \
_getlogin.s \
_longjmp.s \
audit.s \
auditctl.s \
auditon.s \
+ auditsvc.s \
bind.s \
cerror.s \
chdir.s \
fchmod.s \
fchown.s \
fcntl.s \
+ fgetxattr.s \
fhopen.s \
+ flistxattr.s \
flock.s \
fork.s \
fpathconf.s \
+ fremovexattr.s \
fsctl.s \
+ fsetxattr.s \
fstat.s \
fstatfs.s \
fstatv.s \
getgroups.s \
getitimer.s \
getpeername.s \
- getpgrp.s \
getpgid.s \
+ getpgrp.s \
getpid.s \
getppid.s \
getpriority.s \
getsid.s \
getsockname.s \
getsockopt.s \
- ppc_gettimeofday.s \
getuid.s \
+ getxattr.s \
ioctl.s \
issetugid.s \
kevent.s \
kqueue_from_portset_np.s \
kqueue_portset_np.s \
ktrace.s \
+ lchown.s \
link.s \
lio_listio.s \
listen.s \
+ listxattr.s \
load_shared_file.s \
longjmp.s \
lseek.s \
pathconf.s \
pipe.s \
posix_madvise.s \
- processor_facilities.s \
+ ppc_gettimeofday.s \
pread.s \
+ processor_facilities.s \
profil.s \
- pwrite.s \
- ptrace.s \
pthread_sigmask.s \
+ ptrace.s \
+ pwrite.s \
quota.s \
quotactl.s \
read.s \
reboot.s \
recvfrom.s \
recvmsg.s \
+ removexattr.s \
rename.s \
reset_shared_file.s \
revoke.s \
setsockopt.s \
settimeofday.s \
setuid.s \
+ setxattr.s \
shmat.s \
shmctl.s \
shmdt.s \
wait4.s \
write.s \
writev.s
+
+.for _src in fhopen.s getfh.s nfsclnt.s
+CFLAGS-${_src} += -DNFSCLIENT
+.endfor
+
+CFLAGS-nfssvc.s += -DNFSSERVER
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+#include <architecture/ppc/mode_independent_asm.h>
+
+
+/* These are the functions in <libkern/OSAtomic.h>.
+ * The actual primitives are implemented on the commpage.
+ */
+
+
+/* int32_t OSAtomicAdd32( int32_t theAmount, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicAdd32)
+ ba _COMM_PAGE_ATOMIC_ADD32
+
+
+/* int32_t OSAtomicOr32( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicOr32)
+ mflr r12 // save return address
+ mr r5,r4 // move ptr to where compare-and-swap wants it
+ mr r11,r3 // copy mask
+1:
+ lwz r3,0(r5) // get old value
+ or r4,r3,r11 // make new value
+ bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12
+ cmpwi r3,0 // did swap occur?
+ beq-- 1b // compare-and-swap failed, try again
+ mtlr r12 // restore return adddress
+ mr r3,r4 // return new value
+ blr
+
+
+/* int32_t OSAtomicAnd32( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicAnd32)
+ mflr r12 // save return address
+ mr r5,r4 // move ptr to where compare-and-swap wants it
+ mr r11,r3 // copy mask
+1:
+ lwz r3,0(r5) // get old value
+ and r4,r3,r11 // make new value
+ bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12
+ cmpwi r3,0 // did swap occur?
+ beq-- 1b // compare-and-swap failed, try again
+ mtlr r12 // restore return adddress
+ mr r3,r4 // return new value
+ blr
+
+
+/* int32_t OSAtomicXor32( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicXor32)
+ mflr r12 // save return address
+ mr r5,r4 // move ptr to where compare-and-swap wants it
+ mr r11,r3 // copy mask
+1:
+ lwz r3,0(r5) // get old value
+ xor r4,r3,r11 // make new value
+ bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12
+ cmpwi r3,0 // did swap occur?
+ beq-- 1b // compare-and-swap failed, try again
+ mtlr r12 // restore return adddress
+ mr r3,r4 // return new value
+ blr
+
+
+/* int64_t OSAtomicAdd64( int64_t theAmount, int64_t *theValue ); */
+
+#if defined(__ppc64__)
+MI_ENTRY_POINT(_OSAtomicAdd64)
+ ba _COMM_PAGE_ATOMIC_ADD64
+#endif /* defined(__ppc64__) */
+
+
+/* bool OSAtomicCompareAndSwap32( int32_t oldValue, int32_t newValue, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicCompareAndSwap32)
+ ba _COMM_PAGE_COMPARE_AND_SWAP32
+
+
+/* bool OSAtomicCompareAndSwap64( int364_t oldValue, int64_t newValue, int64_t *theValue ); */
+
+#if defined(__ppc64__)
+MI_ENTRY_POINT(_OSAtomicCompareAndSwap64)
+ ba _COMM_PAGE_COMPARE_AND_SWAP64
+#endif /* defined(__ppc64__) */
+
+
+/* bool OSAtomicTestAndSet( uint32_t n, void *theAddress ); */
+
+MI_ENTRY_POINT(_OSAtomicTestAndSet)
+ mflr r12 // save return
+ srwi r5,r3,3 // get byte offset of n
+ rlwinm r6,r3,0,0x7 // get bit position within byte
+ add r4,r4,r5 // r4 points to byte containing the bit
+ lis r10,0x8000 // light bit 0
+ rlwimi r6,r4,3,0x18 // r6 is bit position within word
+ clrrgi r5,r4,2 // point to word containing the bit
+ srw r10,r10,r6 // get mask for bit
+ addi r9,r6,1 // save bit position + 1
+1:
+ lwz r3,0(r5) // get old word
+ rlwnm r11,r3,r9,0x1 // right justify old value of bit
+ or r4,r3,r10 // set it in new word
+ bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12
+ cmpwi r3,0 // did swap occur?
+ beq-- 1b // compare-and-swap failed, try again
+ mtlr r12 // restore return adddress
+ mr r3,r11 // return original value of bit
+ blr
+
+
+/* bool OSAtomicTestAndClear( uint32_t n, void *theAddress ); */
+
+MI_ENTRY_POINT(_OSAtomicTestAndClear)
+ mflr r12 // save return
+ srwi r5,r3,3 // get byte offset of n
+ rlwinm r6,r3,0,0x7 // get bit position within byte
+ add r4,r4,r5 // r4 points to byte containing the bit
+ lis r10,0x8000 // light bit 0
+ rlwimi r6,r4,3,0x18 // r6 is bit position within word
+ clrrgi r5,r4,2 // point to word containing the bit
+ srw r10,r10,r6 // get mask for bit
+ addi r9,r6,1 // save bit position + 1
+1:
+ lwz r3,0(r5) // get old word
+ rlwnm r11,r3,r9,0x1 // right justify old value of bit
+ andc r4,r3,r10 // clear it in new word
+ bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12
+ cmpwi r3,0 // did swap occur?
+ beq-- 1b // compare-and-swap failed, try again
+ mtlr r12 // restore return adddress
+ mr r3,r11 // return original value of bit
+ blr
+
+
+/* void * OSAtomicDequeue( void ** inList, size_t inOffset); */
+
+MI_ENTRY_POINT(_OSAtomicDequeue)
+ ba _COMM_PAGE_DEQUEUE
+
+
+/* void OSAtomicEnqueue( void ** inList, void * inNewLink, size_t inOffset); */
+
+MI_ENTRY_POINT(_OSAtomicEnqueue)
+ ba _COMM_PAGE_ENQUEUE
+
+
+/* bool OSSpinLockTry( OSSpinLock *lock ); */
+
+MI_ENTRY_POINT(_OSSpinLockTry)
+ ba _COMM_PAGE_SPINLOCK_TRY
+
+
+/* void OSSpinLockLock( OSSpinLock *lock ); */
+
+MI_ENTRY_POINT(_OSSpinLockLock)
+ ba _COMM_PAGE_SPINLOCK_LOCK
+
+
+/* void OSSpinLockUnlock( OSSpinLock *lock ); */
+
+MI_ENTRY_POINT(_OSSpinLockUnlock)
+ ba _COMM_PAGE_SPINLOCK_UNLOCK
+
+
+/* void OSMemoryBarrier( void ); */
+
+MI_ENTRY_POINT(_OSMemoryBarrier)
+ ba _COMM_PAGE_MEMORY_BARRIER
+
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* Created.
*/
-#define KERNEL_PRIVATE 1
/*
* Header files.
*/
-#import <architecture/ppc/asm_help.h>
-#import <architecture/ppc/pseudo_inst.h>
-#import <mach/ppc/exception.h>
+#include <architecture/ppc/mode_independent_asm.h>
#import <sys/syscall.h>
/* From rhapsody kernel mach/ppc/syscall_sw.h */
_##trap_name: @\
li r0,trap_number @\
sc @\
- blr @\
- END(trap_name)
+ blr
#define kernel_trap_0(trap_name,trap_number) \
simple_kernel_trap(trap_name,trap_number)
#define SYSCALL(name, nargs) \
.globl cerror @\
-LEAF(_##name) @\
- kernel_trap_args_##nargs @\
+ MI_ENTRY_POINT(_##name) @\
+ kernel_trap_args_##nargs @\
li r0,SYS_##name @\
- sc @\
- b 1f @\
- blr @\
-1: BRANCH_EXTERN(cerror) @\
-.text \
-2: nop
+ sc @\
+ b 1f @\
+ blr @\
+1: MI_BRANCH_EXTERNAL(cerror)
+
#define SYSCALL_NONAME(name, nargs) \
.globl cerror @\
- kernel_trap_args_##nargs @\
+ kernel_trap_args_##nargs @\
li r0,SYS_##name @\
- sc @\
- b 1f @\
- b 2f @\
-1: BRANCH_EXTERN(cerror) @\
-.text \
-2: nop
+ sc @\
+ b 1f @\
+ b 2f @\
+1: MI_BRANCH_EXTERNAL(cerror) @\
+2:
+
#define PSEUDO(pseudo, name, nargs) \
-LEAF(_##pseudo) @\
+ .globl _##pseudo @\
+ .text @\
+ .align 2 @\
+_##pseudo: @\
SYSCALL_NONAME(name, nargs)
#undef END
#import <mach/ppc/syscall_sw.h>
-
-#if !defined(SYS_getdirentriesattr)
-#define SYS_getdirentriesattr 222
-#endif
-
-#if !defined(SYS_semsys)
-#define SYS_semsys 251
-#define SYS_msgsys 252
-#define SYS_shmsys 253
-#define SYS_semctl 254
-#define SYS_semget 255
-#define SYS_semop 256
-#define SYS_semconfig 257
-#define SYS_msgctl 258
-#define SYS_msgget 259
-#define SYS_msgsnd 260
-#define SYS_msgrcv 261
-#define SYS_shmat 262
-#define SYS_shmctl 263
-#define SYS_shmdt 264
-#define SYS_shmget 265
-#endif
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* @APPLE_LICENSE_HEADER_END@
*/
-/* void _longjmp(jmp_buf env, int val); */
-
-/* int _longjmp(jmp_buf env); */
/*
* Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
*
* Created. Derived from longjmp.s
*/
-#include <architecture/ppc/asm_help.h>
-#include "_setjmp.h"
-
-#define VRSave 256
+/* We use mode-independent "g" opcodes such as "lg", and/or
+ * mode-independent macros such as MI_CALL_EXTERNAL. These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
-/* special flag bit definitions copied from /osfmk/ppc/thread_act.h */
+#include "_setjmp.h"
-#define floatUsedbit 1
-#define vectorUsedbit 2
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+#define VRSave 256
-#if defined(__DYNAMIC__)
- .data
- .non_lazy_symbol_pointer
- .align 2
-L_memmove$non_lazy_ptr:
- .indirect_symbol _memmove
- .long 0
- .non_lazy_symbol_pointer
- .align 2
-L__cpu_has_altivec$non_lazy_ptr:
- .indirect_symbol __cpu_has_altivec
- .long 0
- .text
-#endif
-
-LEAF(__longjmp)
- ; need to restore FPRs or VRs?
-
- lwz r5,JMP_flags(r3)
- lwz r6,JMP_addr_at_setjmp(r3)
- rlwinm r7,r5,0,vectorUsedbit,vectorUsedbit
- rlwinm r8,r5,0,floatUsedbit,floatUsedbit
- cmpw cr1,r3,r6 ; jmp_buf still at same address?
- cmpwi cr3,r7,0 ; set cr3 iff VRs in use (non-volatile CR)
- cmpwi cr4,r8,0 ; set cr4 iff FPRs in use (non-volatile CR)
- beq+ cr1,LRestoreVRs
+/* int _longjmp(jmp_buf env, int val); */
+
+MI_ENTRY_POINT(__longjmp)
+ lg r6,JMP_addr_at_setjmp(r3)
+ lbz r7, _COMM_PAGE_ALTIVEC(0)
+ cmpg cr1,r3,r6 ; jmpbuf still at same address?
+ cmpwi cr2,r7,0 ; Altivec available? (using non-volatile cr)
+ beq++ cr1,LRestoreVRs ; jmpbuf has not moved
; jmp_buf was moved since setjmp (or is uninitialized.)
; We must move VRs and FPRs to be quadword aligned at present address.
- stw r3,JMP_addr_at_setjmp(r3) ; update, in case we longjmp to this again
- mr r31,r4 ; save "val" arg across memmove
- mr r30,r3 ; and jmp_buf ptr
+ stg r3,JMP_addr_at_setjmp(r3) ; update, in case we longjmp to this again
+ mr r31,r4 ; save "val" arg across memmove
+ mr r30,r3 ; and jmp_buf ptr
addi r3,r3,JMP_vr_base_addr
addi r4,r6,JMP_vr_base_addr
- rlwinm r3,r3,0,0,27 ; r3 <- QW aligned addr where they should be
- rlwinm r4,r4,0,0,27 ; r4 <- QW aligned addr where they originally were
- sub r7,r4,r6 ; r7 <- offset of VRs/FPRs within jmp_buf
- add r4,r30,r7 ; r4 <- where they are now
+ clrrgi r3,r3,4 ; r3 <- QW aligned addr where they should be
+ clrrgi r4,r4,4 ; r4 <- QW aligned addr where they originally were
+ sub r7,r4,r6 ; r7 <- offset of VRs/FPRs within jmp_buf
+ add r4,r30,r7 ; r4 <- where they are now
li r5,(JMP_buf_end - JMP_vr_base_addr)
-#if defined(__DYNAMIC__)
- bcl 20,31,1f ; Get pic-base
-1: mflr r12
- addis r12, r12, ha16(L_memmove$non_lazy_ptr - 1b)
- lwz r12, lo16(L_memmove$non_lazy_ptr - 1b)(r12)
- mtctr r12 ; Get address left by dyld
- bctrl
-#else
- bl _memmove
-#endif
- mr r3,r30
- mr r4,r31
+
+ MI_CALL_EXTERNAL(_memmove)
+
+ mr r3,r30 ; restore parameters
+ mr r4,r31
; Restore VRs iff any
- ; cr3 - bne if VRs
- ; cr4 - bne if FPRs
+ ; cr2 - beq if AltiVec not available
LRestoreVRs:
- beq+ cr3,LZeroVRSave ; no VRs
- lwz r0,JMP_vrsave(r3)
+ lg r0,JMP_vrsave(r3) ; get VRSAVE at setjmp()
addi r6,r3,JMP_vr_base_addr
- cmpwi r0,0 ; any live VRs?
- mtspr VRSave,r0
- beq+ LRestoreFPRs
- lvx v20,0,r6
- li r7,16*1
- lvx v21,r7,r6
- li r7,16*2
- lvx v22,r7,r6
- li r7,16*3
- lvx v23,r7,r6
- li r7,16*4
- lvx v24,r7,r6
- li r7,16*5
- lvx v25,r7,r6
- li r7,16*6
- lvx v26,r7,r6
- li r7,16*7
- lvx v27,r7,r6
- li r7,16*8
- lvx v28,r7,r6
- li r7,16*9
- lvx v29,r7,r6
- li r7,16*10
- lvx v30,r7,r6
- li r7,16*11
- lvx v31,r7,r6
- b LRestoreFPRs ; skip zeroing VRSave
-
- ; Zero VRSave iff Altivec is supported, but VRs were not in use
- ; at setjmp time. This covers the case where VRs are first used after
- ; the setjmp but before the longjmp, and where VRSave is nonzero at
- ; the longjmp. We need to zero it now, or it will always remain
- ; nonzero since they are sticky bits.
-
-LZeroVRSave:
-#if defined(__DYNAMIC__)
- bcl 20,31,1f
-1: mflr r9 ; get our address
- addis r6,r9,ha16(L__cpu_has_altivec$non_lazy_ptr - 1b)
- lwz r7,lo16(L__cpu_has_altivec$non_lazy_ptr - 1b)(r6)
- lwz r7,0(r7) ; load the flag
-#else
- lis r7, ha16(__cpu_has_altivec)
- lwz r7, lo16(__cpu_has_altivec)(r7)
-#endif
- cmpwi r7,0
- li r8,0
- beq LRestoreFPRs ; no Altivec, so skip
- mtspr VRSave,r8
+ beq-- cr2,LRestoreFPRs ; AltiVec not available so skip
+ cmpwi r0,0 ; any live VRs?
+ mtspr VRSave,r0 ; update VRSAVE whether 0 or not
+ beq++ LRestoreFPRs ; VRSAVE is 0 so no VRs to reload
+ lvx v20,0,r6
+ li r7,16*1
+ lvx v21,r7,r6
+ li r7,16*2
+ lvx v22,r7,r6
+ li r7,16*3
+ lvx v23,r7,r6
+ li r7,16*4
+ lvx v24,r7,r6
+ li r7,16*5
+ lvx v25,r7,r6
+ li r7,16*6
+ lvx v26,r7,r6
+ li r7,16*7
+ lvx v27,r7,r6
+ li r7,16*8
+ lvx v28,r7,r6
+ li r7,16*9
+ lvx v29,r7,r6
+ li r7,16*10
+ lvx v30,r7,r6
+ li r7,16*11
+ lvx v31,r7,r6
- ; Restore FPRs if any
- ; cr4 - bne iff FPRs
+ ; Restore FPRs
LRestoreFPRs:
- beq cr4,LRestoreGPRs ; FPRs not in use at setjmp
addi r6,r3,JMP_fp_base_addr
- rlwinm r6,r6,0,0,27 ; mask off low 4 bits to qw align
- lfd f14,0*8(r6)
- lfd f15,1*8(r6)
- lfd f16,2*8(r6)
- lfd f17,3*8(r6)
- lfd f18,4*8(r6)
- lfd f19,5*8(r6)
- lfd f20,6*8(r6)
- lfd f21,7*8(r6)
- lfd f22,8*8(r6)
- lfd f23,9*8(r6)
- lfd f24,10*8(r6)
- lfd f25,11*8(r6)
- lfd f26,12*8(r6)
- lfd f27,13*8(r6)
- lfd f28,14*8(r6)
- lfd f29,15*8(r6)
- lfd f30,16*8(r6)
- lfd f31,17*8(r6)
+ lfd f0,JMP_fpscr(r3) ; get FPSCR from non-sliding section of jmpbuf
+ clrrgi r6,r6,4 ; mask off low 4 bits to qw align
+ lfd f14,0*8(r6)
+ lfd f15,1*8(r6)
+ lfd f16,2*8(r6)
+ lfd f17,3*8(r6)
+ lfd f18,4*8(r6)
+ lfd f19,5*8(r6)
+ lfd f20,6*8(r6)
+ lfd f21,7*8(r6)
+ lfd f22,8*8(r6)
+ lfd f23,9*8(r6)
+ lfd f24,10*8(r6)
+ lfd f25,11*8(r6)
+ lfd f26,12*8(r6)
+ lfd f27,13*8(r6)
+ lfd f28,14*8(r6)
+ lfd f29,15*8(r6)
+ lfd f30,16*8(r6)
+ lfd f31,17*8(r6)
+ mtfsf 0xFF,f0 ; restore entire FPSCR
; Restore GPRs
-LRestoreGPRs:
- lwz r31, JMP_r31(r3)
- /* r1, r14-r30 */
- lwz r1, JMP_r1 (r3)
- lwz r2, JMP_r2 (r3)
- lwz r13, JMP_r13(r3)
- lwz r14, JMP_r14(r3)
- lwz r15, JMP_r15(r3)
- lwz r16, JMP_r16(r3)
- lwz r17, JMP_r17(r3)
- lwz r18, JMP_r18(r3)
- lwz r19, JMP_r19(r3)
- lwz r20, JMP_r20(r3)
- lwz r21, JMP_r21(r3)
- lwz r22, JMP_r22(r3)
- lwz r23, JMP_r23(r3)
- lwz r24, JMP_r24(r3)
- lwz r25, JMP_r25(r3)
- lwz r26, JMP_r26(r3)
- lwz r27, JMP_r27(r3)
- lwz r28, JMP_r28(r3)
- lwz r29, JMP_r29(r3)
- lwz r30, JMP_r30(r3)
- lwz r0, JMP_cr(r3)
- mtcrf 0xff,r0
- lwz r0, JMP_lr(r3)
- mtlr r0
- lwz r0, JMP_ctr(r3) ; XXX ctr is volatile
- mtctr r0
- lwz r0, JMP_xer(r3) ; XXX xer is volatile
- mtxer r0
- mr. r3, r4
- bnelr
- li r3, 1
- blr
+ lg r5, JMP_cr(r3) ; r5 <- CR
+ lg r6, JMP_lr(r3) ; r6 <- LR (ie, return addres)
+ cmplgi r4,0 ; is return value 0? (not permitted)
+ lg r1, JMP_r1 (r3)
+ lg r2, JMP_r2 (r3)
+ lg r13, JMP_r13(r3)
+ lg r14, JMP_r14(r3)
+ lg r15, JMP_r15(r3)
+ lg r16, JMP_r16(r3)
+ lg r17, JMP_r17(r3)
+ mtcrf 0x20,r5 ; restore cr2 (we only restore non-volatile CRs)
+ lg r18, JMP_r18(r3)
+ lg r19, JMP_r19(r3)
+ lg r20, JMP_r20(r3)
+ lg r21, JMP_r21(r3)
+ mtctr r6 ; set up return address, avoiding LR since it will mispredict
+ lg r22, JMP_r22(r3)
+ lg r23, JMP_r23(r3)
+ lg r24, JMP_r24(r3)
+ lg r25, JMP_r25(r3)
+ mtcrf 0x10,r5 ; restore cr3
+ lg r26, JMP_r26(r3)
+ lg r27, JMP_r27(r3)
+ lg r28, JMP_r28(r3)
+ lg r29, JMP_r29(r3)
+ mtcrf 0x08,r5 ; restore cr4
+ lg r30, JMP_r30(r3)
+ lg r31, JMP_r31(r3)
+ mr r3,r4 ; move return code into position (cr0 is set on r4)
+ bnectr++ ; return code was not 0
+ li r3, 1 ; cannot return zero from longjmp(), so return 1 instead
+ bctr
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* is bcopy'd to a different alignment between the setjmp
* and longjmp, we need to save the jmp_buf address in the
* jmp_buf at setjmp time, so we can realign before reloading.
+ *
+ * ALSO NOTE: the typedef for jmpbufs in <ppc/setjmp.h> is
+ * 192 ints (0x300 bytes) long, due to incorrectly assuming
+ * that we need to save all 32 VRs in a jmpbuf. This is
+ * fortuitous, because when it came time to add additional
+ * fields and expand GPRs for 64-bit mode, there was plenty
+ * of unused space!
*/
+ /* 32-bit-mode layout */
+
+#if defined(__ppc__)
+
#define JMP_r1 0x00
#define JMP_r2 0x04
#define JMP_r13 0x08
#define JMP_r31 0x50
#define JMP_lr 0x54
#define JMP_cr 0x58
-#define JMP_ctr 0x5c
-#define JMP_xer 0x60
-#define JMP_sig 0x64
-#define JMP_SIGFLAG 0x68
-#define JMP_flags 0x6c
+#define JMP_SIGFLAG 0x5c
+#define JMP_sig 0x60 /* reserve 8 bytes for sigmask */
+#define JMP_fpscr 0x68 /* reserve 8 bytes for FPSCR too */
#define JMP_vrsave 0x70
#define JMP_addr_at_setjmp 0x74
/* 12 bytes padding here */
/* save room for 18 FPRs (f14-f31), or 0x90 bytes */
#define JMP_buf_end 0x1d4
+
+ /* 64-bit-mode layout */
+
+#elif defined(__ppc64__)
+
+#define JMP_r1 0x00
+#define JMP_r2 0x08
+#define JMP_r13 0x10
+#define JMP_r14 0x18
+#define JMP_r15 0x20
+#define JMP_r16 0x28
+#define JMP_r17 0x30
+#define JMP_r18 0x38
+#define JMP_r19 0x40
+#define JMP_r20 0x48
+#define JMP_r21 0x50
+#define JMP_r22 0x58
+#define JMP_r23 0x60
+#define JMP_r24 0x68
+#define JMP_r25 0x70
+#define JMP_r26 0x78
+#define JMP_r27 0x80
+#define JMP_r28 0x88
+#define JMP_r29 0x90
+#define JMP_r30 0x98
+#define JMP_r31 0xa0
+#define JMP_lr 0xa8
+#define JMP_cr 0xb0
+#define JMP_sig 0xb8
+#define JMP_SIGFLAG 0xc0
+#define JMP_fpscr 0xc8
+#define JMP_vrsave 0xd0
+#define JMP_addr_at_setjmp 0xd8
+/* 12 bytes padding here */
+#define JMP_vr_base_addr 0x0ec
+/* save room for 12 VRs (v20-v31), or 0xC0 bytes */
+#define JMP_fp_base_addr 0x1ac
+/* save room for 18 FPRs (f14-f31), or 0x90 bytes */
+#define JMP_buf_end 0x23c
+
+#else
+#error architecture not supported
+#endif
\ No newline at end of file
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* Created. Derived from setjmp.s
*/
+/* We use mode-independent "g" opcodes such as "stg", and/or
+ * mode-independent macros such as MI_GET_ADDRESS. These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
-#include <architecture/ppc/asm_help.h>
#include "_setjmp.h"
#define VRSave 256
-/* special flag bit definitions copied from /osfmk/ppc/thread_act.h */
-#define floatUsedbit 1
-#define vectorUsedbit 2
+MI_ENTRY_POINT(__setjmp)
+ lbz r7, _COMM_PAGE_ALTIVEC(0) ; get "AltiVec available" flag
-#define FlagsFastTrap 0x7FF3
+ stg r1, JMP_r1(r3)
+ stg r2, JMP_r2(r3)
+ stg r13, JMP_r13(r3)
+ stg r14, JMP_r14(r3)
+ stg r15, JMP_r15(r3)
+ stg r16, JMP_r16(r3)
+ stg r17, JMP_r17(r3)
+ stg r18, JMP_r18(r3)
+ stg r19, JMP_r19(r3)
+ mfcr r0 ; we only need to save cr2-cr4
+ stg r20, JMP_r20(r3)
+ stg r21, JMP_r21(r3)
+ stg r22, JMP_r22(r3)
+ stg r23, JMP_r23(r3)
+ stg r24, JMP_r24(r3)
+ mflr r5
+ stg r25, JMP_r25(r3)
+ stg r26, JMP_r26(r3)
+ stg r27, JMP_r27(r3)
+ stg r28, JMP_r28(r3)
+ stg r29, JMP_r29(r3)
+ stg r30, JMP_r30(r3)
+ stg r31, JMP_r31(r3)
+ stg r0, JMP_cr(r3)
+ stg r5, JMP_lr(r3)
-
-LEAF(__setjmp)
- stw r31, JMP_r31(r3)
- /* r1, r2, r13-r30 */
- stw r1, JMP_r1(r3)
- stw r2, JMP_r2(r3)
- stw r13, JMP_r13(r3)
- stw r14, JMP_r14(r3)
- stw r15, JMP_r15(r3)
- stw r16, JMP_r16(r3)
- stw r17, JMP_r17(r3)
- stw r18, JMP_r18(r3)
- stw r19, JMP_r19(r3)
- stw r20, JMP_r20(r3)
- stw r21, JMP_r21(r3)
- stw r22, JMP_r22(r3)
- mfcr r0
- stw r23, JMP_r23(r3)
- stw r24, JMP_r24(r3)
- mflr r5
- stw r25, JMP_r25(r3)
- stw r26, JMP_r26(r3)
- mfctr r6 ; XXX ctr is volatile
- stw r27, JMP_r27(r3)
- stw r28, JMP_r28(r3)
- mfxer r7 ; XXX xer is volatile
- stw r29, JMP_r29(r3)
- stw r30, JMP_r30(r3)
- stw r0, JMP_cr(r3)
- stw r5, JMP_lr(r3)
- stw r6, JMP_ctr(r3)
- stw r7, JMP_xer(r3)
-
- mr r31,r3 ; save jmp_buf ptr
- li r0,FlagsFastTrap
- sc ; get FPR-inuse and VR-inuse flags from kernel
- rlwinm r4,r3,0,floatUsedbit,floatUsedbit
- rlwinm. r5,r3,0,vectorUsedbit,vectorUsedbit
- cmpwi cr1,r4,0 ; set CR1 bne iff FPRs in use
- stw r3,JMP_flags(r31)
- stw r31,JMP_addr_at_setjmp(r31)
- mr r3,r31 ; restore jmp_buf ptr
- lwz r31,JMP_r31(r31)
- beq LSaveFPRsIfNecessary ; skip if vectorUsedbit was 0
-
- ; must save VRs and VRSAVE
-
- mfspr r4,VRSave
- andi. r0,r4,0xFFF ; we only care about v20-v31
- stw r0,JMP_vrsave(r3) ; set up effective VRSAVE
- beq LSaveFPRsIfNecessary ; no live non-volatile VRs
- addi r6,r3,JMP_vr_base_addr
- stvx v20,0,r6
- li r4,16*1
- stvx v21,r4,r6
- li r4,16*2
- stvx v22,r4,r6
- li r4,16*3
- stvx v23,r4,r6
- li r4,16*4
- stvx v24,r4,r6
- li r4,16*5
- stvx v25,r4,r6
- li r4,16*6
- stvx v26,r4,r6
- li r4,16*7
- stvx v27,r4,r6
- li r4,16*8
- stvx v28,r4,r6
- li r4,16*9
- stvx v29,r4,r6
- li r4,16*10
- stvx v30,r4,r6
- li r4,16*11
- stvx v31,r4,r6
-
- ; must save FPRs if they are live in this thread
- ; CR1 = bne iff FPRs are in use
-
-LSaveFPRsIfNecessary:
- beq cr1,LExit ; FPRs not in use
- addi r6,r3,JMP_fp_base_addr
- rlwinm r6,r6,0,0,27 ; mask off low 4 bits to qw align
+ addi r6,r3,JMP_fp_base_addr ; point to base of FPR save area
+ stg r3,JMP_addr_at_setjmp(r3) ; remember original address of jmpbuf
+ clrrgi r6,r6,4 ; mask off low 4 bits to qw align
+ mffs f0 ; get FPSCR
stfd f14,0*8(r6)
stfd f15,1*8(r6)
stfd f16,2*8(r6)
stfd f29,15*8(r6)
stfd f30,16*8(r6)
stfd f31,17*8(r6)
+ stfd f0,JMP_fpscr(r3) ; save fpscr in non-sliding region of jmpbuf
+
+ cmpwi r7,0 ; is AltiVec available? (test _COMM_PAGE_ALTIVEC)
+ addi r6,r3,JMP_vr_base_addr ; get base address of VR save area
+ addi r8,r3,JMP_vrsave ; we'll need this address below
+ li r3,0 ; set return value (always 0 on setjmp)
+ beqlr-- ; exit if no Altivec
+
+ mfspr r4,VRSave ; AltiVec available, so get VRSAVE mask
+ andi. r0,r4,0xFFF ; we only care about v20-v31
+ stg r0,0(r8) ; save effective VRSAVE in JMP_vrsave
+ beqlr++ ; if no live non-volatile VRs, we're done
+
+ stvx v20,0,r6
+ li r4,16*1
+ stvx v21,r4,r6
+ li r4,16*2
+ stvx v22,r4,r6
+ li r4,16*3
+ stvx v23,r4,r6
+ li r4,16*4
+ stvx v24,r4,r6
+ li r4,16*5
+ stvx v25,r4,r6
+ li r4,16*6
+ stvx v26,r4,r6
+ li r4,16*7
+ stvx v27,r4,r6
+ li r4,16*8
+ stvx v28,r4,r6
+ li r4,16*9
+ stvx v29,r4,r6
+ li r4,16*10
+ stvx v30,r4,r6
+ li r4,16*11
+ stvx v31,r4,r6
-LExit:
- li r3, 0
- blr
+ blr
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+SYSCALL(auditsvc, 2)
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
*/
-#import <architecture/ppc/asm_help.h>
-#import <architecture/ppc/pseudo_inst.h>
+/* We use mode-independent "g" opcodes such as "srgi", and/or
+ * mode-independent macros such as MI_GET_ADDRESS. These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
- .globl _errno
+ .globl _errno
-NESTED(cerror, 0, 1, 0, 0)
- REG_TO_EXTERN(r3,_errno)
- CALL_EXTERN(_cthread_set_errno_self)
- li32 r3,-1
- li32 r4,-1 /* in case a 64-bit value is returned */
- RETURN
-END(cerror)
+MI_ENTRY_POINT(cerror)
+ MI_PUSH_STACK_FRAME
+ MI_GET_ADDRESS(r12,_errno)
+ stw r3,0(r12) /* save syscall return code in global */
+ MI_CALL_EXTERNAL(_cthread_set_errno_self)
+ li r3,-1 /* then bug return value */
+ li r4,-1 /* in case we're returning a long-long in 32-bit mode, etc */
+ MI_POP_STACK_FRAME_AND_RETURN
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+SYSCALL(fgetxattr, 5)
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+SYSCALL(flistxattr, 4)
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* Created from M68K sources
*/
-#import <sys/syscall.h>
-#import <architecture/ppc/asm_help.h>
-#import <architecture/ppc/pseudo_inst.h>
-#import <mach/ppc/syscall_sw.h>
+/* We use mode-independent "g" opcodes such as "srgi". These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
+#include "SYS.h"
-/* We use 8 bytes for LOCAL_VAR(1) and LOCAL_VAR(2) */
-NESTED(_fork, 8, 0, 0, 0)
- CALL_EXTERN(__cthread_fork_prepare)
+
+MI_ENTRY_POINT(_fork)
+ MI_PUSH_STACK_FRAME
+
+ MI_CALL_EXTERNAL(__cthread_fork_prepare)
+
#if defined(__DYNAMIC__)
-.cstring
+ .cstring
LC1:
.ascii "__dyld_fork_prepare\0"
-.text
+ .text
.align 2
mflr r0
- bl 1f
+ bcl 20,31,1f
1: mflr r3
mtlr r0
addis r3,r3,ha16(LC1-1b)
addi r3,r3,lo16(LC1-1b)
- addi r4,r1,LOCAL_VAR(1)
- bl __dyld_func_lookup
- lwz r3,LOCAL_VAR(1)(r1)
+ addi r4,r1,SF_LOCAL1
+ bl __dyld_func_lookup
+ lg r3,SF_LOCAL1(r1)
mtspr ctr,r3
bctrl
#endif
- li r0,SYS_fork
- sc
- b Lbotch // error return
- cmpwi r4,0
- beq Lparent // parent, since a1 == 0 in parent,
- // 1 in child
+ li r0,SYS_fork
+ sc // do the fork
+ b Lbotch // error return
+
+ cmpwi r4,0 // parent (r4==0) or child (r4==1) ?
+ beq Lparent // parent, since r4==0
+
+
+/* Here if we are the child. */
+
#if defined(__DYNAMIC__)
-.cstring
+ .cstring
LC3:
.ascii "__dyld_fork_child\0"
-.text
+ .text
.align 2
mflr r0
- bl 1f
+ bcl 20,31,1f
1: mflr r3
mtlr r0
addis r3,r3,ha16(LC3-1b)
addi r3,r3,lo16(LC3-1b)
- addi r4,r1,LOCAL_VAR(1)
- bl __dyld_func_lookup
- lwz r3,LOCAL_VAR(1)(r1)
+ addi r4,r1,SF_LOCAL1
+ bl __dyld_func_lookup
+ lg r3,SF_LOCAL1(r1)
mtspr ctr,r3
bctrl
#endif
- li r3,0x0 // clear cached pid in child
- REG_TO_EXTERN(r3,__current_pid)
- CALL_EXTERN(__cthread_fork_child)
+
+ li r9,0
+ MI_GET_ADDRESS(r8,__current_pid)
+ stw r9,0(r8) // clear cached pid in child
+
+ MI_CALL_EXTERNAL(__cthread_fork_child)
+
#if defined(__DYNAMIC__)
-.cstring
+ .cstring
LC4:
.ascii "__dyld_fork_child_final\0"
-.text
+ .text
.align 2
mflr r0
- bl 1f
+ bcl 20,31,1f
1: mflr r3
mtlr r0
addis r3,r3,ha16(LC4-1b)
addi r3,r3,lo16(LC4-1b)
- addi r4,r1,LOCAL_VAR(1)
- bl __dyld_func_lookup
- lwz r3,LOCAL_VAR(1)(r1)
+ addi r4,r1,SF_LOCAL1
+ bl __dyld_func_lookup
+ lg r3,SF_LOCAL1(r1)
mtspr ctr,r3
bctrl
#endif
- li r3,0
+ li r3,0 // flag for "we are the child"
b Lreturn
+
+/* Here if we are the parent, with:
+ * r3 = child's pid
+ */
Lparent:
+ stg r3,SF_LOCAL2(r1) // save child pid in stack
+
#if defined(__DYNAMIC__)
- stw r3,LOCAL_VAR(2)(r1) // save child pid
mflr r0
- bl 1f
+ bcl 20,31,1f
1: mflr r3
mtlr r0
addis r3,r3,ha16(LC2-1b)
addi r3,r3,lo16(LC2-1b)
- addi r4,r1,LOCAL_VAR(1)
- bl __dyld_func_lookup
- lwz r3,LOCAL_VAR(1)(r1)
+ addi r4,r1,SF_LOCAL1
+ bl __dyld_func_lookup
+ lg r3,SF_LOCAL1(r1)
mtspr ctr,r3
bctrl
#endif
- CALL_EXTERN(__cthread_fork_parent)
-#if defined(__DYNAMIC__)
- lwz r3,LOCAL_VAR(2)(r1)
-#endif
- b Lreturn
+
+ b Lparent_return // clean up and return child's pid
+
+
+/* Here if the fork() syscall failed. We're still the parent. */
Lbotch:
+
#if defined(__DYNAMIC__)
-.cstring
+ .cstring
LC2:
.ascii "__dyld_fork_parent\0"
-.text
+ .text
.align 2
- stw r3,LOCAL_VAR(2)(r1) // save error value
+ stg r3,SF_LOCAL2(r1) // save error return in stack
mflr r0
- bl 1f
+ bcl 20,31,1f
1: mflr r3
mtlr r0
addis r3,r3,ha16(LC2-1b)
addi r3,r3,lo16(LC2-1b)
- addi r4,r1,LOCAL_VAR(1)
- bl __dyld_func_lookup
- lwz r3,LOCAL_VAR(1)(r1)
+ addi r4,r1,SF_LOCAL1
+ bl __dyld_func_lookup
+ lg r3,SF_LOCAL1(r1)
mtspr ctr,r3
bctrl
- lwz r3,LOCAL_VAR(2)(r1) // restore error value for cerror
-
+ lg r3,SF_LOCAL2(r1) // restore error code
#endif
- CALL_EXTERN(cerror)
+
+ MI_CALL_EXTERNAL(cerror)
+ li r3,-1 // get an error return code
+ stg r3,SF_LOCAL2(r1) // save return code in stack
+
/*
* We use cthread_fork_parent() to clean up after a fork error
* (unlock cthreads and mailloc packages) so the parent
* process can Malloc() after fork() errors without
* deadlocking.
*/
- CALL_EXTERN_AGAIN(__cthread_fork_parent)
- li32 r3,-1 // error return
-Lreturn: RETURN
-END(_fork)
+
+Lparent_return:
+ MI_CALL_EXTERNAL(__cthread_fork_parent)
+ lg r3,SF_LOCAL2(r1) // return -1 on error, child's pid on success
+
+Lreturn:
+ MI_POP_STACK_FRAME_AND_RETURN
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+SYSCALL(fremovexattr, 3)
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+SYSCALL(fsetxattr, 5)
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#import "SYS.h"
-PSEUDO(getegid,getgid,0)
- mr a0,a1
- blr
+SYSCALL(getegid,0)
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#import "SYS.h"
-PSEUDO(geteuid,getuid,0)
- mr a0,a1
- blr
-
+SYSCALL(geteuid,0)
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* @APPLE_LICENSE_HEADER_END@
*/
#include "SYS.h"
- .data
- EXPORT(__current_pid)
- .long 0
-TEXT
-LEAF(_getpid)
+ .data
+ .globl __current_pid
+ .align 2
+__current_pid:
+ .long 0
+
+MI_ENTRY_POINT(_getpid)
#if defined(__DYNAMIC__)
- mflr r0
- bcl 20,31,1f
+ mflr r0 // note we cannot use MI_GET_ADDRESS...
+ bcl 20,31,1f // ...because we define __current_pid
1:
mflr r5
mtlr r0
addis r5, r5, ha16(__current_pid - 1b)
addi r5, r5, lo16(__current_pid - 1b)
#else
- lis r5,ha16(__current_pid)
+ lis r5,hi16(__current_pid)
ori r5,r5,lo16(__current_pid)
#endif
- lwz r3,0(r5) // get the cached pid
- cmpwi r3,0 // if positive,
- bgtlr+ // return it
+ lwz r3,0(r5) // get the cached pid
+ cmpwi r3,0 // if positive,
+ bgtlr++ // return it
SYSCALL_NONAME(getpid, 0)
lwarx r4,0,r5 // see if we can cache it
- cmpwi r4,0 // we cant if there are any
- bltlr- // vforks in progress
+ cmpwi r4,0 // we can't if there are any...
+ blt-- 1f // ...vforks in progress
- stwcx. r3,0,r5 // ignore cache conflicts
- blr
-END(_getpid)
+ stwcx. r3,0,r5 // ignore cache conflicts
+ blr
+1:
+ li r6,-4 // on 970, cancel the reservation using red zone...
+ stwcx. r3,r6,r1 // ...to avoid an errata
+ blr
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#import "SYS.h"
-PSEUDO(getppid,getpid,0)
- mr a0,a1
- blr
+SYSCALL(getppid,0)
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+SYSCALL(getxattr, 5)
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+SYSCALL(lchown, 3)
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+SYSCALL(listxattr, 4)
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* Created. Derived from _setjmp.s, setjmp.c and setjmp.s
*/
+/* We use mode-independent "g" opcodes such as "stg", and/or
+ * mode-independent macros such as MI_GET_ADDRESS. These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
#include "SYS.h"
-#include <architecture/ppc/asm_help.h>
#include "_setjmp.h"
/*
/* void siglongjmp(sigjmp_buf env, int val); */
-LEAF(_siglongjmp)
- lwz r0, JMP_SIGFLAG(r3) ; load sigflag saved by siglongjmp()
- cmpwi cr1,r0,0 ; this changes cr1[EQ] which is volatile
- beq- cr1, L__longjmp ; if r0 == 0 do _longjmp()
+MI_ENTRY_POINT(_siglongjmp)
+ lg r0, JMP_SIGFLAG(r3) ; load sigflag saved by siglongjmp()
+ cmpgi cr1,r0,0 ; this changes cr1 which is volatile
+ beq-- cr1, L__exit ; if r0 == 0 do _longjmp()
; else *** fall through *** to longjmp()
/* void longjmp(jmp_buf env, int val); */
-LEAF(_longjmp)
-L_longjmp:
- mr r30, r3
- mr r31, r4
- lwz r3, JMP_sig(r3) ; restore the signal mask
- CALL_EXTERN(_sigsetmask)
- mr r4, r31
- mr r3, r30
-L__longjmp:
- BRANCH_EXTERN(__longjmp)
+MI_ENTRY_POINT(_longjmp)
+ mr r30, r3 ; preserve args across _sigsetmask
+ mr r31, r4
+
+ /* NB: this code assumes the signal mask is an int. Change the "lwz" below
+ * if not. The JMP_sig field is already 8 bytes in the jmpbuf.
+ */
+ lwz r3, JMP_sig(r3) ; restore the signal mask
+ MI_CALL_EXTERNAL(_sigsetmask) // make a (deprecated!) syscall to set the mask
+ mr r4, r31
+ mr r3, r30
+L__exit:
+ MI_BRANCH_EXTERNAL(__longjmp)
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*/
/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */
-#import <architecture/ppc/pseudo_inst.h>
#import "SYS.h"
SYSCALL(mount, 4)
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#import "SYS.h"
-LEAF(_pipe)
- stw r3,ARG(1)(r1) // preserve fildes on stack
+MI_ENTRY_POINT(_pipe)
+ mr r12,r3 // save fildes across syscall
SYSCALL_NONAME(pipe, 0)
- lwz r11,ARG(1)(r1) // restore fildes
- stw r3,0(r11)
- stw r4,4(r11)
- li r3,0
+ stw r3,0(r12)
+ stw r4,4(r12)
+ li r3,0
blr
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <machine/cpu_capabilities.h>
#undef __APPLE_API_PRIVATE
-LEAF(___commpage_gettimeofday)
+MI_ENTRY_POINT(___commpage_gettimeofday)
ba _COMM_PAGE_GETTIMEOFDAY
- .globl cerror
-LEAF(___ppc_gettimeofday)
- li r0,SYS_gettimeofday
- mr r12,r3
- sc
- b 1f
- b 2f
-1: BRANCH_EXTERN(cerror)
-2:
- mr. r12,r12
- beq 3f
- stw r3,0(r12)
- stw r4,4(r12)
- li r3,0
+
+MI_ENTRY_POINT(___ppc_gettimeofday)
+ mr r12,r3 // save ptr to timeval
+ SYSCALL_NONAME(gettimeofday,0)
+ mr. r12,r12 // was timeval ptr null?
+ beq 3f
+ stw r3,0(r12)
+ stw r4,4(r12)
+ li r3,0
3:
blr
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#import "SYS.h"
-LEAF(_ptrace)
- li r7,0
- REG_TO_EXTERN(r7,_errno)
-SYSCALL_NONAME(ptrace, 4)
+MI_ENTRY_POINT(_ptrace)
+ li r7,0
+ MI_GET_ADDRESS(r8,_errno)
+ stw r7,0(r8)
+ SYSCALL_NONAME(ptrace, 4)
blr
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#import "SYS.h"
SYSCALL(reboot, 2)
- BRANCH_EXTERN(_abort)
+ MI_BRANCH_EXTERNAL(_abort)
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+SYSCALL(removexattr, 3)
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* Created. Derived from _setjmp.s, setjmp.c and setjmp.s
*/
+/* We use mode-independent "g" opcodes such as "stg", and/or
+ * mode-independent macros such as MI_GET_ADDRESS. These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
+
#include "SYS.h"
-#include <architecture/ppc/asm_help.h>
#include "_setjmp.h"
/*
/* int sigsetjmp(sigjmp_buf env, int savemask); */
-LEAF(_sigsetjmp)
- cmpwi cr1,r4,0 ; this changes cr1[EQ] which is volatile
- stw r4, JMP_SIGFLAG(r3) ; save the sigflag for use by siglongjmp()
- beq- cr1, L__setjmp ; if r4 == 0 do _setjmp()
+MI_ENTRY_POINT(_sigsetjmp)
+ cmpgi cr1,r4,0 ; this changes cr1 which is volatile
+ stg r4, JMP_SIGFLAG(r3) ; save the sigflag for use by siglongjmp()
+ beq-- cr1, L__exit ; if r4 == 0 do _setjmp()
; else *** fall through *** to setjmp()
/* int setjmp(jmp_buf env); */
-LEAF(_setjmp)
-L_setjmp:
- mflr r0
- stw r31, JMP_r31(r3)
- stw r0, JMP_lr(r3)
- mr r31, r3
- li r3, 1 ; get the previous signal mask
- li r4, 0
- la r5, JMP_sig(r31) ; get address where previous mask needs to be
- CALL_EXTERN(_sigprocmask)
- mr r3, r31
- lwz r0, JMP_lr(r3)
- mtlr r0
- lwz r31, JMP_r31(r3)
-L__setjmp:
- BRANCH_EXTERN(__setjmp)
+MI_ENTRY_POINT(_setjmp)
+ mflr r0
+ stg r31, JMP_r31(r3)
+ stg r0, JMP_lr(r3)
+ mr r31, r3 ; save ptr to jmpbuf across call
+ li r3, 1 ; get the previous signal mask
+ li r4, 0
+ la r5, JMP_sig(r31) ; get address where previous mask needs to be
+ MI_CALL_EXTERNAL(_sigprocmask) // make a syscall to get mask
+ mr r3, r31 ; restore jmp_buf ptr
+ lg r0, JMP_lr(r31)
+ lg r31, JMP_r31(r31)
+ mtlr r0
+L__exit:
+ MI_BRANCH_EXTERNAL(__setjmp)
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include "SYS.h"
+
+SYSCALL(setxattr, 5)
+
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* Created.
*/
-#import "assym.h"
#import "SYS.h"
/*
* r3 = sigcontext pointer
*/
-LEAF(_sigreturn)
+MI_ENTRY_POINT(_sigreturn)
/* Now call the kernel routine to restore the rest */
SYSCALL_NONAME(sigreturn, 1)
blr
-END(_sigreturn)
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* Created from fork.s
*
*/
-#if 0
-#import <sys/syscall.h>
-#import <architecture/ppc/asm_help.h>
-#import <architecture/ppc/pseudo_inst.h>
-#import <mach/ppc/syscall_sw.h>
-
-/* We use 8 bytes for LOCAL_VAR(1) and LOCAL_VAR(2) */
-NESTED(_vfork, 8, 0, 0, 0)
- CALL_EXTERN(__cthread_fork_prepare)
-#if defined(__DYNAMIC__)
-.cstring
-LC1:
- .ascii "__dyld_fork_prepare\0"
-.text
- .align 2
- mflr r0
- bl 1f
-1: mflr r3
- mtlr r0
- addis r3,r3,ha16(LC1-1b)
- addi r3,r3,lo16(LC1-1b)
- addi r4,r1,LOCAL_VAR(1)
- bl __dyld_func_lookup
- lwz r3,LOCAL_VAR(1)(r1)
- mtspr ctr,r3
- bctrl
-#endif
- li r0,SYS_vfork
- sc
- b Lbotch // error return
- cmpwi r4,0
- beq Lparent // parent, since a1 == 0 in parent,
- // 1 in child
-#if defined(__DYNAMIC__)
-.cstring
-LC3:
- .ascii "__dyld_fork_child\0"
-.text
- .align 2
- mflr r0
- bl 1f
-1: mflr r3
- mtlr r0
- addis r3,r3,ha16(LC3-1b)
- addi r3,r3,lo16(LC3-1b)
- addi r4,r1,LOCAL_VAR(1)
- bl __dyld_func_lookup
- lwz r3,LOCAL_VAR(1)(r1)
- mtspr ctr,r3
- bctrl
-#endif
- li r3,0
- REG_TO_EXTERN(r3, EXT(_current_pid))
- CALL_EXTERN(_fork_mach_init)
- CALL_EXTERN(__cthread_fork_child)
-#if defined(__DYNAMIC__)
-.cstring
-LC4:
- .ascii "__dyld_fork_child_final\0"
-.text
- .align 2
- mflr r0
- bl 1f
-1: mflr r3
- mtlr r0
- addis r3,r3,ha16(LC4-1b)
- addi r3,r3,lo16(LC4-1b)
- addi r4,r1,LOCAL_VAR(1)
- bl __dyld_func_lookup
- lwz r3,LOCAL_VAR(1)(r1)
- mtspr ctr,r3
- bctrl
-#endif
-
- li r3,0
- b Lreturn
+/* We use mode-independent "g" opcodes such as "srgi", and/or
+ * mode-independent macros such as MI_GET_ADDRESS. These expand
+ * into word operations when targeting __ppc__, and into doubleword
+ * operations when targeting __ppc64__.
+ */
+#include <architecture/ppc/mode_independent_asm.h>
-Lparent:
-#if defined(__DYNAMIC__)
- stw r3,LOCAL_VAR(2)(r1) // save child pid
- mflr r0
- bl 1f
-1: mflr r3
- mtlr r0
- addis r3,r3,ha16(LC2-1b)
- addi r3,r3,lo16(LC2-1b)
- addi r4,r1,LOCAL_VAR(1)
- bl __dyld_func_lookup
- lwz r3,LOCAL_VAR(1)(r1)
- mtspr ctr,r3
- bctrl
-#endif
- CALL_EXTERN(__cthread_fork_parent)
-#if defined(__DYNAMIC__)
- lwz r3,LOCAL_VAR(2)(r1)
-#endif
- b Lreturn
+/* In vfork(), the child runs in parent's address space. */
-Lbotch:
-#if defined(__DYNAMIC__)
-.cstring
-LC2:
- .ascii "__dyld_fork_parent\0"
-.text
- .align 2
- stw r3,LOCAL_VAR(2)(r1) // save error value
- mflr r0
- bl 1f
-1: mflr r3
- mtlr r0
- addis r3,r3,ha16(LC2-1b)
- addi r3,r3,lo16(LC2-1b)
- addi r4,r1,LOCAL_VAR(1)
- bl __dyld_func_lookup
- lwz r3,LOCAL_VAR(1)(r1)
- mtspr ctr,r3
- bctrl
- lwz r3,LOCAL_VAR(2)(r1) // restore error value for cerror
-
-#endif
- CALL_EXTERN(cerror)
- /*
- * We use cthread_fork_parent() to clean up after a fork error
- * (unlock cthreads and mailloc packages) so the parent
- * process can Malloc() after fork() errors without
- * deadlocking.
- */
- CALL_EXTERN_AGAIN(__cthread_fork_parent)
- li32 r3,-1 // error return
-Lreturn: RETURN
-END(_vfork)
-#else
#include "SYS.h"
-LEAF(_vfork)
-#if defined(__DYNAMIC__)
- PICIFY(__current_pid)
- mr r5,PICIFY_REG
- NON_LAZY_STUB(__current_pid)
-#else
- lis r5,ha16(__current_pid)
- ori r5,r5,lo16(__current_pid)
-#endif
+MI_ENTRY_POINT(_vfork)
+ MI_GET_ADDRESS(r5,__current_pid) // get address of __current_pid in r5
2:
- lwarx r6,0,r5 // dont cache pid across vfork
+ lwarx r6,0,r5 // don't cache pid across vfork
cmpwi r6,0
- ble- 3f // is another vfork in progress
- li r6,0 // if not, erase the stored pid
+ ble-- 3f // is another vfork in progress
+ li r6,0 // if not, erase the stored pid
3:
addi r6,r6,-1 // count the parallel vforks in
stwcx. r6,0,r5 // negative cached pid values
- bne- 2b
+ bne-- 2b
- li r0,SYS_vfork
+ li r0,SYS_vfork
sc
- b Lbotch // error return
+ b Lbotch // error return
cmpwi r4,0
- beq Lparent // parent, since a1 == 0 in parent,
+ beq Lparent // parent, since a1 == 0 in parent,
- li r3,0 // child
+ li r3,0 // child
blr
-Lparent:
- lwarx r6,0,r5 // were back, decrement vfork count
+Lparent: // r3 == child's pid
+ lwarx r6,0,r5 // we're back, decrement vfork count
addi r6,r6,1
stwcx. r6,0,r5
- bne- Lparent
- blr
+ bne-- Lparent
+ blr // return pid
Lbotch:
lwarx r6,0,r5 // never went, decrement vfork count
addi r6,r6,1
stwcx. r6,0,r5
- bne- Lbotch
+ bne-- Lbotch
- BRANCH_EXTERN(cerror)
-END(_vfork)
-#endif
+ MI_BRANCH_EXTERNAL(cerror)
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+# searching ppc directory as a fallback to avoid unnecessary code duplication
+.PATH: ${.CURDIR}/ppc/gen
+
+MDSRCS += \
+ abs.s \
+ ecvt.c \
+ ffs.s \
+ fp.h \
+ icacheinval.s \
+ mcount.s \
+ setjmperr.c
+
+SUPPRESSSRCS += memcpy.c memmove.c memset.c
--- /dev/null
+# searching ppc directory as a fallback to avoid unnecessary code duplication
+.PATH: ${.CURDIR}/ppc/mach
+
+MDSRCS += mach_absolute_time.s
--- /dev/null
+# searching ppc directory as a fallback to avoid unnecessary code duplication
+.PATH: ${.CURDIR}/ppc/pthreads
+
+MDSRCS += \
+ init_cpu_capabilities.c \
+ get_cpu_capabilities.s \
+ pthread_set_self.s \
+ pthread_self.s \
+ pthread_getspecific.s
--- /dev/null
+.PATH: ${.CURDIR}/ppc/stdlib
+# Long double is just double precision.
+FBSDSRCS+=machdep_ldisd.c
--- /dev/null
+# searching ppc directory as a fallback to avoid unnecessary code duplication
+#
+.PATH: ${.CURDIR}/ppc/string
+
+MDSRCS += \
+ bcopy.s \
+ bzero.s \
+ memcmp.s \
+ strcat.s \
+ strcmp.s \
+ strcpy.s \
+ strlcat.s \
+ strlcpy.s \
+ strlen.s \
+ strncat.s \
+ strncmp.s \
+ strncpy.s
+
+SUPPRESSSRCS += bcmp.c
+
--- /dev/null
+# searching ppc directory as a fallback to avoid unnecessary code duplication
+.PATH: ${.CURDIR}/ppc/sys
+
+MDSRCS+= ATPgetreq.s \
+ ATPgetrsp.s \
+ ATPsndreq.s \
+ ATPsndrsp.s \
+ ATgetmsg.s \
+ ATputmsg.s \
+ ATsocket.s \
+ OSAtomic.s \
+ _exit.s \
+ _getlogin.s \
+ _longjmp.s \
+ _pthread_kill.s \
+ _setjmp.s \
+ _setlogin.s \
+ _sysctl.s \
+ accept.s \
+ access.s \
+ acct.s \
+ add_profil.s \
+ adjtime.s \
+ aio_cancel.s \
+ aio_error.s \
+ aio_fsync.s \
+ aio_read.s \
+ aio_return.s \
+ aio_suspend.s \
+ aio_write.s \
+ audit.s \
+ auditctl.s \
+ auditon.s \
+ auditsvc.s \
+ bind.s \
+ cerror.s \
+ chdir.s \
+ checkuseraccess.s \
+ chflags.s \
+ chmod.s \
+ chown.s \
+ chroot.s \
+ close.s \
+ connect.s \
+ dup.s \
+ dup2.s \
+ exchangedata.s \
+ execve.s \
+ fchdir.s \
+ fchflags.s \
+ fchmod.s \
+ fchown.s \
+ fcntl.s \
+ fgetxattr.s \
+ fhopen.s \
+ flistxattr.s \
+ flock.s \
+ fork.s \
+ fpathconf.s \
+ fremovexattr.s \
+ fsctl.s \
+ fsetxattr.s \
+ fstat.s \
+ fstatfs.s \
+ fstatv.s \
+ fsync.s \
+ ftruncate.s \
+ futimes.s \
+ getattrlist.s \
+ getaudit.s \
+ getaudit_addr.s \
+ getauid.s \
+ getdirentries.s \
+ getdirentriesattr.s \
+ getegid.s \
+ geteuid.s \
+ getfh.s \
+ getfsstat.s \
+ getgid.s \
+ getgroups.s \
+ getitimer.s \
+ getpeername.s \
+ getpgid.s \
+ getpgrp.s \
+ getpid.s \
+ getppid.s \
+ getpriority.s \
+ getrlimit.s \
+ getrusage.s \
+ getsid.s \
+ getsockname.s \
+ getsockopt.s \
+ getuid.s \
+ getxattr.s \
+ ioctl.s \
+ issetugid.s \
+ kevent.s \
+ kill.s \
+ kqueue.s \
+ kqueue_from_portset_np.s \
+ kqueue_portset_np.s \
+ ktrace.s \
+ link.s \
+ lio_listio.s \
+ listen.s \
+ listxattr.s \
+ load_shared_file.s \
+ longjmp.s \
+ lseek.s \
+ lstat.s \
+ lstatv.s \
+ madvise.s \
+ mincore.s \
+ minherit.s \
+ mkcomplex.s \
+ mkdir.s \
+ mkfifo.s \
+ mknod.s \
+ mlock.s \
+ mlockall.s \
+ mmap.s \
+ mount.s \
+ mprotect.s \
+ msgctl.s \
+ msgget.s \
+ msgrcv.s \
+ msgsnd.s \
+ msgsys.s \
+ msync.s \
+ munlock.s \
+ munlockall.s \
+ munmap.s \
+ new_system_shared_regions.s \
+ nfsclnt.s \
+ nfssvc.s \
+ open.s \
+ pathconf.s \
+ pipe.s \
+ posix_madvise.s \
+ ppc_gettimeofday.s \
+ pread.s \
+ processor_facilities.s \
+ profil.s \
+ pthread_sigmask.s \
+ ptrace.s \
+ pwrite.s \
+ quota.s \
+ quotactl.s \
+ read.s \
+ readlink.s \
+ readv.s \
+ reboot.s \
+ recvfrom.s \
+ recvmsg.s \
+ removexattr.s \
+ rename.s \
+ reset_shared_file.s \
+ revoke.s \
+ rmdir.s \
+ searchfs.s \
+ select.s \
+ sem_close.s \
+ sem_destroy.s \
+ sem_getvalue.s \
+ sem_init.s \
+ sem_post.s \
+ sem_trywait.s \
+ sem_wait.s \
+ semconfig.s \
+ semctl.s \
+ semget.s \
+ semop.s \
+ semsys.s \
+ sendmsg.s \
+ sendto.s \
+ setattrlist.s \
+ setaudit.s \
+ setaudit_addr.s \
+ setauid.s \
+ setegid.s \
+ seteuid.s \
+ setgid.s \
+ setgroups.s \
+ setitimer.s \
+ setjmp.s \
+ setpgid.s \
+ setpriority.s \
+ setprivexec.s \
+ setquota.s \
+ setrlimit.s \
+ setsid.s \
+ setsockopt.s \
+ settimeofday.s \
+ setuid.s \
+ setxattr.s \
+ shmat.s \
+ shmctl.s \
+ shmdt.s \
+ shmget.s \
+ shmsys.s \
+ shutdown.s \
+ sigaltstack.s \
+ sigpending.s \
+ sigprocmask.s \
+ sigreturn.s \
+ sigwait.s \
+ socket.s \
+ socketpair.s \
+ stat.s \
+ statfs.s \
+ statv.s \
+ swapon.s \
+ symlink.s \
+ sync.s \
+ syscall.s \
+ systable.s \
+ truncate.s \
+ umask.s \
+ undelete.s \
+ unlink.s \
+ unmount.s \
+ utimes.s \
+ vfork.s \
+ wait4.s \
+ write.s \
+ writev.s
+
+.for _src in fhopen.s getfh.s nfsclnt.s
+CFLAGS-${_src} += -DNFSCLIENT
+.endfor
+
+CFLAGS-nfssvc.s += -DNFSSERVER
-.PATH: ${.CURDIR}/${MACHINE_ARCH}/pthreads ${.CURDIR}/pthreads
-
.if exists(${.CURDIR}/${MACHINE_ARCH}/pthreads/Makefile.inc)
.include "${.CURDIR}/${MACHINE_ARCH}/pthreads/Makefile.inc"
.endif
-SRCS += pthread_cond.c pthread_tsd.c pthread.c \
+.PATH: ${.CURDIR}/pthreads
+
+MISRCS += pthread_cond.c pthread_tsd.c pthread.c \
pthread_mutex.c thread_setup.c lock.s stack.s pthread_rwlock.c
PTHREADS_INSTHDRS += pthread.h pthread_impl.h sched.h
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <machine/cpu_capabilities.h>
#undef __APPLE_API_PRIVATE
-#if defined(__ppc__)
+#if defined(__ppc__) || defined(__ppc64__)
#import <architecture/ppc/asm_help.h>
#import <architecture/ppc/pseudo_inst.h>
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#define STACK_START(stack_low) (STACK_BASE(stack_low) - STACK_RESERVED)
#define STACK_SELF(sp) STACK_START(sp)
-#if defined(__ppc__)
+#if defined(__ppc__) || defined(__ppc64__)
static const vm_address_t PTHREAD_STACK_HINT = 0xF0000000;
#elif defined(__i386__)
static const vm_address_t PTHREAD_STACK_HINT = 0xB0000000;
int mib[2];
size_t len;
int numcpus;
+ void *stackaddr;
count = HOST_PRIORITY_INFO_COUNT;
info = (host_info_t)&priority_info;
thread = &_thread;
LIST_INSERT_HEAD(&__pthread_head, thread, plist);
_pthread_set_self(thread);
- _pthread_create(thread, attrs, (void *)USRSTACK, mach_thread_self());
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_USRSTACK;
+ len = sizeof (stackaddr);
+ if (sysctl (mib, 2, &stackaddr, &len, NULL, 0) != 0)
+ stackaddr = (void *)USRSTACK;
+ _pthread_create(thread, attrs, stackaddr, mach_thread_self());
thread->detached = PTHREAD_CREATE_JOINABLE|_PTHREAD_CREATE_PARENT;
/* See if we're on a multiprocessor and set _spin_tries if so. */
}
#endif
+#if defined(_OBJC_PAGE_BASE_ADDRESS)
+{
+ vm_address_t objcRTPage = (vm_address_t)_OBJC_PAGE_BASE_ADDRESS;
+ kr = vm_map(mach_task_self(),
+ &objcRTPage, vm_page_size * 4, vm_page_size - 1,
+ VM_FLAGS_FIXED | VM_MAKE_TAG(0), // Which tag to use?
+ MACH_PORT_NULL,
+ (vm_address_t)0, FALSE,
+ (vm_prot_t)0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE,
+ VM_INHERIT_DEFAULT);
+ /* We ignore the return result here. The ObjC runtime will just have to deal. */
+}
+#endif
+
mig_init(1); /* enable multi-threaded mig interfaces */
return 0;
}
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#include <unistd.h>
#include <limits.h>
#include <signal.h>
+#include <sys/types.h> /* temporary - need to fix correctly */
#ifndef _POSIX_C_SOURCE
#include <mach/mach_types.h>
/* These will be moved to unistd.h */
-
-/* These two should be defined also */
-#undef _POSIX_THREAD_PROCESS_SHARED
-#undef _POSIX_THREAD_SAFE_FUNCTIONS
-
/*
* Note: These data structures are meant to be opaque. Only enough
* structure is exposed to support initializers.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
LIST_ENTRY(_pthread) plist;
} *pthread_t;
+// suppress pthread_t typedef in signal.h
+#define _PTHREAD_T_DECLARED
+
/*
* This will cause a compile-time failure if someone moved the tsd field
* and we need to change _PTHREAD_TSD_OFFSET in pthread_machdep.h
boolean_t freeStackOnExit;/* Should we free the stack when we exit? */
} pthread_attr_t;
+// suppress pthread_attr_t typedef in sys/signal.h
+#define _PTHREAD_ATTR_T_DECLARED
+
/*
* Mutex attributes
*/
/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
#ifndef _POSIX_PTHREAD_MACHDEP_H
#define _POSIX_PTHREAD_MACHDEP_H
+#ifdef __LP64__
+#define _PTHREAD_TSD_OFFSET 0x68
+#else
#define _PTHREAD_TSD_OFFSET 0x48
+#endif /* __LP64__ */
+
#ifndef __ASSEMBLER__
-typedef long pthread_lock_t;
+typedef int32_t pthread_lock_t;
#endif
#define LOCK_INIT(l) ((l) = 0)
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
.text
-#if defined(__ppc__)
+#if defined(__ppc__) || defined(__ppc64__)
#import <architecture/ppc/asm_help.h>
#import <architecture/ppc/pseudo_inst.h>
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* Machine specific support for thread initialization
*/
-#if defined(__ppc__)
+#if defined(__ppc__) || defined(__ppc64__)
#include <architecture/ppc/cframe.h>
#endif
{
kern_return_t r;
unsigned int count;
-#if defined(__ppc__)
+#if defined(__ppc__) || defined(__ppc64__)
struct ppc_thread_state state = {0};
struct ppc_thread_state *ts = &state;
.if ${MACHINE_ARCH} == "i386"
-SRCS+= cmpdi2.c divdi3.c moddi3.c qdivrem.c ucmpdi2.c udivdi3.c umoddi3.c
+MISRCS+= cmpdi2.c divdi3.c moddi3.c qdivrem.c ucmpdi2.c udivdi3.c umoddi3.c
.else
-SRCS+= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c fixdfdi.c \
+MISRCS+= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c fixdfdi.c \
fixsfdi.c fixunsdfdi.c fixunssfdi.c floatdidf.c floatdisf.c \
floatunsdidf.c iordi3.c lshldi3.c lshrdi3.c moddi3.c muldi3.c \
negdi2.c notdi2.c qdivrem.c subdi3.c ucmpdi2.c udivdi3.c umoddi3.c \
# regex sources
.PATH: ${.CURDIR}/regex
-CFLAGS+=-DPOSIX_MISTAKE
-
.include "Makefile.fbsd_begin"
-FBSDSRCS= regcomp.c regerror.c regexec.c regfree.c
-FBSDORIGHDRS= cclass.h cname.h engine.c regex2.h utils.h
+FBSDMISRCS= regcomp.c regerror.c regexec.c regfree.c
+CFLAGS-regcomp-fbsd.c+= -DPOSIX_MISTAKE
+FBSDHDRS= cclass.h cname.h engine.c regex2.h utils.h
.include "Makefile.fbsd_end"
.if ${LIB} == "c"
# $FreeBSD: src/lib/libc/rpc/Makefile.inc,v 1.21 2001/10/04 21:03:17 wpaul Exp $
.PATH: ${.CURDIR}/../libc/rpc ${.CURDIR}/.
-SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \
+MISRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \
clnt_dg.c clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c \
clnt_vc.c rpc_dtablesize.c getnetconfig.c getnetpath.c getrpcent.c \
getrpcport.c mt_misc.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \
svc_raw.c svc_run.c svc_simple.c svc_vc.c
# XDR
-SRCS+= xdr.c xdr_array.c xdr_float.c xdr_mem.c xdr_rec.c xdr_reference.c \
+MISRCS+= xdr.c xdr_array.c xdr_float.c xdr_mem.c xdr_rec.c xdr_reference.c \
xdr_stdio.c
# Secure-RPC
-SRCS+= auth_time.c auth_des.c authdes_prot.c des_crypt.c des_soft.c \
+MISRCS+= auth_time.c auth_des.c authdes_prot.c des_crypt.c des_soft.c \
crypt_client.c key_call.c key_prot_xdr.c getpublickey.c \
svc_auth_des.c
# Resolver stuff
-SRCS+= netname.c netnamer.c rpcdname.c
+MISRCS+= netname.c netnamer.c rpcdname.c
# Misc Source
-SRCS+= rtime.c
+MISRCS+= rtime.c
# generated sources
-SRCS+= crypt_clnt.c crypt_xdr.c crypt.h
-
-CFLAGS+= -DBROKEN_DES -DPORTMAP -DDES_BUILTIN
+MISRCS+= crypt_clnt.c crypt_xdr.c crypt.h
CLEANFILES+= crypt_clnt.c crypt_xdr.c crypt.h
--- /dev/null
+--- fgets.3.orig Fri May 28 14:34:54 2004
++++ fgets.3 Fri May 28 14:35:03 2004
+@@ -152,11 +152,6 @@
+ .Xr ferror 3 ,
+ .Xr fgetln 3 ,
+ .Xr fgetws 3
+-.Rs
+-.%T "The FreeBSD Security Architecture"
+-.Re
+-(See
+-.Pa /usr/share/doc/{to be determined} . )
+ .Sh STANDARDS
+ The functions
+ .Fn fgets
---- findfp.c.orig Tue May 20 15:22:41 2003
-+++ findfp.c Sun Jul 20 18:50:26 2003
+--- findfp.c.orig Wed Dec 10 13:02:27 2003
++++ findfp.c Wed Dec 10 13:04:25 2003
@@ -47,6 +47,7 @@
#include <stdlib.h>
#include <string.h>
/*
* We can't make this 'static' until 6.0-current due to binary
-@@ -81,17 +83,6 @@
- std(__SWR|__SNBF, STDERR_FILENO)
- };
-
--/*
-- * The following kludge is done to ensure enough binary compatibility
-- * with future versions of libc. Or rather it allows us to work with
-- * libraries that have been built with a newer libc that defines these
-- * symbols and expects libc to provide them. We only have need to support
-- * i386 and alpha because they are the only "old" systems we have deployed.
-- */
--FILE *__stdinp = &__sF[0];
--FILE *__stdoutp = &__sF[1];
--FILE *__stderrp = &__sF[2];
--
- struct glue __sglue = { &uglue, 3, __sF };
- static struct glue *lastglue = &uglue;
-
-@@ -113,7 +104,7 @@
+@@ -113,7 +115,7 @@
{
struct glue *g;
static FILE empty;
FILE *p;
struct __sFILEX *fx;
-@@ -179,6 +170,7 @@
+@@ -179,6 +181,7 @@
fp->_lb._base = NULL; /* no line buffer */
fp->_lb._size = 0;
/* fp->_lock = NULL; */ /* once set always set (reused) */
* SUCH DAMAGE.
*
* @(#)floatio.h 8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/floatio.h,v 1.4 2003/04/05 22:11:42 das Exp $
+ * $FreeBSD: src/lib/libc/stdio/floatio.h,v 1.5 2004/01/18 08:28:47 das Exp $
*/
/*
#error "floating point buffers too small"
#endif
+char *__hdtoa(double, const char *, int, int *, int *, char **);
+char *__hldtoa(long double, const char *, int, int *, int *, char **);
char *__ldtoa(long double *, int, int, int *, int *, char **);
--- /dev/null
+--- ftell.c.orig Tue May 20 15:22:42 2003
++++ ftell.c Tue May 25 13:14:32 2004
+@@ -105,6 +105,7 @@
+ * Find offset of underlying I/O object, then
+ * adjust for buffered bytes.
+ */
++ __sflush(fp); /* may adjust seek offset on append stream */
+ if (fp->_flags & __SOFF)
+ pos = fp->_offset;
+ else {
--- /dev/null
+--- mktemp.c.orig Tue Mar 30 22:56:07 2004
++++ mktemp.c Tue Mar 30 23:39:22 2004
+@@ -40,6 +40,7 @@
+ #include "namespace.h"
+ #include <sys/types.h>
+ #include <sys/stat.h>
++#include <sys/syslimits.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <stdio.h>
+@@ -106,13 +107,14 @@
+ int domkdir;
+ int slen;
+ {
+- char *start, *trv, *suffp;
++ char *start, *trv, *suffp, *carryp;
+ char *pad;
+ struct stat sbuf;
+ int rval;
+ uint32_t rand;
++ char carrybuf[NAME_MAX];
+
+- if (doopen != NULL && domkdir) {
++ if ((doopen != NULL && domkdir) || slen < 0) {
+ errno = EINVAL;
+ return (0);
+ }
+@@ -122,7 +124,7 @@
+ trv -= slen;
+ suffp = trv;
+ --trv;
+- if (trv < path) {
++ if (trv < path || NULL != strchr(suffp, '/')) {
+ errno = EINVAL;
+ return (0);
+ }
+@@ -134,6 +136,9 @@
+ }
+ start = trv + 1;
+
++ /* save first combination of random characters */
++ memcpy(carrybuf, start, suffp - start);
++
+ /*
+ * check the target directory.
+ */
+@@ -170,14 +175,25 @@
+ return (errno == ENOENT);
+
+ /* If we have a collision, cycle through the space of filenames */
+- for (trv = start;;) {
+- if (*trv == '\0' || trv == suffp)
+- return (0);
++ for (trv = start, carryp = carrybuf;;) {
++ /* have we tried all possible permutations? */
++ if (trv == suffp)
++ return (0); /* yes - exit with EEXIST */
+ pad = strchr(padchar, *trv);
+- if (pad == NULL || *++pad == '\0')
+- *trv++ = padchar[0];
+- else {
+- *trv++ = *pad;
++ if (pad == NULL) {
++ /* this should never happen */
++ errno = EIO;
++ return (0);
++ }
++ /* increment character */
++ *trv = (*++pad == '\0') ? padchar[0] : *pad;
++ /* carry to next position? */
++ if (*trv == *carryp) {
++ /* increment position and loop */
++ ++trv;
++ ++carryp;
++ } else {
++ /* try with new name */
+ break;
+ }
+ }
---- printf.3.orig Thu Aug 21 18:19:02 2003
-+++ printf.3 Thu Aug 21 18:17:44 2003
+--- printf.3.orig Fri May 28 14:31:32 2004
++++ printf.3 Fri May 28 14:33:23 2004
@@ -287,6 +287,20 @@
.Xr localeconv 3 .
.El
.It
-+An optional seperator character (
++An optional separator character (
+.Cm \ , | \; | \ : | _
-+) used for seperating multiple values when printing an AltiVec vector,
++) used for separating multiple values when printing an AltiVec vector,
+or other multi-value unit.
+.Pp
+NOTE: This is an AltiVec only extension onto the
.It
A character that specifies the type of conversion to be applied.
.El
+@@ -785,11 +821,6 @@
+ .Xr scanf 3 ,
+ .Xr setlocale 3 ,
+ .Xr wprintf 3
+-.Rs
+-.%T "The FreeBSD Security Architecture"
+-.Re
+-(See
+-.Pa "/usr/share/doc/{to be determined}" . )
+ .Sh STANDARDS
+ Subject to the caveats noted in the
+ .Sx BUGS
+++ /dev/null
-Index: sscanf.c
-===================================================================
-RCS file: /cvs/root/Libc/stdio/FreeBSD/sscanf.c,v
-retrieving revision 1.2
-diff -u -d -b -w -u -r1.2 sscanf.c
---- sscanf.c 2003/05/20 22:22:44 1.2
-+++ sscanf.c 2003/06/03 06:56:38
-@@ -66,6 +66,12 @@
- struct __sFILEX extra;
- FILE f;
-
-+#if defined(__APPLE_PR3275149_HACK__)
-+ /* If the string is NULL and we're using the broken Jaguar behavior, there's no sense in proceeding any further since we know we can return 0 */
-+ if (str && str[0] == '\0')
-+ return 0;
-+#endif
-+
- f._file = -1;
- f._flags = __SRD;
- f._bf._base = f._p = (unsigned char *)str;
--- /dev/null
+--- tmpnam.3.orig Fri May 28 14:35:53 2004
++++ tmpnam.3 Fri May 28 14:36:02 2004
+@@ -229,11 +229,6 @@
+ .Sh SEE ALSO
+ .Xr mkstemp 3 ,
+ .Xr mktemp 3
+-.Rs
+-.%T "The FreeBSD Security Architecture"
+-.Re
+-(See
+-.Pa "/usr/share/doc/{to be determined}" . )
+ .Sh STANDARDS
+ The
+ .Fn tmpfile
static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.59 2003/04/19 23:53:19 das Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.65 2004/05/02 10:55:05 das Exp $");
/*
* Actual printf innards.
#include "local.h"
#include "fvwrite.h"
-/* Define FLOATING_POINT to get floating point. */
-#define FLOATING_POINT
-
union arg {
int intarg;
u_int uintarg;
ptrdiff_t *pptrdiffarg;
size_t *psizearg;
intmax_t *pintmaxarg;
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
double doublearg;
long double longdoublearg;
#endif
static char *
__wcsconv(wchar_t *wcsarg, int prec)
{
+ static const mbstate_t initial;
+ mbstate_t mbs;
char buf[MB_LEN_MAX];
wchar_t *p;
char *convbuf, *mbp;
size_t clen, nbytes;
- mbstate_t mbs;
/*
* Determine the number of bytes to output and allocate space for
* the output.
*/
- memset(&mbs, 0, sizeof(mbs));
if (prec >= 0) {
nbytes = 0;
p = wcsarg;
+ mbs = initial;
for (;;) {
clen = wcrtomb(buf, *p++, &mbs);
if (clen == 0 || clen == (size_t)-1 ||
}
} else {
p = wcsarg;
+ mbs = initial;
nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs);
if (nbytes == (size_t)-1)
return (NULL);
*/
mbp = convbuf;
p = wcsarg;
- memset(&mbs, 0, sizeof(mbs));
+ mbs = initial;
while (mbp - convbuf < nbytes) {
clen = wcrtomb(mbp, *p++, &mbs);
if (clen == 0 || clen == (size_t)-1)
return (ret);
}
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
#define dtoa __dtoa
#define freedtoa __freedtoa
static int exponent(char *, int, int);
-#endif /* FLOATING_POINT */
+#endif /* !NO_FLOATING_POINT */
/*
* The size of the buffer we use as scratch space for integer
char sign; /* sign prefix (' ', '+', '-', or \0) */
char thousands_sep; /* locale specific thousands separator */
const char *grouping; /* locale specific numeric grouping rules */
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
/*
* We can decompose the printed representation of floating
* point numbers into several parts, some of which may be empty:
thousands_sep = '\0';
grouping = NULL;
convbuf = NULL;
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
dtoaresult = NULL;
decimal_point = localeconv()->decimal_point;
#endif
}
width = n;
goto reswitch;
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
case 'L':
flags |= LONGDBL;
goto rflag;
/*FALLTHROUGH*/
case 'c':
if (flags & LONGINT) {
+ static const mbstate_t initial;
mbstate_t mbs;
size_t mbseqlen;
- memset(&mbs, 0, sizeof(mbs));
+ mbs = initial;
mbseqlen = wcrtomb(cp = buf,
(wchar_t)GETARG(wint_t), &mbs);
if (mbseqlen == (size_t)-1) {
}
base = 10;
goto number;
-#ifdef FLOATING_POINT
-#ifdef HEXFLOAT
+#ifndef NO_FLOATING_POINT
case 'a':
case 'A':
if (ch == 'a') {
xdigs = xdigs_upper;
expchar = 'P';
}
- /*
- * XXX We don't actually have a conversion
- * XXX routine for this yet.
- */
+ if (prec >= 0)
+ prec++;
+ if (dtoaresult != NULL)
+ freedtoa(dtoaresult);
if (flags & LONGDBL) {
- fparg.ldbl = (double)GETARG(long double);
+ fparg.ldbl = GETARG(long double);
dtoaresult = cp =
__hldtoa(fparg.ldbl, xdigs, prec,
&expt, &signflag, &dtoaend);
__hdtoa(fparg.dbl, xdigs, prec,
&expt, &signflag, &dtoaend);
}
- goto fp_begin;
-#endif
+ if (prec < 0)
+ prec = dtoaend - cp;
+ if (expt == INT_MAX)
+ ox[1] = '\0';
+ goto fp_common;
case 'e':
case 'E':
expchar = ch;
if (expt == 9999)
expt = INT_MAX;
}
+fp_common:
if (signflag)
sign = '-';
if (expt == INT_MAX) { /* inf or nan */
lead = expt;
}
break;
-#endif /* FLOATING_POINT */
+#endif /* !NO_FLOATING_POINT */
case 'n':
/*
* Assignment-like behavior is specified if the
realsz = dprec > size ? dprec : size;
if (sign)
realsz++;
- else if (ox[1])
+ if (ox[1])
realsz += 2;
prsize = width > realsz ? width : realsz;
PAD(width - realsz, blanks);
/* prefix */
- if (sign) {
+ if (sign)
PRINT(&sign, 1);
- } else if (ox[1]) { /* ox[1] is either x, X, or \0 */
+
+ if (ox[1]) { /* ox[1] is either x, X, or \0 */
ox[0] = '0';
PRINT(ox, 2);
}
PAD(dprec - size, zeroes);
/* the string or number proper */
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
if ((flags & FPT) == 0) {
PRINT(cp, size);
} else { /* glue together f_p fragments */
done:
FLUSH();
error:
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
if (dtoaresult != NULL)
freedtoa(dtoaresult);
#endif
tablesize = STATIC_ARG_TBL_SIZE;
tablemax = 0;
nextarg = 1;
- memset (typetable, T_UNUSED, STATIC_ARG_TBL_SIZE);
+ for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
+ typetable[n] = T_UNUSED;
/*
* Scan the format for conversions (`%' character).
}
width = n;
goto reswitch;
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
case 'L':
flags |= LONGDBL;
goto rflag;
case 'i':
ADDSARG();
break;
-#ifdef FLOATING_POINT
-#ifdef HEXFLOAT
+#ifndef NO_FLOATING_POINT
case 'a':
case 'A':
-#endif
case 'e':
case 'E':
case 'f':
else
ADDTYPE(T_DOUBLE);
break;
-#endif /* FLOATING_POINT */
+#endif /* !NO_FLOATING_POINT */
case 'n':
if (flags & INTMAXT)
ADDTYPE(TP_INTMAXT);
case TP_INTMAXT:
(*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *);
break;
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
case T_DOUBLE:
(*argtable) [n].doublearg = va_arg (ap, double);
break;
enum typeid *const oldtable = *typetable;
const int oldsize = *tablesize;
enum typeid *newtable;
- int newsize = oldsize * 2;
+ int n, newsize = oldsize * 2;
if (newsize < nextarg + 1)
newsize = nextarg + 1;
if (oldsize == STATIC_ARG_TBL_SIZE) {
- if ((newtable = malloc(newsize)) == NULL)
+ if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
abort(); /* XXX handle better */
- bcopy(oldtable, newtable, oldsize);
+ bcopy(oldtable, newtable, oldsize * sizeof(enum typeid));
} else {
- if ((newtable = reallocf(oldtable, newsize)) == NULL)
+ newtable = reallocf(oldtable, newsize * sizeof(enum typeid));
+ if (newtable == NULL)
abort(); /* XXX handle better */
}
- memset(&newtable[oldsize], T_UNUSED, newsize - oldsize);
+ for (n = oldsize; n < newsize; n++)
+ newtable[n] = T_UNUSED;
*typetable = newtable;
*tablesize = newsize;
}
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
static int
exponent(char *p0, int exp, int fmtch)
}
return (p - p0);
}
-#endif /* FLOATING_POINT */
+#endif /* !NO_FLOATING_POINT */
---- vfprintf.c.orig Thu Jul 24 12:42:14 2003
-+++ vfprintf.c Tue Apr 6 17:44:49 2004
+--- vfprintf.c.orig Sun May 30 01:12:48 2004
++++ vfprintf.c Sun May 30 01:18:16 2004
@@ -58,6 +58,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "un-namespace.h"
-@@ -66,9 +67,20 @@
+@@ -66,6 +67,12 @@
#include "local.h"
#include "fvwrite.h"
+#ifdef ALTIVEC
+#include <machine/cpu_capabilities.h>
+
-+#define VECTORTYPE vector unsigned char
++#define VECTORTYPE vector unsigned char
+#endif /* ALTIVEC */
-+
- /* Define FLOATING_POINT to get floating point. */
- #define FLOATING_POINT
-
-+/* if no floating point, turn off HEXFLOAT as well */
-+#if defined(HEXFLOAT) && !defined(FLOATING_POINT)
-+#undef HEXFLOAT
-+#endif /* defined(HEXFLOAT) && !defined(FLOATING_POINT) */
+
union arg {
int intarg;
u_int uintarg;
-@@ -88,7 +100,7 @@
- long *plongarg;
- long long *plonglongarg;
- ptrdiff_t *pptrdiffarg;
-- size_t *psizearg;
-+ ssize_t *psizearg;
- intmax_t *pintmaxarg;
- #ifdef FLOATING_POINT
- double doublearg;
-@@ -96,6 +108,16 @@
+@@ -93,6 +100,16 @@
#endif
wint_t wintarg;
wchar_t *pwchararg;
};
/*
-@@ -106,7 +128,11 @@
+@@ -103,7 +120,11 @@
T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
};
static int __sprint(FILE *, struct __suio *);
-@@ -119,6 +145,37 @@
+@@ -116,6 +137,37 @@
static void __find_arguments(const char *, va_list, union arg **);
static void __grow_type_table(int, enum typeid **, int *);
/*
* Flush out all the vectors defined by the given uio,
* then reset it so that it can be reused.
-@@ -424,6 +481,15 @@
-
- #endif /* FLOATING_POINT */
-
-+#ifdef HEXFLOAT
-+extern int __hdtoa(double d, const char *xdigs, int prec, char *cp,
-+ int *expt, int *signflag, char **dtoaend);
-+#if !__TYPE_LONGDOUBLE_IS_DOUBLE
-+extern int __hldtoa(long double d, const char *xdigs, int prec, char *cp,
-+ int *expt, int *signflag, char **dtoaend);
-+#endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */
-+#endif /* HEXFLOAT */
-+
- /*
- * The size of the buffer we use as scratch space for integer
- * conversions, among other things. Technically, we would need the
-@@ -452,6 +518,9 @@
+@@ -451,6 +503,9 @@
#define PTRDIFFT 0x800 /* ptrdiff_t */
#define INTMAXT 0x1000 /* intmax_t */
#define CHARINT 0x2000 /* print char using int format */
/*
* Non-MT-safe version
-@@ -503,6 +572,11 @@
+@@ -502,6 +557,11 @@
int nseps; /* number of group separators with ' */
int nrepeats; /* number of repeats of the last group */
#endif
u_long ulval; /* integer arguments %[diouxX] */
uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
int base; /* base for [diouxX] conversion */
-@@ -535,6 +609,12 @@
-
- static const char xdigs_lower[16] = "0123456789abcdef";
- static const char xdigs_upper[16] = "0123456789ABCDEF";
-+#ifdef HEXFLOAT
-+#define HEXFLOATDELTA 32
-+#define HEXFLOATSTART 32
-+ static char *hexfloat = NULL;
-+ static int hexfloatlen = 0;
-+#endif /* HEXFLOAT */
-
- /*
- * BEWARE, these `goto error' on error, and PAD uses `n'.
-@@ -575,15 +655,6 @@
+@@ -574,15 +634,6 @@
}
/*
* To extend shorts properly, we need both signed and unsigned
* argument extraction methods.
*/
-@@ -634,7 +705,6 @@
+@@ -633,7 +684,6 @@
val = GETARG (int); \
}
thousands_sep = '\0';
grouping = NULL;
convbuf = NULL;
-@@ -643,8 +713,10 @@
+@@ -642,8 +692,10 @@
decimal_point = localeconv()->decimal_point;
#endif
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
-@@ -676,6 +748,9 @@
+@@ -675,6 +727,9 @@
}
if (ch == '\0')
goto done;
fmt++; /* skip over '%' */
flags = 0;
-@@ -684,6 +759,9 @@
+@@ -683,6 +738,9 @@
prec = -1;
sign = '\0';
ox[1] = '\0';
rflag: ch = *fmt++;
reswitch: switch (ch) {
-@@ -699,6 +777,11 @@
+@@ -698,6 +756,11 @@
case '#':
flags |= ALT;
goto rflag;
case '*':
/*-
* ``A negative field width argument is taken as a
-@@ -807,6 +890,12 @@
- }
- size = (int)mbseqlen;
- } else {
+@@ -793,6 +856,12 @@
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'c':
+#ifdef ALTIVEC
-+ if (flags & VECTOR) {
-+ SETVEC(vval);
-+ break;
-+ }
++ if (flags & VECTOR) {
++ SETVEC(vval);
++ break;
++ }
+#endif /* ALTIVEC */
- *(cp = buf) = GETARG(int);
- size = 1;
- }
-@@ -817,6 +906,12 @@
+ if (flags & LONGINT) {
+ static const mbstate_t initial;
+ mbstate_t mbs;
+@@ -817,6 +886,12 @@
/*FALLTHROUGH*/
case 'd':
case 'i':
+ if (flags & VECTOR) {
+ SETVEC(vval);
+ break;
-+ } else
++ }
+#endif /* ALTIVEC */
if (flags & INTMAX_SIZE) {
ujval = SJARG();
if ((intmax_t)ujval < 0) {
-@@ -836,6 +931,13 @@
- #ifdef HEXFLOAT
+@@ -835,6 +910,13 @@
+ #ifndef NO_FLOATING_POINT
case 'a':
case 'A':
+#ifdef ALTIVEC
if (ch == 'a') {
ox[1] = 'x';
xdigs = xdigs_lower;
-@@ -845,25 +947,51 @@
- xdigs = xdigs_upper;
- expchar = 'P';
- }
-- /*
-- * XXX We don't actually have a conversion
-- * XXX routine for this yet.
-- */
-+ if (!hexfloat) {
-+ hexfloat = malloc(hexfloatlen = HEXFLOATSTART);
-+ if (!hexfloat)
-+ goto error;
-+ }
-+ if (prec > hexfloatlen - 1) {
-+ int hlen = prec + HEXFLOATDELTA;
-+ char *hf = realloc(hexfloat, hlen);
-+ if (hf == NULL)
-+ goto error;
-+ hexfloat = hf;
-+ hexfloatlen = hlen;
-+ }
-+ cp = hexfloat;
- if (flags & LONGDBL) {
-- fparg.ldbl = (double)GETARG(long double);
-- dtoaresult = cp =
-- __hldtoa(fparg.ldbl, xdigs, prec,
-+#if __TYPE_LONGDOUBLE_IS_DOUBLE
-+ fparg.dbl = (double)GETARG(long double);
-+ prec = __hdtoa(fparg.dbl, xdigs, prec, cp,
- &expt, &signflag, &dtoaend);
-+#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */
-+ fparg.ldbl = GETARG(long double);
-+ prec = __hldtoa(fparg.ldbl, xdigs, prec, cp,
-+ &expt, &signflag, &dtoaend);
-+#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */
- } else {
- fparg.dbl = GETARG(double);
-- dtoaresult = cp =
-- __hdtoa(fparg.dbl, xdigs, prec,
-+ prec = __hdtoa(fparg.dbl, xdigs, prec, cp,
- &expt, &signflag, &dtoaend);
- }
-- goto fp_begin;
-+ prec++;
-+ if (expt == INT_MAX)
-+ ox[1] = 0;
-+ else
-+ expt++;
-+ goto hex_begin;
- #endif
+@@ -866,6 +948,13 @@
+ goto fp_common;
case 'e':
case 'E':
+#ifdef ALTIVEC
expchar = ch;
if (prec < 0) /* account for digit before decpt */
prec = DEFPREC + 1;
-@@ -872,10 +1000,24 @@
+@@ -874,10 +963,24 @@
goto fp_begin;
case 'f':
case 'F':
expchar = ch - ('g' - 'e');
if (prec == 0)
prec = 1;
-@@ -884,6 +1026,17 @@
- prec = DEFPREC;
- if (dtoaresult != NULL)
- freedtoa(dtoaresult);
-+#if __TYPE_LONGDOUBLE_IS_DOUBLE
-+ if (flags & LONGDBL)
-+ fparg.dbl = (double)GETARG(long double);
-+ else
-+ fparg.dbl = GETARG(double);
-+ dtoaresult = cp =
-+ dtoa(fparg.dbl, expchar ? 2 : 3, prec,
-+ &expt, &signflag, &dtoaend);
-+ if (expt == 9999)
-+ expt = INT_MAX;
-+#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */
- if (flags & LONGDBL) {
- fparg.ldbl = GETARG(long double);
- dtoaresult = cp =
-@@ -897,6 +1050,10 @@
- if (expt == 9999)
- expt = INT_MAX;
- }
-+#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */
-+#ifdef HEXFLOAT
-+hex_begin:
-+#endif /* HEXFLOAT */
- if (signflag)
- sign = '-';
- if (expt == INT_MAX) { /* inf or nan */
-@@ -990,6 +1147,12 @@
+@@ -993,6 +1096,12 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
+ if (flags & VECTOR) {
+ SETVEC(vval);
+ break;
-+ } else
++ }
+#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -1004,6 +1167,12 @@
+@@ -1007,6 +1116,12 @@
* defined manner.''
* -- ANSI X3J11
*/
ujval = (uintmax_t)(uintptr_t)GETARG(void *);
base = 16;
xdigs = xdigs_lower;
-@@ -1053,6 +1222,12 @@
+@@ -1056,6 +1171,12 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'u':
+ if (flags & VECTOR) {
+ SETVEC(vval);
+ break;
-+ } else
++ }
+#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -1065,6 +1240,12 @@
+@@ -1068,6 +1189,12 @@
case 'x':
xdigs = xdigs_lower;
hex:
+ if (flags & VECTOR) {
+ SETVEC(vval);
+ break;
-+ } else
++ }
+#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -1109,6 +1290,14 @@
+@@ -1112,6 +1239,14 @@
if (size > BUF) /* should never happen */
abort();
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
goto done;
-@@ -1120,6 +1309,186 @@
+@@ -1123,6 +1258,184 @@
break;
}
+ * finish up the format specifier.
+ */
+ if (flags & SHORTINT) {
-+ vfmt[j++] = 'h';
++ if (ch != 'c')
++ vfmt[j++] = 'h';
+ vcnt = 8;
+ } else if (flags & LONGINT) {
-+ vfmt[j++] = 'l';
++ if (ch != 'c')
++ vfmt[j++] = 'l';
+ vcnt = 4;
+ } else {
+ switch (ch) {
+ VPRINT(vcnt, 0);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if (vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
+ VPRINT(vcnt, i);
+ VPRINT(vcnt, 0, prec);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if (vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
+ VPRINT(vcnt, i, prec);
+ VPRINT(vcnt, 0, width);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if (vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
+ VPRINT(vcnt, i, width);
+ VPRINT(vcnt, 0, width, prec);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if (vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
+ VPRINT(vcnt, i, width, prec);
/*
* All reasonable formats wind up here. At this point, `cp'
* points to a string which (if not flags&LADJUST) should be
-@@ -1137,7 +1506,7 @@
- realsz = dprec > size ? dprec : size;
- if (sign)
- realsz++;
-- else if (ox[1])
-+ if (ox[1])
- realsz += 2;
-
- prsize = width > realsz ? width : realsz;
-@@ -1151,9 +1520,9 @@
- PAD(width - realsz, blanks);
-
- /* prefix */
-- if (sign) {
-+ if (sign)
- PRINT(&sign, 1);
-- } else if (ox[1]) { /* ox[1] is either x, X, or \0 */
-+ if (ox[1]) { /* ox[1] is either x, X, or \0 */
- ox[0] = '0';
- PRINT(ox, 2);
- }
-@@ -1400,6 +1769,11 @@
+@@ -1405,6 +1718,11 @@
if (flags & LONGINT)
ADDTYPE(T_WINT);
else
ADDTYPE(T_INT);
break;
case 'D':
-@@ -1407,6 +1781,11 @@
+@@ -1412,6 +1730,11 @@
/*FALLTHROUGH*/
case 'd':
case 'i':
+#endif
ADDSARG();
break;
- #ifdef FLOATING_POINT
-@@ -1419,6 +1798,11 @@
+ #ifndef NO_FLOATING_POINT
+@@ -1422,6 +1745,11 @@
case 'f':
case 'g':
case 'G':
if (flags & LONGDBL)
ADDTYPE(T_LONG_DOUBLE);
else
-@@ -1447,9 +1831,19 @@
+@@ -1450,9 +1778,19 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
ADDTYPE(TP_VOID);
break;
case 'S':
-@@ -1467,6 +1861,11 @@
+@@ -1470,6 +1808,11 @@
case 'u':
case 'X':
case 'x':
ADDUARG();
break;
default: /* "%?" prints ?, unless ? is NUL */
-@@ -1552,6 +1951,12 @@
+@@ -1555,6 +1898,12 @@
(*argtable) [n].longdoublearg = va_arg (ap, long double);
break;
#endif
--- /dev/null
+--- vfscanf.c.orig Tue Nov 18 16:48:06 2003
++++ vfscanf.c Tue Nov 18 17:35:55 2003
+@@ -99,7 +99,9 @@
+ #define CT_FLOAT 4 /* %[efgEFG] conversion */
+
+ static const u_char *__sccl(char *, const u_char *);
+-static int parsefloat(FILE *, char *, char *);
++#ifdef FLOATING_POINT
++static int parsefloat(FILE *, char **, size_t);
++#endif /* FLOATING_POINT */
+
+ int __scanfdebug = 0;
+
+@@ -133,7 +135,6 @@
+ int flags; /* flags as defined above */
+ char *p0; /* saves original value of p when necessary */
+ int nassigned; /* number of fields assigned */
+- int nconversions; /* number of conversions */
+ int nread; /* number of characters consumed from fp */
+ int base; /* base argument to conversion function */
+ char ccltab[256]; /* character class table for %[...] */
+@@ -150,7 +151,6 @@
+ ORIENT(fp, -1);
+
+ nassigned = 0;
+- nconversions = 0;
+ nread = 0;
+ for (;;) {
+ c = *fmt++;
+@@ -288,7 +288,6 @@
+ break;
+
+ case 'n':
+- nconversions++;
+ if (flags & SUPPRESS) /* ??? */
+ continue;
+ if (flags & SHORTSHORT)
+@@ -421,7 +420,6 @@
+ nread += r;
+ nassigned++;
+ }
+- nconversions++;
+ break;
+
+ case CT_CCL:
+@@ -525,7 +523,6 @@
+ nassigned++;
+ }
+ nread += n;
+- nconversions++;
+ break;
+
+ case CT_STRING:
+@@ -607,7 +604,6 @@
+ nread += p - p0;
+ nassigned++;
+ }
+- nconversions++;
+ continue;
+
+ case CT_INT:
+@@ -758,39 +754,42 @@
+ nassigned++;
+ }
+ nread += p - buf;
+- nconversions++;
+ break;
+
+ #ifdef FLOATING_POINT
+ case CT_FLOAT:
++ {
++ char *pbuf;
+ /* scan a floating point number as if by strtod */
+- if (width == 0 || width > sizeof(buf) - 1)
+- width = sizeof(buf) - 1;
+- if ((width = parsefloat(fp, buf, buf + width)) == 0)
++ if ((width = parsefloat(fp, &pbuf, width)) == 0) {
++ if (pbuf)
++ free(pbuf);
+ goto match_failure;
++ }
+ if ((flags & SUPPRESS) == 0) {
+ if (flags & LONGDBL) {
+- long double res = strtold(buf, &p);
++ long double res = strtold(pbuf, &p);
+ *va_arg(ap, long double *) = res;
+ } else if (flags & LONG) {
+- double res = strtod(buf, &p);
++ double res = strtod(pbuf, &p);
+ *va_arg(ap, double *) = res;
+ } else {
+- float res = strtof(buf, &p);
++ float res = strtof(pbuf, &p);
+ *va_arg(ap, float *) = res;
+ }
+- if (__scanfdebug && p - buf != width)
++ if (__scanfdebug && p - pbuf != width)
+ abort();
+ nassigned++;
+ }
+ nread += width;
+- nconversions++;
++ free(pbuf);
+ break;
++ }
+ #endif /* FLOATING_POINT */
+ }
+ }
+ input_failure:
+- return (nconversions != 0 ? nassigned : EOF);
++ return (nassigned ? nassigned : EOF);
+ match_failure:
+ return (nassigned);
+ }
+@@ -910,7 +909,7 @@
+
+ #ifdef FLOATING_POINT
+ static int
+-parsefloat(FILE *fp, char *buf, char *end)
++parsefloat(FILE *fp, char **buf, size_t width)
+ {
+ char *commit, *p;
+ int infnanpos = 0;
+@@ -921,7 +920,16 @@
+ unsigned char c;
+ char decpt = *localeconv()->decimal_point;
+ _Bool gotmantdig = 0, ishex = 0;
++ char *b, *e;
++ size_t s;
+
++ s = (width == 0 ? BUF : width + 1);
++ b = (char *)malloc(s);
++ if (b == NULL) {
++ *buf = NULL;
++ return 0;
++ }
++ e = b + (s - 1);
+ /*
+ * We set commit = p whenever the string we have read so far
+ * constitutes a valid representation of a floating point
+@@ -931,8 +939,8 @@
+ * always necessary to read at least one character that doesn't
+ * match; thus, we can't short-circuit "infinity" or "nan(...)".
+ */
+- commit = buf - 1;
+- for (p = buf; p < end; ) {
++ commit = b - 1;
++ for (p = b; width == 0 || p < e; ) {
+ c = *fp->_p;
+ reswitch:
+ switch (state) {
+@@ -1046,6 +1054,17 @@
+ default:
+ abort();
+ }
++ if (p >= e) {
++ size_t diff = (p - b);
++ s += BUF;
++ b = (char *)reallocf(b, s);
++ if (b == NULL) {
++ *buf = NULL;
++ return 0;
++ }
++ e = b + (s - 1);
++ p = b + diff;
++ }
+ *p++ = c;
+ if (--fp->_r > 0)
+ fp->_p++;
+@@ -1057,6 +1076,7 @@
+ while (commit < --p)
+ __ungetc(*(u_char *)p, fp);
+ *++commit = '\0';
+- return (commit - buf);
++ *buf = b;
++ return (commit - b);
+ }
+ #endif
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#if 0
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
-__FBSDID("FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.58 2003/04/14 11:24:53 das Exp");
#endif
-__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.14 2003/11/12 08:49:12 tjr Exp $");
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.20 2004/05/02 20:09:14 obrien Exp $");
/*
* Actual wprintf innards.
#include "local.h"
#include "fvwrite.h"
-/* Define FLOATING_POINT to get floating point. */
-#define FLOATING_POINT
-
union arg {
int intarg;
u_int uintarg;
ptrdiff_t *pptrdiffarg;
size_t *psizearg;
intmax_t *pintmaxarg;
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
double doublearg;
long double longdoublearg;
#endif
static int __sbprintf(FILE *, const wchar_t *, va_list);
static wint_t __xfputwc(wchar_t, FILE *);
-static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const wchar_t *, int,
+static wchar_t *__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int,
char, const char *);
-static wchar_t *__ultoa(u_long, wchar_t *, int, int, const wchar_t *, int,
+static wchar_t *__ultoa(u_long, wchar_t *, int, int, const char *, int,
char, const char *);
static wchar_t *__mbsconv(char *, int);
static void __find_arguments(const wchar_t *, va_list, union arg **);
static wint_t
__xfputwc(wchar_t wc, FILE *fp)
{
+ static const mbstate_t initial;
+ mbstate_t mbs;
char buf[MB_LEN_MAX];
struct __suio uio;
struct __siov iov;
- size_t i, len;
- int ret;
+ size_t len;
if ((fp->_flags & __SSTR) == 0)
return (__fputwc(wc, fp));
- if ((len = wcrtomb(buf, wc, NULL)) == (size_t)-1) {
+ mbs = initial;
+ if ((len = wcrtomb(buf, wc, &mbs)) == (size_t)-1) {
fp->_flags |= __SERR;
return (WEOF);
}
* use the given digits.
*/
static wchar_t *
-__ultoa(u_long val, wchar_t *endp, int base, int octzero, const wchar_t *xdigs,
+__ultoa(u_long val, wchar_t *endp, int base, int octzero, const char *xdigs,
int needgrp, char thousep, const char *grp)
{
wchar_t *cp = endp;
/* Identical to __ultoa, but for intmax_t. */
static wchar_t *
__ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero,
- const wchar_t *xdigs, int needgrp, char thousep, const char *grp)
+ const char *xdigs, int needgrp, char thousep, const char *grp)
{
wchar_t *cp = endp;
intmax_t sval;
static wchar_t *
__mbsconv(char *mbsarg, int prec)
{
+ static const mbstate_t initial;
+ mbstate_t mbs;
wchar_t *convbuf, *wcp;
const char *p;
size_t insize, nchars, nconv;
*/
p = mbsarg;
insize = nchars = 0;
+ mbs = initial;
while (nchars != (size_t)prec) {
- nconv = mbrlen(p, MB_CUR_MAX, NULL);
+ nconv = mbrlen(p, MB_CUR_MAX, &mbs);
if (nconv == 0 || nconv == (size_t)-1 ||
nconv == (size_t)-2)
break;
return (NULL);
wcp = convbuf;
p = mbsarg;
+ mbs = initial;
while (insize != 0) {
- nconv = mbrtowc(wcp, p, insize, NULL);
+ nconv = mbrtowc(wcp, p, insize, &mbs);
if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2)
break;
wcp++;
return (ret);
}
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
#define dtoa __dtoa
#define freedtoa __freedtoa
static int exponent(wchar_t *, int, wchar_t);
-#endif /* FLOATING_POINT */
+#endif /* !NO_FLOATING_POINT */
/*
* The size of the buffer we use as scratch space for integer
wchar_t sign; /* sign prefix (' ', '+', '-', or \0) */
char thousands_sep; /* locale specific thousands separator */
const char *grouping; /* locale specific numeric grouping rules */
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
/*
* We can decompose the printed representation of floating
* point numbers into several parts, some of which may be empty:
int realsz; /* field size expanded by dprec, sign, etc */
int size; /* size of converted field or string */
int prsize; /* max size of printed field */
- const wchar_t *xdigs; /* digits for [xX] conversion */
+ const char *xdigs; /* digits for [xX] conversion */
wchar_t buf[BUF]; /* buffer with space for digits of uintmax_t */
wchar_t ox[2]; /* space for 0x hex-prefix */
union arg *argtable; /* args, built due to positional arg */
static wchar_t zeroes[PADSIZE] =
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
- static const wchar_t xdigs_lower[16] = L"0123456789abcdef";
- static const wchar_t xdigs_upper[16] = L"0123456789ABCDEF";
+ static const char xdigs_lower[16] = "0123456789abcdef";
+ static const char xdigs_upper[16] = "0123456789ABCDEF";
/*
* BEWARE, these `goto error' on error, PRINT uses `n2' and
thousands_sep = '\0';
grouping = NULL;
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
decimal_point = localeconv()->decimal_point;
#endif
convbuf = NULL;
}
width = n;
goto reswitch;
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
case 'L':
flags |= LONGDBL;
goto rflag;
}
base = 10;
goto number;
-#ifdef FLOATING_POINT
-#ifdef HEXFLOAT
+#ifndef NO_FLOATING_POINT
case 'a':
case 'A':
if (ch == 'a') {
xdigs = xdigs_upper;
expchar = 'P';
}
- /*
- * XXX We don't actually have a conversion
- * XXX routine for this yet.
- */
+ if (prec >= 0)
+ prec++;
if (flags & LONGDBL) {
- fparg.ldbl = (double)GETARG(long double);
+ fparg.ldbl = GETARG(long double);
dtoaresult =
__hldtoa(fparg.ldbl, xdigs, prec,
&expt, &signflag, &dtoaend);
__hdtoa(fparg.dbl, xdigs, prec,
&expt, &signflag, &dtoaend);
}
+ if (prec < 0)
+ prec = dtoaend - dtoaresult;
+ if (expt == INT_MAX)
+ ox[1] = '\0';
if (convbuf != NULL)
free(convbuf);
+ ndig = dtoaend - dtoaresult;
cp = convbuf = __mbsconv(dtoaresult, -1);
freedtoa(dtoaresult);
- goto fp_begin;
-#endif
+ goto fp_common;
case 'e':
case 'E':
expchar = ch;
ndig = dtoaend - dtoaresult;
cp = convbuf = __mbsconv(dtoaresult, -1);
freedtoa(dtoaresult);
+fp_common:
if (signflag)
sign = '-';
if (expt == INT_MAX) { /* inf or nan */
lead = expt;
}
break;
-#endif /* FLOATING_POINT */
+#endif /* !NO_FLOATING_POINT */
case 'n':
/*
* Assignment-like behavior is specified if the
realsz = dprec > size ? dprec : size;
if (sign)
realsz++;
- else if (ox[1])
+ if (ox[1])
realsz += 2;
prsize = width > realsz ? width : realsz;
PAD(width - realsz, blanks);
/* prefix */
- if (sign) {
+ if (sign)
PRINT(&sign, 1);
- } else if (ox[1]) { /* ox[1] is either x, X, or \0 */
+
+ if (ox[1]) { /* ox[1] is either x, X, or \0 */
ox[0] = '0';
PRINT(ox, 2);
}
PAD(dprec - size, zeroes);
/* the string or number proper */
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
if ((flags & FPT) == 0) {
PRINT(cp, size);
} else { /* glue together f_p fragments */
tablesize = STATIC_ARG_TBL_SIZE;
tablemax = 0;
nextarg = 1;
- memset (typetable, T_UNUSED, STATIC_ARG_TBL_SIZE);
+ for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
+ typetable[n] = T_UNUSED;
/*
* Scan the format for conversions (`%' character).
}
width = n;
goto reswitch;
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
case 'L':
flags |= LONGDBL;
goto rflag;
case 'i':
ADDSARG();
break;
-#ifdef FLOATING_POINT
-#ifdef HEXFLOAT
+#ifndef NO_FLOATING_POINT
case 'a':
case 'A':
-#endif
case 'e':
case 'E':
case 'f':
else
ADDTYPE(T_DOUBLE);
break;
-#endif /* FLOATING_POINT */
+#endif /* !NO_FLOATING_POINT */
case 'n':
if (flags & INTMAXT)
ADDTYPE(TP_INTMAXT);
case TP_INTMAXT:
(*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *);
break;
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
case T_DOUBLE:
(*argtable) [n].doublearg = va_arg (ap, double);
break;
enum typeid *const oldtable = *typetable;
const int oldsize = *tablesize;
enum typeid *newtable;
- int newsize = oldsize * 2;
+ int n, newsize = oldsize * 2;
if (newsize < nextarg + 1)
newsize = nextarg + 1;
if (oldsize == STATIC_ARG_TBL_SIZE) {
- if ((newtable = malloc(newsize)) == NULL)
+ if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
abort(); /* XXX handle better */
- bcopy(oldtable, newtable, oldsize);
+ bcopy(oldtable, newtable, oldsize * sizeof(enum typeid));
} else {
- if ((newtable = reallocf(oldtable, newsize)) == NULL)
+ newtable = reallocf(oldtable, newsize * sizeof(enum typeid));
+ if (newtable == NULL)
abort(); /* XXX handle better */
}
- memset(&newtable[oldsize], T_UNUSED, newsize - oldsize);
+ for (n = oldsize; n < newsize; n++)
+ newtable[n] = T_UNUSED;
*typetable = newtable;
*tablesize = newsize;
}
-#ifdef FLOATING_POINT
+#ifndef NO_FLOATING_POINT
static int
exponent(wchar_t *p0, int exp, wchar_t fmtch)
}
return (p - p0);
}
-#endif /* FLOATING_POINT */
+#endif /* !NO_FLOATING_POINT */
---- vfwprintf.c.orig Tue Apr 6 17:39:47 2004
-+++ vfwprintf.c Tue Apr 6 17:46:51 2004
-@@ -64,15 +64,27 @@
+--- vfwprintf.c.orig Sun May 30 01:25:05 2004
++++ vfwprintf.c Sun May 30 01:26:53 2004
+@@ -63,12 +63,19 @@
#include <string.h>
#include <wchar.h>
#include <wctype.h>
+#ifdef ALTIVEC
+#include <machine/cpu_capabilities.h>
+
-+#define VECTORTYPE vector unsigned char
++#define VECTORTYPE vector unsigned char
+#endif /* ALTIVEC */
-+
- /* Define FLOATING_POINT to get floating point. */
- #define FLOATING_POINT
-
-+/* if no floating point, turn off HEXFLOAT as well */
-+#if defined(HEXFLOAT) && !defined(FLOATING_POINT)
-+#undef HEXFLOAT
-+#endif /* defined(HEXFLOAT) && !defined(FLOATING_POINT) */
+
union arg {
int intarg;
u_int uintarg;
-@@ -92,7 +104,7 @@
- long *plongarg;
- long long *plonglongarg;
- ptrdiff_t *pptrdiffarg;
-- size_t *psizearg;
-+ ssize_t *psizearg;
- intmax_t *pintmaxarg;
- #ifdef FLOATING_POINT
- double doublearg;
-@@ -100,6 +112,16 @@
+@@ -96,6 +103,16 @@
#endif
wint_t wintarg;
wchar_t *pwchararg;
};
/*
-@@ -110,7 +132,11 @@
+@@ -106,7 +123,11 @@
T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
T_PTRDIFFT, TP_PTRDIFFT, T_SIZET, TP_SIZET,
T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
};
static int __sbprintf(FILE *, const wchar_t *, va_list);
-@@ -123,6 +149,37 @@
+@@ -119,6 +140,37 @@
static void __find_arguments(const wchar_t *, va_list, union arg **);
static void __grow_type_table(int, enum typeid **, int *);
/*
* Helper function for `fprintf to unbuffered unix file': creates a
* temporary buffer. We only work on write-only files; this avoids
-@@ -444,6 +501,15 @@
-
- #endif /* FLOATING_POINT */
-
-+#ifdef HEXFLOAT
-+extern int __hdtoa(double d, const char *xdigs, int prec, char *cp,
-+ int *expt, int *signflag, char **dtoaend);
-+#if !__TYPE_LONGDOUBLE_IS_DOUBLE
-+extern int __hldtoa(long double d, const char *xdigs, int prec, char *cp,
-+ int *expt, int *signflag, char **dtoaend);
-+#endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */
-+#endif /* HEXFLOAT */
-+
- /*
- * The size of the buffer we use as scratch space for integer
- * conversions, among other things. Technically, we would need the
-@@ -472,6 +538,9 @@
+@@ -474,6 +526,9 @@
#define PTRDIFFT 0x800 /* ptrdiff_t */
#define INTMAXT 0x1000 /* intmax_t */
#define CHARINT 0x2000 /* print char using int format */
/*
* Non-MT-safe version
-@@ -522,6 +591,11 @@
+@@ -524,6 +579,11 @@
int nseps; /* number of group separators with ' */
int nrepeats; /* number of repeats of the last group */
#endif
u_long ulval; /* integer arguments %[diouxX] */
uintmax_t ujval; /* %j, %ll, %q, %t, %z integers */
int base; /* base for [diouxX] conversion */
-@@ -551,6 +625,15 @@
-
- static const wchar_t xdigs_lower[16] = L"0123456789abcdef";
- static const wchar_t xdigs_upper[16] = L"0123456789ABCDEF";
-+#ifdef HEXFLOAT
-+#define HEXFLOATDELTA 32
-+#define HEXFLOATSTART 32
-+ static char *hexfloat = NULL;
-+ static int hexfloatlen = 0;
-+ const char *xdigs0; /* digits for [aA] conversion */
-+ static const char xdigs_lower0[16] = "0123456789abcdef";
-+ static const char xdigs_upper0[16] = "0123456789ABCDEF";
-+#endif /* HEXFLOAT */
-
- /*
- * BEWARE, these `goto error' on error, PRINT uses `n2' and
-@@ -579,15 +662,6 @@
+@@ -581,15 +641,6 @@
} while(0)
/*
* To extend shorts properly, we need both signed and unsigned
* argument extraction methods.
*/
-@@ -638,7 +712,6 @@
+@@ -640,7 +691,6 @@
val = GETARG (int); \
}
-
thousands_sep = '\0';
grouping = NULL;
- #ifdef FLOATING_POINT
-@@ -646,8 +719,10 @@
+ #ifndef NO_FLOATING_POINT
+@@ -648,8 +698,10 @@
#endif
convbuf = NULL;
/* sorry, fwprintf(read_only_file, L"") returns WEOF, not 0 */
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
-@@ -676,6 +751,9 @@
+@@ -678,6 +730,9 @@
}
if (ch == '\0')
goto done;
fmt++; /* skip over '%' */
flags = 0;
-@@ -684,6 +762,9 @@
+@@ -686,6 +741,9 @@
prec = -1;
sign = '\0';
ox[1] = '\0';
rflag: ch = *fmt++;
reswitch: switch (ch) {
-@@ -699,6 +780,11 @@
+@@ -701,6 +759,11 @@
case '#':
flags |= ALT;
goto rflag;
case '*':
/*-
* ``A negative field width argument is taken as a
-@@ -796,8 +882,18 @@
+@@ -796,6 +859,12 @@
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
case 'c':
- if (flags & LONGINT)
- *(cp = buf) = (wchar_t)GETARG(wint_t);
+#ifdef ALTIVEC
-+ else {
-+ if (flags & VECTOR) {
-+ SETVEC(vval);
-+ break;
-+ }
-+ *(cp = buf) = (wchar_t)btowc(GETARG(int));
++ if (flags & VECTOR) {
++ SETVEC(vval);
++ break;
+ }
-+#else /* ALTIVEC */
- else
- *(cp = buf) = (wchar_t)btowc(GETARG(int));
+#endif /* ALTIVEC */
- size = 1;
- sign = '\0';
- break;
-@@ -806,6 +902,12 @@
+ if (flags & LONGINT)
+ *(cp = buf) = (wchar_t)GETARG(wint_t);
+ else
+@@ -808,6 +877,12 @@
/*FALLTHROUGH*/
case 'd':
case 'i':
+ if (flags & VECTOR) {
+ SETVEC(vval);
+ break;
-+ } else
++ }
+#endif /* ALTIVEC */
if (flags & INTMAX_SIZE) {
ujval = SJARG();
if ((intmax_t)ujval < 0) {
-@@ -825,38 +927,74 @@
- #ifdef HEXFLOAT
- case 'a':
- case 'A':
-+#ifdef ALTIVEC
-+ if (flags & VECTOR) {
-+ flags |= FPT;
-+ SETVEC(vval);
-+ break;
-+ }
-+#endif /* ALTIVEC */
- if (ch == 'a') {
- ox[1] = 'x';
-- xdigs = xdigs_lower;
-+ xdigs0 = xdigs_lower0;
- expchar = 'p';
- } else {
- ox[1] = 'X';
-- xdigs = xdigs_upper;
-+ xdigs0 = xdigs_upper0;
- expchar = 'P';
- }
-- /*
-- * XXX We don't actually have a conversion
-- * XXX routine for this yet.
-- */
-+ if (!hexfloat) {
-+ hexfloat = malloc(hexfloatlen = HEXFLOATSTART);
-+ if (!hexfloat)
-+ goto error;
-+ }
-+ /* one extra for integer part and another for null */
-+ if (prec > hexfloatlen - 2) {
-+ int hlen = prec + HEXFLOATDELTA;
-+ char *hf = realloc(hexfloat, hlen);
-+ if (hf == NULL)
-+ goto error;
-+ hexfloat = hf;
-+ hexfloatlen = hlen;
-+ }
- if (flags & LONGDBL) {
-- fparg.ldbl = (double)GETARG(long double);
-- dtoaresult =
-- __hldtoa(fparg.ldbl, xdigs, prec,
-- &expt, &signflag, &dtoaend);
-+#if __TYPE_LONGDOUBLE_IS_DOUBLE
-+ fparg.dbl = (double)GETARG(long double);
-+ prec = __hdtoa(fparg.dbl, xdigs0, prec,
-+ hexfloat, &expt, &signflag, &dtoaend);
-+#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */
-+ fparg.ldbl = GETARG(long double);
-+ prec = __hldtoa(fparg.ldbl, xdigs0, prec,
-+ hexfloat, &expt, &signflag, &dtoaend);
-+#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */
- } else {
- fparg.dbl = GETARG(double);
-- dtoaresult =
-- __hdtoa(fparg.dbl, xdigs, prec,
-- &expt, &signflag, &dtoaend);
-+ prec = __hdtoa(fparg.dbl, xdigs0, prec,
-+ hexfloat, &expt, &signflag, &dtoaend);
-+ }
-+ prec++;
-+ if (expt == INT_MAX) {
-+ ox[1] = 0;
-+ hexfloat[1] = 0;
-+ } else {
-+ expt++;
-+ *dtoaend = 0;
-+ ndig = dtoaend - hexfloat;
- }
- if (convbuf != NULL)
- free(convbuf);
-- cp = convbuf = __mbsconv(dtoaresult, -1);
-- freedtoa(dtoaresult);
-- goto fp_begin;
-+ cp = convbuf = __mbsconv(hexfloat, -1);
-+ goto hex_begin;
- #endif
- case 'e':
- case 'E':
-+#ifdef ALTIVEC
-+ if (flags & VECTOR) {
-+ flags |= FPT;
-+ SETVEC(vval);
-+ break;
-+ }
-+#endif /* ALTIVEC */
- expchar = ch;
- if (prec < 0) /* account for digit before decpt */
- prec = DEFPREC + 1;
-@@ -865,10 +1003,24 @@
+@@ -868,10 +943,24 @@
goto fp_begin;
case 'f':
case 'F':
expchar = ch - ('g' - 'e');
if (prec == 0)
prec = 1;
-@@ -877,6 +1029,17 @@
- prec = DEFPREC;
- if (convbuf != NULL)
- free(convbuf);
-+#if __TYPE_LONGDOUBLE_IS_DOUBLE
-+ if (flags & LONGDBL)
-+ fparg.ldbl = GETARG(long double);
-+ else
-+ fparg.dbl = GETARG(double);
-+ dtoaresult =
-+ dtoa(fparg.dbl, expchar ? 2 : 3, prec,
-+ &expt, &signflag, &dtoaend);
-+ if (expt == 9999)
-+ expt = INT_MAX;
-+#else /* ! __TYPE_LONGDOUBLE_IS_DOUBLE */
- if (flags & LONGDBL) {
- fparg.ldbl = GETARG(long double);
- dtoaresult =
-@@ -890,9 +1053,13 @@
- if (expt == 9999)
- expt = INT_MAX;
- }
-+#endif /* __TYPE_LONGDOUBLE_IS_DOUBLE */
- ndig = dtoaend - dtoaresult;
- cp = convbuf = __mbsconv(dtoaresult, -1);
- freedtoa(dtoaresult);
-+#ifdef HEXFLOAT
-+hex_begin:
-+#endif /* HEXFLOAT */
- if (signflag)
- sign = '-';
- if (expt == INT_MAX) { /* inf or nan */
-@@ -985,6 +1152,12 @@
+@@ -989,6 +1078,12 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
+ if (flags & VECTOR) {
+ SETVEC(vval);
+ break;
-+ } else
++ }
+#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -999,6 +1172,12 @@
+@@ -1003,6 +1098,12 @@
* defined manner.''
* -- ANSI X3J11
*/
ujval = (uintmax_t)(uintptr_t)GETARG(void *);
base = 16;
xdigs = xdigs_lower;
-@@ -1051,6 +1230,12 @@
+@@ -1055,6 +1156,12 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'u':
+ if (flags & VECTOR) {
+ SETVEC(vval);
+ break;
-+ } else
++ }
+#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -1063,6 +1248,12 @@
+@@ -1067,6 +1174,12 @@
case 'x':
xdigs = xdigs_lower;
hex:
+ if (flags & VECTOR) {
+ SETVEC(vval);
+ break;
-+ } else
++ }
+#endif /* ALTIVEC */
if (flags & INTMAX_SIZE)
ujval = UJARG();
else
-@@ -1107,6 +1298,14 @@
+@@ -1111,6 +1224,14 @@
if (size > BUF) /* should never happen */
abort();
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
goto done;
-@@ -1118,6 +1317,185 @@
+@@ -1122,6 +1243,183 @@
break;
}
+ * finish up the format specifier.
+ */
+ if (flags & SHORTINT) {
-+ vfmt[j++] = 'h';
++ if (ch != 'c')
++ vfmt[j++] = 'h';
+ vcnt = 8;
+ } else if (flags & LONGINT) {
-+ vfmt[j++] = 'l';
++ if (ch != 'c')
++ vfmt[j++] = 'l';
+ vcnt = 4;
+ } else {
+ switch (ch) {
+ VPRINT(vcnt, 0);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if (vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
+ VPRINT(vcnt, i);
+ VPRINT(vcnt, 0, prec);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if (vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
+ VPRINT(vcnt, i, prec);
+ VPRINT(vcnt, 0, width);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if (vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
+ VPRINT(vcnt, i, width);
+ VPRINT(vcnt, 0, width, prec);
+ for (i = 1; i < vcnt; i++) {
+ /* Separator. */
-+ if (vsep)
-+ PRINT(&vsep, 1);
++ PRINT(&vsep, 1);
+
+ /* Element. */
+ VPRINT(vcnt, i, width, prec);
/*
* All reasonable formats wind up here. At this point, `cp'
* points to a string which (if not flags&LADJUST) should be
-@@ -1135,7 +1513,7 @@
- realsz = dprec > size ? dprec : size;
- if (sign)
- realsz++;
-- else if (ox[1])
-+ if (ox[1])
- realsz += 2;
-
- prsize = width > realsz ? width : realsz;
-@@ -1149,9 +1527,9 @@
- PAD(width - realsz, blanks);
-
- /* prefix */
-- if (sign) {
-+ if (sign)
- PRINT(&sign, 1);
-- } else if (ox[1]) { /* ox[1] is either x, X, or \0 */
-+ if (ox[1]) { /* ox[1] is either x, X, or \0 */
- ox[0] = '0';
- PRINT(ox, 2);
- }
-@@ -1394,6 +1772,11 @@
+@@ -1400,6 +1698,11 @@
if (flags & LONGINT)
ADDTYPE(T_WINT);
else
ADDTYPE(T_INT);
break;
case 'D':
-@@ -1413,6 +1796,11 @@
+@@ -1417,6 +1720,11 @@
case 'f':
case 'g':
case 'G':
if (flags & LONGDBL)
ADDTYPE(T_LONG_DOUBLE);
else
-@@ -1441,9 +1829,19 @@
+@@ -1445,9 +1753,19 @@
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
ADDTYPE(TP_VOID);
break;
case 'S':
-@@ -1461,6 +1859,11 @@
+@@ -1465,6 +1783,11 @@
case 'u':
case 'X':
case 'x':
ADDUARG();
break;
default: /* "%?" prints ?, unless ? is NUL */
-@@ -1546,6 +1949,12 @@
+@@ -1550,6 +1873,12 @@
(*argtable) [n].longdoublearg = va_arg (ap, long double);
break;
#endif
--- /dev/null
+--- vfwscanf.c.orig Tue Nov 18 16:48:06 2003
++++ vfwscanf.c Tue Nov 18 17:36:22 2003
+@@ -100,7 +100,9 @@
+ #define CT_INT 3 /* %[dioupxX] conversion */
+ #define CT_FLOAT 4 /* %[efgEFG] conversion */
+
+-static int parsefloat(FILE *, wchar_t *, wchar_t *);
++#ifdef FLOATING_POINT
++static int parsefloat(FILE *, wchar_t **, size_t);
++#endif /* FLOATING_POINT */
+
+ extern int __scanfdebug;
+
+@@ -136,7 +138,6 @@
+ int flags; /* flags as defined above */
+ wchar_t *p0; /* saves original value of p when necessary */
+ int nassigned; /* number of fields assigned */
+- int nconversions; /* number of conversions */
+ int nread; /* number of characters consumed from fp */
+ int base; /* base argument to conversion function */
+ wchar_t buf[BUF]; /* buffer for numeric conversions */
+@@ -154,7 +155,6 @@
+ { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+
+ nassigned = 0;
+- nconversions = 0;
+ nread = 0;
+ ccls = ccle = NULL;
+ for (;;) {
+@@ -308,7 +308,6 @@
+ break;
+
+ case 'n':
+- nconversions++;
+ if (flags & SUPPRESS) /* ??? */
+ continue;
+ if (flags & SHORTSHORT)
+@@ -411,7 +410,6 @@
+ if (!(flags & SUPPRESS))
+ nassigned++;
+ }
+- nconversions++;
+ break;
+
+ case CT_CCL:
+@@ -476,7 +474,6 @@
+ }
+ }
+ nread += n;
+- nconversions++;
+ break;
+
+ case CT_STRING:
+@@ -537,7 +534,6 @@
+ nassigned++;
+ }
+ }
+- nconversions++;
+ continue;
+
+ case CT_INT:
+@@ -680,47 +676,49 @@
+ nassigned++;
+ }
+ nread += p - buf;
+- nconversions++;
+ break;
+
+ #ifdef FLOATING_POINT
+ case CT_FLOAT:
++ {
++ wchar_t *pbuf;
+ /* scan a floating point number as if by strtod */
+- if (width == 0 || width > sizeof(buf) /
+- sizeof(*buf) - 1)
+- width = sizeof(buf) / sizeof(*buf) - 1;
+- if ((width = parsefloat(fp, buf, buf + width)) == 0)
++ if ((width = parsefloat(fp, &pbuf, width)) == 0) {
++ if (pbuf)
++ free(pbuf);
+ goto match_failure;
++ }
+ if ((flags & SUPPRESS) == 0) {
+ if (flags & LONGDBL) {
+- long double res = wcstold(buf, &p);
++ long double res = wcstold(pbuf, &p);
+ *va_arg(ap, long double *) = res;
+ } else if (flags & LONG) {
+- double res = wcstod(buf, &p);
++ double res = wcstod(pbuf, &p);
+ *va_arg(ap, double *) = res;
+ } else {
+- float res = wcstof(buf, &p);
++ float res = wcstof(pbuf, &p);
+ *va_arg(ap, float *) = res;
+ }
+- if (__scanfdebug && p - buf != width)
++ if (__scanfdebug && p - pbuf != width)
+ abort();
+ nassigned++;
+ }
+ nread += width;
+- nconversions++;
++ free(pbuf);
+ break;
++ }
+ #endif /* FLOATING_POINT */
+ }
+ }
+ input_failure:
+- return (nconversions != 0 ? nassigned : EOF);
++ return (nassigned ? nassigned : EOF);
+ match_failure:
+ return (nassigned);
+ }
+
+ #ifdef FLOATING_POINT
+ static int
+-parsefloat(FILE *fp, wchar_t *buf, wchar_t *end)
++parsefloat(FILE *fp, wchar_t **buf, size_t width)
+ {
+ wchar_t *commit, *p;
+ int infnanpos = 0;
+@@ -731,7 +729,16 @@
+ wchar_t c;
+ wchar_t decpt = (wchar_t)(unsigned char)*localeconv()->decimal_point;
+ _Bool gotmantdig = 0, ishex = 0;
++ wchar_t *b, *e;
++ size_t s;
+
++ s = (width == 0 ? BUF : width + 1);
++ b = (wchar_t *)malloc(s * sizeof(wchar_t));
++ if (b == NULL) {
++ *buf = NULL;
++ return 0;
++ }
++ e = b + (s - 1);
+ /*
+ * We set commit = p whenever the string we have read so far
+ * constitutes a valid representation of a floating point
+@@ -741,9 +748,9 @@
+ * always necessary to read at least one character that doesn't
+ * match; thus, we can't short-circuit "infinity" or "nan(...)".
+ */
+- commit = buf - 1;
++ commit = b - 1;
+ c = WEOF;
+- for (p = buf; p < end; ) {
++ for (p = b; width == 0 || p < e; ) {
+ if ((c = __fgetwc(fp)) == WEOF)
+ break;
+ reswitch:
+@@ -858,6 +865,17 @@
+ default:
+ abort();
+ }
++ if (p >= e) {
++ size_t diff = (p - b);
++ s += BUF;
++ b = (wchar_t *)reallocf(b, s * sizeof(wchar_t));
++ if (b == NULL) {
++ *buf = NULL;
++ return 0;
++ }
++ e = b + (s - 1);
++ p = b + diff;
++ }
+ *p++ = c;
+ c = WEOF;
+ }
+@@ -868,6 +886,7 @@
+ while (commit < --p)
+ __ungetwc(*p, fp);
+ *++commit = '\0';
+- return (commit - buf);
++ *buf = b;
++ return (commit - b);
+ }
+ #endif
--- /dev/null
+--- vswprintf.c.orig Tue May 20 15:22:44 2003
++++ vswprintf.c Wed Nov 12 00:30:05 2003
+@@ -48,6 +48,7 @@
+ mbstate_t mbs;
+ char *mbp;
+ int ret, sverrno;
++ size_t conv;
+
+ if (n == 0) {
+ errno = EINVAL;
+@@ -78,13 +79,13 @@
+ * XXX Undo the conversion from wide characters to multibyte that
+ * fputwc() did in __vfwprintf().
+ */
+- if (mbsrtowcs(s, (const char **)&mbp, n, &mbs) == (size_t)-1) {
++ if ((conv = mbsrtowcs(s, (const char **)&mbp, n, &mbs)) == (size_t)-1) {
+ free(f._bf._base);
+ errno = EILSEQ;
+ return (-1);
+ }
+ free(f._bf._base);
+- if (s[n - 1] != L'\0') {
++ if (conv >= n) {
+ s[n - 1] = L'\0';
+ errno = EOVERFLOW;
+ return (-1);
.Xr localeconv 3 .
.El
.It
-+An optional seperator character (
++An optional separator character (
+.Cm \ , | \; | \ : | _
-+) used for seperating multiple values when printing an AltiVec vector,
++) used for separating multiple values when printing an AltiVec vector,
+or other multi-value unit.
+.Pp
+NOTE: This is an AltiVec only extension onto the
# stdio sources
.PATH: ${.CURDIR}/stdio
-CFLAGS+= -DHEXFLOAT
-
-SRCS += hexfloat.c
-
.include "Makefile.fbsd_begin"
-FBSDSRCS= _flock_stub.c asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.c \
+FBSDMISRCS= _flock_stub.c asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.c \
fflush.c fgetc.c fgetln.c fgetpos.c fgets.c fgetwc.c fgetws.c \
fileno.c findfp.c flags.c fopen.c fprintf.c fpurge.c fputc.c fputs.c \
fputwc.c fputws.c fread.c freopen.c fscanf.c fseek.c fsetpos.c \
unlocked.c vasprintf.c vfprintf.c vfscanf.c vfwprintf.c vfwscanf.c \
vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c vswprintf.c \
vswscanf.c vwprintf.c vwscanf.c wbuf.c wprintf.c wscanf.c wsetup.c
-FBSDORIGHDRS= floatio.h fvwrite.h glue.h local.h
+FBSDHDRS= floatio.h fvwrite.h glue.h local.h
.include "Makefile.fbsd_end"
+.for _src in vfprintf-fbsd.c vfwprintf-fbsd.c
+CFLAGS-${_src} += -fshort-enums
+.endfor
+
.if ${LIB} == "c"
.include "Makefile.fbsd_begin"
FBSDMAN3= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fgetws.3 flockfile.3 \
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifdef HEXFLOAT
-
-/*
- * hexfloat.c provides routines that vfprintf and vfwprintf can call to convert
- * floating point numbers to hexidecimal, as used by the %a and %A conversions.
- * This is necessarily dependent not only on the floating point data format,
- * but also byte order and existence of long double type.
- *
- * The union hexdouble represents the IEEE-754 double precision format, while
- * union hexlongdouble represents the IEEE-754 extended double precision
- * format.
- */
-
-#include <stdio.h>
-#include <math.h>
-#include <limits.h>
-
-#define EXPBIAS 1023
-#define EXPMIN -1022
-#define EXPSPECIAL 2047
-#define FRACTHEX 13
-
-union hexdouble {
- double d;
- struct {
-#if defined(__ppc__)
- unsigned int sign:1;
- unsigned int exp:11;
- unsigned long long fract:52;
-#elif defined(__i386__)
- unsigned long long fract:52;
- unsigned int exp:11;
- unsigned int sign:1;
-#else
-#error Unsupported architecture
-#endif
- } s;
-};
-
-#if !__TYPE_LONGDOUBLE_IS_DOUBLE
-#ifdef __i386__
-
-#define LEXPBIAS 16383
-#define LEXPMIN -16382
-#define LEXPSPECIAL 32767
-#define LFRACTHEX 16
-
-union hexlongdouble {
- long double d;
- struct {
- unsigned long long fract:63;
- unsigned int i:1;
- unsigned int exp:15;
- unsigned int sign:1;
- } s;
-};
-#endif /* __i386__ */
-#endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */
-
-int
-__hdtoa(double d, const char *xdigs, int prec, char *cp,
- int *expt, int *signflag, char **dtoaend)
-{
- union hexdouble u;
- char buf[FRACTHEX];
- char *hp;
- int i;
- long long fract;
- //char *start = cp; //DEBUG
-
- u.d = d;
- //printf("\nsign=%d exp=%x fract=%llx\n", u.s.sign, u.s.exp, u.s.fract); //DEBUG
- *signflag = u.s.sign;
- fract = u.s.fract;
- switch (u.s.exp) {
- case EXPSPECIAL: /* NaN or Inf */
- *expt = INT_MAX;
- *cp = (fract ? 'N' : 'I');
- return 0;
- case 0: /* Zero or denormalized */
- *cp++ = '0';
- *expt = (fract ? EXPMIN : 0);
- break;
- default: /* Normal numbers */
- *cp++ = '1';
- *expt = u.s.exp - EXPBIAS;
- break;
- }
- if (prec < 0)
- prec = FRACTHEX;
- //printf("prec=%d expt=%d\n", prec, *expt); //DEBUG
- if (prec > 0) {
- int dig = (prec > FRACTHEX ? FRACTHEX : prec);
- int zero = prec - dig;
- int shift = FRACTHEX - dig;
- if (shift > 0)
- fract >>= (shift << 2);
- for (hp = buf + dig, i = dig; i > 0; i--) {
- *--hp = xdigs[fract & 0xf];
- fract >>= 4;
- }
- strncpy(cp, hp, dig);
- cp += dig;
- while(zero-- > 0)
- *cp++ = '0';
- }
- *dtoaend = cp;
- //while (start < cp) putchar(*start++); //DEBUG
- //putchar('\n'); //DEBUG
- return prec;
-}
-
-#if !__TYPE_LONGDOUBLE_IS_DOUBLE
-#ifdef __i386__
-int
-__hldtoa(long double d, const char *xdigs, int prec, char *cp,
- int *expt, int *signflag, char **dtoaend)
-{
- union hexlongdouble u;
- char buf[LFRACTHEX];
- char *hp;
- int i;
- unsigned long long fract;
- //char *start = cp; //DEBUG
-
- u.d = d;
- //printf("d=%Lg u.d=%Lg\n", d, u.d); //DEBUG
- //printf("\nsign=%d exp=%x fract=%llx\n", u.s.sign, u.s.exp, u.s.fract); //DEBUG
- *signflag = u.s.sign;
- fract = (u.s.fract << 1);
- switch (u.s.exp) {
- case LEXPSPECIAL: /* NaN or Inf */
- *expt = INT_MAX;
- *cp = (fract ? 'N' : 'I');
- return 0;
- default: /* Normal or denormalized */
- *cp++ = u.s.i ? '1' : '0';
- *expt = u.s.exp - LEXPBIAS;
- break;
- }
- if (prec < 0)
- prec = LFRACTHEX;
- //printf("prec=%d expt=%d\n", prec, *expt); //DEBUG
- if (prec > 0) {
- int dig = (prec > LFRACTHEX ? LFRACTHEX : prec);
- int zero = prec - dig;
- int shift = LFRACTHEX - dig;
- if (shift > 0)
- fract >>= (shift << 2);
- for (hp = buf + dig, i = dig; i > 0; i--) {
- *--hp = xdigs[fract & 0xf];
- fract >>= 4;
- }
- strncpy(cp, hp, dig);
- cp += dig;
- while(zero-- > 0)
- *cp++ = '0';
- }
- *dtoaend = cp;
- //while (start < cp) putchar(*start++); //DEBUG
- //putchar('\n'); //DEBUG
- return prec;
-}
-#endif /* __i386__ */
-#endif /* !__TYPE_LONGDOUBLE_IS_DOUBLE */
-
-#endif /* HEXFLOAT */
static char sccsid[] = "@(#)atexit.c 8.2 (Berkeley) 7/3/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdlib/atexit.c,v 1.6 2002/03/22 21:53:09 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/stdlib/atexit.c,v 1.7 2003/12/19 17:11:20 kan Exp $");
#include "namespace.h"
#include <stddef.h>
#include "libc_private.h"
+#define ATEXIT_FN_EMPTY 0
+#define ATEXIT_FN_STD 1
+#define ATEXIT_FN_CXA 2
+
static pthread_mutex_t atexit_mutex = PTHREAD_MUTEX_INITIALIZER;
#define _MUTEX_LOCK(x) if (__isthreaded) _pthread_mutex_lock(x)
#define _MUTEX_UNLOCK(x) if (__isthreaded) _pthread_mutex_unlock(x)
-struct atexit *__atexit; /* points to head of LIFO stack */
+struct atexit {
+ struct atexit *next; /* next in list */
+ int ind; /* next index in this table */
+ struct atexit_fn {
+ int fn_type; /* ATEXIT_? from above */
+ union {
+ void (*std_func)(void);
+ void (*cxa_func)(void *);
+ } fn_ptr; /* function pointer */
+ void *fn_arg; /* argument for CXA callback */
+ void *fn_dso; /* shared module handle */
+ } fns[ATEXIT_SIZE]; /* the table itself */
+};
+
+static struct atexit *__atexit; /* points to head of LIFO stack */
/*
- * Register a function to be performed at exit.
+ * Register the function described by 'fptr' to be called at application
+ * exit or owning shared object unload time. This is a helper function
+ * for atexit and __cxa_atexit.
*/
-int
-atexit(fn)
- void (*fn)();
+static int
+atexit_register(struct atexit_fn *fptr)
{
static struct atexit __atexit0; /* one guaranteed table */
struct atexit *p;
p->next = __atexit;
__atexit = p;
}
- p->fns[p->ind++] = fn;
+ p->fns[p->ind++] = *fptr;
+ _MUTEX_UNLOCK(&atexit_mutex);
+ return 0;
+}
+
+/*
+ * Register a function to be performed at exit.
+ */
+int
+atexit(void (*func)(void))
+{
+ struct atexit_fn fn;
+ int error;
+
+ fn.fn_type = ATEXIT_FN_STD;
+ fn.fn_ptr.std_func = func;;
+ fn.fn_arg = NULL;
+ fn.fn_dso = NULL;
+
+ error = atexit_register(&fn);
+ return (error);
+}
+
+/*
+ * Register a function to be performed at exit or when an shared object
+ * with given dso handle is unloaded dynamically.
+ */
+int
+__cxa_atexit(void (*func)(void *), void *arg, void *dso)
+{
+ struct atexit_fn fn;
+ int error;
+
+ fn.fn_type = ATEXIT_FN_CXA;
+ fn.fn_ptr.cxa_func = func;;
+ fn.fn_arg = arg;
+ fn.fn_dso = dso;
+
+ error = atexit_register(&fn);
+ return (error);
+}
+
+/*
+ * Call all handlers registered with __cxa_atexit for the shared
+ * object owning 'dso'. Note: if 'dso' is NULL, then all remaining
+ * handlers are called.
+ */
+void
+__cxa_finalize(void *dso)
+{
+ struct atexit *p;
+ struct atexit_fn fn;
+ int n;
+
+ _MUTEX_LOCK(&atexit_mutex);
+ for (p = __atexit; p; p = p->next) {
+ for (n = p->ind; --n >= 0;) {
+ if (p->fns[n].fn_type == ATEXIT_FN_EMPTY)
+ continue; /* already been called */
+ if (dso != NULL && dso != p->fns[n].fn_dso)
+ continue; /* wrong DSO */
+ fn = p->fns[n];
+ /*
+ Mark entry to indicate that this particular handler
+ has already been called.
+ */
+ p->fns[n].fn_type = ATEXIT_FN_EMPTY;
+ _MUTEX_UNLOCK(&atexit_mutex);
+
+ /* Call the function of correct type. */
+ if (fn.fn_type == ATEXIT_FN_CXA)
+ fn.fn_ptr.cxa_func(fn.fn_arg);
+ else if (fn.fn_type == ATEXIT_FN_STD)
+ fn.fn_ptr.std_func();
+ _MUTEX_LOCK(&atexit_mutex);
+ }
+ }
_MUTEX_UNLOCK(&atexit_mutex);
- return (0);
}
--- /dev/null
+--- atexit.c.orig Thu Mar 11 13:16:53 2004
++++ atexit.c Mon Mar 15 12:47:39 2004
+@@ -45,6 +45,9 @@
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <pthread.h>
++#if defined(__DYNAMIC__)
++#include <mach-o/dyld.h>
++#endif /* defined(__DYNAMIC__) */
+ #include "atexit.h"
+ #include "un-namespace.h"
+
+@@ -125,7 +128,11 @@
+ fn.fn_type = ATEXIT_FN_STD;
+ fn.fn_ptr.std_func = func;;
+ fn.fn_arg = NULL;
++#if defined(__DYNAMIC__)
++ fn.fn_dso = (void *)_dyld_get_image_header_containing_address((unsigned long) func);
++#else /* ! defined(__DYNAMIC__) */
+ fn.fn_dso = NULL;
++#endif /* defined(__DYNAMIC__) */
+
+ error = atexit_register(&fn);
+ return (error);
* SUCH DAMAGE.
*
* @(#)atexit.h 8.2 (Berkeley) 7/3/94
- * $FreeBSD: src/lib/libc/stdlib/atexit.h,v 1.2 2002/03/22 23:42:03 obrien Exp $
+ * $FreeBSD: src/lib/libc/stdlib/atexit.h,v 1.3 2003/12/19 17:11:20 kan Exp $
*/
/* must be at least 32 to guarantee ANSI conformance */
#define ATEXIT_SIZE 32
-struct atexit {
- struct atexit *next; /* next in list */
- int ind; /* next index in this table */
- void (*fns[ATEXIT_SIZE])(); /* the table itself */
-};
-
-extern struct atexit *__atexit; /* points to head of LIFO stack */
+void __cxa_finalize(void *dso);
static char sccsid[] = "@(#)exit.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdlib/exit.c,v 1.6 2002/03/22 21:53:10 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/stdlib/exit.c,v 1.7 2003/12/19 17:11:20 kan Exp $");
#include "namespace.h"
#include <stdlib.h>
exit(status)
int status;
{
- struct atexit *p;
- int n;
-
/* Ensure that the auto-initialization routine is linked in: */
extern int _thread_autoinit_dummy_decl;
_thread_autoinit_dummy_decl = 1;
- for (p = __atexit; p; p = p->next)
- for (n = p->ind; --n >= 0;)
- (*p->fns[n])();
+ __cxa_finalize(NULL);
if (__cleanup)
(*__cleanup)();
_exit(status);
---- exit.c.orig Mon Apr 28 16:37:26 2003
-+++ exit.c Sat May 3 14:28:31 2003
-@@ -46,15 +46,6 @@
+--- exit.c.orig Wed Mar 10 14:20:34 2004
++++ exit.c Wed Mar 10 14:38:14 2004
+@@ -46,26 +46,12 @@
void (*__cleanup)();
/*
* Exit, flushing stdio buffers if necessary.
*/
void
-@@ -63,11 +54,6 @@
+ exit(status)
+ int status;
{
- struct atexit *p;
- int n;
--
- /* Ensure that the auto-initialization routine is linked in: */
- extern int _thread_autoinit_dummy_decl;
-
- _thread_autoinit_dummy_decl = 1;
-
- for (p = __atexit; p; p = p->next)
- for (n = p->ind; --n >= 0;)
+-
+ __cxa_finalize(NULL);
+ if (__cleanup)
+ (*__cleanup)();
--- /dev/null
+--- realpath.c.orig Fri Aug 15 19:22:17 2003
++++ realpath.c Tue Dec 9 14:36:32 2003
+@@ -40,8 +40,27 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
++#include <sys/attr.h>
++#include <sys/vnode.h>
+ #include "un-namespace.h"
+
++struct attrs {
++ u_int32_t len;
++ attrreference_t name;
++ fsobj_type_t type;
++ char buf[PATH_MAX];
++};
++
++static struct attrlist alist = {
++ ATTR_BIT_MAP_COUNT,
++ 0,
++ ATTR_CMN_NAME | ATTR_CMN_OBJTYPE,
++ 0,
++ 0,
++ 0,
++ 0,
++};
++
+ /*
+ * char *realpath(const char *path, char resolved[PATH_MAX]);
+ *
+@@ -52,11 +71,12 @@
+ char *
+ realpath(const char *path, char resolved[PATH_MAX])
+ {
++ struct attrs attrs;
+ struct stat sb;
+ char *p, *q, *s;
+- size_t left_len, resolved_len;
++ size_t left_len, resolved_len, save_resolved_len;
+ unsigned symlinks;
+- int serrno, slen;
++ int serrno, slen, useattrs, islink;
+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
+
+ serrno = errno;
+@@ -127,6 +147,13 @@
+ }
+
+ /*
++ * Save resolved_len, so that we can later null out
++ * the the appended next_token, and replace with the
++ * real name (matters on case-insensitive filesystems).
++ */
++ save_resolved_len = resolved_len;
++
++ /*
+ * Append the next path component and lstat() it. If
+ * lstat() fails we still can return successfully if
+ * there are no more path components left.
+@@ -136,14 +163,22 @@
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+- if (lstat(resolved, &sb) != 0) {
++ if (getattrlist(resolved, &alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) {
++ useattrs = 1;
++ islink = (attrs.type == VLNK);
++ } else if (errno == EOPNOTSUPP || errno == EINVAL) {
++ if ((useattrs = lstat(resolved, &sb)) == 0)
++ islink = S_ISLNK(sb.st_mode);
++ } else
++ useattrs = -1;
++ if (useattrs < 0) {
+ if (errno == ENOENT && p == NULL) {
+ errno = serrno;
+ return (resolved);
+ }
+ return (NULL);
+ }
+- if (S_ISLNK(sb.st_mode)) {
++ if (islink) {
+ if (symlinks++ > MAXSYMLINKS) {
+ errno = ELOOP;
+ return (NULL);
+@@ -184,7 +219,30 @@
+ }
+ }
+ left_len = strlcpy(left, symlink, sizeof(left));
++ } else if (useattrs) {
++ /*
++ * attrs already has the real name.
++ */
++
++ resolved[save_resolved_len] = '\0';
++ resolved_len = strlcat(resolved, (const char *)&attrs.name + attrs.name.attr_dataoffset, PATH_MAX);
++ if (resolved_len >= PATH_MAX) {
++ errno = ENAMETOOLONG;
++ return (NULL);
++ }
+ }
++ /*
++ * For the case of useattrs == 0, we could scan the directory
++ * and try to match the inode. There are many problems with
++ * this: (1) the directory may not be readable, (2) for multiple
++ * hard links, we would find the first, but not necessarily
++ * the one specified in the path, (3) we can't try to do
++ * a case-insensitive search to match the right one in (2),
++ * because the underlying filesystem may do things like
++ * decompose composed characters. For most cases, doing
++ * nothing is the right thing when useattrs == 0, so we punt
++ * for now.
++ */
+ }
+
+ /*
# from @(#)Makefile.inc 8.3 (Berkeley) 2/4/95
# $FreeBSD: src/lib/libc/stdlib/Makefile.inc,v 1.45 2003/04/05 07:33:46 tjr Exp $
+# machine-dependent stdlib sources
+.if exists(${.CURDIR}/${MACHINE_ARCH}/stdlib/Makefile.inc)
+.include "${.CURDIR}/${MACHINE_ARCH}/stdlib/Makefile.inc"
+.endif
+
# machine-independent stdlib sources
-.PATH: ${.CURDIR}/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib
+.PATH: ${.CURDIR}/stdlib
MISRCS+=a64l.c l64a.c
strfmon.c strhash.c strtoimax.c strtol.c strtoll.c strtoq.c strtoul.c \
strtoull.c strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c \
twalk.c
-FBSDORIGHDRS= atexit.h
+FBSDHDRS= atexit.h
.include "Makefile.fbsd_end"
-# machine-dependent stdlib sources
-.if exists(${.CURDIR}/${MACHINE_ARCH}/stdlib/Makefile.inc)
-.include "${.CURDIR}/${MACHINE_ARCH}/stdlib/Makefile.inc"
-.endif
-
.if ${LIB} == "c"
MAN3+= a64l.3
.Fn l64a
functions conform to
.St -xpg4.2 .
-
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+.\" Copyright (c) 1980, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ftime.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD: /repoman/r/ncvs/src/lib/libcompat/4.1/ftime.3,v 1.11 2001/10/01 16:09:14 ru Exp $
+.\"
+.Dd June 4, 1993
+.Dt FTIME 3
+.Os
+.Sh NAME
+.Nm ftime
+.Nd get date and time
+.Sh LIBRARY
+.Lb libcompat
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/timeb.h
+.Ft int
+.Fn ftime "struct timeb *tp"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is obsoleted by
+.Xr gettimeofday 2 .
+.Ef
+.Pp
+The
+.Fn ftime
+routine fills in a structure pointed to by its argument,
+as defined by
+.Aq Pa sys/timeb.h :
+.Bd -literal -offset indent
+/*
+ * Structure returned by ftime system call
+ */
+struct timeb
+{
+ time_t time;
+ unsigned short millitm;
+ short timezone;
+ short dstflag;
+};
+.Ed
+.Pp
+The structure contains the time since the epoch in seconds,
+up to 1000 milliseconds of more-precise interval,
+the local time zone (measured in minutes of time westward from Greenwich),
+and a flag that, if nonzero, indicates that
+Daylight Saving time applies locally during the appropriate part of the year.
+.Sh SEE ALSO
+.Xr gettimeofday 2 ,
+.Xr settimeofday 2 ,
+.Xr ctime 3 ,
+.Xr time 3
+.Sh HISTORY
+The
+.Nm
+function appeared in
+.Bx 4.2 .
--- /dev/null
+--- ftime.3.orig Sat Jan 3 18:59:56 2004
++++ ftime.3 Tue Jan 13 17:41:55 2004
+@@ -38,8 +38,6 @@
+ .Sh NAME
+ .Nm ftime
+ .Nd get date and time
+-.Sh LIBRARY
+-.Lb libcompat
+ .Sh SYNOPSIS
+ .In sys/types.h
+ .In sys/timeb.h
--- /dev/null
+/*
+ * Copyright (c) 1994 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+#ifndef lint
+static char rcsid[] = "$FreeBSD: /repoman/r/ncvs/src/lib/libcompat/4.1/ftime.c,v 1.5 1999/08/28 00:04:12 peter Exp $";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+
+int
+ftime(tbp)
+ struct timeb *tbp;
+{
+ struct timezone tz;
+ struct timeval t;
+
+ if (gettimeofday(&t, &tz) < 0)
+ return (-1);
+ tbp->millitm = t.tv_usec / 1000;
+ tbp->time = t.tv_sec;
+ tbp->timezone = tz.tz_minuteswest;
+ tbp->dstflag = tz.tz_dsttime;
+
+ return (0);
+}
---- localtime.c.orig Thu Aug 7 18:34:10 2003
-+++ localtime.c Thu Aug 7 16:57:55 2003
+--- localtime.c.orig Thu Oct 30 23:10:33 2003
++++ localtime.c Thu Oct 30 23:25:06 2003
@@ -24,6 +24,18 @@
#include <sys/stat.h>
#include <fcntl.h>
+ *----------------------------------------------------------------*/
+ if (p->token >= 0)
+ notify_cancel(p->token);
-+ if (*file == 0) {
++ if (!file || *file == 0) {
+ /* no time zone file to monitor */
+ p->token = -1;
+ return;
lcl_is_set = (strlen(name) < sizeof(lcl_TZname));
if (lcl_is_set)
(void) strcpy(lcl_TZname, name);
-@@ -995,15 +1234,24 @@
+@@ -995,15 +1234,25 @@
lclptr->ttis[0].tt_gmtoff = 0;
lclptr->ttis[0].tt_abbrind = 0;
(void) strcpy(lclptr->chars, gmt);
+#ifdef NOTIFY_TZ
-+ *fullname = 0;
++ if (fullname)
++ *fullname = 0;
+#endif /* NOTIFY_TZ */
} else if (tzload(name, lclptr) != 0)
if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
_MUTEX_LOCK(&lcl_mutex);
tzset_basic();
_MUTEX_UNLOCK(&lcl_mutex);
-@@ -1030,6 +1278,9 @@
+@@ -1030,6 +1279,9 @@
int i;
const time_t t = *timep;
sp = lclptr;
#ifdef ALL_STATE
if (sp == NULL) {
-@@ -1087,7 +1338,7 @@
+@@ -1087,7 +1339,7 @@
if (__isthreaded != 0) {
_pthread_mutex_lock(&localtime_mutex);
if (_pthread_key_create(&localtime_key, free) < 0) {
_pthread_mutex_unlock(&localtime_mutex);
return(NULL);
-@@ -1123,14 +1374,30 @@
+@@ -1123,14 +1375,30 @@
const long offset;
struct tm * const tmp;
{
}
_MUTEX_UNLOCK(&gmt_mutex);
timesub(timep, offset, gmtptr, tmp);
-@@ -1145,7 +1412,7 @@
+@@ -1145,7 +1413,7 @@
else {
#ifdef ALL_STATE
if (gmtptr == NULL)
else tmp->TM_ZONE = gmtptr->chars;
#endif /* defined ALL_STATE */
#ifndef ALL_STATE
-@@ -1165,7 +1432,7 @@
+@@ -1165,7 +1433,7 @@
if (__isthreaded != 0) {
_pthread_mutex_lock(&gmtime_mutex);
.PATH: ${.CURDIR}/stdtime
-CFLAGS += -DNOTIFY_TZ
+CFLAGS-localtime-fbsd.c += -DNOTIFY_TZ
+
+MISRCS += getdate.c
.include "Makefile.fbsd_begin"
-FBSDSRCS= asctime.c difftime.c localtime.c strftime.c strptime.c timelocal.c \
- time32.c
-FBSDORIGHDRS= private.h timelocal.h tzfile.h
+FBSDMISRCS= asctime.c difftime.c ftime.c localtime.c \
+ strftime.c strptime.c timelocal.c time32.c
+FBSDHDRS= private.h timelocal.h tzfile.h
.include "Makefile.fbsd_end"
.if ${LIB} == "c"
.include "Makefile.fbsd_begin"
-FBSDMAN3= ctime.3 strftime.3 strptime.3 time2posix.3
+FBSDMAN3= ctime.3 ftime.3 strftime.3 strptime.3 time2posix.3
FBSDMAN5= tzfile.5
.include "Makefile.fbsd_end"
+MAN3 += getdate.3 timegm.3
+MLINKS += timegm.3 timelocal.3
+
MLINKS+=ctime.3 asctime.3 ctime.3 difftime.3 ctime.3 gmtime.3 \
- ctime.3 localtime.3 ctime.3 mktime.3 ctime.3 timegm.3 \
+ ctime.3 localtime.3 ctime.3 mktime.3 \
ctime.3 ctime_r.3 ctime.3 localtime_r.3 ctime.3 gmtime_r.3 \
ctime.3 asctime_r.3
MLINKS+=time2posix.3 posix2time.3
--- /dev/null
+'\" t
+.Dd January 3, 2004
+.Dt GETDATE 3
+.Os
+.Sh NAME
+.Nm getdate
+.Nd convert user format date and time
+.Sh SYNOPSIS
+.In time.h
+.Vt extern int getdate_err ;
+.Ft struct tm *
+.Fn getdate "const char *string"
+.Sh DESCRIPTION
+The
+.Fn getdate
+function converts user-definable date and/or
+time specifications pointed to by
+.Fa string
+to a
+.Vt tm
+structure.
+The
+.Vt tm
+structure is defined in the
+.Aq Pa time.h
+header.
+.Pp
+User-supplied templates are used to parse and interpret the
+input string.
+The templates are text files created by the
+user and identified via the environment variable
+.Ev DATEMSK .
+Each line in the template represents an acceptable date
+and/or time specification using conversion specifications
+similar to those used by
+.Xr strftime 3
+and
+.Xr strptime 3 .
+Dates before 1902 and after 2037 are illegal.
+The first line
+in the template that matches the input specification is used
+for interpretation and conversion into the internal time
+format.
+.Pp
+.Ss "Conversion Specifications"
+The following conversion specifications are supported:
+.Bl -tag -width "xxxx"
+.It Cm \&%%
+Same as %.
+.It Cm \&%a
+Locale's abbreviated weekday name.
+.It Cm \&%A
+Locale's full weekday name.
+.It Cm \&%b
+Locale's abbreviated month name.
+.It Cm \&%B
+Locale's full month name.
+.It Cm \&%c
+Locale's appropriate date and time representation.
+.It Cm \&%C
+Century number (the year divided by 100 and truncated
+to an integer as a decimal number [1,99]); single
+digits are preceded by 0.
+If used
+without the %y specifier, this format specifier will
+assume the current year offset in whichever century is
+specified. The only valid years are between 1902-2037.
+.It Cm \&%d
+day of month [01,31]; leading zero is permitted but
+not required.
+.It Cm \&%D
+Date as %m/%d/%y.
+.It Cm \&%e
+Same as %d.
+.It Cm \&%h
+Locale's abbreviated month name.
+.It Cm \&%H
+Hour (24-hour clock) [0,23]; leading zero is permitted
+but not required.
+.It Cm \&%I
+Hour (12-hour clock) [1,12]; leading zero is permitted
+but not required.
+.It Cm \&%j
+Day number of the year [1,366]; leading zeros are permitted but not required.
+.It Cm \&%m
+Month number [1,12]; leading zero is permitted but not
+required.
+.It Cm \&%M
+Minute [0,59]; leading zero is permitted but not
+required.
+.It Cm \&%n
+Any white space.
+.It Cm \&%p
+Locale's equivalent of either a.m. or p.m.
+.It Cm \&%r
+Appropriate time representation in the 12-hour clock
+format with %p.
+.It Cm \&%R
+Time as %H:%M.
+.It Cm \&%S
+Seconds [0,61]; leading zero is permitted but not
+required. The range of values is [00,61] rather than
+[00,59] to allow for the occasional leap second and
+even more occasional double leap second.
+.It Cm \&%t
+Any white space.
+.It Cm \&%T
+Time as %H:%M:%S.
+.It Cm \&%U
+Week number of the year as a decimal number [0,53],
+with Sunday as the first day of the week; leading zero
+is permitted but not required.
+.It Cm \&%w
+Weekday as a decimal number [0,6], with 0 representing
+Sunday.
+.It Cm \&%W
+Week number of the year as a decimal number [0,53],
+with Monday as the first day of the week; leading zero
+is permitted but not required.
+.It Cm \&%x
+Locale's appropriate date representation.
+.It Cm \&%X
+Locale's appropriate time representation.
+.It Cm \&%y
+Year within century. When a century is not otherwise
+specified, values in the range 69-99 refer to years in
+the twentieth century (1969 to 1999 inclusive); values
+in the range 00-68 refer to years in the twenty-first
+century (2000 to 2068 inclusive).
+.It Cm \&%Y
+Year, including the century (for example, 1993).
+.It Cm \&%Z
+Time zone name or no characters if no time zone
+exists.
+.El
+.Ss "Modified Conversion Specifications"
+Some conversion specifications can be modified by the E and
+O modifier characters to indicate that an alternative format
+or specification should be used rather than the one normally
+used by the unmodified specification.
+If the alternative
+format or specification does not exist in the current
+locale, the behavior be as if the unmodified conversion
+specification were used.
+.Bl -tag -width "xxxx"
+.It Cm \&%Ec
+Locale's alternative appropriate date and time
+representation.
+.It Cm \&%EC
+Name of the base year (period) in the locale's alternative representation.
+.It Cm \&%Ex
+Locale's alternative date representation.
+.It Cm \&%EX
+Locale's alternative time representation.
+.It Cm \&%Ey
+Offset from %EC (year only) in the locale's alternative representation.
+.It Cm \&%EY
+Full alternative year representation.
+.It Cm \&%Od
+Day of the month using the locale's alternative
+numeric symbols; leading zeros are permitted but not
+required.
+.It Cm \&%Oe
+Same as %Od.
+.It Cm \&%OH
+Hour (24-hour clock) using the locale's alternative
+numeric symbols.
+.It Cm \&%OI
+Hour (12-hour clock) using the locale's alternative
+numeric symbols.
+.It Cm \&%Om
+Month using the locale's alternative numeric symbols.
+.It Cm \&%OM
+Minutes using the locale's alternative numeric symbols.
+.It Cm \&%OS
+Seconds using the locale's alternative numeric symbols.
+.It Cm \&%OU
+Week number of the year (Sunday as the first day of
+the week) using the locale's alternative numeric symbols.
+.It Cm \&%Ow
+Number of the weekday (Sunday=0) using the locale's
+alternative numeric symbols.
+.It Cm \&%OW
+Week number of the year (Monday as the first day of
+the week) using the locale's alternative numeric symbols.
+.It Cm \&%Oy
+Year (offset from %C) in the locale's alternative
+representation and using the locale's alternative
+numeric symbols.
+.El
+.Ss "Internal Format Conversion"
+The following rules are applied for converting the input
+specification into the internal format:
+.Bl -bullet -offset indent
+.It
+If only the weekday is given, today is assumed if the
+given day is equal to the current day and next week if
+it is less.
+.It
+If only the month is given, the current month is
+assumed if the given month is equal to the current
+month and next year if it is less and no year is
+given.
+(The first day of month is assumed if no day is
+given.)
+.It
+If only the year is given, the values of the tm_mon,
+tm_mday, tm_yday, tm_wday, and tm_isdst members of the
+returned tm structure are not specified.
+.It
+If the century is given, but the year within the century is not given,
+the current year within the century
+is assumed.
+.It
+If no hour, minute, and second are given, the current
+hour, minute, and second are assumed.
+.It
+If no date is given, today is assumed if the given
+hour is greater than the current hour and tomorrow is
+assumed if it is less.
+.El
+.Ss "General Specifications"
+A conversion specification that is an ordinary character is
+executed by scanning the next character from the buffer.
+If the character scanned from the buffer differs from the one
+comprising the conversion specification, the specification
+fails, and the differing and subsequent characters remain
+unscanned.
+.Pp
+A series of conversion specifications composed of
+.Ql %n ,
+.Ql %t ,
+white space characters, or any combination is executed by
+scanning up to the first character that is not white space
+(which remains unscanned), or until no more characters can
+be scanned.
+.Pp
+Any other conversion specification is executed by scanning
+characters until a character matching the next conversion
+specification is scanned, or until no more characters can be
+scanned.
+These characters, except the one matching the next
+conversion specification, are then compared to the locale
+values associated with the conversion specifier.
+If a match is found, values for the appropriate
+.Vt tm
+structure members
+are set to values corresponding to the locale information.
+If no match is found,
+.Fn getdate
+fails and no more characters are scanned.
+.Pp
+The month names, weekday names, era names, and alternative
+numeric symbols can consist of any combination of upper and
+lower case letters.
+The user can request that the input
+date or time specification be in a specific language by setting the
+.Ev LC_TIME
+category using
+.Xr setlocale 3 .
+.Sh RETURN VALUES
+If successful,
+.Fn getdate
+returns a pointer to a
+.Vt tm
+structure; otherwise, it returns
+.Dv NULL
+and sets the global variable
+.Va getdate_err
+to indicate the error.
+Subsequent calls to
+.Fn getdate
+alter the contents of
+.Va getdate_err .
+.Pp
+The following is a complete list of the
+.Va getdate_err
+settings and their meanings:
+.Bl -tag -width "xxx"
+.It 1
+The DATEMSK environment variable is null or undefined.
+.It 2
+The template file cannot be opened for reading.
+.It 3
+Failed to get file status information.
+.It 4
+The template file is not a regular file.
+.It 5
+An error is encountered while reading the template
+file.
+.It 6
+The
+.Xr malloc 3
+function failed (not enough memory is
+available).
+.It 7
+There is no line in the template that matches the
+input.
+.It 8
+The input specification is invalid (for example,
+February 31).
+.El
+.Sh USAGE
+The
+.Fn getdate
+function makes explicit use of macros
+described on the
+.Xr ctype 3
+manual page.
+.Sh EXAMPLES
+Example 1: Examples of the
+.Fn getdate
+function.
+.Pp
+The following example shows the possible contents of a template:
+.Bd -literal
+%m
+%A %B %d %Y, %H:%M:%S
+%A
+%B
+%m/%d/%y %I %p
+%d,%m,%Y %H:%M
+at %A the %dst of %B in %Y
+run job at %I %p,%B %dnd
+%A den %d. %B %Y %H.%M Uhr
+.Ed
+.Pp
+The following are examples of valid input specifications for
+the above template:
+.Bd -literal
+getdate("10/1/87 4 PM")
+getdate("Friday")
+getdate("Friday September 19 1987, 10:30:30")
+getdate("24,9,1986 10:30")
+getdate("at monday the 1st of december in 1986")
+getdate("run job at 3 PM, december 2nd")
+.Pp
+.Ed
+If the
+.Ev LANG
+environment variable is set to de (German), the
+following is valid:
+.Bd -literal
+getdate("freitag den 10. oktober 1986 10.30 Uhr")
+.Ed
+.Pp
+Local time and date specification are also supported.
+The following examples show how local date and time specification
+can be defined in the template.
+.Pp
+.Bf -literal
+.TS
+box;
+c | c
+l | l .
+Invocation Line in Template
+getdate("11/27/86") %m/%d/%y
+getdate("27.11.86") %d.%m.%y
+getdate("86-11-27") %y-%m-%d
+getdate("Friday 12:00:00") %A %H:%M:%S
+.TE
+.Ef
+.Pp
+The following examples illustrate the Internal Format
+Conversion rules.
+Assume that the current date is
+.Li Mon Sep 22 12:19:47 EDT 1986
+and the
+.Ev LANG
+environment variable is not set.
+.Pp
+.Bf -literal
+.TS
+box;
+c | c | c
+l | l | l .
+Input Template Line Date
+Mon %a Mon Sep 22 12:19:48 EDT 1986
+Sun %a Sun Sep 28 12:19:49 EDT 1986
+Fri %a Fri Sep 26 12:19:49 EDT 1986
+September %B Mon Sep 1 12:19:49 EDT 1986
+January %B Thu Jan 1 12:19:49 EST 1987
+December %B Mon Dec 1 12:19:49 EDT 1986
+Sep Mon %b %a Mon Sep 1 12:19:50 EDT 1986
+Jan Fri %b %a Fri Jan 2 12:19:50 EST 1987
+Dec Mon %b %a Mon Dec 1 12:19:50 EST 1986
+Jan Wed 1989 %b %a %Y Wed Jan 4 12:19:51 EST 1989
+Fri 9 %a %H Fri Sep 26 09:00:00 EDT 1986
+Feb 10:30 %b %H:%S Sun Feb 1 10:00:30 EST 1987
+10:30 %H:%M Tue Sep 23 10:30:00 EDT 1986
+13:30 %H:%M Mon Sep 22 13:30:00 EDT 1986
+.TE
+.Ef
+.Pp
+.Sh "SEE ALSO"
+.Xr ctype 3 ,
+.Xr mktime 3 ,
+.Xr setlocale 3 ,
+.Xr strftime 3 ,
+.Xr strptime 3 ,
+.Xr environ 5
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+enum {
+ DATEMSK_NOT_DEFINED = 1,
+ CANT_OPEN,
+ CANT_FSTAT,
+ NOT_FILE,
+ IO_ERROR,
+ OUT_OF_MEMORY,
+ NO_MATCH,
+ INVALID_DATE
+};
+
+#define DATEMSK "DATEMSK"
+#define TM_SEC_SET 0x01
+#define TM_MIN_SET 0x02
+#define TM_HOUR_SET 0x04
+#define TM_MDAY_SET 0x01
+#define TM_MON_SET 0x02
+#define TM_YEAR_SET 0x04
+#define UNDEFINED -1
+
+static struct tm tmundef = {
+ UNDEFINED,
+ UNDEFINED,
+ UNDEFINED,
+ UNDEFINED,
+ UNDEFINED,
+ UNDEFINED,
+ UNDEFINED
+};
+
+int getdate_err;
+
+/*
+ * getdate
+ *
+ * Call strptime() on each line of the DATEMSK file, and manipulate the
+ * resulting tm structure.
+ */
+struct tm *
+getdate(const char *str)
+{
+ static struct tm tm, *now, *result = NULL;
+ time_t t;
+ FILE *fp;
+ int bufsiz, offset, len, dateset, timeset, saveerrno, wday_set;
+ char *buf;
+ struct stat st;
+ char *file = getenv(DATEMSK);
+
+ if(!file || !*file) {
+ getdate_err = DATEMSK_NOT_DEFINED;
+ return NULL;
+ }
+ saveerrno = errno;
+ if((fp = fopen(file, "r")) == NULL) {
+ getdate_err = CANT_OPEN;
+ errno = saveerrno;
+ return NULL;
+ }
+ do {
+ if(fstat(fileno(fp), &st) < 0) {
+ getdate_err = CANT_FSTAT;
+ break;
+ }
+ if((st.st_mode & S_IFMT) != S_IFREG) {
+ getdate_err = NOT_FILE;
+ break;
+ }
+ if((buf = malloc(bufsiz = BUFSIZ)) == NULL) {
+ getdate_err = OUT_OF_MEMORY;
+ break;
+ }
+ do {
+ offset = 0;
+ for(;;) {
+ if(fgets(buf + offset, bufsiz - offset, fp) == NULL) {
+ if(ferror(fp)) {
+ getdate_err = IO_ERROR;
+ break;
+ }
+ if(offset == 0) {
+ getdate_err = NO_MATCH;
+ break;
+ }
+ len = strlen(buf);
+ } else if((len = strlen(buf)) == bufsiz - 1
+ && buf[len - 1] != '\n') {
+ char *newptr = realloc(buf, (bufsiz += BUFSIZ));
+ if(newptr == NULL) {
+ getdate_err = OUT_OF_MEMORY;
+ break;
+ }
+ buf = newptr;
+ offset = len;
+ continue;
+ }
+ if(buf[len - 1] == '\n')
+ buf[len - 1] = 0;
+ tm = tmundef;
+ if(strptime(str, buf, &tm) == NULL) {
+ offset = 0;
+ continue;
+ }
+ time(&t);
+ now = localtime(&t);
+ dateset = timeset = 0;
+ if(tm.tm_sec != UNDEFINED)
+ timeset |= TM_SEC_SET;
+ if(tm.tm_min != UNDEFINED)
+ timeset |= TM_MIN_SET;
+ if(tm.tm_hour != UNDEFINED)
+ timeset |= TM_HOUR_SET;
+ if(tm.tm_mday != UNDEFINED)
+ dateset |= TM_MDAY_SET;
+ if(tm.tm_mon != UNDEFINED)
+ dateset |= TM_MON_SET;
+ if(tm.tm_year != UNDEFINED)
+ dateset |= TM_YEAR_SET;
+ wday_set = tm.tm_wday;
+
+ switch(timeset) {
+ case 0:
+ tm.tm_sec = now->tm_sec;
+ tm.tm_min = now->tm_min;
+ tm.tm_hour = now->tm_hour;
+ break;
+
+ case TM_SEC_SET:
+ tm.tm_hour = now->tm_hour;
+ tm.tm_min = now->tm_min;
+ if(tm.tm_sec < now->tm_sec)
+ tm.tm_min++;
+ break;
+
+ case TM_MIN_SET:
+ tm.tm_hour = now->tm_hour;
+ if(tm.tm_min < now->tm_min)
+ tm.tm_hour++;
+ tm.tm_sec = 0;
+ break;
+
+ case TM_MIN_SET | TM_SEC_SET:
+ tm.tm_hour = now->tm_hour;
+ if((60 * tm.tm_min + tm.tm_sec)
+ < (60 * now->tm_min + now->tm_sec))
+ tm.tm_hour++;
+ break;
+
+ case TM_HOUR_SET:
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ break;
+
+ case TM_HOUR_SET | TM_SEC_SET:
+ tm.tm_min = 0;
+ break;
+
+ case TM_HOUR_SET | TM_MIN_SET:
+ tm.tm_sec = 0;
+ break;
+ }
+
+ switch(dateset) {
+ case 0:
+ tm.tm_mday = now->tm_mday;
+ if(tm.tm_hour < now->tm_hour)
+ tm.tm_mday++;
+ tm.tm_mon = now->tm_mon;
+ tm.tm_year = now->tm_year;
+ break;
+
+ case TM_MDAY_SET:
+ tm.tm_year = now->tm_year;
+ tm.tm_mon = now->tm_mon;
+ if(tm.tm_mday < now->tm_mday)
+ tm.tm_mon++;
+ break;
+
+ case TM_MON_SET:
+ case TM_MON_SET | TM_MDAY_SET:
+ tm.tm_year = now->tm_year;
+ if(tm.tm_mon < now->tm_mon)
+ tm.tm_year++;
+ if(!(dateset & TM_MDAY_SET))
+ tm.tm_mday = 1;
+ break;
+
+ case TM_YEAR_SET:
+ case TM_YEAR_SET | TM_MON_SET:
+ if(!(dateset & TM_MON_SET))
+ tm.tm_mon = 1;
+ tm.tm_mday = 1;
+ break;
+
+ case TM_YEAR_SET | TM_MDAY_SET:
+ tm.tm_mon = now->tm_mon;
+ if(tm.tm_mday < now->tm_mday)
+ tm.tm_mon++;
+ break;
+ }
+
+ tm.tm_wday = now->tm_wday;
+ tm.tm_gmtoff = now->tm_gmtoff; /* XXX: can't grok timezones */
+ tm.tm_isdst = -1;
+
+ if(mktime(&tm) == (time_t)-1) {
+ getdate_err = INVALID_DATE;
+ break;
+ }
+ if(wday_set != UNDEFINED) {
+ int delta = wday_set - tm.tm_wday;
+ if(delta && (dateset & TM_MDAY_SET)) {
+ getdate_err = INVALID_DATE;
+ break;
+ }
+ if(delta < 0)
+ delta += 7;
+ tm.tm_mday += delta;
+ if(mktime(&tm) == (time_t)-1) {
+ getdate_err = INVALID_DATE;
+ break;
+ }
+ }
+ result = &tm;
+ }
+ } while(0);
+
+ free(buf);
+ } while(0);
+
+ fclose(fp);
+ errno = saveerrno;
+ return result;
+}
--- /dev/null
+.\" Copyright (C) 2001 Andries Brouwer <aeb@cwi.nl>
+.\"
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one
+.\"
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date. The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein. The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\"
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\"
+.TH TIMEGM 3 2001-12-26 "GNU" "Linux Programmer's Manual"
+.SH NAME
+timegm, timelocal \- inverses for gmtime and localtime
+.SH SYNOPSIS
+.nf
+.B #include <time.h>
+.sp
+.BI "time_t timelocal (struct tm *" tm );
+.sp
+.BI "time_t timegm (struct tm *" tm );
+.SH DESCRIPTION
+The functions
+.B timelocal()
+and
+.B timegm()
+are the inverses to
+.BR localtime (3)
+and
+.BR gmtime (3).
+.SH NOTES
+These functions are GNU extensions.
+The
+.B timelocal()
+function is equivalent to the POSIX standard function
+.BR mktime (3).
+There is no reason to ever use it.
+.LP
+For a portable version of
+.BR timegm() ,
+set the
+.B TZ
+environment variable to UTC, call
+.B mktime()
+and restore the value of
+.BR TZ .
+Something like
+
+.RS
+.nf
+#include <time.h>
+#include <stdlib.h>
+
+time_t my_timegm (struct tm *tm) {
+ time_t ret;
+ char *tz;
+
+ tz = getenv("TZ");
+ setenv("TZ", "", 1);
+ tzset();
+ ret = mktime(tm);
+ if (tz)
+ setenv("TZ", tz, 1);
+ else
+ unsetenv("TZ");
+ tzset();
+ return ret;
+}
+.fi
+.RE
+.SH "SEE ALSO"
+.BR gmtime (3),
+.BR localtime (3),
+.BR mktime (3),
+.BR tzset (3)
+++ /dev/null
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/bcopy.c,v 1.5 2002/09/01 21:53:46 robert Exp $");
-
-/*
- * sizeof(word) MUST BE A POWER OF TWO
- * SO THAT wmask BELOW IS ALL ONES
- */
-typedef int word; /* "word" used for optimal copy speed */
-
-#define wsize sizeof(word)
-#define wmask (wsize - 1)
-
-/*
- * Copy a block of memory, handling overlap.
- * This is the routine that actually implements
- * (the portable versions of) bcopy, memcpy, and memmove.
- */
-#if defined(MEMCOPY) || defined(MEMMOVE)
-#include <string.h>
-
-void *
-#ifdef MEMCOPY
-memcpy
-#else
-memmove
-#endif
-(void *dst0, const void *src0, size_t length)
-#else
-#include <strings.h>
-
-void
-bcopy(const void *src0, void *dst0, size_t length)
-#endif
-{
- char *dst = dst0;
- const char *src = src0;
- size_t t;
-
- if (length == 0 || dst == src) /* nothing to do */
- goto done;
-
- /*
- * Macros: loop-t-times; and loop-t-times, t>0
- */
-#define TLOOP(s) if (t) TLOOP1(s)
-#define TLOOP1(s) do { s; } while (--t)
-
- if ((unsigned long)dst < (unsigned long)src) {
- /*
- * Copy forward.
- */
- t = (int)src; /* only need low bits */
- if ((t | (int)dst) & wmask) {
- /*
- * Try to align operands. This cannot be done
- * unless the low bits match.
- */
- if ((t ^ (int)dst) & wmask || length < wsize)
- t = length;
- else
- t = wsize - (t & wmask);
- length -= t;
- TLOOP1(*dst++ = *src++);
- }
- /*
- * Copy whole words, then mop up any trailing bytes.
- */
- t = length / wsize;
- TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
- t = length & wmask;
- TLOOP(*dst++ = *src++);
- } else {
- /*
- * Copy backwards. Otherwise essentially the same.
- * Alignment works as before, except that it takes
- * (t&wmask) bytes to align, not wsize-(t&wmask).
- */
- src += length;
- dst += length;
- t = (int)src;
- if ((t | (int)dst) & wmask) {
- if ((t ^ (int)dst) & wmask || length <= wsize)
- t = length;
- else
- t &= wmask;
- length -= t;
- TLOOP1(*--dst = *--src);
- }
- t = length / wsize;
- TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
- t = length & wmask;
- TLOOP(*--dst = *--src);
- }
-done:
-#if defined(MEMCOPY) || defined(MEMMOVE)
- return (dst0);
-#else
- return;
-#endif
-}
+++ /dev/null
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/bzero.c,v 1.2 2002/03/22 21:53:19 obrien Exp $");
-
-#define BZERO
-#include "memset.c"
--- /dev/null
+--- index.c.orig Tue May 20 15:23:54 2003
++++ index.c Tue Dec 16 00:58:24 2003
+@@ -52,8 +52,9 @@
+ #endif
+ (const char *p, int ch)
+ {
++ char c = ch;
+ for (;; ++p) {
+- if (*p == ch)
++ if (*p == c)
+ return ((char *)p);
+ if (*p == '\0')
+ return (NULL);
---- memcpy.3.orig Tue May 20 15:23:54 2003
-+++ memcpy.3 Sat Jun 21 06:17:05 2003
-@@ -58,6 +58,18 @@
+--- memcpy.3.orig Fri May 28 17:44:25 2004
++++ memcpy.3 Fri May 28 17:45:22 2004
+@@ -41,7 +41,7 @@
+ .Os
+ .Sh NAME
+ .Nm memcpy
+-.Nd copy byte string
++.Nd copy memory area
+ .Sh LIBRARY
+ .Lb libc
+ .Sh SYNOPSIS
+@@ -54,10 +54,22 @@
+ function
+ copies
+ .Fa len
+-bytes from string
++bytes from memory area
.Fa src
- to string
+-to string
++to memory area
.Fa dst .
+If
+.Fa src
+and
+.Fa dst
-+overlap, behaviour is undefined.
++overlap, behavior is undefined.
+Applications in which
+.Fa src
+and
+++ /dev/null
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/memcpy.c,v 1.2 2002/03/22 21:53:19 obrien Exp $");
-
-#define MEMCOPY
-#include "bcopy.c"
+++ /dev/null
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/memmove.c,v 1.2 2002/03/22 21:53:19 obrien Exp $");
-
-#define MEMMOVE
-#include "bcopy.c"
--- /dev/null
+--- rindex.c.orig Tue May 20 15:23:54 2003
++++ rindex.c Tue Dec 16 00:58:56 2003
+@@ -53,9 +53,10 @@
+ (const char *p, int ch)
+ {
+ char *save;
++ char c = ch;
+
+ for (save = NULL;; ++p) {
+- if (*p == ch)
++ if (*p == c)
+ save = (char *)p;
+ if (*p == '\0')
+ return (save);
--- /dev/null
+--- strcat.3.orig Fri May 28 16:23:18 2004
++++ strcat.3 Fri May 28 16:23:32 2004
+@@ -114,7 +114,7 @@
+ void
+ foo(const char *arbitrary_string)
+ {
+- char onstack[8];
++ char onstack[8] = "";
+
+ #if defined(BAD)
+ /*
+@@ -149,11 +149,6 @@
+ .Xr strcpy 3 ,
+ .Xr strlcat 3 ,
+ .Xr strlcpy 3
+-.Rs
+-.%T "The FreeBSD Security Architecture"
+-.Re
+-(See
+-.Pa "/usr/share/doc/{to be decided}" . )
+ .Sh STANDARDS
+ The
+ .Fn strcat
+++ /dev/null
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strcmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/strcmp.c,v 1.5 2002/03/21 18:44:54 obrien Exp $");
-
-#include <string.h>
-
-/*
- * Compare strings.
- */
-int
-strcmp(s1, s2)
- const char *s1, *s2;
-{
- while (*s1 == *s2++)
- if (*s1++ == 0)
- return (0);
- return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
-}
--- /dev/null
+Index: strcpy.3
+===================================================================
+RCS file: /cvs/root/Libc/string/FreeBSD/strcpy.3,v
+retrieving revision 1.2
+diff -u -r1.2 strcpy.3
+--- strcpy.3 2003/05/20 22:23:54 1.2
++++ strcpy.3 2003/10/24 18:27:22
+@@ -179,11 +179,6 @@
+ .Xr memcpy 3 ,
+ .Xr memmove 3 ,
+ .Xr strlcpy 3
+-.Rs
+-.%T "The FreeBSD Security Architecture"
+-.Re
+-(See
+-.Pa "/usr/share/doc/{to be decided}" . )
+ .Sh STANDARDS
+ The
+ .Fn strcpy
# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
# $FreeBSD: src/lib/libc/string/Makefile.inc,v 1.32 2002/11/18 09:50:56 ru Exp $
-.PATH: ${.CURDIR}/${MACHINE_ARCH}/string ${.CURDIR}/string
+# machine-dependent string sources
+.if exists(${.CURDIR}/${MACHINE_ARCH}/string/Makefile.inc)
+.include "${.CURDIR}/${MACHINE_ARCH}/string/Makefile.inc"
+.endif
+
+.PATH: ${.CURDIR}/string
CFLAGS+= -I${.CURDIR}/locale
.include "Makefile.fbsd_begin"
# machine-independent string sources
-FBSDMISRCS+=bcmp.c bcopy.c bzero.c ffs.c index.c memccpy.c memchr.c memcmp.c \
- memcpy.c memmove.c memset.c rindex.c stpcpy.c strcasecmp.c strcat.c \
- strchr.c strcmp.c strcoll.c strcpy.c strcspn.c strdup.c strerror.c \
+FBSDMISRCS+=bcmp.c ffs.c index.c memccpy.c memchr.c memcmp.c \
+ memset.c rindex.c stpcpy.c strcasecmp.c strcat.c \
+ strchr.c strcoll.c strcpy.c strcspn.c strdup.c strerror.c \
strlcat.c strlcpy.c strlen.c strmode.c strncat.c strncmp.c strncpy.c \
strcasestr.c strnstr.c \
strpbrk.c strrchr.c strsep.c strsignal.c strspn.c strstr.c strtok.c \
wmemcpy.c wmemmove.c wmemset.c
.include "Makefile.fbsd_end"
-# machine-dependent string sources
-.if exists(${.CURDIR}/${MACHINE_ARCH}/string/Makefile.inc)
-.include "${.CURDIR}/${MACHINE_ARCH}/string/Makefile.inc"
-.endif
-
.if ${LIB} == "c"
.include "Makefile.fbsd_begin"
FBSDMAN3= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \
# @(#)Makefile.inc 8.3 (Berkeley) 10/24/94
# $FreeBSD: src/lsys/Makefile.inc,v 1.91 2001/09/21 21:35:22 rwatson Exp $
-# sys sources
-.PATH: ${.CURDIR}/${MACHINE_ARCH}/sys ${.CURDIR}/sys
-
-# Include the generated makefile containing the *complete* list
-# of syscall names in MIASM.
-#.include "${.CURDIR}/../../sys/sys/syscall.mk"
-
# Include machine dependent definitions.
#
# MDASM names override the default syscall names in MIASM.
.include "${.CURDIR}/${MACHINE_ARCH}/sys/Makefile.inc"
.endif
+# sys sources
+.PATH: ${.CURDIR}/sys
+
+# Include the generated makefile containing the *complete* list
+# of syscall names in MIASM.
+#.include "${.CURDIR}/../../sys/sys/syscall.mk"
+
# Sources common to both syscall interfaces:
# 3375657: patches for sem_open() sem_unlink() shm_open() shm_unlink()
-CFLAGS+= -D__APPLE_PR3375657_HACK__
-SRCS+= errno.c gettimeofday.c sigcatch.c sigsuspend.c getdtablesize.c \
+MISRCS+= errno.c gettimeofday.c sigcatch.c sigsuspend.c getdtablesize.c \
sigaction.c sigtramp.c crt_externs.c \
sem_open.c sem_unlink.c shm_open.c shm_unlink.c fix-3375657.c
+.for _src in sem_open.c sem_unlink.c shm_open.c shm_unlink.c fix-3375657.c
+CFLAGS-${_src} += -D__APPLE_PR3375657_HACK__
+.endfor
+
# Add machine dependent asm sources:
SRCS+=${MDASM}
sem_unlink.2 sem_wait.2 shm_open.2 shm_unlink.2 \
sigwait.2 getdtablesize.2 setreuid.2 setregid.2 \
nanosleep.2
+MAN3+= atomic.3 atomicqueue.3 barrier.3 spinlock.3
+MLINKS+= atomic.3 OSAtomicAdd32.3
+MLINKS+= atomic.3 OSAtomicIncrement32.3
+MLINKS+= atomic.3 OSAtomicDecrement32.3
+MLINKS+= atomic.3 OSAtomicOr32.3
+MLINKS+= atomic.3 OSAtomicAnd32.3
+MLINKS+= atomic.3 OSAtomicXor32.3
+MLINKS+= atomic.3 OSAtomicAdd64.3
+MLINKS+= atomic.3 OSAtomicIncrement64.3
+MLINKS+= atomic.3 OSAtomicDecrement64.3
+MLINKS+= atomic.3 OSAtomicCompareAndSwap32.3
+MLINKS+= atomic.3 OSAtomicCompareAndSwap64.3
+MLINKS+= atomic.3 OSAtomicTestAndSet.3
+MLINKS+= atomic.3 OSAtomicTestAndClear.3
+MLINKS+= atomicqueue.3 OSAtomicDequeue.3
+MLINKS+= atomicqueue.3 OSAtomicEnqueue.3
+MLINKS+= barrier.3 OSMemoryBarrier.3
+MLINKS+= spinlock.3 OSSpinLockTry.3
+MLINKS+= spinlock.3 OSSpinLockLock.3
+MLINKS+= spinlock.3 OSSpinLockUnlock.3
+
#MAN+= _exit.2 accept.2 access.2 acct.2 adjtime.2 \
# aio_cancel.2 aio_error.2 aio_read.2 aio_return.2 \
# aio_suspend.2 aio_waitcomplete.2 aio_write.2 \
fchmod
chown
fchown
+lchown
chroot
close
connect
--- /dev/null
+.Dd May 26, 2004
+.Dt ATOMIC 3
+.Os Darwin
+.Sh NAME
+.Nm OSAtomicAdd32 ,
+.Nm OSAtomicIncrement32 ,
+.Nm OSAtomicDecrement32 ,
+.Nm OSAtomicOr32 ,
+.Nm OSAtomicAnd32 ,
+.Nm OSAtomicXor32 ,
+.Nm OSAtomicAdd64 ,
+.Nm OSAtomicIncrement64 ,
+.Nm OSAtomicDecrement64 ,
+.Nm OSAtomicCompareAndSwap32 ,
+.Nm OSAtomicCompareAndSwap64 ,
+.Nm OSAtomicTestAndSet ,
+.Nm OSAtomicTestAndClear
+.Nd atomic add, increment, decrement, or, and, xor, compare and swap, test and set, and test and clear
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In libkern/OSAtomic.h
+.Ft int32_t
+.Fn OSAtomicAdd32 "int32_t theAmount, int32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicIncrement32 "int32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicDecrement32 "int32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicOr32 "uint32_t theMask, uint32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicAnd32 "uint32_t theMask, uint32_t *theValue"
+.Ft int32_t
+.Fn OSAtomicXor32 "uint32_t theMask, uint32_t *theValue"
+.Ft int64_t
+.Fn OSAtomicAdd64 "int64_t theAmount, int64_t *theValue"
+.Ft int64_t
+.Fn OSAtomicIncrement64 "int64_t *theValue"
+.Ft int64_t
+.Fn OSAtomicDecrement64 "int64_t *theValue"
+.Ft bool
+.Fn OSAtomicCompareAndSwap32 "int32_t oldValue" "int32_t newValue" "int32_t *theValue"
+.Ft bool
+.Fn OSAtomicCompareAndSwap64 "int64_t oldValue" "int64_t newValue" "int64_t *theValue"
+.Ft bool
+.Fn OSAtomicTestAndSet "uint32_t n, void *theAddress"
+.Ft bool
+.Fn OSAtomicTestAndClear "uint32_t n, void *theAddress"
+.Sh DESCRIPTION
+These functions are thread and multiprocessor safe, but do not incorporate memory barriers
+and thus cannot be used by themselves to synchronize shared memory other than the memory
+being operated on (ie,
+.Fa theValue
+and
+.Fa theAddress
+). The logical (and, or, xor) and bit test operations are layered on top of the
+.Fn OSAtomicCompareAndSwap
+primitives. The memory address
+.Fa theValue
+must be naturally aligned, ie 32-bit aligned for 32-bit operations and 64-bit
+aligned for 64-bit operations. The 64-bit operations are only implemented for
+64-bit processes.
+.Pp
+.Fn OSAtomicCompareAndSwap32
+and
+.Fn OSAtomicCompareAndSwap64
+compare
+.Fa oldValue
+to
+.Fa *theValue ,
+and set
+.Fa *theValue
+to
+.Fa newValue
+if the comparison is equal. The comparison and assignment
+occur as one atomic operation.
+.Pp
+.Fn OSAtomicTestAndSet
+and
+.Fn OSAtomicTestAndClear
+operate on bit (0x80 >> (
+.Fa n
+& 7)) of byte ((char*)
+.Fa theAddress
++ (
+.Fa n
+>> 3)). They set the named bit to either 1 or 0, respectively.
+.Fa theAddress
+need not be aligned.
+.Sh RETURN VALUES
+The arithmetic and logical operations return the new value, after the operation has been performed.
+The compare-and-swap operations return true if the comparison was equal, ie if the swap occured.
+The bit test and set/clear operations return the original value of the bit.
+.Sh SEE ALSO
+.Xr atomicqueue 3 ,
+.Xr spinlock 3 ,
+.Xr barrier 3
--- /dev/null
+.Dd May 26, 2004
+.Dt ATOMICQUEUE 3
+.Os Darwin
+.Sh NAME
+.Nm OSAtomicEnqueue ,
+.Nm OSAtomicDequeue
+.Nd atomic enqueue and dequeue on a singly linked list
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In libkern/OSAtomic.h
+.Ft void
+.Fn OSAtomicEnqueue "void ** inList, void * inNewLink, size_t inOffset"
+.Ft void *
+.Fn OSAtomicDequeue "void ** inList, size_t inOffset"
+.Sh DESCRIPTION
+.Fn OSAtomicEnqueue
+and
+.Fn OSAtomicDequeue
+operate on zero-terminated singly-linked lists of structures whose
+link field need not be the first element.
+They are thread safe and incorporate memory barriers as required to
+synchronize access to the shared memory. The list is last in, first out.
+.Pp
+If thread safety is not a requirement, then the queue(3) package is more
+flexible and possibly more efficient.
+.Pp
+.Fa inList
+is the pointer to the head of the list. It is not a structure, and should be
+initialized to
+.Dv NIL .
+.Fa inOffset
+is the offset within the structure of the link field.
+.Fa inNewLink
+is a pointer to the structure to be queued on the list:
+.Bd -literal -offset indent
+typedef struct node {
+ long data1;
+ struct node *link;
+ int data2;
+} node;
+
+node *head = NIL;
+node n1, n2;
+node *p;
+
+/* put n1 on the list */
+OSAtomicEnqueue( (void**) &head, &n1, offsetof(node,link));
+
+/* then put n2 on the list */
+OSAtomicEnqueue( (void**) &head, &n2, offsetof(node,link));
+
+/* dequeue n2 (ie, the node most recently added) */
+p = OSAtomicDequeue( (void**) &head, offsetof(node,link));
+.Ed
+.Sh RETURN VALUES
+.Fn OSAtomicDequeue
+returns a pointer to the node removed from the list, or
+.Dv NIL
+if the list is empty.
+.Sh SEE ALSO
+.Xr atomic 3 ,
+.Xr spinlock 3 ,
+.Xr barrier 3 ,
+.Xr queue 3
\ No newline at end of file
--- /dev/null
+.Dd May 26, 2004
+.Dt BARRIER 3
+.Os Darwin
+.Sh NAME
+.Nm OSMemoryBarrier
+.Nd memory barrier to order loads and stores
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In libkern/OSAtomic.h
+.Ft void
+.Fn OSMemoryBarrier "void"
+.Sh DESCRIPTION
+.Fn OSMemoryBarrier
+strictly orders memory accesses in a weakly ordered memory model such as with PowerPC,
+by creating a barrier. All loads and stores executed in sequential program order before
+the barrier will complete with respect to the memory coherence mechanism, before any
+load or store executed after the barrier. Used with an atomic operation, the barrier
+can be used to create custom synchronization protocols as an alternative to the
+spinlock or queue/dequeue operations. Note that this barrier does not order uncached loads
+and stores. On a uniprocessor, the barrier operation is typically optimized into a nop.
+.Sh SEE ALSO
+.Xr atomic 3 ,
+.Xr atomicqueue 3 ,
+.Xr spinlock 3
\ No newline at end of file
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
tp = &localtv;
}
-#ifdef __ppc__
+#if defined(__ppc__) || defined(__ppc64__)
{
extern int __ppc_gettimeofday(struct timeval *, struct timezone *);
extern int __commpage_gettimeofday(struct timeval *);
.Os
.Sh NAME
.Nm nanosleep
-.Nd suspend process execution for an interval measured in nanoseconds
+.Nd suspend thread execution for an interval measured in nanoseconds
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.Fn nanosleep "const struct timespec *rqtp" "struct timespec *rmtp"
.Sh DESCRIPTION
.Fn Nanosleep
-causes the process to sleep for the specified time. An unmasked signal will
+causes the calling thread to sleep for the specified time
+(the actual time slept may be longer, due to system latencies
+and possible limitations in the timer resolution of the hardware).
+An unmasked signal will
cause it to terminate the sleep early, regardless of the
.Dv SA_RESTART
value on the interrupting signal.
.Sh STANDARDS
.Fn pthread_kill
conforms to ISO/IEC 9945-1:1996 (``POSIX.1'')
-
.Sh STANDARDS
.Fn pthread_sigmask
conforms to ISO/IEC 9945-1:1996 (``POSIX.1'')
-
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
.Fa name .
.Pp
If successful,
-.Fn sem_close
+.Fn sem_unlink
will return 0. Otherwise, -1 is returned and
.Va errno
is set, and the state of the semaphore is unchanged.
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
*/
#import "sigcatch.h"
+#import <sys/types.h>
#import <signal.h>
-#import <sys/signal.h>
#import <ucontext.h>
/*
/* These defn should match the kernel one */
#define UC_TRAD 1
-#ifdef __ppc__
+#if defined(__ppc__) || defined(__ppc64__)
#define UC_TRAD64 20
#define UC_TRAD64_VEC 25
#define UC_FLAVOR 30
#define UC_FLAVOR64_VEC_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int))
#endif
-#ifdef __ppc__
+#if defined(__ppc__) || defined(__ppc64__)
/* This routine will be replaced by an assembly soon */
static int
-restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle)
+restore64_state(mcontext_t mctx, mcontext64_t mctx64)
{
if (mctx->ss.srr0 != (unsigned int)mctx64->ss.srr0)
return(0);
if (mctx->ss.ctr != (unsigned int)mctx64->ss.ctr)
return(0);
- if (bcmp(&mctx->fs, &mctx64->ss, (PPC_FLOAT_STATE_COUNT * sizeof(int))))
- return(0);
- if ((sigstyle == UC_DUAL_VEC) && bcmp(&mctx->vs, &mctx64->vs, (PPC_VECTOR_STATE_COUNT * sizeof(int))))
- return(0);
-
return(1);
}
siginfo_t *sinfo,
struct ucontext *uctx
) {
-#ifdef __ppc__
+#if defined(__ppc__) || defined(__ppc64__)
int ctxstyle = UC_FLAVOR;
#endif
mcontext_t mctx;
#if defined(__DYNAMIC__)
__in_sigtramp++;
#endif
-#ifndef __ppc__
+#ifdef __i386__
if (sigstyle == UC_TRAD)
sa_handler(sig);
-#else /* __ppc__ */
+#elif defined(__ppc__) || defined(__ppc64__)
if ((sigstyle == UC_TRAD) || (sigstyle == UC_TRAD64) || (sigstyle == UC_TRAD64_VEC))
sa_handler(sig);
mctx = uctx->uc_mcontext;
mctx64 = (mcontext64_t)((char *)(uctx->uc_mcontext) + sizeof(struct mcontext));
/* restore 64bit state ? */
- if (restore64_state(mctx, mctx64, sigstyle)) {
+ if (restore64_state(mctx, mctx64)) {
uctx->uc_mcontext = (void *)mctx64;
if (sigstyle == UC_DUAL) {
uctx->uc_mcsize = UC_FLAVOR64_SIZE;
}
} else
ctxstyle = sigstyle;
-#endif /* __ppc__ */
+#endif /* __ppc__ || __ppc64__ */
#if defined(__DYNAMIC__)
__in_sigtramp--;
#endif
-#ifdef __ppc__
+#if defined(__ppc__) || defined(__ppc64__)
{
/* sigreturn(uctx, ctxstyle); */
/* syscall (SYS_SIGRETURN, uctx, ctxstyle); */
}
#else
sigreturn(uctx);
-#endif /* __ppc__ */
+#endif /* __ppc__ || __ppc64__ */
}
--- /dev/null
+.Dd May 26, 2004
+.Dt SPINLOCK 3
+.Os Darwin
+.Sh NAME
+.Nm OSSpinLockTry ,
+.Nm OSSpinLockLock ,
+.Nm OSSpinLockUnlock
+.Nd atomic spin lock synchronization primitives
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In libkern/OSAtomic.h
+.Ft bool
+.Fn OSSpinLockTry "OSSpinLock *lock"
+.Ft void
+.Fn OSSpinLockLock "OSSpinLock *lock"
+.Ft void
+.Fn OSSpinLockUnlock "OSSpinLock *lock"
+.Sh DESCRIPTION
+Spin locks are a simple, fast, thread-safe synchronization primitive that is
+suitable in situations where contention is expected to be low. The spinlock
+operations use memory barriers to synchronize access to shared memory protected
+by the lock. Preemption is possible while the lock is held.
+.Pp
+.Ft OSSpinLock
+is an integer type. The convention is that unlocked is zero, and locked is nonzero.
+Locks must be naturally aligned and cannot be in cache-inhibited memory.
+.Pp
+.Fn OSSpinLockLock
+will spin if the lock is already held, but employs various strategies to back off,
+making it immune to most priority-inversion livelocks. But because it can spin, it
+may be inefficient in some situations.
+.Pp
+.Fn OSSpinLockTry
+immediately returns false if the lock was held, true if it took the lock.
+It does not spin.
+.Pp
+.Fn OSSpinLockUnlock
+unconditionally unlocks the lock by zeroing it.
+.Sh RETURN VALUES
+.Fn OSSpinLockTry
+returns true if it took the lock, false if the lock was already held.
+.Sh SEE ALSO
+.Xr atomic 3 ,
+.Xr atomicqueue 3 ,
+.Xr barrier 3
\ No newline at end of file
.include "${.CURDIR}/${MACHINE_ARCH}/threads/Makefile.inc"
.endif
-SRCS += cprocs.c cthreads.c lu_utils.c mig_support.c
+MISRCS += cprocs.c cthreads.c lu_utils.c mig_support.c
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* Routines for supporting fork() of multi-threaded programs.
*/
-void _cproc_fork_child()
+void
+_cproc_fork_child()
/*
* Called in the child after a fork(). Resets cproc data structures to
* coincide with the reality that we now have a single cproc and cthread.
#undef errno
extern int errno;
-void cthread_set_errno_self(error)
+extern int *__error(void);
+
+void
+cthread_set_errno_self(error)
int error;
{
- pthread_t t;
+ int *ep = __error();
+
+ if (ep != &errno)
+ *ep = error;
- t = pthread_self();
- if (t && (t->sig == _PTHREAD_SIG)) {
- t->err_no = error;
- }
errno = error;
}
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
.PATH: ${.CURDIR}/${MACHINE_ARCH}/util ${.CURDIR}/util
-SRCS += login.c login_tty.c logout.c logwtmp.c pty.c fparseln.c \
+MISRCS += login.c login_tty.c logout.c logwtmp.c pty.c fparseln.c \
opendev.c
.if ${LIB} == "c"
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
*
* @APPLE_LICENSE_HEADER_START@
*
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
--- /dev/null
+# uuid sources
+.PATH: ${.CURDIR}/uuid
+
+UUIDSRCS = clear.c compare.c copy.c gen_uuid.c isnull.c pack.c parse.c \
+ unpack.c unparse.c
+UUIDHDRS = uuid.h uuidP.h
+UUIDFROMMAN = libuuid.3.in
+UUIDTOMAN = uuid.3.in
+UUIDMAN3 = uuid_clear.3.in uuid_compare.3.in uuid_copy.3.in uuid_generate.3.in \
+ uuid_is_null.3.in uuid_parse.3.in uuid_unparse.3.in
+
+.for _src in ${UUIDSRCS}
+${SYMROOT}/${_src:R}-uuid.${_src:E}: uuidsrc/${_src} _AUTOPATCHSYM
+MISRCS+= ${_src}
+AUTOPATCHSRCS+= ${SYMROOT}/${_src:R}-uuid.${_src:E}
+.endfor
+
+.for _src in ${UUIDHDRS}
+${SYMROOT}/${_src}: uuidsrc/${_src} _AUTOPATCHSYM
+AUTOPATCHHDRS+= ${SYMROOT}/${_src}
+.endfor
+
+.for _src in ${UUIDMAN3}
+${_src:R}-uuid.${_src:E}: uuidsrc/${_src} _AUTOPATCH
+MAN3+= ${_src:R}
+AUTOPATCHMAN+= ${_src:R}
+.endfor
+
+${UUIDTOMAN:R}-uuid.${UUIDTOMAN:E}: uuidsrc/${UUIDFROMMAN} _AUTOPATCH
+MAN3+= ${UUIDTOMAN:R}
+AUTOPATCHMAN+= ${UUIDTOMAN:R}
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+// MacOS-specific settings for uuid
+#define HAVE_NETINET_IN_H
+#define HAVE_NET_IF_DL_H
+#define HAVE_NET_IF_H
+#define HAVE_SA_LEN
+#define HAVE_SRANDOM
+#define HAVE_STDINT_H
+#define HAVE_STDLIB_H
+#define HAVE_SYS_IOCTL_H
+#define HAVE_SYS_SOCKET_H
+#define HAVE_SYS_SOCKIO_H
+#define HAVE_UNISTD_H
+#define UUID_UNPARSE_DEFAULT_UPPER
--- /dev/null
+s/@E2FSPROGS_MONTH@/April/g
+s/@E2FSPROGS_YEAR@/2004/g
+s/@E2FSPROGS_VERSION@/1.36/g
--- /dev/null
+/*
+ * clear.c -- Clear a UUID
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * 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, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+#include "string.h"
+
+#include "uuidP.h"
+
+void uuid_clear(uuid_t uu)
+{
+ memset(uu, 0, 16);
+}
+
--- /dev/null
+/*
+ * compare.c --- compare whether or not two UUID's are the same
+ *
+ * Returns 0 if the two UUID's are different, and 1 if they are the same.
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * 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, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+#include "uuidP.h"
+#include <string.h>
+
+#define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1);
+
+int uuid_compare(const uuid_t uu1, const uuid_t uu2)
+{
+ struct uuid uuid1, uuid2;
+
+ uuid_unpack(uu1, &uuid1);
+ uuid_unpack(uu2, &uuid2);
+
+ UUCMP(uuid1.time_low, uuid2.time_low);
+ UUCMP(uuid1.time_mid, uuid2.time_mid);
+ UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version);
+ UUCMP(uuid1.clock_seq, uuid2.clock_seq);
+ return memcmp(uuid1.node, uuid2.node, 6);
+}
+
--- /dev/null
+/*
+ * copy.c --- copy UUIDs
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * 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, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+#include "uuidP.h"
+
+void uuid_copy(uuid_t dst, const uuid_t src)
+{
+ unsigned char *cp1;
+ const unsigned char *cp2;
+ int i;
+
+ for (i=0, cp1 = dst, cp2 = src; i < 16; i++)
+ *cp1++ = *cp2++;
+}
--- /dev/null
+/*
+ * gen_uuid.c --- generate a DCE-compatible uuid
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * 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, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+/*
+ * Force inclusion of SVID stuff since we need it if we're compiling in
+ * gcc-wall wall mode
+ */
+#define _SVID_SOURCE
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NET_IF_DL_H
+#include <net/if_dl.h>
+#endif
+
+#include "uuidP.h"
+
+#ifdef HAVE_SRANDOM
+#define srand(x) srandom(x)
+#define rand() random()
+#endif
+
+static int get_random_fd(void)
+{
+ struct timeval tv;
+ static int fd = -2;
+ int i;
+
+ if (fd == -2) {
+ gettimeofday(&tv, 0);
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd == -1)
+ fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
+ srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
+ }
+ /* Crank the random number generator a few times */
+ gettimeofday(&tv, 0);
+ for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
+ rand();
+ return fd;
+}
+
+
+/*
+ * Generate a series of random bytes. Use /dev/urandom if possible,
+ * and if not, use srandom/random.
+ */
+static void get_random_bytes(void *buf, int nbytes)
+{
+ int i, n = nbytes, fd = get_random_fd();
+ int lose_counter = 0;
+ unsigned char *cp = (unsigned char *) buf;
+
+ if (fd >= 0) {
+ while (n > 0) {
+ i = read(fd, cp, n);
+ if (i <= 0) {
+ if (lose_counter++ > 16)
+ break;
+ continue;
+ }
+ n -= i;
+ cp += i;
+ lose_counter = 0;
+ }
+ }
+
+ /*
+ * We do this all the time, but this is the only source of
+ * randomness if /dev/random/urandom is out to lunch.
+ */
+ for (cp = buf, i = 0; i < nbytes; i++)
+ *cp++ ^= (rand() >> 7) & 0xFF;
+ return;
+}
+
+/*
+ * Get the ethernet hardware address, if we can find it...
+ */
+static int get_node_id(unsigned char *node_id)
+{
+#ifdef HAVE_NET_IF_H
+ int sd;
+ struct ifreq ifr, *ifrp;
+ struct ifconf ifc;
+ char buf[1024];
+ int n, i;
+ unsigned char *a;
+#ifdef AF_LINK
+ struct sockaddr_dl *sdlp;
+#endif
+
+/*
+ * BSD 4.4 defines the size of an ifreq to be
+ * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
+ * However, under earlier systems, sa_len isn't present, so the size is
+ * just sizeof(struct ifreq)
+ */
+#ifdef HAVE_SA_LEN
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#define ifreq_size(i) max(sizeof(struct ifreq),\
+ sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
+#else
+#define ifreq_size(i) sizeof(struct ifreq)
+#endif /* HAVE_SA_LEN*/
+
+ sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+ if (sd < 0) {
+ return -1;
+ }
+ memset(buf, 0, sizeof(buf));
+ ifc.ifc_len = sizeof(buf);
+ ifc.ifc_buf = buf;
+ if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
+ close(sd);
+ return -1;
+ }
+ n = ifc.ifc_len;
+ for (i = 0; i < n; i+= ifreq_size(*ifrp) ) {
+ ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
+ strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
+#ifdef SIOCGIFHWADDR
+ if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
+ continue;
+ a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
+#else
+#ifdef SIOCGENADDR
+ if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
+ continue;
+ a = (unsigned char *) ifr.ifr_enaddr;
+#else
+#ifdef AF_LINK
+ sdlp = (struct sockaddr_dl *) &ifrp->ifr_addr;
+ if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6))
+ continue;
+ a = (unsigned char *) &sdlp->sdl_data[sdlp->sdl_nlen];
+#else
+ /*
+ * XXX we don't have a way of getting the hardware
+ * address
+ */
+ close(sd);
+ return 0;
+#endif /* AF_LINK */
+#endif /* SIOCGENADDR */
+#endif /* SIOCGIFHWADDR */
+ if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
+ continue;
+ if (node_id) {
+ memcpy(node_id, a, 6);
+ close(sd);
+ return 1;
+ }
+ }
+ close(sd);
+#endif
+ return 0;
+}
+
+/* Assume that the gettimeofday() has microsecond granularity */
+#define MAX_ADJUSTMENT 10
+
+static int get_clock(uint32_t *clock_high, uint32_t *clock_low, uint16_t *ret_clock_seq)
+{
+ static int adjustment = 0;
+ static struct timeval last = {0, 0};
+ static uint16_t clock_seq;
+ struct timeval tv;
+ unsigned long long clock_reg;
+
+try_again:
+ gettimeofday(&tv, 0);
+ if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
+ get_random_bytes(&clock_seq, sizeof(clock_seq));
+ clock_seq &= 0x3FFF;
+ last = tv;
+ last.tv_sec--;
+ }
+ if ((tv.tv_sec < last.tv_sec) ||
+ ((tv.tv_sec == last.tv_sec) &&
+ (tv.tv_usec < last.tv_usec))) {
+ clock_seq = (clock_seq+1) & 0x3FFF;
+ adjustment = 0;
+ last = tv;
+ } else if ((tv.tv_sec == last.tv_sec) &&
+ (tv.tv_usec == last.tv_usec)) {
+ if (adjustment >= MAX_ADJUSTMENT)
+ goto try_again;
+ adjustment++;
+ } else {
+ adjustment = 0;
+ last = tv;
+ }
+
+ clock_reg = tv.tv_usec*10 + adjustment;
+ clock_reg += ((unsigned long long) tv.tv_sec)*10000000;
+ clock_reg += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
+
+ *clock_high = clock_reg >> 32;
+ *clock_low = clock_reg;
+ *ret_clock_seq = clock_seq;
+ return 0;
+}
+
+void uuid_generate_time(uuid_t out)
+{
+ static unsigned char node_id[6];
+ static int has_init = 0;
+ struct uuid uu;
+ uint32_t clock_mid;
+
+ if (!has_init) {
+ if (get_node_id(node_id) <= 0) {
+ get_random_bytes(node_id, 6);
+ /*
+ * Set multicast bit, to prevent conflicts
+ * with IEEE 802 addresses obtained from
+ * network cards
+ */
+ node_id[0] |= 0x01;
+ }
+ has_init = 1;
+ }
+ get_clock(&clock_mid, &uu.time_low, &uu.clock_seq);
+ uu.clock_seq |= 0x8000;
+ uu.time_mid = (uint16_t) clock_mid;
+ uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000;
+ memcpy(uu.node, node_id, 6);
+ uuid_pack(&uu, out);
+}
+
+void uuid_generate_random(uuid_t out)
+{
+ uuid_t buf;
+ struct uuid uu;
+
+ get_random_bytes(buf, sizeof(buf));
+ uuid_unpack(buf, &uu);
+
+ uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
+ uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
+ uuid_pack(&uu, out);
+}
+
+/*
+ * This is the generic front-end to uuid_generate_random and
+ * uuid_generate_time. It uses uuid_generate_random only if
+ * /dev/urandom is available, since otherwise we won't have
+ * high-quality randomness.
+ */
+void uuid_generate(uuid_t out)
+{
+ if (get_random_fd() >= 0)
+ uuid_generate_random(out);
+ else
+ uuid_generate_time(out);
+}
--- /dev/null
+/*
+ * isnull.c --- Check whether or not the UUID is null
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * 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, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+#include "uuidP.h"
+
+/* Returns 1 if the uuid is the NULL uuid */
+int uuid_is_null(const uuid_t uu)
+{
+ const unsigned char *cp;
+ int i;
+
+ for (i=0, cp = uu; i < 16; i++)
+ if (*cp++)
+ return 0;
+ return 1;
+}
+
--- /dev/null
+.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca)
+.\"
+.\" %Begin-Header%
+.\" 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, and the entire permission notice in its entirety,
+.\" including the disclaimer of warranties.
+.\" 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. The name of the author may not be used to endorse or promote
+.\" products derived from this software without specific prior
+.\" written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+.\" WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+.\" DAMAGE.
+.\" %End-Header%
+.\"
+.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger
+.TH UUID 3 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "@E2FSPROGS_VERSION@"
+.SH NAME
+uuid \- DCE compatible Universally Unique Identifier library
+.SH SYNOPSIS
+.B #include <uuid/uuid.h>
+.SH DESCRIPTION
+The
+UUID
+library is used to generate unique identifiers for objects that may be
+accessible beyond the local system. This library
+generates UUIDs compatible with those created by the Open Software
+Foundation (OSF) Distributed Computing Environment (DCE) utility
+.BR uuidgen .
+.sp
+The UUIDs generated by this library can be reasonably expected to be
+unique within a system, and unique across all systems. They could
+be used, for instance, to generate unique HTTP cookies across multiple
+web servers without communication between the servers, and without fear
+of a name clash.
+.SH "CONFORMING TO"
+OSF DCE 1.1
+.SH AUTHOR
+Theodore Y. Ts'o
+.SH AVAILABILITY
+.UR http://e2fsprogs.sourceforge.net/
+http://e2fsprogs.sourceforge.net/
+.UE
+.SH "SEE ALSO"
+.BR uuid_clear (3),
+.BR uuid_compare (3),
+.BR uuid_copy (3),
+.BR uuid_generate (3),
+.BR uuid_is_null (3),
+.BR uuid_parse (3),
+.BR uuid_unparse (3)
--- /dev/null
+/*
+ * Internal routine for packing UUID's
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * 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, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+#include <string.h>
+#include "uuidP.h"
+
+void uuid_pack(const struct uuid *uu, uuid_t ptr)
+{
+ uint32_t tmp;
+ unsigned char *out = ptr;
+
+ tmp = uu->time_low;
+ out[3] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[2] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[1] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[0] = (unsigned char) tmp;
+
+ tmp = uu->time_mid;
+ out[5] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[4] = (unsigned char) tmp;
+
+ tmp = uu->time_hi_and_version;
+ out[7] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[6] = (unsigned char) tmp;
+
+ tmp = uu->clock_seq;
+ out[9] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[8] = (unsigned char) tmp;
+
+ memcpy(out+10, uu->node, 6);
+}
+
--- /dev/null
+/*
+ * parse.c --- UUID parsing
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * 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, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "uuidP.h"
+
+int uuid_parse(const char *in, uuid_t uu)
+{
+ struct uuid uuid;
+ int i;
+ const char *cp;
+ char buf[3];
+
+ if (strlen(in) != 36)
+ return -1;
+ for (i=0, cp = in; i <= 36; i++,cp++) {
+ if ((i == 8) || (i == 13) || (i == 18) ||
+ (i == 23)) {
+ if (*cp == '-')
+ continue;
+ else
+ return -1;
+ }
+ if (i== 36)
+ if (*cp == 0)
+ continue;
+ if (!isxdigit(*cp))
+ return -1;
+ }
+ uuid.time_low = strtoul(in, NULL, 16);
+ uuid.time_mid = strtoul(in+9, NULL, 16);
+ uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
+ uuid.clock_seq = strtoul(in+19, NULL, 16);
+ cp = in+24;
+ buf[2] = 0;
+ for (i=0; i < 6; i++) {
+ buf[0] = *cp++;
+ buf[1] = *cp++;
+ uuid.node[i] = strtoul(buf, NULL, 16);
+ }
+
+ uuid_pack(&uuid, uu);
+ return 0;
+}
--- /dev/null
+/*
+ * Internal routine for unpacking UUID
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * 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, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+#include <string.h>
+#include "uuidP.h"
+
+void uuid_unpack(const uuid_t in, struct uuid *uu)
+{
+ const uint8_t *ptr = in;
+ uint32_t tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_low = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_mid = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_hi_and_version = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->clock_seq = tmp;
+
+ memcpy(uu->node, ptr, 6);
+}
+
--- /dev/null
+/*
+ * unparse.c -- convert a UUID to string
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * 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, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+
+#include "uuidP.h"
+
+static const char *fmt_lower =
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
+
+static const char *fmt_upper =
+ "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X";
+
+#ifdef UUID_UNPARSE_DEFAULT_UPPER
+#define FMT_DEFAULT fmt_upper
+#else
+#define FMT_DEFAULT fmt_lower
+#endif
+
+static void uuid_unparse_x(const uuid_t uu, char *out, const char *fmt)
+{
+ struct uuid uuid;
+
+ uuid_unpack(uu, &uuid);
+ sprintf(out, fmt,
+ uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
+ uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
+ uuid.node[0], uuid.node[1], uuid.node[2],
+ uuid.node[3], uuid.node[4], uuid.node[5]);
+}
+
+void uuid_unparse_lower(const uuid_t uu, char *out)
+{
+ uuid_unparse_x(uu, out, fmt_lower);
+}
+
+void uuid_unparse_upper(const uuid_t uu, char *out)
+{
+ uuid_unparse_x(uu, out, fmt_upper);
+}
+
+void uuid_unparse(const uuid_t uu, char *out)
+{
+ uuid_unparse_x(uu, out, FMT_DEFAULT);
+}
--- /dev/null
+/*
+ * Public include file for the UUID library
+ *
+ * Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * 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, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+#ifndef _UUID_UUID_H
+#define _UUID_UUID_H
+
+typedef unsigned char uuid_t[16];
+
+#define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \
+ static const uuid_t name __attribute__ ((unused)) = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15}\r
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void uuid_clear(uuid_t uu);
+
+int uuid_compare(const uuid_t uu1, const uuid_t uu2);
+
+void uuid_copy(uuid_t dst, const uuid_t src);
+
+void uuid_generate(uuid_t out);
+void uuid_generate_random(uuid_t out);
+void uuid_generate_time(uuid_t out);
+
+int uuid_is_null(const uuid_t uu);
+
+int uuid_parse(const char *in, uuid_t uu);
+
+void uuid_unparse(const uuid_t uu, char *out);
+void uuid_unparse_lower(const uuid_t uu, char *out);
+void uuid_unparse_upper(const uuid_t uu, char *out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _UUID_UUID_H */
--- /dev/null
+/*
+ * uuid.h -- private header file for uuids
+ *
+ * Copyright (C) 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * 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, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 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. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#include <uuid/uuid_types.h>
+#endif
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "uuid.h"
+
+/*
+ * Offset between 15-Oct-1582 and 1-Jan-70
+ */
+#define TIME_OFFSET_HIGH 0x01B21DD2
+#define TIME_OFFSET_LOW 0x13814000
+
+struct uuid {
+ uint32_t time_low;
+ uint16_t time_mid;
+ uint16_t time_hi_and_version;
+ uint16_t clock_seq;
+ uint8_t node[6];
+};
+
+/* UUID Variant definitions */
+#define UUID_VARIANT_NCS 0
+#define UUID_VARIANT_DCE 1
+#define UUID_VARIANT_MICROSOFT 2
+#define UUID_VARIANT_OTHER 3
+
+/* UUID Type definitions */
+#define UUID_TYPE_DCE_TIME 1
+#define UUID_TYPE_DCE_RANDOM 4
+
+/*
+ * prototypes
+ */
+void uuid_pack(const struct uuid *uu, uuid_t ptr);
+void uuid_unpack(const uuid_t in, struct uuid *uu);
+
+time_t uuid_time(const uuid_t uu, struct timeval *ret_tv);
+int uuid_type(const uuid_t uu);
+int uuid_variant(const uuid_t uu);
--- /dev/null
+.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca)
+.\"
+.\" %Begin-Header%
+.\" 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, and the entire permission notice in its entirety,
+.\" including the disclaimer of warranties.
+.\" 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. The name of the author may not be used to endorse or promote
+.\" products derived from this software without specific prior
+.\" written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+.\" WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+.\" DAMAGE.
+.\" %End-Header%
+.\"
+.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger
+.TH UUID_CLEAR 3 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "@E2FSPROGS_VERSION@"
+.SH NAME
+uuid_clear \- reset value of UUID variable to the NULL value
+.SH SYNOPSIS
+.nf
+.B #include <uuid/uuid.h>
+.sp
+.BI "void uuid_clear(uuid_t " uu );
+.fi
+.SH DESCRIPTION
+The
+.B uuid_clear
+function sets the value of the supplied uuid variable
+.I uu
+to the NULL value.
+.SH AUTHOR
+Theodore Y. Ts'o
+.SH AVAILABILITY
+.UR http://e2fsprogs.sourceforge.net/
+http://e2fsprogs.sourceforge.net/
+.UE
+.SH "SEE ALSO"
+.BR uuid (3),
+.BR uuid_compare (3),
+.BR uuid_copy (3),
+.BR uuid_generate (3),
+.BR uuid_is_null (3),
+.BR uuid_parse (3),
+.BR uuid_unparse (3)
--- /dev/null
+.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca)
+.\"
+.\" %Begin-Header%
+.\" 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, and the entire permission notice in its entirety,
+.\" including the disclaimer of warranties.
+.\" 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. The name of the author may not be used to endorse or promote
+.\" products derived from this software without specific prior
+.\" written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+.\" WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+.\" DAMAGE.
+.\" %End-Header%
+.\"
+.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger
+.TH UUID_COMPARE 3 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "@E2FSPROGS_VERSION@"
+.SH NAME
+uuid_compare \- compare whether two UUIDs are the same
+.SH SYNOPSIS
+.nf
+.B #include <uuid/uuid.h>
+.sp
+.BI "int uuid_compare(uuid_t " uu1 ", uuid_t " uu2)
+.fi
+.SH DESCRIPTION
+The
+.B uuid_compare
+function compares the two supplied uuid variables
+.IR uu1 " and " uu2
+to each other.
+.SH RETURN VALUE
+Returns an integer less than, equal to, or greater than zero if
+.I uu1
+is found, respectively, to be lexigraphically less than, equal, or
+greater than
+.IR uu2 .
+.SH AUTHOR
+Theodore Y. Ts'o
+.SH AVAILABILITY
+.UR http://e2fsprogs.sourceforge.net/
+http://e2fsprogs.sourceforge.net/
+.UE
+.SH "SEE ALSO"
+.BR uuid (3),
+.BR uuid_clear (3),
+.BR uuid_copy (3),
+.BR uuid_generate (3),
+.BR uuid_is_null (3),
+.BR uuid_parse (3),
+.BR uuid_unparse (3)
--- /dev/null
+.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca)
+.\"
+.\" %Begin-Header%
+.\" 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, and the entire permission notice in its entirety,
+.\" including the disclaimer of warranties.
+.\" 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. The name of the author may not be used to endorse or promote
+.\" products derived from this software without specific prior
+.\" written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+.\" WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+.\" DAMAGE.
+.\" %End-Header%
+.\"
+.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger
+.TH UUID_COPY 3 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "@E2FSPROGS_VERSION@"
+.SH NAME
+uuid_copy \- copy a UUID value
+.SH SYNOPSIS
+.nf
+.B #include <uuid/uuid.h>
+.sp
+.BI "void uuid_copy(uuid_t " dst ", uuid_t " src);
+.fi
+.SH DESCRIPTION
+The
+.B uuid_copy
+function copies the UUID variable
+.IR src " to " dst .
+.SH RETURN VALUE
+The copied UUID is returned in the location pointed to by
+.IR dst .
+.SH AUTHOR
+Theodore Y. Ts'o
+.SH AVAILABILITY
+.UR http://e2fsprogs.sourceforge.net/
+http://e2fsprogs.sourceforge.net/
+.UE
+.SH "SEE ALSO"
+.BR uuid (3),
+.BR uuid_clear (3),
+.BR uuid_compare (3),
+.BR uuid_generate (3),
+.BR uuid_is_null (3),
+.BR uuid_parse (3),
+.BR uuid_unparse (3)
--- /dev/null
+.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca)
+.\"
+.\" %Begin-Header%
+.\" 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, and the entire permission notice in its entirety,
+.\" including the disclaimer of warranties.
+.\" 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. The name of the author may not be used to endorse or promote
+.\" products derived from this software without specific prior
+.\" written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+.\" WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+.\" DAMAGE.
+.\" %End-Header%
+.\"
+.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger
+.TH UUID_GENERATE 3 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "@E2FSPROGS_VERSION@"
+.SH NAME
+uuid_generate, uuid_generate_random, uuid_generate_time \- create a new unique UUID value
+.SH SYNOPSIS
+.nf
+.B #include <uuid/uuid.h>
+.sp
+.BI "void uuid_generate(uuid_t " out );
+.BI "void uuid_generate_random(uuid_t " out );
+.BI "void uuid_generate_time(uuid_t " out );
+.fi
+.SH DESCRIPTION
+The
+.B uuid_generate
+function creates a new universally unique identifier (UUID). The uuid will
+be generated based on high-quality randomness from
+.IR /dev/urandom ,
+if available. If it is not available, then
+.B uuid_generate
+will use an alternative algorithm which uses the current time, the
+local ethernet MAC address (if available), and random data generated
+using a pseudo-random generator.
+.sp
+The
+.B uuid_generate_random
+function forces the use of the all-random UUID format, even if
+a high-quality random number generator (i.e.,
+.IR /dev/urandom )
+is not available, in which case a pseudo-random
+generator will be subsituted. Note that the use of a pseudo-random
+generator may compromise the uniqueness of UUID's
+generated in this fashion.
+.sp
+The
+.B uuid_generate_time
+function forces the use of the alternative algorithm which uses the
+current time and the local ethernet MAC address (if available).
+This algorithm used to be the default one used to generate UUID, but
+because of the use of the ethernet MAC address, it can leak
+information about when and where the UUID was generated. This can cause
+privacy problems in some applications, so the
+.B uuid_generate
+function only uses this algorithm if a high-quality source of
+randomness is not available.
+.sp
+The UUID is 16 bytes (128 bits) long, which gives approximately 3.4x10^38
+unique values (there are approximately 10^80 elemntary particles in
+the universe according to Carl Sagan's
+.IR Cosmos ).
+The new UUID can reasonably be considered unique among all UUIDs created
+on the local system, and among UUIDs created on other systems in the past
+and in the future.
+.SH RETURN VALUE
+The newly created UUID is returned in the memory location pointed to by
+.IR out .
+.SH "CONFORMING TO"
+OSF DCE 1.1
+.SH AUTHOR
+Theodore Y. Ts'o
+.SH AVAILABILITY
+.UR http://e2fsprogs.sourceforge.net/
+http://e2fsprogs.sourceforge.net/
+.UE
+.SH "SEE ALSO"
+.BR uuid (3),
+.BR uuidgen (1),
+.BR uuid_clear (3),
+.BR uuid_compare (3),
+.BR uuid_copy (3),
+.BR uuid_is_null (3),
+.BR uuid_parse (3),
+.BR uuid_unparse (3)
--- /dev/null
+.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca)
+.\"
+.\" %Begin-Header%
+.\" 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, and the entire permission notice in its entirety,
+.\" including the disclaimer of warranties.
+.\" 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. The name of the author may not be used to endorse or promote
+.\" products derived from this software without specific prior
+.\" written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+.\" WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+.\" DAMAGE.
+.\" %End-Header%
+.\"
+.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger
+.TH UUID_IS_NULL 3 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "@E2FSPROGS_VERSION@"
+.SH NAME
+uuid_is_null \- compare the value of the UUID to the NULL value
+.SH SYNOPSIS
+.nf
+.B #include <uuid/uuid.h>
+.sp
+.BI "int uuid_is_null(uuid_t " uu );
+.fi
+.SH DESCRIPTION
+The
+.B uuid_is_null
+function compares the value of the supplied UUID variable
+.I uu
+to the NULL value. If the value is equal to the NULL UUID, 1 is returned,
+otherwise 0 is returned.
+.SH AUTHOR
+Theodore Y. Ts'o
+.SH AVAILABILITY
+.UR http://e2fsprogs.sourceforge.net/
+http://e2fsprogs.sourceforge.net/
+.UE
+.SH "SEE ALSO"
+.BR uuid (3),
+.BR uuid_clear (3),
+.BR uuid_compare (3),
+.BR uuid_copy (3),
+.BR uuid_generate (3),
+.BR uuid_parse (3),
+.BR uuid_unparse (3)
--- /dev/null
+.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca)
+.\"
+.\" %Begin-Header%
+.\" 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, and the entire permission notice in its entirety,
+.\" including the disclaimer of warranties.
+.\" 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. The name of the author may not be used to endorse or promote
+.\" products derived from this software without specific prior
+.\" written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+.\" WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+.\" DAMAGE.
+.\" %End-Header%
+.\"
+.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger
+.TH UUID_PARSE 3 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "@E2FSPROGS_VERSION@"
+.SH NAME
+uuid_parse \- convert an input UUID string into binary representation
+.SH SYNOPSIS
+.nf
+.B #include <uuid/uuid.h>
+.sp
+.BI "int uuid_parse( char *" in ", uuid_t " uu );
+.fi
+.SH DESCRIPTION
+The
+.B uuid_parse
+function converts the UUID string given by
+.I in
+into the binary representation. The input UUID is a string of the form
+1b4e28ba\-2fa1\-11d2\-883f\-b9a761bde3fb (in
+.BR printf (3)
+format "%08x\-%04x\-%04x\-%04x\-%012x", 36 bytes plus the trailing '\\0').
+.SH RETURN VALUE
+Upon successfully parsing the input string, 0 is returned, and the UUID is
+stored in the location pointed to by
+.IR uu ,
+otherwise \-1 is returned.
+.SH "CONFORMING TO"
+OSF DCE 1.1
+.SH AUTHOR
+Theodore Y. Ts'o
+.SH AVAILABILITY
+.UR http://e2fsprogs.sourceforge.net/
+http://e2fsprogs.sourceforge.net/
+.UE
+.SH "SEE ALSO"
+.BR uuid (3),
+.BR uuid_clear (3),
+.BR uuid_compare (3),
+.BR uuid_copy (3),
+.BR uuid_generate (3),
+.BR uuid_is_null (3),
+.BR uuid_unparse (3)
--- /dev/null
+.\" Copyright 1999 Andreas Dilger (adilger@enel.ucalgary.ca)
+.\"
+.\" %Begin-Header%
+.\" 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, and the entire permission notice in its entirety,
+.\" including the disclaimer of warranties.
+.\" 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. The name of the author may not be used to endorse or promote
+.\" products derived from this software without specific prior
+.\" written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+.\" WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
+.\" DAMAGE.
+.\" %End-Header%
+.\"
+.\" Created Wed Mar 10 17:42:12 1999, Andreas Dilger
+.TH UUID_UNPARSE 3 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "@E2FSPROGS_VERSION@"
+.SH NAME
+uuid_unparse \- convert an UUID from binary representation to a string
+.SH SYNOPSIS
+.nf
+.B #include <uuid/uuid.h>
+.sp
+.BI "void uuid_unparse(uuid_t " uu ", char *" out );
+.BI "void uuid_unparse_upper(uuid_t " uu ", char *" out );
+.BI "void uuid_unparse_lower(uuid_t " uu ", char *" out );
+.fi
+.SH DESCRIPTION
+The
+.B uuid_unparse
+function converts the supplied UUID
+.I uu
+from the binary representation into a 36\-byte string (plus tailing '\\0')
+of the form 1b4e28ba\-2fa1\-11d2\-883f\-b9a76 and stores this value in the
+character string pointed to by
+.IR out .
+The case of the hex digits returned by
+.B uuid_unparse
+may be upper or lower case, and is
+dependent on the system-dependent local default.
+.PP
+If the case of the
+hex digits is important then the functions
+.B uuid_unparse_upper
+and
+.B uuid_unparse_lower
+may be used.
+.SH "CONFORMING TO"
+OSF DCE 1.1
+.SH AUTHOR
+Theodore Y. Ts'o
+.SH AVAILABILITY
+.UR http://e2fsprogs.sourceforge.net/
+http://e2fsprogs.sourceforge.net/
+.UE
+.SH "SEE ALSO"
+.BR uuid (3),
+.BR uuid_clear (3),
+.BR uuid_compare (3),
+.BR uuid_copy (3),
+.BR uuid_generate (3),
+.BR uuid_is_null (3),
+.BR uuid_parse (3)
# $FreeBSD: src/lib/libc/xdr/Makefile.inc,v 1.12 2001/03/27 17:26:57 ru Exp $
.PATH: ${.CURDIR}/../libc/xdr ${.CURDIR}/.
-SRCS+= xdr.c xdr_array.c xdr_float.c xdr_mem.c \
+MISRCS+= xdr.c xdr_array.c xdr_float.c xdr_mem.c \
xdr_rec.c xdr_reference.c xdr_stdio.c
.if ${LIB} == "c"
# yp sources
.PATH: ${.CURDIR}/../libc/yp
-SRCS+= xdryp.c yp.h yp_xdr.c yplib.c
+MISRCS+= xdryp.c yp.h yp_xdr.c yplib.c
CLEANFILES+= yp.h yp_xdr.c
RPCSRC= ${DESTDIR}/usr/include/rpcsvc/yp.x