From: Apple Date: Tue, 29 Jun 2004 05:26:23 +0000 (+0000) Subject: Libc-339.tar.gz X-Git-Tag: v339^0 X-Git-Url: https://git.saurik.com/apple/libc.git/commitdiff_plain/59e0d9fe772464b93d835d2a2964457702469a43 Libc-339.tar.gz --- diff --git a/GNUmakefile b/GNUmakefile index 4e75674..64535b6 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -5,17 +5,19 @@ ifndef $(SYMROOT) 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 @@ -26,9 +28,19 @@ endif # 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: @@ -46,61 +58,54 @@ build: build-profile 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 ; \ @@ -113,6 +118,12 @@ build-ppc-profile: 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 ; \ @@ -125,6 +136,12 @@ build-ppc-debug: 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 ; \ @@ -137,6 +154,12 @@ build-ppc-dynamic: 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 ; \ @@ -150,12 +173,33 @@ build-ppc: 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)" @@ -172,6 +216,11 @@ installhdrs-real: 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 @@ -214,9 +263,9 @@ install-man: 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 \ diff --git a/Makefile b/Makefile index 0647549..4ded090 100644 --- a/Makefile +++ b/Makefile @@ -19,16 +19,24 @@ CC = gcc-3.3 .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 @@ -39,9 +47,15 @@ PRECIOUSLIB= yes 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 diff --git a/Makefile.fbsd_begin b/Makefile.fbsd_begin index 5f996f0..f64f188 100644 --- a/Makefile.fbsd_begin +++ b/Makefile.fbsd_begin @@ -20,5 +20,5 @@ FBSDMAN8= FBSDMAN9= FBSDMDSRCS= FBSDMISRCS= -FBSDORIGHDRS= +FBSDHDRS= FBSDSRCS= diff --git a/Makefile.fbsd_end b/Makefile.fbsd_end index 835bd0d..9b43be0 100644 --- a/Makefile.fbsd_end +++ b/Makefile.fbsd_end @@ -12,48 +12,33 @@ 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 diff --git a/Makefile.inc b/Makefile.inc index b739e28..2fc409e 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -15,9 +15,30 @@ NOASM= # 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: @@ -28,6 +49,7 @@ FBSDPATCHMAN= .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" @@ -50,15 +72,16 @@ FBSDPATCHMAN= .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: diff --git a/Makefile.xbs b/Makefile.xbs index 70ac4fa..bd098dd 100644 --- a/Makefile.xbs +++ b/Makefile.xbs @@ -23,85 +23,112 @@ .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} @@ -118,33 +145,48 @@ installhdrs-md: gen_md_mig_defs 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 '' $$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/ @@ -155,7 +197,9 @@ install_lib${LIB}_debug.a: 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} diff --git a/SYSCALL-LIST b/SYSCALL-LIST index 82879f9..9b909f9 100644 --- a/SYSCALL-LIST +++ b/SYSCALL-LIST @@ -14,6 +14,7 @@ chmod fchmod chown fchown +lchown chroot close connect diff --git a/compat-43/FreeBSD/Makefile.inc b/compat-43/FreeBSD/Makefile.inc index e4abb4d..aa345f0 100644 --- a/compat-43/FreeBSD/Makefile.inc +++ b/compat-43/FreeBSD/Makefile.inc @@ -4,7 +4,7 @@ # 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 diff --git a/compat-43/Makefile.inc b/compat-43/Makefile.inc index 33deee3..5d36b09 100644 --- a/compat-43/Makefile.inc +++ b/compat-43/Makefile.inc @@ -4,9 +4,9 @@ # 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" diff --git a/compat-43/setregid.c b/compat-43/setregid.c index 748943a..cd00c14 100644 --- a/compat-43/setregid.c +++ b/compat-43/setregid.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/compat-43/setreuid.c b/compat-43/setreuid.c index 3a6626a..ff66ff9 100644 --- a/compat-43/setreuid.c +++ b/compat-43/setreuid.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/compat-43/sigcompat.c b/compat-43/sigcompat.c index ef1a691..d4b2f8f 100644 --- a/compat-43/sigcompat.c +++ b/compat-43/sigcompat.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -61,7 +63,8 @@ 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; @@ -84,7 +87,8 @@ static int sigvec__(signo, sv, osv, bind) return (ret); } -int sigvec(signo, sv, osv) +int +sigvec(signo, sv, osv) int signo; struct sigvec *sv, *osv; { @@ -92,7 +96,8 @@ int sigvec(signo, sv, osv) } #if defined(__DYNAMIC__) -int _sigvec_nobind(signo, sv, osv) +int +_sigvec_nobind(signo, sv, osv) int signo; struct sigvec *sv, *osv; { @@ -100,7 +105,8 @@ int _sigvec_nobind(signo, sv, osv) } #endif -int sigsetmask(mask) +int +sigsetmask(mask) int mask; { int omask, n; @@ -111,7 +117,8 @@ int sigsetmask(mask) return (omask); } -int sigblock(mask) +int +sigblock(mask) int mask; { int omask, n; @@ -122,13 +129,15 @@ int sigblock(mask) 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; @@ -139,7 +148,9 @@ int sighold(sig) sigaddset(&mask, sig); return(sigprocmask(SIG_BLOCK, &mask,(sigset_t *)0)); } -int sigrelse(sig) + +int +sigrelse(sig) int sig; { sigset_t mask; @@ -151,3 +162,11 @@ int sigrelse(sig) return(sigprocmask(SIG_UNBLOCK, &mask,(sigset_t *)0)); } + +int +sigignore(sig) + int sig; +{ + return (signal(sig, SIG_IGN) == SIG_ERR ? -1 : 0); +} + diff --git a/db/Makefile.inc b/db/Makefile.inc index 5806603..39357c7 100644 --- a/db/Makefile.inc +++ b/db/Makefile.inc @@ -1,7 +1,6 @@ # 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" diff --git a/db/btree/FreeBSD/bt_close.c b/db/btree/FreeBSD/bt_close.c new file mode 100644 index 0000000..c211d5b --- /dev/null +++ b/db/btree/FreeBSD/bt_close.c @@ -0,0 +1,186 @@ +/*- + * 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 +__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 + +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include +#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); +} diff --git a/db/btree/FreeBSD/bt_conv.c b/db/btree/FreeBSD/bt_conv.c new file mode 100644 index 0000000..7496a3c --- /dev/null +++ b/db/btree/FreeBSD/bt_conv.c @@ -0,0 +1,223 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_conv.c,v 1.2 2002/03/21 22:46:25 obrien Exp $"); + +#include + +#include + +#include +#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); +} diff --git a/db/btree/FreeBSD/bt_debug.c b/db/btree/FreeBSD/bt_debug.c new file mode 100644 index 0000000..606ecff --- /dev/null +++ b/db/btree/FreeBSD/bt_debug.c @@ -0,0 +1,331 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_debug.c,v 1.2 2002/03/22 21:52:01 obrien Exp $"); + +#include + +#include +#include +#include + +#include +#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 diff --git a/db/btree/FreeBSD/bt_delete.c b/db/btree/FreeBSD/bt_delete.c new file mode 100644 index 0000000..6204464 --- /dev/null +++ b/db/btree/FreeBSD/bt_delete.c @@ -0,0 +1,659 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_delete.c,v 1.2 2002/03/21 22:46:25 obrien Exp $"); + +#include + +#include +#include +#include + +#include +#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); +} diff --git a/db/btree/FreeBSD/bt_get.c b/db/btree/FreeBSD/bt_get.c new file mode 100644 index 0000000..0d91ae4 --- /dev/null +++ b/db/btree/FreeBSD/bt_get.c @@ -0,0 +1,107 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_get.c,v 1.2 2002/03/22 21:52:01 obrien Exp $"); + +#include + +#include +#include +#include + +#include +#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); +} diff --git a/db/btree/FreeBSD/bt_open.c b/db/btree/FreeBSD/bt_open.c new file mode 100644 index 0000000..c8a103a --- /dev/null +++ b/db/btree/FreeBSD/bt_open.c @@ -0,0 +1,449 @@ +/*- + * 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 +__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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include +#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); +} diff --git a/db/btree/FreeBSD/bt_overflow.c b/db/btree/FreeBSD/bt_overflow.c new file mode 100644 index 0000000..5e0f1ae --- /dev/null +++ b/db/btree/FreeBSD/bt_overflow.c @@ -0,0 +1,230 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_overflow.c,v 1.3 2002/03/22 21:52:01 obrien Exp $"); + +#include + +#include +#include +#include + +#include +#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); +} diff --git a/db/btree/FreeBSD/bt_page.c b/db/btree/FreeBSD/bt_page.c new file mode 100644 index 0000000..3392709 --- /dev/null +++ b/db/btree/FreeBSD/bt_page.c @@ -0,0 +1,102 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_page.c,v 1.3 2002/03/22 21:52:01 obrien Exp $"); + +#include + +#include + +#include +#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)); +} diff --git a/db/btree/FreeBSD/bt_put.c b/db/btree/FreeBSD/bt_put.c new file mode 100644 index 0000000..0dca165 --- /dev/null +++ b/db/btree/FreeBSD/bt_put.c @@ -0,0 +1,325 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_put.c,v 1.4 2003/05/30 11:05:08 tmm Exp $"); + +#include + +#include +#include +#include +#include + +#include +#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); +} diff --git a/db/btree/FreeBSD/bt_search.c b/db/btree/FreeBSD/bt_search.c new file mode 100644 index 0000000..cee177d --- /dev/null +++ b/db/btree/FreeBSD/bt_search.c @@ -0,0 +1,215 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_search.c,v 1.2 2002/03/21 22:46:25 obrien Exp $"); + +#include + +#include + +#include +#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); +} diff --git a/db/btree/FreeBSD/bt_seq.c b/db/btree/FreeBSD/bt_seq.c new file mode 100644 index 0000000..662e195 --- /dev/null +++ b/db/btree/FreeBSD/bt_seq.c @@ -0,0 +1,462 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_seq.c,v 1.3 2002/03/21 22:46:25 obrien Exp $"); + +#include + +#include +#include +#include +#include + +#include +#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); +} diff --git a/db/btree/FreeBSD/bt_split.c b/db/btree/FreeBSD/bt_split.c new file mode 100644 index 0000000..704eefc --- /dev/null +++ b/db/btree/FreeBSD/bt_split.c @@ -0,0 +1,827 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_split.c,v 1.5 2003/02/16 17:29:09 nectar Exp $"); + +#include + +#include +#include +#include +#include + +#include +#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); +} diff --git a/db/btree/FreeBSD/bt_utils.c b/db/btree/FreeBSD/bt_utils.c new file mode 100644 index 0000000..e9acfb7 --- /dev/null +++ b/db/btree/FreeBSD/bt_utils.c @@ -0,0 +1,262 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/btree/bt_utils.c,v 1.3 2003/01/01 18:48:42 schweikh Exp $"); + +#include + +#include +#include +#include + +#include +#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); +} diff --git a/db/btree/FreeBSD/btree.h b/db/btree/FreeBSD/btree.h new file mode 100644 index 0000000..d5adeb7 --- /dev/null +++ b/db/btree/FreeBSD/btree.h @@ -0,0 +1,384 @@ +/*- + * 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 + +#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" diff --git a/db/btree/FreeBSD/btree.h.patch b/db/btree/FreeBSD/btree.h.patch new file mode 100644 index 0000000..58d011b --- /dev/null +++ b/db/btree/FreeBSD/btree.h.patch @@ -0,0 +1,8 @@ +--- 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" diff --git a/db/btree/FreeBSD/extern.h b/db/btree/FreeBSD/extern.h new file mode 100644 index 0000000..478f6af --- /dev/null +++ b/db/btree/FreeBSD/extern.h @@ -0,0 +1,71 @@ +/*- + * 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 diff --git a/db/btree/Makefile.inc b/db/btree/Makefile.inc index ffdf5e5..f08b96f 100644 --- a/db/btree/Makefile.inc +++ b/db/btree/Makefile.inc @@ -1,8 +1,18 @@ # 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 diff --git a/db/btree/PB.project b/db/btree/PB.project deleted file mode 100644 index 8de9a71..0000000 --- a/db/btree/PB.project +++ /dev/null @@ -1,42 +0,0 @@ -{ - 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"; -} diff --git a/db/btree/bt_close.c b/db/btree/bt_close.c deleted file mode 100644 index 15ee817..0000000 --- a/db/btree/bt_close.c +++ /dev/null @@ -1,207 +0,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@ - */ -/*- - * 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 -#ifndef __APPLE_ -#endif - -#include - -#include -#include -#include -#include -#include - -#include -#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); -} diff --git a/db/btree/bt_conv.c b/db/btree/bt_conv.c deleted file mode 100644 index 4bf6ee8..0000000 --- a/db/btree/bt_conv.c +++ /dev/null @@ -1,244 +0,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@ - */ -/*- - * 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 - -#include - -#include - -#include -#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); -} diff --git a/db/btree/bt_debug.c b/db/btree/bt_debug.c deleted file mode 100644 index f6d9a54..0000000 --- a/db/btree/bt_debug.c +++ /dev/null @@ -1,352 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include - -#include -#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 diff --git a/db/btree/bt_delete.c b/db/btree/bt_delete.c deleted file mode 100644 index 02715e9..0000000 --- a/db/btree/bt_delete.c +++ /dev/null @@ -1,680 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include - -#include -#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); -} diff --git a/db/btree/bt_extern.h b/db/btree/bt_extern.h deleted file mode 100644 index 9531a46..0000000 --- a/db/btree/bt_extern.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 diff --git a/db/btree/bt_get.c b/db/btree/bt_get.c deleted file mode 100644 index d8415a5..0000000 --- a/db/btree/bt_get.c +++ /dev/null @@ -1,128 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include - -#include -#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); -} diff --git a/db/btree/bt_open.c b/db/btree/bt_open.c deleted file mode 100644 index a01bf4b..0000000 --- a/db/btree/bt_open.c +++ /dev/null @@ -1,468 +0,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@ - */ -/*- - * 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 - -/* - * 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 -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#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); -} diff --git a/db/btree/bt_overflow.c b/db/btree/bt_overflow.c deleted file mode 100644 index 2886277..0000000 --- a/db/btree/bt_overflow.c +++ /dev/null @@ -1,251 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include - -#include -#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); -} diff --git a/db/btree/bt_page.c b/db/btree/bt_page.c deleted file mode 100644 index 8785de1..0000000 --- a/db/btree/bt_page.c +++ /dev/null @@ -1,123 +0,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@ - */ -/*- - * 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 - -#include - -#include - -#include -#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)); -} diff --git a/db/btree/bt_put.c b/db/btree/bt_put.c deleted file mode 100644 index 331e4f3..0000000 --- a/db/btree/bt_put.c +++ /dev/null @@ -1,344 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include -#include - -#include -#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); -} diff --git a/db/btree/bt_search.c b/db/btree/bt_search.c deleted file mode 100644 index 884f060..0000000 --- a/db/btree/bt_search.c +++ /dev/null @@ -1,236 +0,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@ - */ -/*- - * 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 - -#include - -#include - -#include -#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); -} diff --git a/db/btree/bt_seq.c b/db/btree/bt_seq.c deleted file mode 100644 index 3362c8c..0000000 --- a/db/btree/bt_seq.c +++ /dev/null @@ -1,483 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include -#include - -#include -#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); -} diff --git a/db/btree/bt_split.c b/db/btree/bt_split.c deleted file mode 100644 index 2e8a8e2..0000000 --- a/db/btree/bt_split.c +++ /dev/null @@ -1,848 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include -#include - -#include -#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); -} diff --git a/db/btree/bt_stack.c b/db/btree/bt_stack.c deleted file mode 100644 index 05ab0c4..0000000 --- a/db/btree/bt_stack.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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 - -#include -#include -#include - -#include -#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); -} diff --git a/db/btree/bt_utils.c b/db/btree/bt_utils.c deleted file mode 100644 index 3d42600..0000000 --- a/db/btree/bt_utils.c +++ /dev/null @@ -1,283 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include - -#include -#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); -} diff --git a/db/btree/btree.h b/db/btree/btree.h deleted file mode 100644 index 31f1a77..0000000 --- a/db/btree/btree.h +++ /dev/null @@ -1,406 +0,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@ - */ -/*- - * 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 - -#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" diff --git a/db/btree/extern.h b/db/btree/extern.h deleted file mode 100644 index b7c9a73..0000000 --- a/db/btree/extern.h +++ /dev/null @@ -1,93 +0,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@ - */ -/*- - * 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 diff --git a/db/db/FreeBSD/db.c b/db/db/FreeBSD/db.c new file mode 100644 index 0000000..9c65e55 --- /dev/null +++ b/db/db/FreeBSD/db.c @@ -0,0 +1,101 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/db/db.c,v 1.2 2002/03/22 21:52:01 obrien Exp $"); + +#include + +#include +#include +#include +#include + +#include + +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; +} diff --git a/db/db/Makefile.inc b/db/db/Makefile.inc index 67c4fef..73c57e9 100644 --- a/db/db/Makefile.inc +++ b/db/db/Makefile.inc @@ -1,6 +1,11 @@ # 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" diff --git a/db/db/db.c b/db/db/db.c deleted file mode 100644 index 89947ff..0000000 --- a/db/db/db.c +++ /dev/null @@ -1,122 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include -#include - -#include - -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; -} diff --git a/db/hash/FreeBSD/extern.h b/db/hash/FreeBSD/extern.h new file mode 100644 index 0000000..2259ac0 --- /dev/null +++ b/db/hash/FreeBSD/extern.h @@ -0,0 +1,66 @@ +/*- + * 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 diff --git a/db/hash/FreeBSD/hash.c b/db/hash/FreeBSD/hash.c new file mode 100644 index 0000000..f3ef3ea --- /dev/null +++ b/db/hash/FreeBSD/hash.c @@ -0,0 +1,1006 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash.c,v 1.11 2002/03/21 22:46:26 obrien Exp $"); + +#include "namespace.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef DEBUG +#include +#endif +#include "un-namespace.h" + +#include +#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 diff --git a/db/hash/FreeBSD/hash.c.patch b/db/hash/FreeBSD/hash.c.patch new file mode 100644 index 0000000..a945d69 --- /dev/null +++ b/db/hash/FreeBSD/hash.c.patch @@ -0,0 +1,11 @@ +--- hash.c.orig Thu Mar 21 14:46:26 2002 ++++ hash.c Sat Oct 18 18:30:33 2003 +@@ -58,7 +58,7 @@ + #include + #include "hash.h" + #include "page.h" +-#include "extern.h" ++#include "hash_extern.h" + + static int alloc_segs(HTAB *, int); + static int flush_meta(HTAB *); diff --git a/db/hash/FreeBSD/hash.h b/db/hash/FreeBSD/hash.h new file mode 100644 index 0000000..33fefa7 --- /dev/null +++ b/db/hash/FreeBSD/hash.h @@ -0,0 +1,294 @@ +/*- + * 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 + * + * 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 diff --git a/db/hash/FreeBSD/hash_bigkey.c b/db/hash/FreeBSD/hash_bigkey.c new file mode 100644 index 0000000..487df5b --- /dev/null +++ b/db/hash/FreeBSD/hash_bigkey.c @@ -0,0 +1,670 @@ +/*- + * 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 +__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 + +#include +#include +#include +#include + +#ifdef DEBUG +#include +#endif + +#include +#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); +} diff --git a/db/hash/FreeBSD/hash_bigkey.c.patch b/db/hash/FreeBSD/hash_bigkey.c.patch new file mode 100644 index 0000000..64e0c6c --- /dev/null +++ b/db/hash/FreeBSD/hash_bigkey.c.patch @@ -0,0 +1,11 @@ +--- 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 + #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); diff --git a/db/hash/FreeBSD/hash_buf.c b/db/hash/FreeBSD/hash_buf.c new file mode 100644 index 0000000..2a81cb6 --- /dev/null +++ b/db/hash/FreeBSD/hash_buf.c @@ -0,0 +1,356 @@ +/*- + * 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 +__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 + +#include +#include +#include + +#ifdef DEBUG +#include +#endif + +#include +#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); +} diff --git a/db/hash/FreeBSD/hash_buf.c.patch b/db/hash/FreeBSD/hash_buf.c.patch new file mode 100644 index 0000000..5431734 --- /dev/null +++ b/db/hash/FreeBSD/hash_buf.c.patch @@ -0,0 +1,11 @@ +--- 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 + #include "hash.h" + #include "page.h" +-#include "extern.h" ++#include "hash_extern.h" + + static BUFHEAD *newbuf(HTAB *, u_int32_t, BUFHEAD *); + diff --git a/db/hash/FreeBSD/hash_func.c b/db/hash/FreeBSD/hash_func.c new file mode 100644 index 0000000..d46d620 --- /dev/null +++ b/db/hash/FreeBSD/hash_func.c @@ -0,0 +1,214 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_func.c,v 1.5 2003/02/16 17:29:09 nectar Exp $"); + +#include + +#include +#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); +} diff --git a/db/hash/FreeBSD/hash_func.c.patch b/db/hash/FreeBSD/hash_func.c.patch new file mode 100644 index 0000000..16336d9 --- /dev/null +++ b/db/hash/FreeBSD/hash_func.c.patch @@ -0,0 +1,11 @@ +--- 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 + #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; diff --git a/db/hash/FreeBSD/hash_log2.c b/db/hash/FreeBSD/hash_log2.c new file mode 100644 index 0000000..827dbef --- /dev/null +++ b/db/hash/FreeBSD/hash_log2.c @@ -0,0 +1,56 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/hash/hash_log2.c,v 1.2 2002/03/21 18:47:38 obrien Exp $"); + +#include + +#include + +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); +} diff --git a/db/hash/FreeBSD/hash_page.c b/db/hash/FreeBSD/hash_page.c new file mode 100644 index 0000000..8c4b0b5 --- /dev/null +++ b/db/hash/FreeBSD/hash_page.c @@ -0,0 +1,948 @@ +/*- + * 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 +__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 + +#include +#include +#include +#include +#include +#include +#include +#ifdef DEBUG +#include +#endif +#include "un-namespace.h" + +#include +#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 diff --git a/db/hash/FreeBSD/hash_page.c.patch b/db/hash/FreeBSD/hash_page.c.patch new file mode 100644 index 0000000..807837c --- /dev/null +++ b/db/hash/FreeBSD/hash_page.c.patch @@ -0,0 +1,11 @@ +--- 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 + #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); diff --git a/db/hash/FreeBSD/ndbm.c b/db/hash/FreeBSD/ndbm.c new file mode 100644 index 0000000..8561c8c --- /dev/null +++ b/db/hash/FreeBSD/ndbm.c @@ -0,0 +1,231 @@ +/*- + * 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 +__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 + +#include +#include +#include + +#include +#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); +} diff --git a/db/hash/FreeBSD/ndbm.c.patch b/db/hash/FreeBSD/ndbm.c.patch new file mode 100644 index 0000000..7be0d7a --- /dev/null +++ b/db/hash/FreeBSD/ndbm.c.patch @@ -0,0 +1,20 @@ +--- ndbm.c.orig Wed Oct 22 19:07:02 2003 ++++ ndbm.c Wed Dec 17 09:24:33 2003 +@@ -51,6 +51,7 @@ + #include + #include + ++#include + #include + #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]; diff --git a/db/hash/FreeBSD/page.h b/db/hash/FreeBSD/page.h new file mode 100644 index 0000000..2cf7460 --- /dev/null +++ b/db/hash/FreeBSD/page.h @@ -0,0 +1,93 @@ +/*- + * 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; diff --git a/db/hash/Makefile.inc b/db/hash/Makefile.inc index 45f5d8d..5276509 100644 --- a/db/hash/Makefile.inc +++ b/db/hash/Makefile.inc @@ -1,7 +1,17 @@ # 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 diff --git a/db/hash/extern.h b/db/hash/extern.h deleted file mode 100644 index 267b182..0000000 --- a/db/hash/extern.h +++ /dev/null @@ -1,88 +0,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@ - */ -/*- - * 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 diff --git a/db/hash/hash.c b/db/hash/hash.c deleted file mode 100644 index b22f1c6..0000000 --- a/db/hash/hash.c +++ /dev/null @@ -1,1025 +0,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@ - */ -/*- - * 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 - -#include -#include - -#include -#include -#include -#include -#include -#include -#ifdef DEBUG -#include -#endif - -#include -#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 diff --git a/db/hash/hash.h b/db/hash/hash.h deleted file mode 100644 index 9a061d2..0000000 --- a/db/hash/hash.h +++ /dev/null @@ -1,316 +0,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@ - */ -/*- - * 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 - * - * 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 diff --git a/db/hash/hash_bigkey.c b/db/hash/hash_bigkey.c deleted file mode 100644 index 91ed98a..0000000 --- a/db/hash/hash_bigkey.c +++ /dev/null @@ -1,691 +0,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@ - */ -/*- - * 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 - -/* - * 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 - -#include -#include -#include -#include - -#ifdef DEBUG -#include -#endif - -#include -#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); -} diff --git a/db/hash/hash_buf.c b/db/hash/hash_buf.c deleted file mode 100644 index a9c2af3..0000000 --- a/db/hash/hash_buf.c +++ /dev/null @@ -1,377 +0,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@ - */ -/*- - * 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 - -/* - * PACKAGE: hash - * - * DESCRIPTION: - * Contains buffer management - * - * ROUTINES: - * External - * __buf_init - * __get_buf - * __buf_free - * __reclaim_buf - * Internal - * newbuf - */ - -#include - -#include -#include -#include - -#ifdef DEBUG -#include -#endif - -#include -#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); -} diff --git a/db/hash/hash_func.c b/db/hash/hash_func.c deleted file mode 100644 index bd5fbcd..0000000 --- a/db/hash/hash_func.c +++ /dev/null @@ -1,235 +0,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@ - */ -/*- - * 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 - -#include - -#include -#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); -} diff --git a/db/hash/hash_log2.c b/db/hash/hash_log2.c deleted file mode 100644 index d601d75..0000000 --- a/db/hash/hash_log2.c +++ /dev/null @@ -1,77 +0,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@ - */ -/*- - * 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 - -#include - -#include - -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); -} diff --git a/db/hash/hash_page.c b/db/hash/hash_page.c deleted file mode 100644 index a48fe48..0000000 --- a/db/hash/hash_page.c +++ /dev/null @@ -1,967 +0,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@ - */ -/*- - * 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 - -/* - * PACKAGE: hashing - * - * DESCRIPTION: - * Page manipulation for hashing package. - * - * ROUTINES: - * - * External - * __get_page - * __add_ovflpage - * Internal - * overflow_page - * open_temp - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#ifdef DEBUG -#include -#endif - -#include -#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 diff --git a/db/hash/hsearch.c b/db/hash/hsearch.c deleted file mode 100644 index 94af4e6..0000000 --- a/db/hash/hsearch.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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 - -#include -#include - -#include -#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; - } -} diff --git a/db/hash/ndbm.c b/db/hash/ndbm.c deleted file mode 100644 index fa86368..0000000 --- a/db/hash/ndbm.c +++ /dev/null @@ -1,252 +0,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@ - */ -/*- - * 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 - -/* - * This package provides a dbm compatible interface to the new hashing - * package described in db(3). - */ - -#include - -#include -#include -#include - -#include -#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); -} diff --git a/db/hash/page.h b/db/hash/page.h deleted file mode 100644 index 14863ec..0000000 --- a/db/hash/page.h +++ /dev/null @@ -1,115 +0,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@ - */ -/*- - * 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; diff --git a/db/hash/search.h b/db/hash/search.h deleted file mode 100644 index 8ddecfb..0000000 --- a/db/hash/search.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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)); diff --git a/db/man/FreeBSD/btree.3 b/db/man/FreeBSD/btree.3 new file mode 100644 index 0000000..2dc095e --- /dev/null +++ b/db/man/FreeBSD/btree.3 @@ -0,0 +1,275 @@ +.\" 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. diff --git a/db/man/FreeBSD/dbm.3 b/db/man/FreeBSD/dbm.3 new file mode 100644 index 0000000..535c00e --- /dev/null +++ b/db/man/FreeBSD/dbm.3 @@ -0,0 +1,234 @@ +.\" 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 . diff --git a/db/man/FreeBSD/dbopen.3 b/db/man/FreeBSD/dbopen.3 new file mode 100644 index 0000000..91d0e29 --- /dev/null +++ b/db/man/FreeBSD/dbopen.3 @@ -0,0 +1,550 @@ +.\" 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. diff --git a/db/man/FreeBSD/hash.3 b/db/man/FreeBSD/hash.3 new file mode 100644 index 0000000..78454fb --- /dev/null +++ b/db/man/FreeBSD/hash.3 @@ -0,0 +1,200 @@ +.\" 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. diff --git a/db/man/FreeBSD/mpool.3 b/db/man/FreeBSD/mpool.3 new file mode 100644 index 0000000..c6ff2e4 --- /dev/null +++ b/db/man/FreeBSD/mpool.3 @@ -0,0 +1,247 @@ +.\" 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 diff --git a/db/man/FreeBSD/recno.3 b/db/man/FreeBSD/recno.3 new file mode 100644 index 0000000..7f069cf --- /dev/null +++ b/db/man/FreeBSD/recno.3 @@ -0,0 +1,232 @@ +.\" 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. diff --git a/db/man/Makefile.inc b/db/man/Makefile.inc index 3ee0369..a17ae48 100644 --- a/db/man/Makefile.inc +++ b/db/man/Makefile.inc @@ -1,10 +1,12 @@ # 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 diff --git a/db/man/btree.3 b/db/man/btree.3 deleted file mode 100644 index b8cee89..0000000 --- a/db/man/btree.3 +++ /dev/null @@ -1,272 +0,0 @@ -.\" 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. diff --git a/db/man/dbm.3 b/db/man/dbm.3 deleted file mode 100644 index 55b076b..0000000 --- a/db/man/dbm.3 +++ /dev/null @@ -1,196 +0,0 @@ -.\" 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 . diff --git a/db/man/dbopen.3 b/db/man/dbopen.3 deleted file mode 100644 index f04c771..0000000 --- a/db/man/dbopen.3 +++ /dev/null @@ -1,539 +0,0 @@ -.\" 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. diff --git a/db/man/hash.3 b/db/man/hash.3 deleted file mode 100644 index f51bb06..0000000 --- a/db/man/hash.3 +++ /dev/null @@ -1,191 +0,0 @@ -.\" 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. diff --git a/db/man/mpool.3 b/db/man/mpool.3 deleted file mode 100644 index 36c91e1..0000000 --- a/db/man/mpool.3 +++ /dev/null @@ -1,238 +0,0 @@ -.\" 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 diff --git a/db/man/recno.3 b/db/man/recno.3 deleted file mode 100644 index 7f069cf..0000000 --- a/db/man/recno.3 +++ /dev/null @@ -1,232 +0,0 @@ -.\" 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. diff --git a/db/mpool/FreeBSD/mpool.c b/db/mpool/FreeBSD/mpool.c new file mode 100644 index 0000000..737c03c --- /dev/null +++ b/db/mpool/FreeBSD/mpool.c @@ -0,0 +1,465 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/mpool/mpool.c,v 1.10 2002/03/22 21:52:01 obrien Exp $"); + +#include "namespace.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include + +#define __MPOOLINTERFACE_PRIVATE +#include + +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 diff --git a/db/mpool/Makefile.inc b/db/mpool/Makefile.inc index 4438d14..96c5c75 100644 --- a/db/mpool/Makefile.inc +++ b/db/mpool/Makefile.inc @@ -1,6 +1,11 @@ # 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" diff --git a/db/mpool/mpool.c b/db/mpool/mpool.c deleted file mode 100644 index 55bdefe..0000000 --- a/db/mpool/mpool.c +++ /dev/null @@ -1,484 +0,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@ - */ -/*- - * 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 - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#define __MPOOLINTERFACE_PRIVATE -#include - -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 diff --git a/db/recno/FreeBSD/extern.h b/db/recno/FreeBSD/extern.h new file mode 100644 index 0000000..8c59f47 --- /dev/null +++ b/db/recno/FreeBSD/extern.h @@ -0,0 +1,55 @@ +/*- + * 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); diff --git a/db/recno/FreeBSD/extern.h.patch b/db/recno/FreeBSD/extern.h.patch new file mode 100644 index 0000000..c0bce23 --- /dev/null +++ b/db/recno/FreeBSD/extern.h.patch @@ -0,0 +1,11 @@ +--- 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); diff --git a/db/recno/FreeBSD/rec_close.c b/db/recno/FreeBSD/rec_close.c new file mode 100644 index 0000000..fea96ae --- /dev/null +++ b/db/recno/FreeBSD/rec_close.c @@ -0,0 +1,188 @@ +/*- + * 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 +__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 +#include +#include + +#include +#include +#include +#include +#include "un-namespace.h" + +#include +#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); +} diff --git a/db/recno/FreeBSD/rec_delete.c b/db/recno/FreeBSD/rec_delete.c new file mode 100644 index 0000000..1205594 --- /dev/null +++ b/db/recno/FreeBSD/rec_delete.c @@ -0,0 +1,199 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_delete.c,v 1.2 2002/03/21 22:46:28 obrien Exp $"); + +#include + +#include +#include +#include + +#include +#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); +} diff --git a/db/recno/FreeBSD/rec_get.c b/db/recno/FreeBSD/rec_get.c new file mode 100644 index 0000000..d9da658 --- /dev/null +++ b/db/recno/FreeBSD/rec_get.c @@ -0,0 +1,313 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_get.c,v 1.5 2002/03/22 21:52:02 obrien Exp $"); + +#include + +#include +#include +#include +#include +#include +#include + +#include +#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); +} diff --git a/db/recno/FreeBSD/rec_open.c b/db/recno/FreeBSD/rec_open.c new file mode 100644 index 0000000..a431f6f --- /dev/null +++ b/db/recno/FreeBSD/rec_open.c @@ -0,0 +1,245 @@ +/*- + * 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 +__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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include +#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); +} diff --git a/db/recno/FreeBSD/rec_put.c b/db/recno/FreeBSD/rec_put.c new file mode 100644 index 0000000..14cc811 --- /dev/null +++ b/db/recno/FreeBSD/rec_put.c @@ -0,0 +1,287 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_put.c,v 1.6 2002/03/22 21:52:02 obrien Exp $"); + +#include + +#include +#include +#include +#include + +#include +#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); +} diff --git a/db/recno/FreeBSD/rec_search.c b/db/recno/FreeBSD/rec_search.c new file mode 100644 index 0000000..3353bfb --- /dev/null +++ b/db/recno/FreeBSD/rec_search.c @@ -0,0 +1,128 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_search.c,v 1.4 2002/03/21 18:47:38 obrien Exp $"); + +#include + +#include +#include + +#include +#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); +} diff --git a/db/recno/FreeBSD/rec_seq.c b/db/recno/FreeBSD/rec_seq.c new file mode 100644 index 0000000..6ed3384 --- /dev/null +++ b/db/recno/FreeBSD/rec_seq.c @@ -0,0 +1,134 @@ +/*- + * 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 +#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 + +#include +#include +#include +#include + +#include +#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); +} diff --git a/db/recno/FreeBSD/rec_utils.c b/db/recno/FreeBSD/rec_utils.c new file mode 100644 index 0000000..81fa1d6 --- /dev/null +++ b/db/recno/FreeBSD/rec_utils.c @@ -0,0 +1,124 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/db/recno/rec_utils.c,v 1.2 2002/03/22 21:52:02 obrien Exp $"); + +#include + +#include +#include +#include + +#include +#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); +} diff --git a/db/recno/FreeBSD/recno.h b/db/recno/FreeBSD/recno.h new file mode 100644 index 0000000..b0c0af7 --- /dev/null +++ b/db/recno/FreeBSD/recno.h @@ -0,0 +1,40 @@ +/*- + * 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" diff --git a/db/recno/FreeBSD/recno.h.patch b/db/recno/FreeBSD/recno.h.patch new file mode 100644 index 0000000..a3d1ec3 --- /dev/null +++ b/db/recno/FreeBSD/recno.h.patch @@ -0,0 +1,10 @@ +--- 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" diff --git a/db/recno/Makefile.inc b/db/recno/Makefile.inc index 63ff12a..f1de47b 100644 --- a/db/recno/Makefile.inc +++ b/db/recno/Makefile.inc @@ -1,9 +1,17 @@ # 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 diff --git a/db/recno/extern.h b/db/recno/extern.h deleted file mode 100644 index eacfc95..0000000 --- a/db/recno/extern.h +++ /dev/null @@ -1,77 +0,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@ - */ -/*- - * 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); diff --git a/db/recno/rec_close.c b/db/recno/rec_close.c deleted file mode 100644 index 9d6a8c3..0000000 --- a/db/recno/rec_close.c +++ /dev/null @@ -1,207 +0,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@ - */ -/*- - * 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 - -#include -#include -#include - -#include -#include -#include -#include - -#include -#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); -} diff --git a/db/recno/rec_delete.c b/db/recno/rec_delete.c deleted file mode 100644 index d739f3c..0000000 --- a/db/recno/rec_delete.c +++ /dev/null @@ -1,220 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include - -#include -#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); -} diff --git a/db/recno/rec_get.c b/db/recno/rec_get.c deleted file mode 100644 index e0fe787..0000000 --- a/db/recno/rec_get.c +++ /dev/null @@ -1,334 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include -#include -#include -#include - -#include -#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); -} diff --git a/db/recno/rec_open.c b/db/recno/rec_open.c deleted file mode 100644 index 8513ee2..0000000 --- a/db/recno/rec_open.c +++ /dev/null @@ -1,264 +0,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@ - */ -/*- - * 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 - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#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); -} diff --git a/db/recno/rec_put.c b/db/recno/rec_put.c deleted file mode 100644 index 90567ef..0000000 --- a/db/recno/rec_put.c +++ /dev/null @@ -1,308 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include -#include - -#include -#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); -} diff --git a/db/recno/rec_search.c b/db/recno/rec_search.c deleted file mode 100644 index 2b2f989..0000000 --- a/db/recno/rec_search.c +++ /dev/null @@ -1,149 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include - -#include -#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); -} diff --git a/db/recno/rec_seq.c b/db/recno/rec_seq.c deleted file mode 100644 index 652e366..0000000 --- a/db/recno/rec_seq.c +++ /dev/null @@ -1,150 +0,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@ - */ -/*- - * 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 -#include - -#include -#include -#include -#include - -#include -#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); -} diff --git a/db/recno/rec_utils.c b/db/recno/rec_utils.c deleted file mode 100644 index cf76316..0000000 --- a/db/recno/rec_utils.c +++ /dev/null @@ -1,145 +0,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@ - */ -/*- - * 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 - -#include - -#include -#include -#include - -#include -#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); -} diff --git a/db/recno/recno.h b/db/recno/recno.h deleted file mode 100644 index 3995d7a..0000000 --- a/db/recno/recno.h +++ /dev/null @@ -1,62 +0,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@ - */ -/*- - * 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" diff --git a/emulated/Makefile.inc b/emulated/Makefile.inc new file mode 100644 index 0000000..6b5ec84 --- /dev/null +++ b/emulated/Makefile.inc @@ -0,0 +1,12 @@ +.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 diff --git a/emulated/bsd_signal.3 b/emulated/bsd_signal.3 new file mode 100644 index 0000000..591a062 --- /dev/null +++ b/emulated/bsd_signal.3 @@ -0,0 +1,119 @@ +.\" 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 . diff --git a/emulated/bsd_signal.c b/emulated/bsd_signal.c new file mode 100644 index 0000000..971b35c --- /dev/null +++ b/emulated/bsd_signal.c @@ -0,0 +1,46 @@ +/* + * 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 + +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); +} diff --git a/emulated/statvfs.3 b/emulated/statvfs.3 new file mode 100644 index 0000000..e29ef44 --- /dev/null +++ b/emulated/statvfs.3 @@ -0,0 +1,208 @@ +.\" +.\" 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 . diff --git a/emulated/statvfs.c b/emulated/statvfs.c new file mode 100644 index 0000000..fe88553 --- /dev/null +++ b/emulated/statvfs.c @@ -0,0 +1,86 @@ +/* + * 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 +#include + +#include /* 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 */ diff --git a/emulated/tcgetsid.3 b/emulated/tcgetsid.3 new file mode 100644 index 0000000..a88355a --- /dev/null +++ b/emulated/tcgetsid.3 @@ -0,0 +1,75 @@ +.\" 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 . diff --git a/emulated/tcgetsid.c b/emulated/tcgetsid.c new file mode 100644 index 0000000..9f99eec --- /dev/null +++ b/emulated/tcgetsid.c @@ -0,0 +1,44 @@ +/* + * 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 +#include + +pid_t +tcgetsid(int fildes) +{ + pid_t sid; + + if (ioctl(fildes, TIOCGSID, (char *)&sid) < 0) + return ((pid_t)-1); + + return (sid); +} + +/* EOF */ diff --git a/fbsdcompat/_fbsd_compat_.h b/fbsdcompat/_fbsd_compat_.h index d2a6167..8d5b8fb 100644 --- a/fbsdcompat/_fbsd_compat_.h +++ b/fbsdcompat/_fbsd_compat_.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -33,8 +35,6 @@ #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_ /* diff --git a/fbsdcompat/_fpmath.h b/fbsdcompat/_fpmath.h index 3baf93f..83a08a8 100644 --- a/fbsdcompat/_fpmath.h +++ b/fbsdcompat/_fpmath.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -45,7 +47,7 @@ * 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 { @@ -61,6 +63,9 @@ 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; \ diff --git a/fbsdcompat/fpmath.h b/fbsdcompat/fpmath.h index ddf0a9a..f52a6bd 100644 --- a/fbsdcompat/fpmath.h +++ b/fbsdcompat/fpmath.h @@ -1,25 +1,3 @@ -/* - * 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 * Copyright (c) 2002 David Schultz @@ -46,7 +24,7 @@ * 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 @@ -67,6 +45,9 @@ union IEEEf2bits { } bits; }; +#define DBL_MANH_SIZE 20 +#define DBL_MANL_SIZE 32 + union IEEEd2bits { double d; struct { diff --git a/fbsdcompat/libc_private.h b/fbsdcompat/libc_private.h index cf4cf05..af39a63 100644 --- a/fbsdcompat/libc_private.h +++ b/fbsdcompat/libc_private.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/fbsdcompat/machine/atomic.h b/fbsdcompat/machine/atomic.h index f87a3c5..dc3ddf4 100644 --- a/fbsdcompat/machine/atomic.h +++ b/fbsdcompat/machine/atomic.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/fbsdcompat/namespace.h b/fbsdcompat/namespace.h index c7aa0b7..7e4fdf0 100644 --- a/fbsdcompat/namespace.h +++ b/fbsdcompat/namespace.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/fbsdcompat/spinlock.h b/fbsdcompat/spinlock.h index 4fc0901..791d952 100644 --- a/fbsdcompat/spinlock.h +++ b/fbsdcompat/spinlock.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/fbsdcompat/sys/cdefs.h b/fbsdcompat/sys/cdefs.h index d0237a2..521fb6d 100644 --- a/fbsdcompat/sys/cdefs.h +++ b/fbsdcompat/sys/cdefs.h @@ -45,6 +45,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/fbsdcompat/sys/endian.h b/fbsdcompat/sys/endian.h index 287dbd9..e9c8f51 100644 --- a/fbsdcompat/sys/endian.h +++ b/fbsdcompat/sys/endian.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/fbsdcompat/un-namespace.h b/fbsdcompat/un-namespace.h index c7aa0b7..7e4fdf0 100644 --- a/fbsdcompat/un-namespace.h +++ b/fbsdcompat/un-namespace.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/fixdups.ed b/fixdups.ed new file mode 100644 index 0000000..009f6d9 --- /dev/null +++ b/fixdups.ed @@ -0,0 +1,2 @@ +//;.+1,$g//d +w diff --git a/gdtoa/FreeBSD/_hdtoa.c b/gdtoa/FreeBSD/_hdtoa.c new file mode 100644 index 0000000..1a85986 --- /dev/null +++ b/gdtoa/FreeBSD/_hdtoa.c @@ -0,0 +1,432 @@ +/*- + * Copyright (c) 2004 David Schultz + * 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 +__FBSDID("$FreeBSD: src/lib/libc/gdtoa/_hdtoa.c,v 1.2 2004/01/21 04:51:50 grehan Exp $"); + +#include +#include +#include +#include +#include +#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) */ diff --git a/gdtoa/FreeBSD/_ldtoa.c b/gdtoa/FreeBSD/_ldtoa.c index 3560ebb..ededc68 100644 --- a/gdtoa/FreeBSD/_ldtoa.c +++ b/gdtoa/FreeBSD/_ldtoa.c @@ -25,7 +25,7 @@ */ #include -__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 #include @@ -79,6 +79,9 @@ __ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign, break; case FP_SUBNORMAL: kind = STRTOG_Denormal; +#ifdef LDBL_IMPLICIT_NBIT + be++; +#endif break; case FP_INFINITE: kind = STRTOG_Infinite; diff --git a/gdtoa/FreeBSD/gdtoa-gethex.c b/gdtoa/FreeBSD/gdtoa-gethex.c index 0f9ae33..fadb5de 100644 --- a/gdtoa/FreeBSD/gdtoa-gethex.c +++ b/gdtoa/FreeBSD/gdtoa-gethex.c @@ -51,7 +51,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) 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 @@ -164,6 +164,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) if (e > fpi->emax) { ovfl: Bfree(b); + *bp = 0; return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; } irv = STRTOG_Normal; @@ -173,7 +174,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) 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: @@ -191,6 +192,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) } } Bfree(b); + *bp = 0; return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow; } k = n - 1; @@ -224,18 +226,18 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) 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 diff --git a/gdtoa/FreeBSD/gdtoa-strtod.c b/gdtoa/FreeBSD/gdtoa-strtod.c index f1a0c04..4913d50 100644 --- a/gdtoa/FreeBSD/gdtoa-strtod.c +++ b/gdtoa/FreeBSD/gdtoa-strtod.c @@ -114,15 +114,17 @@ strtod 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; diff --git a/gdtoa/Makefile.inc b/gdtoa/Makefile.inc index aaf7c85..e7fe795 100644 --- a/gdtoa/Makefile.inc +++ b/gdtoa/Makefile.inc @@ -3,7 +3,7 @@ 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 \ @@ -11,5 +11,5 @@ FBSDSRCS= _ldtoa.c glue.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" diff --git a/gdtoa/arith.h b/gdtoa/arith.h index 3a17fc4..b20ee85 100644 --- a/gdtoa/arith.h +++ b/gdtoa/arith.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -29,6 +31,11 @@ #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 diff --git a/gen/FreeBSD/exec.3.patch b/gen/FreeBSD/exec.3.patch new file mode 100644 index 0000000..b22f837 --- /dev/null +++ b/gen/FreeBSD/exec.3.patch @@ -0,0 +1,64 @@ +--- 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 diff --git a/gen/FreeBSD/fmtmsg.3 b/gen/FreeBSD/fmtmsg.3 new file mode 100644 index 0000000..3320bd0 --- /dev/null +++ b/gen/FreeBSD/fmtmsg.3 @@ -0,0 +1,260 @@ +.\" +.\" Copyright (c) 2002 Mike Barcroft +.\" 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. diff --git a/gen/FreeBSD/fmtmsg.c b/gen/FreeBSD/fmtmsg.c new file mode 100644 index 0000000..4db35dc --- /dev/null +++ b/gen/FreeBSD/fmtmsg.c @@ -0,0 +1,220 @@ +/*- + * Copyright (c) 2002 Mike Barcroft + * 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 +__FBSDID("$FreeBSD: src/lib/libc/gen/fmtmsg.c,v 1.5 2003/05/01 19:03:13 nectar Exp $"); + +#include +#include +#include +#include + +/* 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); +} diff --git a/gen/FreeBSD/fpclassify.3 b/gen/FreeBSD/fpclassify.3 new file mode 100644 index 0000000..3366bcb --- /dev/null +++ b/gen/FreeBSD/fpclassify.3 @@ -0,0 +1,130 @@ +.\" Copyright (c) 2003 Mike Barcroft +.\" 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. diff --git a/gen/FreeBSD/fpclassify.3.patch b/gen/FreeBSD/fpclassify.3.patch new file mode 100644 index 0000000..fadc0de --- /dev/null +++ b/gen/FreeBSD/fpclassify.3.patch @@ -0,0 +1,18 @@ +--- 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 diff --git a/gen/FreeBSD/getpeereid.3 b/gen/FreeBSD/getpeereid.3 new file mode 100644 index 0000000..6b5aed0 --- /dev/null +++ b/gen/FreeBSD/getpeereid.3 @@ -0,0 +1,137 @@ +.\" +.\" 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 . diff --git a/gen/FreeBSD/getpeereid.c b/gen/FreeBSD/getpeereid.c new file mode 100644 index 0000000..5608c48 --- /dev/null +++ b/gen/FreeBSD/getpeereid.c @@ -0,0 +1,54 @@ +/* + * 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 +__FBSDID("$FreeBSD: src/lib/libc/gen/getpeereid.c,v 1.6 2002/12/16 13:42:13 maxim Exp $"); + +#include +#include +#include +#include + +#include +#include + +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); +} diff --git a/gen/FreeBSD/getprogname.3.patch b/gen/FreeBSD/getprogname.3.patch new file mode 100644 index 0000000..be7858d --- /dev/null +++ b/gen/FreeBSD/getprogname.3.patch @@ -0,0 +1,12 @@ +--- 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 , diff --git a/gen/FreeBSD/glob.3 b/gen/FreeBSD/glob.3 new file mode 100644 index 0000000..ce07fdd --- /dev/null +++ b/gen/FreeBSD/glob.3 @@ -0,0 +1,469 @@ +.\" 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 . diff --git a/gen/FreeBSD/glob.c b/gen/FreeBSD/glob.c new file mode 100644 index 0000000..6af42d9 --- /dev/null +++ b/gen/FreeBSD/glob.c @@ -0,0 +1,905 @@ +/* + * 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 +__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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 diff --git a/gen/FreeBSD/isgreater.3 b/gen/FreeBSD/isgreater.3 new file mode 100644 index 0000000..93972dc --- /dev/null +++ b/gen/FreeBSD/isgreater.3 @@ -0,0 +1,102 @@ +.\" Copyright (c) 2003 David Schultz +.\" 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 . diff --git a/gen/FreeBSD/isgreater.3.patch b/gen/FreeBSD/isgreater.3.patch new file mode 100644 index 0000000..f65e8ce --- /dev/null +++ b/gen/FreeBSD/isgreater.3.patch @@ -0,0 +1,9 @@ +--- 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 . diff --git a/gen/FreeBSD/popen.c.patch b/gen/FreeBSD/popen.c.patch index a5e07fc..e0ce5b8 100644 --- a/gen/FreeBSD/popen.c.patch +++ b/gen/FreeBSD/popen.c.patch @@ -1,6 +1,14 @@ ---- 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 + #include ++#include + + #include + #include +@@ -55,11 +56,14 @@ #include "un-namespace.h" #include "libc_private.h" @@ -8,5 +16,57 @@ +#include +#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]); + } + diff --git a/gen/FreeBSD/signal.3.patch b/gen/FreeBSD/signal.3.patch new file mode 100644 index 0000000..93f4dff --- /dev/null +++ b/gen/FreeBSD/signal.3.patch @@ -0,0 +1,13 @@ +--- 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" diff --git a/gen/FreeBSD/signbit.3 b/gen/FreeBSD/signbit.3 new file mode 100644 index 0000000..42d810d --- /dev/null +++ b/gen/FreeBSD/signbit.3 @@ -0,0 +1,57 @@ +.\" Copyright (c) 2003 Mike Barcroft +.\" 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 . diff --git a/gen/FreeBSD/signbit.3.patch b/gen/FreeBSD/signbit.3.patch new file mode 100644 index 0000000..c2f2e91 --- /dev/null +++ b/gen/FreeBSD/signbit.3.patch @@ -0,0 +1,11 @@ +--- 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 . diff --git a/gen/FreeBSD/sleep.3.patch b/gen/FreeBSD/sleep.3.patch new file mode 100644 index 0000000..94b6511 --- /dev/null +++ b/gen/FreeBSD/sleep.3.patch @@ -0,0 +1,31 @@ +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 diff --git a/gen/FreeBSD/sysconf.3 b/gen/FreeBSD/sysconf.3 new file mode 100644 index 0000000..e14fea2 --- /dev/null +++ b/gen/FreeBSD/sysconf.3 @@ -0,0 +1,212 @@ +.\" 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 . diff --git a/gen/FreeBSD/sysconf.c b/gen/FreeBSD/sysconf.c new file mode 100644 index 0000000..309e163 --- /dev/null +++ b/gen/FreeBSD/sysconf.c @@ -0,0 +1,582 @@ +/*- + * 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 +__FBSDID("$FreeBSD: src/lib/libc/gen/sysconf.c,v 1.20 2002/11/17 08:54:29 dougb Exp $"); + +#include +#include +#include +#include +#include + +#include +#include +#include +#include /* we just need the limits */ +#include +#include + +#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); +} diff --git a/gen/FreeBSD/sysconf.c.patch b/gen/FreeBSD/sysconf.c.patch new file mode 100644 index 0000000..db93bad --- /dev/null +++ b/gen/FreeBSD/sysconf.c.patch @@ -0,0 +1,233 @@ +--- sysconf.c.orig Sun Nov 17 00:54:29 2002 ++++ sysconf.c Wed Apr 14 17:09:36 2004 +@@ -45,6 +45,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -53,8 +55,8 @@ + #include + #include + +-#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; diff --git a/gen/FreeBSD/sysctl.3.patch b/gen/FreeBSD/sysctl.3.patch new file mode 100644 index 0000000..cfdb59f --- /dev/null +++ b/gen/FreeBSD/sysctl.3.patch @@ -0,0 +1,40 @@ +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 diff --git a/gen/FreeBSD/usleep.3.patch b/gen/FreeBSD/usleep.3.patch new file mode 100644 index 0000000..33e6d93 --- /dev/null +++ b/gen/FreeBSD/usleep.3.patch @@ -0,0 +1,29 @@ +--- 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 diff --git a/gen/Makefile.inc b/gen/Makefile.inc index b8e0009..40f3abe 100644 --- a/gen/Makefile.inc +++ b/gen/Makefile.inc @@ -1,61 +1,72 @@ # @(#)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 @@ -64,8 +75,11 @@ MLINKS+=err.3 err_set_exit.3 err.3 err_set_file.3 err.3 errc.3 err.3 errx.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 \ @@ -87,9 +101,11 @@ MLINKS+=getttyent.3 endttyent.3 getttyent.3 getttynam.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 diff --git a/gen/NSSystemDirectories.c b/gen/NSSystemDirectories.c index b351964..d8935a6 100644 --- a/gen/NSSystemDirectories.c +++ b/gen/NSSystemDirectories.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/OSSystemInfo.c b/gen/OSSystemInfo.c index f9225eb..42f1691 100644 --- a/gen/OSSystemInfo.c +++ b/gen/OSSystemInfo.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/arc4random.c b/gen/arc4random.c index 44e7340..c761a71 100644 --- a/gen/arc4random.c +++ b/gen/arc4random.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/assert.c b/gen/assert.c index 4155678..450c288 100644 --- a/gen/assert.c +++ b/gen/assert.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/authentication.c b/gen/authentication.c index 20e3b90..5ffcae8 100644 --- a/gen/authentication.c +++ b/gen/authentication.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/cache.c b/gen/cache.c index f570a55..d6bbe5d 100644 --- a/gen/cache.c +++ b/gen/cache.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/confstr.c b/gen/confstr.c index b760fc7..8bb490c 100644 --- a/gen/confstr.c +++ b/gen/confstr.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -97,6 +99,65 @@ confstr(name, buf, len) 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); diff --git a/gen/crypt.3 b/gen/crypt.3 new file mode 100644 index 0000000..26befb9 --- /dev/null +++ b/gen/crypt.3 @@ -0,0 +1,244 @@ +.\" $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 +.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 diff --git a/gen/crypt.c b/gen/crypt.c index 33ef553..a344d4c 100644 --- a/gen/crypt.c +++ b/gen/crypt.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -57,7 +59,17 @@ */ +/* + * 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 +#endif /* __APPLE_PR_3509199_COMPAT__ */ #include #include #include @@ -935,7 +947,11 @@ STATIC void init_perm(perm, p, chars_in, chars_out) /* * "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; @@ -949,13 +965,21 @@ int setkey(key) } 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; { @@ -970,8 +994,12 @@ int encrypt(block, 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--) { @@ -979,7 +1007,9 @@ int encrypt(block, flag) k >>= 1; } } +#ifdef __APPLE_PR_3509199_COMPAT__ return (0); +#endif /* __APPLE_PR_3509199_COMPAT__ */ } #ifdef DEBUG diff --git a/gen/devname.c b/gen/devname.c index d7132ce..3edcabd 100644 --- a/gen/devname.c +++ b/gen/devname.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/disklabel.c b/gen/disklabel.c index ed86ede..5058b93 100644 --- a/gen/disklabel.c +++ b/gen/disklabel.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/errlst.c b/gen/errlst.c index de1ef5e..ee4cc9d 100644 --- a/gen/errlst.c +++ b/gen/errlst.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -73,7 +75,7 @@ const char *const sys_errlist[] = { "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 */ @@ -172,6 +174,14 @@ const char *const sys_errlist[] = { "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]); diff --git a/gen/fts.c b/gen/fts.c index fa7719e..8db8393 100644 --- a/gen/fts.c +++ b/gen/fts.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/ftw.3 b/gen/ftw.3 new file mode 100644 index 0000000..7b17513 --- /dev/null +++ b/gen/ftw.3 @@ -0,0 +1,209 @@ +.\" $OpenBSD: ftw.3,v 1.4 2003/10/30 18:52:58 jmc Exp $ +.\" +.\" Copyright (c) 2003 Todd C. Miller +.\" +.\" 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 +.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. diff --git a/gen/ftw.c b/gen/ftw.c new file mode 100644 index 0000000..98bb8e8 --- /dev/null +++ b/gen/ftw.c @@ -0,0 +1,95 @@ +/* $OpenBSD: ftw.c,v 1.2 2003/07/21 21:15:32 millert Exp $ */ + +/* + * Copyright (c) 2003 Todd C. Miller + * + * 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 +#include +#include +#include +#include +#include + +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); +} diff --git a/gen/getloadavg.c b/gen/getloadavg.c index ac263c6..6f599dc 100644 --- a/gen/getloadavg.c +++ b/gen/getloadavg.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/getpwent.3 b/gen/getpwent.3 index 1515c49..9c7badf 100644 --- a/gen/getpwent.3 +++ b/gen/getpwent.3 @@ -146,7 +146,7 @@ structure will point to the string .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. diff --git a/gen/getttyent.c b/gen/getttyent.c index 723077b..21f5096 100644 --- a/gen/getttyent.c +++ b/gen/getttyent.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/getusershell.c b/gen/getusershell.c index cd64c5e..9c25b5d 100644 --- a/gen/getusershell.c +++ b/gen/getusershell.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/getvfsbyname.c b/gen/getvfsbyname.c index 8bfab48..6d93228 100644 --- a/gen/getvfsbyname.c +++ b/gen/getvfsbyname.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/glob.3 b/gen/glob.3 deleted file mode 100644 index aa509a3..0000000 --- a/gen/glob.3 +++ /dev/null @@ -1,466 +0,0 @@ -.\" 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 . diff --git a/gen/isinf.3 b/gen/isinf.3 deleted file mode 100644 index dfc7efc..0000000 --- a/gen/isinf.3 +++ /dev/null @@ -1,80 +0,0 @@ -.\" 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. diff --git a/gen/isinf.c b/gen/isinf.c new file mode 100644 index 0000000..2b30164 --- /dev/null +++ b/gen/isinf.c @@ -0,0 +1,34 @@ +/* + * 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 + +/* 3BSD compatibility function */ +#undef isinf +int +isinf(double d) +{ + return __isinfd(d); +} diff --git a/gen/isnan.c b/gen/isnan.c index bcf2de1..ab5a03a 100644 --- a/gen/isnan.c +++ b/gen/isnan.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -20,65 +22,13 @@ * * @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 - -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 -#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); } diff --git a/gen/malloc.3 b/gen/malloc.3 index 53f193f..9d38da1 100644 --- a/gen/malloc.3 +++ b/gen/malloc.3 @@ -22,7 +22,7 @@ .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 @@ -34,6 +34,8 @@ .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 @@ -45,8 +47,9 @@ The .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. @@ -118,6 +121,17 @@ pointer if there is an error, and the allocation pointed to by 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 . @@ -152,7 +166,9 @@ to .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 @@ -196,6 +212,10 @@ can be used. 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 @@ -250,4 +270,4 @@ The list should correspond to this documentation. .Xr leaks 1 , .Xr malloc_history 1 , .Xr abort 3 -.Pa /Developer/Documentation/ReleaseNotes/MallocOptions.html +.Pa /Developer/Documentation/ReleaseNotes/DeveloperTools/MallocOptions.html diff --git a/gen/malloc.c b/gen/malloc.c index d64501d..e864122 100644 --- a/gen/malloc.c +++ b/gen/malloc.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -31,13 +33,13 @@ #import #import #include +#import #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); @@ -61,7 +63,7 @@ static int malloc_check_abort = 0; // default is to sleep, not abort 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) @@ -101,8 +103,8 @@ _malloc_initialize(void) { (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 * @@ -120,26 +122,28 @@ malloc_default_zone(void) { 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"); @@ -154,15 +158,15 @@ set_flags_from_environment(void) { 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) { @@ -175,26 +179,22 @@ set_flags_from_environment(void) { 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"); @@ -202,20 +202,21 @@ set_flags_from_environment(void) { 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 to create/append messages to file 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 to start checking the heap after operations\n" "- MallocCheckHeapEach to repeat the checking of the heap after operations\n" "- MallocCheckHeapSleep to sleep seconds on heap corruption\n" "- MallocCheckHeapAbort to abort on heap corruption if is non-zero\n" "- MallocBadFreeAbort to abort on a bad free if is non-zero\n" - "- MallocHelp - this help!\n", getpid()); + "- MallocHelp - this help!\n"); } } @@ -227,6 +228,7 @@ malloc_create_zone(vm_size_t start_size, unsigned flags) { 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(); @@ -288,11 +290,6 @@ internal_check(void) { 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(); } @@ -307,11 +304,6 @@ malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) { 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; @@ -320,11 +312,6 @@ malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) { 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(); } @@ -398,7 +385,7 @@ malloc_zone_unregister(malloc_zone_t *z) { } } 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 @@ -418,67 +405,24 @@ malloc_get_zone_name(malloc_zone_t *zone) { 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 ************/ @@ -511,7 +455,9 @@ free(void *ptr) { 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(); } @@ -633,14 +579,14 @@ malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **address 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; @@ -649,7 +595,7 @@ malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **address // 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); @@ -734,7 +680,7 @@ malloc_zone_log(malloc_zone_t *zone, void *address) { 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 @@ -780,10 +726,27 @@ _malloc_fork_child() { } } -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 ********************/ @@ -799,7 +762,7 @@ set_malloc_singlethreaded(boolean_t single) { 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; } @@ -809,13 +772,13 @@ void 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; } diff --git a/gen/nanosleep.c b/gen/nanosleep.c index 717f30c..4dd3cbe 100644 --- a/gen/nanosleep.c +++ b/gen/nanosleep.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -23,46 +25,49 @@ #include #include -#include #include -#include -#include -#include +#include #include -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; diff --git a/gen/nftw.c b/gen/nftw.c new file mode 100644 index 0000000..b3ba357 --- /dev/null +++ b/gen/nftw.c @@ -0,0 +1,111 @@ +/* $OpenBSD: nftw.c,v 1.2 2003/07/21 21:15:32 millert Exp $ */ + +/* + * Copyright (c) 2003 Todd C. Miller + * + * 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 +#include +#include +#include +#include +#include + +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); +} diff --git a/gen/nlist.c b/gen/nlist.c index 6961da3..bc09f42 100644 --- a/gen/nlist.c +++ b/gen/nlist.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/scalable_malloc.c b/gen/scalable_malloc.c index 35d08fc..0a7af09 100644 --- a/gen/scalable_malloc.c +++ b/gen/scalable_malloc.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -23,13 +25,14 @@ /* Author: Bertrand Serlet, August 1999 */ -#import "scalable_malloc.h" +#include "scalable_malloc.h" -#import +#include -#import -#import +#include +#include #include +#include /********************* DEFINITIONS ************************/ @@ -39,34 +42,40 @@ #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 @@ -77,35 +86,131 @@ typedef unsigned char grain_t; #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 @@ -115,36 +220,103 @@ typedef unsigned short tiny_region_t; /********************* 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 @@ -164,15 +336,27 @@ typedef unsigned short small_region_t; // 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; @@ -196,7 +380,7 @@ typedef struct { 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; @@ -206,77 +390,177 @@ typedef struct { 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); @@ -288,117 +572,131 @@ szone_error(szone_t *szone, const char *msg, const void *ptr) { } 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) @@ -422,141 +720,156 @@ free_list_count(const free_list_t *ptr) { #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); @@ -570,58 +883,77 @@ set_tiny_meta_header_free(const void *ptr, msize_t msize) { 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); @@ -649,11 +981,11 @@ tiny_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) { 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 @@ -661,6 +993,7 @@ tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize) { 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); @@ -671,7 +1004,8 @@ tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t 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; } @@ -688,39 +1022,54 @@ tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize) { } } +/* + * 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); @@ -728,21 +1077,21 @@ tiny_free_no_lock(szone_t *szone, tiny_region_t *region, void *ptr, msize_t msiz 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; @@ -766,7 +1115,7 @@ tiny_free_no_lock(szone_t *szone, tiny_region_t *region, void *ptr, msize_t msiz 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: @@ -776,160 +1125,215 @@ tiny_free_no_lock(szone_t *szone, tiny_region_t *region, void *ptr, msize_t msiz } 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); } } } @@ -937,55 +1341,71 @@ szone_check_tiny_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) { +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); @@ -995,7 +1415,6 @@ tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_addres block_index += msize; } } - // malloc_printf("Found in tiny region %d in_use and %d free\n", num_in_use, num_free); index++; } if (count) { @@ -1005,17 +1424,26 @@ tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_addres } 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); @@ -1023,24 +1451,27 @@ tiny_malloc_from_free_list(szone_t *szone, msize_t msize) { *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); @@ -1048,8 +1479,8 @@ tiny_malloc_from_free_list(szone_t *szone, msize_t msize) { *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; @@ -1059,26 +1490,24 @@ tiny_malloc_from_free_list(szone_t *szone, msize_t msize) { // 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; @@ -1093,30 +1522,29 @@ tiny_malloc_from_free_list(szone_t *szone, msize_t 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); @@ -1124,10 +1552,10 @@ add_leftover_and_proceed: } 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); @@ -1135,52 +1563,51 @@ return_tiny_alloc: } 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__); @@ -1188,43 +1615,48 @@ tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_reques } 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 @@ -1234,152 +1666,152 @@ free_tiny(szone_t *szone, void *ptr, tiny_region_t *tiny_region) { } 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 @@ -1387,10 +1819,11 @@ small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) { 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); } @@ -1404,30 +1837,33 @@ small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize) { 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; } @@ -1445,49 +1881,55 @@ 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) { - 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; @@ -1496,22 +1938,21 @@ small_free_no_lock(szone_t *szone, small_region_t *region, void *ptr, msize_t ms } } // 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); @@ -1521,110 +1962,201 @@ small_free_no_lock(szone_t *szone, small_region_t *region, void *ptr, msize_t ms } 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; } } @@ -1632,42 +2164,55 @@ 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) { +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); @@ -1676,7 +2221,6 @@ small_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_addre } block_index += msize; } - // malloc_printf("End small region - count=%d\n", count); } index++; } @@ -1687,32 +2231,39 @@ small_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_addre } 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++; @@ -1720,9 +2271,8 @@ small_malloc_from_free_list(szone_t *szone, msize_t msize) { // 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; } @@ -1730,13 +2280,12 @@ small_malloc_from_free_list(szone_t *szone, msize_t msize) { } 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; @@ -1744,62 +2293,65 @@ try_small_from_end: 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; } @@ -1810,15 +2362,17 @@ small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_reque 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); @@ -1828,32 +2382,35 @@ 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) { - // 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); @@ -1862,11 +2419,14 @@ free_small(szone_t *szone, void *ptr, small_region_t *small_region) { } 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)); } @@ -1876,61 +2436,68 @@ 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) { - 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; @@ -1944,68 +2511,84 @@ small_free_list_check(szone_t *szone, grain_t grain) { #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 @@ -2013,35 +2596,39 @@ large_entries_rehash_after_entry_no_lock(szone_t *szone, } 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); @@ -2049,19 +2636,22 @@ large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, } 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); } @@ -2073,31 +2663,28 @@ large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate) { } } +// 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(); } @@ -2105,102 +2692,40 @@ large_free_no_lock(szone_t *szone, large_entry_t *entry) { 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); @@ -2211,36 +2736,48 @@ large_in_use_enumerator(task_t task, void *context, /********************* 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)); } @@ -2248,7 +2785,6 @@ huge_entry_append(szone_t *szone, huge_entry_t huge) { 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! @@ -2256,53 +2792,58 @@ 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) { +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(); } @@ -2310,54 +2851,49 @@ large_and_huge_malloc(szone_t *szone, unsigned num_pages) { 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(); } @@ -2365,50 +2901,49 @@ free_large_or_huge(szone_t *szone, void *ptr) { } 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. @@ -2425,19 +2960,22 @@ try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, s * 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 */ @@ -2446,12 +2984,11 @@ try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, s 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 */ @@ -2466,7 +3003,6 @@ try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, s // 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; } @@ -2474,124 +3010,157 @@ try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, s /********************* 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) { @@ -2600,7 +3169,6 @@ szone_size(szone_t *szone, const void *ptr) { 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); @@ -2610,92 +3178,113 @@ szone_size(szone_t *szone, const void *ptr) { } 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 @@ -2704,27 +3293,33 @@ szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count) 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; } @@ -2733,80 +3328,92 @@ szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count) { 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; } } @@ -2816,53 +3423,61 @@ unsigned szone_check_start = 0; 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); @@ -2870,39 +3485,37 @@ szone_check_all(szone_t *szone, const char *function) { } 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); @@ -2911,9 +3524,11 @@ szone_ptr_in_use_enumerator(task_t task, void *context, // 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; @@ -2932,17 +3547,22 @@ scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count) } 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++; } @@ -2951,35 +3571,40 @@ szone_print(szone_t *szone, boolean_t verbose) { 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; @@ -3008,11 +3633,22 @@ scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsign } 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; @@ -3030,36 +3666,31 @@ static const struct malloc_introspection_t szone_introspect = { }; // 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; @@ -3071,6 +3702,17 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) { 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 @@ -3080,16 +3722,7 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) { #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; } @@ -3106,12 +3739,13 @@ create_scalable_zone(size_t initial_size, unsigned debug_flags) { * 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; @@ -3120,24 +3754,29 @@ typedef struct { } 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; } @@ -3149,11 +3788,13 @@ frozen_realloc(szone_t *zone, void *ptr, size_t new_size) { } 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 ************/ @@ -3171,8 +3812,9 @@ frozen_destroy(szone_t *zone) { * 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; @@ -3188,9 +3830,11 @@ malloc_freezedry(void) { 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. */ @@ -3201,12 +3845,13 @@ malloc_freezedry(void) { 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) { @@ -3233,3 +3878,4 @@ malloc_jumpstart(int cookie) { return 0; } + diff --git a/gen/scalable_malloc.h b/gen/scalable_malloc.h index 6484875..3d1b737 100644 --- a/gen/scalable_malloc.h +++ b/gen/scalable_malloc.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/setlogin.c b/gen/setlogin.c index 174dea7..71d56b7 100644 --- a/gen/setlogin.c +++ b/gen/setlogin.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/sigsetops.c b/gen/sigsetops.c index 827e3c6..cdfb895 100644 --- a/gen/sigsetops.c +++ b/gen/sigsetops.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/stack_logging.c b/gen/stack_logging.c index 10ccc97..3f9da9c 100644 --- a/gen/stack_logging.c +++ b/gen/stack_logging.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -38,7 +40,7 @@ static inline void *allocate_pages(unsigned bytes) { 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; @@ -55,9 +57,9 @@ static inline void copy_pages(const void *source, void *dest, unsigned bytes) { /*************** 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)); @@ -72,7 +74,7 @@ static void *next_frame_address(void *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)); @@ -87,7 +89,7 @@ static void *next_frame_address(void *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 @@ -107,7 +109,7 @@ void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb) { 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; diff --git a/gen/stack_logging.h b/gen/stack_logging.h index cff23a7..0da7e1d 100644 --- a/gen/stack_logging.h +++ b/gen/stack_logging.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -21,7 +23,7 @@ * @APPLE_LICENSE_HEADER_END@ */ -#import +#import #define stack_logging_type_free 0 #define stack_logging_type_generic 1 /* anything that is not allocation/deallocation */ diff --git a/gen/strtofflags.c b/gen/strtofflags.c index 4e19ba3..fdf353a 100644 --- a/gen/strtofflags.c +++ b/gen/strtofflags.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/sysconf.3 b/gen/sysconf.3 deleted file mode 100644 index 4cb8187..0000000 --- a/gen/sysconf.3 +++ /dev/null @@ -1,211 +0,0 @@ -.\" 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 . diff --git a/gen/sysconf.c b/gen/sysconf.c deleted file mode 100644 index e1a0f9c..0000000 --- a/gen/sysconf.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include -#include - -/* - * 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); -} diff --git a/gen/syslog.c b/gen/syslog.c index f607098..216ce85 100644 --- a/gen/syslog.c +++ b/gen/syslog.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/uname.c b/gen/uname.c index c5b2a14..979e7a3 100644 --- a/gen/uname.c +++ b/gen/uname.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/gen/wordexp.3 b/gen/wordexp.3 new file mode 100644 index 0000000..642e249 --- /dev/null +++ b/gen/wordexp.3 @@ -0,0 +1,177 @@ +.\" +.\" 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. diff --git a/gen/wordexp.c b/gen/wordexp.c new file mode 100644 index 0000000..a75b944 --- /dev/null +++ b/gen/wordexp.c @@ -0,0 +1,263 @@ +/* + * 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 +#include +#include + +#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 +#include +#include + +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 */ diff --git a/gen/zone.c b/gen/zone.c index 3e20296..c62d69b 100644 --- a/gen/zone.c +++ b/gen/zone.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -63,18 +65,18 @@ void NXDestroyZone(malloc_zone_t *zone) { 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) { @@ -95,13 +97,13 @@ void _NXMallocDumpZones(void) { 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; } @@ -109,13 +111,13 @@ malloc_zone_t *NXCreateChildZone(malloc_zone_t *parentzone, size_t startsize, si // 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"); } diff --git a/gmon/Makefile.inc b/gmon/Makefile.inc index 1e69c1d..cd920f2 100644 --- a/gmon/Makefile.inc +++ b/gmon/Makefile.inc @@ -4,7 +4,7 @@ # gmon sources .PATH: ${.CURDIR}/gmon -SRCS+= gmon.c +MISRCS+= gmon.c #.if ${LIB} == "c" #MAN+= moncontrol.3 @@ -16,7 +16,9 @@ SRCS+= gmon.c 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 diff --git a/gmon/gmon.c b/gmon/gmon.c index a085e09..b18daab 100644 --- a/gmon/gmon.c +++ b/gmon/gmon.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -364,6 +366,9 @@ char *highpc) 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 @@ -396,6 +401,8 @@ void) 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); diff --git a/i386/gen/Makefile.inc b/i386/gen/Makefile.inc index 21658c7..dde753d 100644 --- a/i386/gen/Makefile.inc +++ b/i386/gen/Makefile.inc @@ -1,9 +1,5 @@ -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 diff --git a/i386/gen/bcopy.s b/i386/gen/bcopy.s deleted file mode 100644 index d9c3bdf..0000000 --- a/i386/gen/bcopy.s +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 - -#include - - 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 diff --git a/i386/gen/bzero.s b/i386/gen/bzero.s deleted file mode 100644 index db162dd..0000000 --- a/i386/gen/bzero.s +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 - -#include - - TEXT - ALIGN - -LEAF(_bzero,0) - movl $(_COMM_PAGE_BZERO), %eax - jmpl %eax diff --git a/i386/gen/ecvt.c b/i386/gen/ecvt.c index 755af1f..5da9f78 100644 --- a/i386/gen/ecvt.c +++ b/i386/gen/ecvt.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/gen/icacheinval.s b/i386/gen/icacheinval.s index db86406..d66522d 100644 --- a/i386/gen/icacheinval.s +++ b/i386/gen/icacheinval.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/gen/isinf.c b/i386/gen/isinf.c deleted file mode 100644 index 9692440..0000000 --- a/i386/gen/isinf.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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); -} diff --git a/i386/gen/mcount.s b/i386/gen/mcount.s index bb0e7d3..82d7a89 100644 --- a/i386/gen/mcount.s +++ b/i386/gen/mcount.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/gen/memcpy.s b/i386/gen/memcpy.s deleted file mode 100644 index 8160b02..0000000 --- a/i386/gen/memcpy.s +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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" diff --git a/i386/gen/memmove.s b/i386/gen/memmove.s deleted file mode 100644 index 50fd4e2..0000000 --- a/i386/gen/memmove.s +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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" diff --git a/i386/gen/setjmperr.c b/i386/gen/setjmperr.c index 8dc2753..79314ef 100644 --- a/i386/gen/setjmperr.c +++ b/i386/gen/setjmperr.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/mach/Makefile.inc b/i386/mach/Makefile.inc index bf4f67b..12bb5f4 100644 --- a/i386/mach/Makefile.inc +++ b/i386/mach/Makefile.inc @@ -1 +1,2 @@ -SRCS += mach_absolute_time.c +.PATH: ${.CURDIR}/i386/mach +MDSRCS += mach_absolute_time.c diff --git a/i386/mach/mach_absolute_time.c b/i386/mach/mach_absolute_time.c index 6c3dcb3..dbe7325 100644 --- a/i386/mach/mach_absolute_time.c +++ b/i386/mach/mach_absolute_time.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,41 +26,25 @@ #include #include #include +#define __APPLE_API_PRIVATE +#include +#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 diff --git a/i386/pthreads/Makefile.inc b/i386/pthreads/Makefile.inc index f4f5b0a..f2cfb8f 100644 --- a/i386/pthreads/Makefile.inc +++ b/i386/pthreads/Makefile.inc @@ -1,3 +1,4 @@ +.PATH: ${.CURDIR}/i386/pthreads MDSRCS += \ init_cpu_capabilities.c \ get_cpu_capabilities.s \ diff --git a/i386/pthreads/get_cpu_capabilities.s b/i386/pthreads/get_cpu_capabilities.s index 51cd899..8803b6c 100644 --- a/i386/pthreads/get_cpu_capabilities.s +++ b/i386/pthreads/get_cpu_capabilities.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/pthreads/init_cpu_capabilities.c b/i386/pthreads/init_cpu_capabilities.c index 94e5d33..49a7e25 100644 --- a/i386/pthreads/init_cpu_capabilities.c +++ b/i386/pthreads/init_cpu_capabilities.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/pthreads/pthread_getspecific.s b/i386/pthreads/pthread_getspecific.s index 52c40bf..3c4bf35 100644 --- a/i386/pthreads/pthread_getspecific.s +++ b/i386/pthreads/pthread_getspecific.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/pthreads/pthread_self.s b/i386/pthreads/pthread_self.s index 5f9083c..8e2bace 100644 --- a/i386/pthreads/pthread_self.s +++ b/i386/pthreads/pthread_self.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/pthreads/pthread_set_self.s b/i386/pthreads/pthread_set_self.s index 3e3b519..6d51d1d 100644 --- a/i386/pthreads/pthread_set_self.s +++ b/i386/pthreads/pthread_set_self.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/string/Makefile.inc b/i386/string/Makefile.inc index e8b30d7..4c6264d 100644 --- a/i386/string/Makefile.inc +++ b/i386/string/Makefile.inc @@ -4,8 +4,9 @@ # # # -#MDSRCS += \ -# strcmp.s - - - +.PATH: ${.CURDIR}/i386/string +MDSRCS += bcopy.s \ + bzero.s \ + memcpy.s \ + memmove.s \ + strcmp.s diff --git a/i386/string/bcopy.s b/i386/string/bcopy.s new file mode 100644 index 0000000..35dbe10 --- /dev/null +++ b/i386/string/bcopy.s @@ -0,0 +1,50 @@ +/* + * 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 + +#include + + 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 diff --git a/i386/string/bzero.s b/i386/string/bzero.s new file mode 100644 index 0000000..d3cbc5d --- /dev/null +++ b/i386/string/bzero.s @@ -0,0 +1,40 @@ +/* + * 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 + +#include + + TEXT + ALIGN + +LEAF(_bzero,0) + movl $(_COMM_PAGE_BZERO), %eax + jmpl %eax diff --git a/i386/string/memcpy.s b/i386/string/memcpy.s new file mode 100644 index 0000000..7ad1ed8 --- /dev/null +++ b/i386/string/memcpy.s @@ -0,0 +1,35 @@ +/* + * 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" diff --git a/i386/string/memmove.s b/i386/string/memmove.s new file mode 100644 index 0000000..473065d --- /dev/null +++ b/i386/string/memmove.s @@ -0,0 +1,35 @@ +/* + * 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" diff --git a/i386/string/strcmp.s b/i386/string/strcmp.s index a21cea6..781f6de 100644 --- a/i386/string/strcmp.s +++ b/i386/string/strcmp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/ATPgetreq.s b/i386/sys/ATPgetreq.s index e74c2e1..171e9f4 100644 --- a/i386/sys/ATPgetreq.s +++ b/i386/sys/ATPgetreq.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/ATPgetrsp.s b/i386/sys/ATPgetrsp.s index 0ef8629..c4482df 100644 --- a/i386/sys/ATPgetrsp.s +++ b/i386/sys/ATPgetrsp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/ATPsndreq.s b/i386/sys/ATPsndreq.s index 28b7f37..feb7464 100644 --- a/i386/sys/ATPsndreq.s +++ b/i386/sys/ATPsndreq.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/ATPsndrsp.s b/i386/sys/ATPsndrsp.s index b260299..251e4b8 100644 --- a/i386/sys/ATPsndrsp.s +++ b/i386/sys/ATPsndrsp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/ATgetmsg.s b/i386/sys/ATgetmsg.s index 3d874d0..7d8bd69 100644 --- a/i386/sys/ATgetmsg.s +++ b/i386/sys/ATgetmsg.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/ATputmsg.s b/i386/sys/ATputmsg.s index 7f25382..5b98ff5 100644 --- a/i386/sys/ATputmsg.s +++ b/i386/sys/ATputmsg.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/ATsocket.s b/i386/sys/ATsocket.s index b503df9..5b16421 100644 --- a/i386/sys/ATsocket.s +++ b/i386/sys/ATsocket.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/Makefile.inc b/i386/sys/Makefile.inc index 4dd00f0..545e91e 100644 --- a/i386/sys/Makefile.inc +++ b/i386/sys/Makefile.inc @@ -1,4 +1,5 @@ -SRCS+= ATPgetreq.s \ +.PATH: ${.CURDIR}/i386/sys +MDSRCS+= ATPgetreq.s \ ATPgetrsp.s \ ATPsndreq.s \ ATPsndrsp.s \ @@ -26,6 +27,7 @@ SRCS+= ATPgetreq.s \ audit.s \ auditctl.s \ auditon.s \ + auditsvc.s \ bind.s \ cerror.s \ chdir.s \ @@ -45,11 +47,15 @@ SRCS+= ATPgetreq.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 \ @@ -70,17 +76,18 @@ SRCS+= ATPgetreq.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 \ @@ -89,9 +96,11 @@ SRCS+= ATPgetreq.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 \ @@ -123,12 +132,12 @@ SRCS+= ATPgetreq.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 \ @@ -137,6 +146,7 @@ SRCS+= ATPgetreq.s \ reboot.s \ recvfrom.s \ recvmsg.s \ + removexattr.s \ rename.s \ reset_shared_file.s \ revoke.s \ @@ -176,6 +186,7 @@ SRCS+= ATPgetreq.s \ setsockopt.s \ settimeofday.s \ setuid.s \ + setxattr.s \ shmat.s \ shmctl.s \ shmdt.s \ @@ -207,3 +218,9 @@ SRCS+= ATPgetreq.s \ wait4.s \ write.s \ writev.s + +.for _src in fhopen.s getfh.s nfsclnt.s +CFLAGS-${_src} += -DNFSCLIENT +.endfor + +CFLAGS-nfssvc.s += -DNFSSERVER diff --git a/i386/sys/SYS.h b/i386/sys/SYS.h index f643887..998e2cf 100644 --- a/i386/sys/SYS.h +++ b/i386/sys/SYS.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -33,7 +35,6 @@ * Created. */ -#define KERNEL_PRIVATE 1 /* * Headers */ diff --git a/i386/sys/_exit.s b/i386/sys/_exit.s index ab99c5f..d8c3f02 100644 --- a/i386/sys/_exit.s +++ b/i386/sys/_exit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/_getlogin.s b/i386/sys/_getlogin.s index fd865ea..bf8d1ca 100644 --- a/i386/sys/_getlogin.s +++ b/i386/sys/_getlogin.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/_pthread_kill.s b/i386/sys/_pthread_kill.s index 04d70a4..eaa2a6e 100644 --- a/i386/sys/_pthread_kill.s +++ b/i386/sys/_pthread_kill.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/_setjmp.s b/i386/sys/_setjmp.s index 8513cad..ea33703 100644 --- a/i386/sys/_setjmp.s +++ b/i386/sys/_setjmp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/_setlogin.s b/i386/sys/_setlogin.s index f4a599f..8eddd51 100644 --- a/i386/sys/_setlogin.s +++ b/i386/sys/_setlogin.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/_sysctl.s b/i386/sys/_sysctl.s index b9276e3..1d9333b 100644 --- a/i386/sys/_sysctl.s +++ b/i386/sys/_sysctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/accept.s b/i386/sys/accept.s index c2e2f1a..c889bb8 100644 --- a/i386/sys/accept.s +++ b/i386/sys/accept.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/access.s b/i386/sys/access.s index 6d19163..e50c46f 100644 --- a/i386/sys/access.s +++ b/i386/sys/access.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/acct.s b/i386/sys/acct.s index cfae023..03e2c98 100644 --- a/i386/sys/acct.s +++ b/i386/sys/acct.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/add_profil.s b/i386/sys/add_profil.s index 485a112..5cccebc 100644 --- a/i386/sys/add_profil.s +++ b/i386/sys/add_profil.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/adjtime.s b/i386/sys/adjtime.s index 8aa59f8..44f0523 100644 --- a/i386/sys/adjtime.s +++ b/i386/sys/adjtime.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/aio_cancel.s b/i386/sys/aio_cancel.s index 00d9942..1f42173 100644 --- a/i386/sys/aio_cancel.s +++ b/i386/sys/aio_cancel.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/aio_error.s b/i386/sys/aio_error.s index 3bc756b..ca41605 100644 --- a/i386/sys/aio_error.s +++ b/i386/sys/aio_error.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/aio_fsync.s b/i386/sys/aio_fsync.s index 6c378f6..3d12301 100644 --- a/i386/sys/aio_fsync.s +++ b/i386/sys/aio_fsync.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/aio_read.s b/i386/sys/aio_read.s index cb85324..a34702d 100644 --- a/i386/sys/aio_read.s +++ b/i386/sys/aio_read.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/aio_return.s b/i386/sys/aio_return.s index b506812..ebe1885 100644 --- a/i386/sys/aio_return.s +++ b/i386/sys/aio_return.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/aio_suspend.s b/i386/sys/aio_suspend.s index 4137a27..6654fff 100644 --- a/i386/sys/aio_suspend.s +++ b/i386/sys/aio_suspend.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/aio_write.s b/i386/sys/aio_write.s index a82151e..66c5c20 100644 --- a/i386/sys/aio_write.s +++ b/i386/sys/aio_write.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/audit.s b/i386/sys/audit.s index 04f7d6d..3bb8e84 100644 --- a/i386/sys/audit.s +++ b/i386/sys/audit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/auditctl.s b/i386/sys/auditctl.s index b557464..5fea33a 100644 --- a/i386/sys/auditctl.s +++ b/i386/sys/auditctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/auditon.s b/i386/sys/auditon.s index 4cff057..33b9334 100644 --- a/i386/sys/auditon.s +++ b/i386/sys/auditon.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/auditsvc.s b/i386/sys/auditsvc.s new file mode 100644 index 0000000..83c3017 --- /dev/null +++ b/i386/sys/auditsvc.s @@ -0,0 +1,28 @@ +/* + * 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 diff --git a/i386/sys/bind.s b/i386/sys/bind.s index fadf791..c6b5e6b 100644 --- a/i386/sys/bind.s +++ b/i386/sys/bind.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/cerror.s b/i386/sys/cerror.s index 53d164d..f2c82db 100644 --- a/i386/sys/cerror.s +++ b/i386/sys/cerror.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/chdir.s b/i386/sys/chdir.s index 0a086d1..5b5aff7 100644 --- a/i386/sys/chdir.s +++ b/i386/sys/chdir.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/checkuseraccess.s b/i386/sys/checkuseraccess.s index e1d57dc..78dcd9b 100644 --- a/i386/sys/checkuseraccess.s +++ b/i386/sys/checkuseraccess.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/chflags.s b/i386/sys/chflags.s index 3a19cfb..b5c8d5f 100644 --- a/i386/sys/chflags.s +++ b/i386/sys/chflags.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/chmod.s b/i386/sys/chmod.s index 912ffa5..105a1a2 100644 --- a/i386/sys/chmod.s +++ b/i386/sys/chmod.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/chown.s b/i386/sys/chown.s index 6683f31..678eb86 100644 --- a/i386/sys/chown.s +++ b/i386/sys/chown.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/chroot.s b/i386/sys/chroot.s index 61676fd..5963ca4 100644 --- a/i386/sys/chroot.s +++ b/i386/sys/chroot.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/close.s b/i386/sys/close.s index e43df39..ecbcd7d 100644 --- a/i386/sys/close.s +++ b/i386/sys/close.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/connect.s b/i386/sys/connect.s index e1ae1db..e521145 100644 --- a/i386/sys/connect.s +++ b/i386/sys/connect.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/dup.s b/i386/sys/dup.s index 62b58d4..cda88c8 100644 --- a/i386/sys/dup.s +++ b/i386/sys/dup.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/dup2.s b/i386/sys/dup2.s index 7e13b9b..85b835a 100644 --- a/i386/sys/dup2.s +++ b/i386/sys/dup2.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/exchangedata.s b/i386/sys/exchangedata.s index 45a7326..2a27cf8 100644 --- a/i386/sys/exchangedata.s +++ b/i386/sys/exchangedata.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/execve.s b/i386/sys/execve.s index e6a6356..cb00042 100644 --- a/i386/sys/execve.s +++ b/i386/sys/execve.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fchdir.s b/i386/sys/fchdir.s index fd86bd2..94f9ddc 100644 --- a/i386/sys/fchdir.s +++ b/i386/sys/fchdir.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fchflags.s b/i386/sys/fchflags.s index 74c650a..940b319 100644 --- a/i386/sys/fchflags.s +++ b/i386/sys/fchflags.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fchmod.s b/i386/sys/fchmod.s index c784388..fe9b69b 100644 --- a/i386/sys/fchmod.s +++ b/i386/sys/fchmod.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fchown.s b/i386/sys/fchown.s index 2a5fa0c..80de605 100644 --- a/i386/sys/fchown.s +++ b/i386/sys/fchown.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fcntl.s b/i386/sys/fcntl.s index fcda4a5..d324ae2 100644 --- a/i386/sys/fcntl.s +++ b/i386/sys/fcntl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fgetxattr.s b/i386/sys/fgetxattr.s new file mode 100644 index 0000000..30fc3eb --- /dev/null +++ b/i386/sys/fgetxattr.s @@ -0,0 +1,28 @@ +/* + * 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 diff --git a/i386/sys/fhopen.s b/i386/sys/fhopen.s index d94e9c7..c886e3c 100644 --- a/i386/sys/fhopen.s +++ b/i386/sys/fhopen.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/flistxattr.s b/i386/sys/flistxattr.s new file mode 100644 index 0000000..7c79e70 --- /dev/null +++ b/i386/sys/flistxattr.s @@ -0,0 +1,28 @@ +/* + * 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 diff --git a/i386/sys/flock.s b/i386/sys/flock.s index ee2c2a8..c0553b7 100644 --- a/i386/sys/flock.s +++ b/i386/sys/flock.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fork.s b/i386/sys/fork.s index ca4506e..54badfd 100644 --- a/i386/sys/fork.s +++ b/i386/sys/fork.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fpathconf.s b/i386/sys/fpathconf.s index 4d6824c..f909212 100644 --- a/i386/sys/fpathconf.s +++ b/i386/sys/fpathconf.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fremovexattr.s b/i386/sys/fremovexattr.s new file mode 100644 index 0000000..de41403 --- /dev/null +++ b/i386/sys/fremovexattr.s @@ -0,0 +1,28 @@ +/* + * 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 diff --git a/i386/sys/fsctl.s b/i386/sys/fsctl.s index 763f145..282d100 100644 --- a/i386/sys/fsctl.s +++ b/i386/sys/fsctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fsetxattr.s b/i386/sys/fsetxattr.s new file mode 100644 index 0000000..5bf55e6 --- /dev/null +++ b/i386/sys/fsetxattr.s @@ -0,0 +1,28 @@ +/* + * 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 diff --git a/i386/sys/fstat.s b/i386/sys/fstat.s index 869c4b9..6f67445 100644 --- a/i386/sys/fstat.s +++ b/i386/sys/fstat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fstatfs.s b/i386/sys/fstatfs.s index 0bf2239..1b1422e 100644 --- a/i386/sys/fstatfs.s +++ b/i386/sys/fstatfs.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fstatv.s b/i386/sys/fstatv.s index d23315b..169a8f4 100644 --- a/i386/sys/fstatv.s +++ b/i386/sys/fstatv.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/fsync.s b/i386/sys/fsync.s index 0433dcd..73afb0d 100644 --- a/i386/sys/fsync.s +++ b/i386/sys/fsync.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/ftruncate.s b/i386/sys/ftruncate.s index 717be65..7147750 100644 --- a/i386/sys/ftruncate.s +++ b/i386/sys/ftruncate.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/futimes.s b/i386/sys/futimes.s index 6a01fae..c989753 100644 --- a/i386/sys/futimes.s +++ b/i386/sys/futimes.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getattrlist.s b/i386/sys/getattrlist.s index 75520e2..23657af 100644 --- a/i386/sys/getattrlist.s +++ b/i386/sys/getattrlist.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getaudit.s b/i386/sys/getaudit.s index 11e5a6e..9d9abb3 100644 --- a/i386/sys/getaudit.s +++ b/i386/sys/getaudit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getaudit_addr.s b/i386/sys/getaudit_addr.s index cdc345f..aa74b66 100644 --- a/i386/sys/getaudit_addr.s +++ b/i386/sys/getaudit_addr.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getauid.s b/i386/sys/getauid.s index 83a3590..e6b069e 100644 --- a/i386/sys/getauid.s +++ b/i386/sys/getauid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getdirentries.s b/i386/sys/getdirentries.s index 95c032f..5d3aaa1 100644 --- a/i386/sys/getdirentries.s +++ b/i386/sys/getdirentries.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getdirentriesattr.s b/i386/sys/getdirentriesattr.s index a0d321b..2971894 100644 --- a/i386/sys/getdirentriesattr.s +++ b/i386/sys/getdirentriesattr.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getegid.s b/i386/sys/getegid.s index 2f6279e..e77b15a 100644 --- a/i386/sys/getegid.s +++ b/i386/sys/getegid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -25,6 +27,5 @@ */ #include "SYS.h" -PSEUDO(getegid, getgid, 0) - movl %edx, %eax - ret // egid = getegid(); +UNIX_SYSCALL(getegid, 0) + ret diff --git a/i386/sys/geteuid.s b/i386/sys/geteuid.s index b0e1563..7cf7644 100644 --- a/i386/sys/geteuid.s +++ b/i386/sys/geteuid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -25,6 +27,5 @@ */ #include "SYS.h" -PSEUDO(geteuid, getuid, 0) - movl %edx, %eax - ret // euid = geteuid(); +UNIX_SYSCALL(geteuid, 0) + ret diff --git a/i386/sys/getfh.s b/i386/sys/getfh.s index 09c4dfe..0b736f6 100644 --- a/i386/sys/getfh.s +++ b/i386/sys/getfh.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getfsstat.s b/i386/sys/getfsstat.s index b0f24a9..73e4479 100644 --- a/i386/sys/getfsstat.s +++ b/i386/sys/getfsstat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getgid.s b/i386/sys/getgid.s index 5c4d7a7..f5d1f21 100644 --- a/i386/sys/getgid.s +++ b/i386/sys/getgid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getgroups.s b/i386/sys/getgroups.s index cc4322a..19f9d72 100644 --- a/i386/sys/getgroups.s +++ b/i386/sys/getgroups.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getitimer.s b/i386/sys/getitimer.s index 9328751..b4d63d1 100644 --- a/i386/sys/getitimer.s +++ b/i386/sys/getitimer.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getpeername.s b/i386/sys/getpeername.s index 6e09c69..4ad2f1a 100644 --- a/i386/sys/getpeername.s +++ b/i386/sys/getpeername.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getpgid.s b/i386/sys/getpgid.s index b0d52f7..5c4db90 100644 --- a/i386/sys/getpgid.s +++ b/i386/sys/getpgid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getpgrp.s b/i386/sys/getpgrp.s index 6a64c7d..91b44c0 100644 --- a/i386/sys/getpgrp.s +++ b/i386/sys/getpgrp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getpid.s b/i386/sys/getpid.s index 4a4e4d1..5e75fc2 100644 --- a/i386/sys/getpid.s +++ b/i386/sys/getpid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getppid.s b/i386/sys/getppid.s index 728577a..b8d6fdf 100644 --- a/i386/sys/getppid.s +++ b/i386/sys/getppid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -25,6 +27,5 @@ */ #include "SYS.h" -PSEUDO(getppid, getpid, 0) - movl %edx, %eax - ret // ppid = getppid(); +UNIX_SYSCALL(getppid,0) + ret diff --git a/i386/sys/getpriority.s b/i386/sys/getpriority.s index af90ad9..b786526 100644 --- a/i386/sys/getpriority.s +++ b/i386/sys/getpriority.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getrlimit.s b/i386/sys/getrlimit.s index 57e56d1..7f5d2c1 100644 --- a/i386/sys/getrlimit.s +++ b/i386/sys/getrlimit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getrusage.s b/i386/sys/getrusage.s index e15e628..d74720f 100644 --- a/i386/sys/getrusage.s +++ b/i386/sys/getrusage.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getsid.s b/i386/sys/getsid.s index 4afddff..2fe63e7 100644 --- a/i386/sys/getsid.s +++ b/i386/sys/getsid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getsockname.s b/i386/sys/getsockname.s index 82ecb70..192d98b 100644 --- a/i386/sys/getsockname.s +++ b/i386/sys/getsockname.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getsockopt.s b/i386/sys/getsockopt.s index 269a334..c471919 100644 --- a/i386/sys/getsockopt.s +++ b/i386/sys/getsockopt.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getuid.s b/i386/sys/getuid.s index 2b36b4f..115402d 100644 --- a/i386/sys/getuid.s +++ b/i386/sys/getuid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/getxattr.s b/i386/sys/getxattr.s new file mode 100644 index 0000000..37db9b2 --- /dev/null +++ b/i386/sys/getxattr.s @@ -0,0 +1,28 @@ +/* + * 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 diff --git a/i386/sys/ioctl.s b/i386/sys/ioctl.s index 528950a..556272a 100644 --- a/i386/sys/ioctl.s +++ b/i386/sys/ioctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/issetugid.s b/i386/sys/issetugid.s index d986045..29f3686 100644 --- a/i386/sys/issetugid.s +++ b/i386/sys/issetugid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/kevent.s b/i386/sys/kevent.s index cedc7c0..0470823 100644 --- a/i386/sys/kevent.s +++ b/i386/sys/kevent.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/kill.s b/i386/sys/kill.s index 59e17ad..e2efe34 100644 --- a/i386/sys/kill.s +++ b/i386/sys/kill.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/kqueue.s b/i386/sys/kqueue.s index 398d766..044c690 100644 --- a/i386/sys/kqueue.s +++ b/i386/sys/kqueue.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/kqueue_from_portset_np.s b/i386/sys/kqueue_from_portset_np.s index b2e4697..c44cc2b 100644 --- a/i386/sys/kqueue_from_portset_np.s +++ b/i386/sys/kqueue_from_portset_np.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/kqueue_portset_np.s b/i386/sys/kqueue_portset_np.s index 1e782ea..a61c9c0 100644 --- a/i386/sys/kqueue_portset_np.s +++ b/i386/sys/kqueue_portset_np.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/ktrace.s b/i386/sys/ktrace.s index 77bd931..59baa16 100644 --- a/i386/sys/ktrace.s +++ b/i386/sys/ktrace.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/lchown.s b/i386/sys/lchown.s new file mode 100644 index 0000000..9e293e6 --- /dev/null +++ b/i386/sys/lchown.s @@ -0,0 +1,28 @@ +/* + * 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 diff --git a/i386/sys/link.s b/i386/sys/link.s index 820375a..91eaa3b 100644 --- a/i386/sys/link.s +++ b/i386/sys/link.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/lio_listio.s b/i386/sys/lio_listio.s index b5fc01f..468c378 100644 --- a/i386/sys/lio_listio.s +++ b/i386/sys/lio_listio.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/listen.s b/i386/sys/listen.s index 8a5ca19..a99b281 100644 --- a/i386/sys/listen.s +++ b/i386/sys/listen.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/listxattr.s b/i386/sys/listxattr.s new file mode 100644 index 0000000..ebff304 --- /dev/null +++ b/i386/sys/listxattr.s @@ -0,0 +1,28 @@ +/* + * 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 diff --git a/i386/sys/load_shared_file.s b/i386/sys/load_shared_file.s index 900bdf8..5c22f92 100644 --- a/i386/sys/load_shared_file.s +++ b/i386/sys/load_shared_file.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/lseek.s b/i386/sys/lseek.s index dfa0b22..dd68b57 100644 --- a/i386/sys/lseek.s +++ b/i386/sys/lseek.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/lstat.s b/i386/sys/lstat.s index b76854e..c9850eb 100644 --- a/i386/sys/lstat.s +++ b/i386/sys/lstat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/lstatv.s b/i386/sys/lstatv.s index d3994d4..52f07e5 100644 --- a/i386/sys/lstatv.s +++ b/i386/sys/lstatv.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/madvise.s b/i386/sys/madvise.s index 849e702..2f1463b 100644 --- a/i386/sys/madvise.s +++ b/i386/sys/madvise.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/mincore.s b/i386/sys/mincore.s index 6b5871e..1a6b5d2 100644 --- a/i386/sys/mincore.s +++ b/i386/sys/mincore.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/minherit.s b/i386/sys/minherit.s index 84a5190..e433227 100644 --- a/i386/sys/minherit.s +++ b/i386/sys/minherit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/mkcomplex.s b/i386/sys/mkcomplex.s index 45285c6..d0f5ae2 100644 --- a/i386/sys/mkcomplex.s +++ b/i386/sys/mkcomplex.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/mkdir.s b/i386/sys/mkdir.s index df857a7..eb7eac8 100644 --- a/i386/sys/mkdir.s +++ b/i386/sys/mkdir.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/mkfifo.s b/i386/sys/mkfifo.s index f7b74df..7b54fe8 100644 --- a/i386/sys/mkfifo.s +++ b/i386/sys/mkfifo.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/mknod.s b/i386/sys/mknod.s index 9170403..e98e111 100644 --- a/i386/sys/mknod.s +++ b/i386/sys/mknod.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/mlock.s b/i386/sys/mlock.s index 6f0b694..845dd3e 100644 --- a/i386/sys/mlock.s +++ b/i386/sys/mlock.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/mlockall.s b/i386/sys/mlockall.s index e85392c..812ff5a 100644 --- a/i386/sys/mlockall.s +++ b/i386/sys/mlockall.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/mmap.s b/i386/sys/mmap.s index e5322fb..3965e8f 100644 --- a/i386/sys/mmap.s +++ b/i386/sys/mmap.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/mount.s b/i386/sys/mount.s index 0dd8b59..497b50e 100644 --- a/i386/sys/mount.s +++ b/i386/sys/mount.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/mprotect.s b/i386/sys/mprotect.s index 403b806..d3e4f49 100644 --- a/i386/sys/mprotect.s +++ b/i386/sys/mprotect.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/msgctl.s b/i386/sys/msgctl.s index 87f891c..64d6227 100644 --- a/i386/sys/msgctl.s +++ b/i386/sys/msgctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/msgget.s b/i386/sys/msgget.s index b707393..c43f7bc 100644 --- a/i386/sys/msgget.s +++ b/i386/sys/msgget.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/msgrcv.s b/i386/sys/msgrcv.s index 265f187..7e7a3e5 100644 --- a/i386/sys/msgrcv.s +++ b/i386/sys/msgrcv.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/msgsnd.s b/i386/sys/msgsnd.s index 7421a4c..d6fb6f0 100644 --- a/i386/sys/msgsnd.s +++ b/i386/sys/msgsnd.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/msgsys.s b/i386/sys/msgsys.s index 78a8809..9f0e6e5 100644 --- a/i386/sys/msgsys.s +++ b/i386/sys/msgsys.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/msync.s b/i386/sys/msync.s index 231f79c..1bae397 100644 --- a/i386/sys/msync.s +++ b/i386/sys/msync.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/munlock.s b/i386/sys/munlock.s index 2d0784b..2f982fc 100644 --- a/i386/sys/munlock.s +++ b/i386/sys/munlock.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/munlockall.s b/i386/sys/munlockall.s index 42dcd11..ec67337 100644 --- a/i386/sys/munlockall.s +++ b/i386/sys/munlockall.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/munmap.s b/i386/sys/munmap.s index bc402ac..4668a18 100644 --- a/i386/sys/munmap.s +++ b/i386/sys/munmap.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/new_system_shared_regions.s b/i386/sys/new_system_shared_regions.s index 38bb951..ce6c2ec 100644 --- a/i386/sys/new_system_shared_regions.s +++ b/i386/sys/new_system_shared_regions.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/nfsclnt.s b/i386/sys/nfsclnt.s index ebfc230..0e24250 100644 --- a/i386/sys/nfsclnt.s +++ b/i386/sys/nfsclnt.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/nfssvc.s b/i386/sys/nfssvc.s index 7c461e1..7ce8c60 100644 --- a/i386/sys/nfssvc.s +++ b/i386/sys/nfssvc.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/open.s b/i386/sys/open.s index 53748d1..3f9460d 100644 --- a/i386/sys/open.s +++ b/i386/sys/open.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/pathconf.s b/i386/sys/pathconf.s index dca4d89..54dba9b 100644 --- a/i386/sys/pathconf.s +++ b/i386/sys/pathconf.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/pipe.s b/i386/sys/pipe.s index bcb5883..268ec16 100644 --- a/i386/sys/pipe.s +++ b/i386/sys/pipe.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/posix_madvise.s b/i386/sys/posix_madvise.s index 5c1535c..e135d37 100644 --- a/i386/sys/posix_madvise.s +++ b/i386/sys/posix_madvise.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/pread.s b/i386/sys/pread.s index 55b145f..07afdd6 100644 --- a/i386/sys/pread.s +++ b/i386/sys/pread.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/profil.s b/i386/sys/profil.s index dfcb2a7..3fe0a48 100644 --- a/i386/sys/profil.s +++ b/i386/sys/profil.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/pthread_sigmask.s b/i386/sys/pthread_sigmask.s index 6f44630..4f5d617 100644 --- a/i386/sys/pthread_sigmask.s +++ b/i386/sys/pthread_sigmask.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/ptrace.s b/i386/sys/ptrace.s index 720e96b..78646d6 100644 --- a/i386/sys/ptrace.s +++ b/i386/sys/ptrace.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/pwrite.s b/i386/sys/pwrite.s index 26e7264..a371730 100644 --- a/i386/sys/pwrite.s +++ b/i386/sys/pwrite.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/quota.s b/i386/sys/quota.s index 254d961..48a6de7 100644 --- a/i386/sys/quota.s +++ b/i386/sys/quota.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/quotactl.s b/i386/sys/quotactl.s index 10de9cf..6f9512b 100644 --- a/i386/sys/quotactl.s +++ b/i386/sys/quotactl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/read.s b/i386/sys/read.s index 1714748..5e94588 100644 --- a/i386/sys/read.s +++ b/i386/sys/read.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/readlink.s b/i386/sys/readlink.s index aeaea49..84d70b6 100644 --- a/i386/sys/readlink.s +++ b/i386/sys/readlink.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/readv.s b/i386/sys/readv.s index eddb6af..2441791 100644 --- a/i386/sys/readv.s +++ b/i386/sys/readv.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/reboot.s b/i386/sys/reboot.s index d020b9c..36a8393 100644 --- a/i386/sys/reboot.s +++ b/i386/sys/reboot.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/recvfrom.s b/i386/sys/recvfrom.s index 2f42b79..73cc423 100644 --- a/i386/sys/recvfrom.s +++ b/i386/sys/recvfrom.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/recvmsg.s b/i386/sys/recvmsg.s index 28c7390..b08c72a 100644 --- a/i386/sys/recvmsg.s +++ b/i386/sys/recvmsg.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/removexattr.s b/i386/sys/removexattr.s new file mode 100644 index 0000000..8c1b86d --- /dev/null +++ b/i386/sys/removexattr.s @@ -0,0 +1,28 @@ +/* + * 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 diff --git a/i386/sys/rename.s b/i386/sys/rename.s index 43e59c2..be1591c 100644 --- a/i386/sys/rename.s +++ b/i386/sys/rename.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/reset_shared_file.s b/i386/sys/reset_shared_file.s index 264188a..116f722 100644 --- a/i386/sys/reset_shared_file.s +++ b/i386/sys/reset_shared_file.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/revoke.s b/i386/sys/revoke.s index bba4914..ccd1fe4 100644 --- a/i386/sys/revoke.s +++ b/i386/sys/revoke.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/rmdir.s b/i386/sys/rmdir.s index a03b1f6..0e43b17 100644 --- a/i386/sys/rmdir.s +++ b/i386/sys/rmdir.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/searchfs.s b/i386/sys/searchfs.s index 990308b..b20d918 100644 --- a/i386/sys/searchfs.s +++ b/i386/sys/searchfs.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/select.s b/i386/sys/select.s index ed61157..ffd04dc 100644 --- a/i386/sys/select.s +++ b/i386/sys/select.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sem_close.s b/i386/sys/sem_close.s index fc67d24..569f8ef 100644 --- a/i386/sys/sem_close.s +++ b/i386/sys/sem_close.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sem_destroy.s b/i386/sys/sem_destroy.s index a4f9542..0df9bd7 100644 --- a/i386/sys/sem_destroy.s +++ b/i386/sys/sem_destroy.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sem_getvalue.s b/i386/sys/sem_getvalue.s index 2dff035..388ab98 100644 --- a/i386/sys/sem_getvalue.s +++ b/i386/sys/sem_getvalue.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sem_init.s b/i386/sys/sem_init.s index 2e5fc53..e803611 100644 --- a/i386/sys/sem_init.s +++ b/i386/sys/sem_init.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sem_post.s b/i386/sys/sem_post.s index 6586aae..61844b3 100644 --- a/i386/sys/sem_post.s +++ b/i386/sys/sem_post.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sem_trywait.s b/i386/sys/sem_trywait.s index cf74144..0f41692 100644 --- a/i386/sys/sem_trywait.s +++ b/i386/sys/sem_trywait.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sem_wait.s b/i386/sys/sem_wait.s index 2f4e8e8..d6e5a1c 100644 --- a/i386/sys/sem_wait.s +++ b/i386/sys/sem_wait.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/semconfig.s b/i386/sys/semconfig.s index c1dbeba..6ebdeed 100644 --- a/i386/sys/semconfig.s +++ b/i386/sys/semconfig.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/semctl.s b/i386/sys/semctl.s index ae98107..1c0ba3c 100644 --- a/i386/sys/semctl.s +++ b/i386/sys/semctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/semget.s b/i386/sys/semget.s index 32d8c33..fb15955 100644 --- a/i386/sys/semget.s +++ b/i386/sys/semget.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/semop.s b/i386/sys/semop.s index 8b1c2ee..8da7938 100644 --- a/i386/sys/semop.s +++ b/i386/sys/semop.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/semsys.s b/i386/sys/semsys.s index f2321ed..5f33630 100644 --- a/i386/sys/semsys.s +++ b/i386/sys/semsys.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sendmsg.s b/i386/sys/sendmsg.s index 3ef0d44..66d169d 100644 --- a/i386/sys/sendmsg.s +++ b/i386/sys/sendmsg.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sendto.s b/i386/sys/sendto.s index 792c330..e2605c0 100644 --- a/i386/sys/sendto.s +++ b/i386/sys/sendto.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setattrlist.s b/i386/sys/setattrlist.s index 26f9d7a..24d9acd 100644 --- a/i386/sys/setattrlist.s +++ b/i386/sys/setattrlist.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setaudit.s b/i386/sys/setaudit.s index 253d5a8..305af1b 100644 --- a/i386/sys/setaudit.s +++ b/i386/sys/setaudit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setaudit_addr.s b/i386/sys/setaudit_addr.s index 4ead3a9..4dc6e6a 100644 --- a/i386/sys/setaudit_addr.s +++ b/i386/sys/setaudit_addr.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setauid.s b/i386/sys/setauid.s index ff5cc60..234fe56 100644 --- a/i386/sys/setauid.s +++ b/i386/sys/setauid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setegid.s b/i386/sys/setegid.s index bdbad71..95f8764 100644 --- a/i386/sys/setegid.s +++ b/i386/sys/setegid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/seteuid.s b/i386/sys/seteuid.s index c3302e2..740575f 100644 --- a/i386/sys/seteuid.s +++ b/i386/sys/seteuid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setgid.s b/i386/sys/setgid.s index df995db..1a8cb5d 100644 --- a/i386/sys/setgid.s +++ b/i386/sys/setgid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setgroups.s b/i386/sys/setgroups.s index 217f57f..c2d784a 100644 --- a/i386/sys/setgroups.s +++ b/i386/sys/setgroups.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setitimer.s b/i386/sys/setitimer.s index 47232da..29bcaca 100644 --- a/i386/sys/setitimer.s +++ b/i386/sys/setitimer.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setjmp.s b/i386/sys/setjmp.s index 2727458..72d6bff 100644 --- a/i386/sys/setjmp.s +++ b/i386/sys/setjmp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setpgid.s b/i386/sys/setpgid.s index b3c8af9..275d624 100644 --- a/i386/sys/setpgid.s +++ b/i386/sys/setpgid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setpriority.s b/i386/sys/setpriority.s index e9546e1..719d973 100644 --- a/i386/sys/setpriority.s +++ b/i386/sys/setpriority.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setprivexec.s b/i386/sys/setprivexec.s index f104e6c..0feab27 100644 --- a/i386/sys/setprivexec.s +++ b/i386/sys/setprivexec.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setquota.s b/i386/sys/setquota.s index 330973b..af7fe8b 100644 --- a/i386/sys/setquota.s +++ b/i386/sys/setquota.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setrlimit.s b/i386/sys/setrlimit.s index ae3e3cf..da0fd9b 100644 --- a/i386/sys/setrlimit.s +++ b/i386/sys/setrlimit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setsid.s b/i386/sys/setsid.s index 42d3cbd..1fe68f8 100644 --- a/i386/sys/setsid.s +++ b/i386/sys/setsid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setsockopt.s b/i386/sys/setsockopt.s index 0c5ffa8..69657b0 100644 --- a/i386/sys/setsockopt.s +++ b/i386/sys/setsockopt.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/settimeofday.s b/i386/sys/settimeofday.s index 87a0b2f..0ce78e6 100644 --- a/i386/sys/settimeofday.s +++ b/i386/sys/settimeofday.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setuid.s b/i386/sys/setuid.s index 25c6245..70aa570 100644 --- a/i386/sys/setuid.s +++ b/i386/sys/setuid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/setxattr.s b/i386/sys/setxattr.s new file mode 100644 index 0000000..822eec6 --- /dev/null +++ b/i386/sys/setxattr.s @@ -0,0 +1,28 @@ +/* + * 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 diff --git a/i386/sys/shmat.s b/i386/sys/shmat.s index 41b50de..324a7aa 100644 --- a/i386/sys/shmat.s +++ b/i386/sys/shmat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/shmctl.s b/i386/sys/shmctl.s index d8320bb..ef7f05b 100644 --- a/i386/sys/shmctl.s +++ b/i386/sys/shmctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/shmdt.s b/i386/sys/shmdt.s index 9cfe18a..71875a4 100644 --- a/i386/sys/shmdt.s +++ b/i386/sys/shmdt.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/shmget.s b/i386/sys/shmget.s index b7441ee..608c078 100644 --- a/i386/sys/shmget.s +++ b/i386/sys/shmget.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/shmsys.s b/i386/sys/shmsys.s index a0736e7..ccafa0f 100644 --- a/i386/sys/shmsys.s +++ b/i386/sys/shmsys.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/shutdown.s b/i386/sys/shutdown.s index fe07517..e556523 100644 --- a/i386/sys/shutdown.s +++ b/i386/sys/shutdown.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sigaltstack.s b/i386/sys/sigaltstack.s index baa6979..5c604a1 100644 --- a/i386/sys/sigaltstack.s +++ b/i386/sys/sigaltstack.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sigpending.s b/i386/sys/sigpending.s index b8acf3f..3d40de0 100644 --- a/i386/sys/sigpending.s +++ b/i386/sys/sigpending.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sigprocmask.s b/i386/sys/sigprocmask.s index 52ce593..ffdc250 100644 --- a/i386/sys/sigprocmask.s +++ b/i386/sys/sigprocmask.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sigreturn.s b/i386/sys/sigreturn.s index 9453116..c88bfd6 100644 --- a/i386/sys/sigreturn.s +++ b/i386/sys/sigreturn.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sigwait.s b/i386/sys/sigwait.s index 1952b31..32fae35 100644 --- a/i386/sys/sigwait.s +++ b/i386/sys/sigwait.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/socket.s b/i386/sys/socket.s index e28a635..0229646 100644 --- a/i386/sys/socket.s +++ b/i386/sys/socket.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/socketpair.s b/i386/sys/socketpair.s index a305faf..b0b9951 100644 --- a/i386/sys/socketpair.s +++ b/i386/sys/socketpair.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/stat.s b/i386/sys/stat.s index 9a6feb2..e2e9899 100644 --- a/i386/sys/stat.s +++ b/i386/sys/stat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/statfs.s b/i386/sys/statfs.s index 6c84dbe..d2405e9 100644 --- a/i386/sys/statfs.s +++ b/i386/sys/statfs.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/statv.s b/i386/sys/statv.s index 6473009..719840d 100644 --- a/i386/sys/statv.s +++ b/i386/sys/statv.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/swapon.s b/i386/sys/swapon.s index fe95cb0..a35f25f 100644 --- a/i386/sys/swapon.s +++ b/i386/sys/swapon.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/symlink.s b/i386/sys/symlink.s index 28a88bc..67eb615 100644 --- a/i386/sys/symlink.s +++ b/i386/sys/symlink.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/sync.s b/i386/sys/sync.s index 1b3d72d..cb14dc5 100644 --- a/i386/sys/sync.s +++ b/i386/sys/sync.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/syscall.s b/i386/sys/syscall.s index 9b28f68..d17cdca 100644 --- a/i386/sys/syscall.s +++ b/i386/sys/syscall.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/systable.s b/i386/sys/systable.s index a2a1b28..def8c50 100644 --- a/i386/sys/systable.s +++ b/i386/sys/systable.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/truncate.s b/i386/sys/truncate.s index 522e0f9..099efa8 100644 --- a/i386/sys/truncate.s +++ b/i386/sys/truncate.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/umask.s b/i386/sys/umask.s index 55ff2bd..88a541a 100644 --- a/i386/sys/umask.s +++ b/i386/sys/umask.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/undelete.s b/i386/sys/undelete.s index 1b55879..be28e64 100644 --- a/i386/sys/undelete.s +++ b/i386/sys/undelete.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/unlink.s b/i386/sys/unlink.s index d0af96b..cd88e3f 100644 --- a/i386/sys/unlink.s +++ b/i386/sys/unlink.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/unmount.s b/i386/sys/unmount.s index f10804a..0a93019 100644 --- a/i386/sys/unmount.s +++ b/i386/sys/unmount.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/utimes.s b/i386/sys/utimes.s index cbc8611..ac6caeb 100644 --- a/i386/sys/utimes.s +++ b/i386/sys/utimes.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -25,5 +27,5 @@ */ #include "SYS.h" -UNIX_SYSCALL(utimes, 1) +UNIX_SYSCALL(utimes, 2) ret diff --git a/i386/sys/vfork.s b/i386/sys/vfork.s index 1a4933a..266b7d1 100644 --- a/i386/sys/vfork.s +++ b/i386/sys/vfork.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/wait4.s b/i386/sys/wait4.s index 5a11f3b..bb69664 100644 --- a/i386/sys/wait4.s +++ b/i386/sys/wait4.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/write.s b/i386/sys/write.s index 6fca232..f31bfc7 100644 --- a/i386/sys/write.s +++ b/i386/sys/write.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/i386/sys/writev.s b/i386/sys/writev.s index 538f68e..11491a0 100644 --- a/i386/sys/writev.s +++ b/i386/sys/writev.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/Makefile.inc b/include/Makefile.inc index cd3a7df..e200974 100644 --- a/include/Makefile.inc +++ b/include/Makefile.inc @@ -1,16 +1,19 @@ .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 \ @@ -19,10 +22,12 @@ INC_INSTHDRS += NSSystemDirectories.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 \ @@ -79,7 +84,11 @@ INC_INSTHDRS += NSSystemDirectories.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} diff --git a/include/NSSystemDirectories.h b/include/NSSystemDirectories.h index b098687..83938a9 100644 --- a/include/NSSystemDirectories.h +++ b/include/NSSystemDirectories.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/_types.h b/include/_types.h new file mode 100644 index 0000000..731e9c8 --- /dev/null +++ b/include/_types.h @@ -0,0 +1,81 @@ +/* + * 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 +#include + +/* + * 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_ */ diff --git a/include/aio.h b/include/aio.h index b031764..2221454 100644 --- a/include/aio.h +++ b/include/aio.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/alloca.h b/include/alloca.h index 83adc88..ef101c4 100644 --- a/include/alloca.h +++ b/include/alloca.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/ar.h b/include/ar.h index 39d7d35..a0a7c9a 100644 --- a/include/ar.h +++ b/include/ar.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/arpa/ftp.h b/include/arpa/ftp.h index 906646b..995966e 100644 --- a/include/arpa/ftp.h +++ b/include/arpa/ftp.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h index b0a41e0..33c96ac 100644 --- a/include/arpa/nameser_compat.h +++ b/include/arpa/nameser_compat.h @@ -1,25 +1,3 @@ -/* - * 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. * diff --git a/include/arpa/telnet.h b/include/arpa/telnet.h index 50e8d71..eecd047 100644 --- a/include/arpa/telnet.h +++ b/include/arpa/telnet.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/arpa/tftp.h b/include/arpa/tftp.h index 2895703..b794bda 100644 --- a/include/arpa/tftp.h +++ b/include/arpa/tftp.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/asm.h b/include/asm.h index c320363..d21a6b5 100644 --- a/include/asm.h +++ b/include/asm.h @@ -1,25 +1,3 @@ -/* - * 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@ */ diff --git a/include/authentication.h b/include/authentication.h index 9870e33..8f8b055 100644 --- a/include/authentication.h +++ b/include/authentication.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/bitstring.h b/include/bitstring.h index 395d727..959d460 100644 --- a/include/bitstring.h +++ b/include/bitstring.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/c.h b/include/c.h index 96b761c..6f72262 100644 --- a/include/c.h +++ b/include/c.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/cpio.h b/include/cpio.h new file mode 100644 index 0000000..d287af6 --- /dev/null +++ b/include/cpio.h @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2002 Mike Barcroft + * 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_ */ diff --git a/include/crt_externs.h b/include/crt_externs.h index f26f205..b27150f 100644 --- a/include/crt_externs.h +++ b/include/crt_externs.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/ctype.h b/include/ctype.h index 136036e..d7f85cf 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -112,6 +114,7 @@ __BEGIN_DECLS int isalnum(int); int isalpha(int); +int isblank(int); int iscntrl(int); int isdigit(int); int isgraph(int); @@ -125,9 +128,10 @@ int tolower(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); @@ -141,6 +145,7 @@ __END_DECLS #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) @@ -154,9 +159,10 @@ __END_DECLS #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) @@ -192,8 +198,12 @@ __END_DECLS 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 @@ -205,22 +215,34 @@ __istype(_BSD_CT_RUNE_T_ c, unsigned long f) 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 */ diff --git a/include/db.h b/include/db.h index b222639..bd1eb9f 100644 --- a/include/db.h +++ b/include/db.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/dirent.h b/include/dirent.h index a571a21..b31e1cb 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -62,14 +64,13 @@ * The kernel defines the format of directory entries returned by * the getdirentries(2) system call. */ -#include +#include <_types.h> #include #ifdef _POSIX_SOURCE typedef void * DIR; #else - -#define d_ino d_fileno /* backward compatibility */ +#include /* definitions for library routines operating on directories. */ #define DIRBLKSIZ 1024 @@ -99,30 +100,36 @@ typedef struct _dirdesc { #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 __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 */ diff --git a/include/disktab.h b/include/disktab.h index 535726a..05245b1 100644 --- a/include/disktab.h +++ b/include/disktab.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/err.h b/include/err.h index 8f31d31..9195051 100644 --- a/include/err.h +++ b/include/err.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/errno.h b/include/errno.h index 9879cc4..b1dc0cf 100644 --- a/include/errno.h +++ b/include/errno.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/fcntl.h b/include/fcntl.h index d4b1ae2..05c73db 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/fmtmsg.h b/include/fmtmsg.h new file mode 100644 index 0000000..256cf33 --- /dev/null +++ b/include/fmtmsg.h @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2002 Mike Barcroft + * 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_ */ diff --git a/include/fnmatch.h b/include/fnmatch.h index cf186f9..b840732 100644 --- a/include/fnmatch.h +++ b/include/fnmatch.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -64,6 +66,8 @@ #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 / after Imatch. */ #define FNM_CASEFOLD 0x10 /* Case insensitive search. */ diff --git a/include/fsproperties.h b/include/fsproperties.h index e506481..46e9b59 100644 --- a/include/fsproperties.h +++ b/include/fsproperties.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/fstab.h b/include/fstab.h index ec83af5..fdd484a 100644 --- a/include/fstab.h +++ b/include/fstab.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/fts.h b/include/fts.h index ccf4118..4977b77 100644 --- a/include/fts.h +++ b/include/fts.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/ftw.h b/include/ftw.h new file mode 100644 index 0000000..1601ad2 --- /dev/null +++ b/include/ftw.h @@ -0,0 +1,60 @@ +/* $OpenBSD: ftw.h,v 1.1 2003/07/21 21:13:18 millert Exp $ */ + +/* + * Copyright (c) 2003 Todd C. Miller + * + * 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 +#include + +/* + * 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 */ diff --git a/include/getopt.h b/include/getopt.h index 2759ab2..15a98bd 100644 --- a/include/getopt.h +++ b/include/getopt.h @@ -1,27 +1,3 @@ -/* - * 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. diff --git a/include/glob.h b/include/glob.h index ce0c637..b749e3c 100644 --- a/include/glob.h +++ b/include/glob.h @@ -1,25 +1,3 @@ -/* - * 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. @@ -56,18 +34,25 @@ * 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 +#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. */ @@ -79,18 +64,26 @@ typedef struct { * 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. */ @@ -99,13 +92,16 @@ typedef struct { #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 diff --git a/include/grp.h b/include/grp.h index fdb0cd7..987a4e2 100644 --- a/include/grp.h +++ b/include/grp.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -63,31 +65,52 @@ #ifndef _GRP_H_ #define _GRP_H_ +#include + +#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 __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 diff --git a/include/iso646.h b/include/iso646.h index df59d44..360c4f8 100644 --- a/include/iso646.h +++ b/include/iso646.h @@ -1,25 +1,3 @@ -/* - * 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. @@ -51,6 +29,7 @@ #ifndef _ISO646_H_ #define _ISO646_H_ +#ifndef __cplusplus #define and && #define and_eq &= #define bitand & @@ -62,5 +41,6 @@ #define or_eq |= #define xor ^ #define xor_eq ^= +#endif /* ! __cplusplus */ #endif /* !_ISO646_H_ */ diff --git a/include/kvm.h b/include/kvm.h index fa9fce0..f71f40e 100644 --- a/include/kvm.h +++ b/include/kvm.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/langinfo.h b/include/langinfo.h index 08dda0f..d793097 100644 --- a/include/langinfo.h +++ b/include/langinfo.h @@ -1,25 +1,3 @@ -/* - * 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 * All rights reserved. @@ -52,10 +30,10 @@ #define _LANGINFO_H_ #include -#include +#include <_types.h> #ifndef _NL_ITEM_DECLARED -typedef int nl_item; +typedef __osx_nl_item nl_item; #define _NL_ITEM_DECLARED #endif diff --git a/include/libc.h b/include/libc.h index 00c0bd9..f42e7dc 100644 --- a/include/libc.h +++ b/include/libc.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -41,13 +43,13 @@ #include #endif +#include #include #include #include #include #include #include -#include #include #include #include diff --git a/include/libgen.h b/include/libgen.h index 6ac5444..6b6747a 100644 --- a/include/libgen.h +++ b/include/libgen.h @@ -1,25 +1,3 @@ -/* - * 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 $ */ @@ -59,12 +37,6 @@ __BEGIN_DECLS 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 diff --git a/include/libkern/Makefile.inc b/include/libkern/Makefile.inc new file mode 100644 index 0000000..b2d4a78 --- /dev/null +++ b/include/libkern/Makefile.inc @@ -0,0 +1,3 @@ +LIBKERN_INSTHDRS += OSAtomic.h + +LIBKERN_INSTHDRS := ${LIBKERN_INSTHDRS:S/^/${.CURDIR}\/include\/libkern\//} diff --git a/include/libkern/OSAtomic.h b/include/libkern/OSAtomic.h new file mode 100644 index 0000000..4bd3c15 --- /dev/null +++ b/include/libkern/OSAtomic.h @@ -0,0 +1,114 @@ +/* + * 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 +#include +#include +#include + +/* 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_ */ diff --git a/include/limits.h b/include/limits.h index bf1964b..184ba7f 100644 --- a/include/limits.h +++ b/include/limits.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/locale.h b/include/locale.h index 37ababb..5e0d9d6 100644 --- a/include/locale.h +++ b/include/locale.h @@ -1,25 +1,3 @@ -/* - * 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. @@ -87,8 +65,16 @@ struct lconv { }; #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 diff --git a/include/malloc/malloc.h b/include/malloc/malloc.h index a39bf7b..c87a624 100644 --- a/include/malloc/malloc.h +++ b/include/malloc/malloc.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -34,8 +36,8 @@ __BEGIN_DECLS 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 */ @@ -50,7 +52,7 @@ typedef struct _malloc_zone_t { 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 ************/ @@ -177,6 +179,17 @@ extern void malloc_zone_log(malloc_zone_t *zone, void *address); 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_ */ diff --git a/include/memory.h b/include/memory.h index abf1034..0380627 100644 --- a/include/memory.h +++ b/include/memory.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/monetary.h b/include/monetary.h index d5e937b..a53d82c 100644 --- a/include/monetary.h +++ b/include/monetary.h @@ -1,25 +1,3 @@ -/* - * 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 * All rights reserved. @@ -52,7 +30,17 @@ #define _MONETARY_H_ #include -#include +#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 *, ...); diff --git a/include/monitor.h b/include/monitor.h index 6903b14..db99210 100644 --- a/include/monitor.h +++ b/include/monitor.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/mpool.h b/include/mpool.h index b628dbc..e811aa3 100644 --- a/include/mpool.h +++ b/include/mpool.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/ndbm.h b/include/ndbm.h index f71cfce..d7c8e22 100644 --- a/include/ndbm.h +++ b/include/ndbm.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -61,41 +63,63 @@ #ifndef _NDBM_H_ #define _NDBM_H_ -#include +#include +#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 #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_ */ diff --git a/include/nl_types.h b/include/nl_types.h index 4adabaf..68a285a 100644 --- a/include/nl_types.h +++ b/include/nl_types.h @@ -1,25 +1,3 @@ -/* - * 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 $ */ /*********************************************************** @@ -57,16 +35,21 @@ up-to-date. Many thanks. #ifndef _NL_TYPES_H_ #define _NL_TYPES_H_ #include +#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 diff --git a/include/nlist.h b/include/nlist.h index c4c1140..835aa79 100644 --- a/include/nlist.h +++ b/include/nlist.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/objc/malloc.h b/include/objc/malloc.h index bccba72..ae45bbd 100644 --- a/include/objc/malloc.h +++ b/include/objc/malloc.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/objc/zone.h b/include/objc/zone.h index efdda56..dad1012 100644 --- a/include/objc/zone.h +++ b/include/objc/zone.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/paths.h b/include/paths.h index 3edd2b8..e90f30c 100644 --- a/include/paths.h +++ b/include/paths.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/protocols/dumprestore.h b/include/protocols/dumprestore.h index a642212..2e1dba6 100644 --- a/include/protocols/dumprestore.h +++ b/include/protocols/dumprestore.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/protocols/routed.h b/include/protocols/routed.h index b5fa2c5..5afcad5 100644 --- a/include/protocols/routed.h +++ b/include/protocols/routed.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/protocols/rwhod.h b/include/protocols/rwhod.h index 84094eb..12f1e3d 100644 --- a/include/protocols/rwhod.h +++ b/include/protocols/rwhod.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/protocols/talkd.h b/include/protocols/talkd.h index 8a8b92e..154760b 100644 --- a/include/protocols/talkd.h +++ b/include/protocols/talkd.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/protocols/timed.h b/include/protocols/timed.h index b691289..5539106 100644 --- a/include/protocols/timed.h +++ b/include/protocols/timed.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/pwd.h b/include/pwd.h index 5aacf28..8fc7eff 100644 --- a/include/pwd.h +++ b/include/pwd.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -66,15 +68,40 @@ #ifndef _PWD_H_ #define _PWD_H_ -#include +#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" @@ -116,15 +143,13 @@ struct passwd *getpwuid(uid_t); 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_ */ diff --git a/include/ranlib.h b/include/ranlib.h index 001eaad..15d1cb6 100644 --- a/include/ranlib.h +++ b/include/ranlib.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/readpassphrase.h b/include/readpassphrase.h index d7ff484..8fbb8f5 100644 --- a/include/readpassphrase.h +++ b/include/readpassphrase.h @@ -1,25 +1,3 @@ -/* - * 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 $ */ diff --git a/include/regex.h b/include/regex.h index 91577bc..eec9325 100644 --- a/include/regex.h +++ b/include/regex.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -63,14 +65,20 @@ #define _REGEX_H_ #include +#include /* 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; @@ -80,16 +88,21 @@ typedef struct { } 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 @@ -103,25 +116,29 @@ typedef struct { #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 diff --git a/include/regexp.h b/include/regexp.h index f560122..d086d62 100644 --- a/include/regexp.h +++ b/include/regexp.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/rune.h b/include/rune.h index 067e272..24f7c79 100644 --- a/include/rune.h +++ b/include/rune.h @@ -1,25 +1,3 @@ -/* - * 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. diff --git a/include/runetype.h b/include/runetype.h index 2aedf2f..d02952c 100644 --- a/include/runetype.h +++ b/include/runetype.h @@ -1,25 +1,3 @@ -/* - * 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. @@ -62,37 +40,33 @@ #define _RUNETYPE_H_ #include -#include +#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 */ diff --git a/include/search.h b/include/search.h index 8befa96..c82cc3e 100644 --- a/include/search.h +++ b/include/search.h @@ -1,25 +1,3 @@ -/* - * 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 * Public domain. @@ -32,7 +10,12 @@ #define _SEARCH_H_ #include -#include +#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; diff --git a/include/semaphore.h b/include/semaphore.h index 638aa61..a9f267b 100644 --- a/include/semaphore.h +++ b/include/semaphore.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/setjmp.h b/include/setjmp.h index 4fced23..8726872 100644 --- a/include/setjmp.h +++ b/include/setjmp.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/sgtty.h b/include/sgtty.h index 1934e78..fcad33e 100644 --- a/include/sgtty.h +++ b/include/sgtty.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/signal.h b/include/signal.h index 20ba75f..89e08ca 100644 --- a/include/signal.h +++ b/include/signal.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -58,10 +60,15 @@ #ifndef _USER_SIGNAL_H #define _USER_SIGNAL_H -#include +#include <_types.h> #include #include +#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]; @@ -69,33 +76,39 @@ 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. */ @@ -104,5 +117,6 @@ __END_DECLS #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 */ diff --git a/include/stab.h b/include/stab.h index 1b70544..95fcc5b 100644 --- a/include/stab.h +++ b/include/stab.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/standards.h b/include/standards.h index 05a3e90..d24b8e1 100644 --- a/include/standards.h +++ b/include/standards.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/stddef.h b/include/stddef.h index 25d403a..d58d336 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -61,46 +63,32 @@ #ifndef __STDDEF_H__ #define __STDDEF_H__ -#include -#include +#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__ */ diff --git a/include/stdio.h b/include/stdio.h index 1860066..f0d5047 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -61,27 +63,36 @@ #ifndef _STDIO_H_ #define _STDIO_H_ -#if !defined(_ANSI_SOURCE) && !defined(__STRICT_ANSI__) -#include -#endif - +#include <_types.h> #include -#include +#ifndef _POSIX_SOURCE +#include +#else /* _POSIX_SOURCE */ +/* set __need___va_list to only define __gnuc_va_list */ +#define __need___va_list +#include +#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 -typedef int64_t fpos_t; +typedef __int64_t fpos_t; #endif #define _FSTDIO /* Define for new stdio with functions. */ @@ -224,9 +235,9 @@ __END_DECLS #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. @@ -238,19 +249,20 @@ int feof(FILE *); 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 *); @@ -259,26 +271,28 @@ extern __const int sys_nerr; /* perror(3) external variables */ 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 /* @@ -290,48 +304,53 @@ __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), @@ -341,14 +360,15 @@ FILE *funopen(const void *, __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 @@ -383,13 +403,13 @@ static __inline int __sputc(int _c, FILE *_p) { #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) @@ -398,4 +418,6 @@ static __inline int __sputc(int _c, FILE *_p) { #define getchar_unlocked() getc_unlocked(stdin) #define putchar_unlocked(x) putc_unlocked(x, stdout) +#endif /* not ANSI */ + #endif /* _STDIO_H_ */ diff --git a/include/stdlib.h b/include/stdlib.h index 165c87c..4d622b2 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -108,8 +110,16 @@ typedef struct { } 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 diff --git a/include/strhash.h b/include/strhash.h index 87bdba8..f8fa55a 100644 --- a/include/strhash.h +++ b/include/strhash.h @@ -1,25 +1,3 @@ -/* - * 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 diff --git a/include/string.h b/include/string.h index 12cd29b..b32f28a 100644 --- a/include/string.h +++ b/include/string.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -64,9 +66,17 @@ 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 @@ -76,8 +86,10 @@ int memcmp(const void *, const void *, size_t); 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 *); @@ -90,7 +102,9 @@ size_t strlen(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 *); @@ -100,24 +114,26 @@ size_t strxfrm(char *, const char *, size_t); /* 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_ */ diff --git a/include/stringlist.h b/include/stringlist.h index ef27658..7f2925a 100644 --- a/include/stringlist.h +++ b/include/stringlist.h @@ -1,25 +1,3 @@ -/* - * 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 $ */ /* diff --git a/include/strings.h b/include/strings.h index e5d837c..03cdafe 100644 --- a/include/strings.h +++ b/include/strings.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/struct.h b/include/struct.h index fcf6038..8096977 100644 --- a/include/struct.h +++ b/include/struct.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/sys/Makefile.inc b/include/sys/Makefile.inc new file mode 100644 index 0000000..509caa8 --- /dev/null +++ b/include/sys/Makefile.inc @@ -0,0 +1,3 @@ +SYS_INSTHDRS += statvfs.h + +SYS_INSTHDRS := ${SYS_INSTHDRS:S/^/${.CURDIR}\/include\/sys\//} diff --git a/include/sys/statvfs.h b/include/sys/statvfs.h new file mode 100644 index 0000000..d672e58 --- /dev/null +++ b/include/sys/statvfs.h @@ -0,0 +1,62 @@ +/* + * 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 + +/* Following types need to be defined in 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_ */ diff --git a/include/sysexits.3 b/include/sysexits.3 new file mode 100644 index 0000000..9a97140 --- /dev/null +++ b/include/sysexits.3 @@ -0,0 +1,132 @@ +.\" +.\" 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. diff --git a/include/sysexits.h b/include/sysexits.h index 55bf1a4..ae18a37 100644 --- a/include/sysexits.h +++ b/include/sysexits.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/syslog.h b/include/syslog.h index d3f4192..470fca1 100644 --- a/include/syslog.h +++ b/include/syslog.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/tar.h b/include/tar.h index 5d2c6c4..b380df4 100644 --- a/include/tar.h +++ b/include/tar.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/termios.h b/include/termios.h index 3d38ce1..e877955 100644 --- a/include/termios.h +++ b/include/termios.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -20,5 +22,20 @@ * * @APPLE_LICENSE_HEADER_END@ */ +#ifndef __TERMIOS_H__ +#define __TERMIOS_H__ + +#include #include +#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__ */ diff --git a/include/time.h b/include/time.h index 3f64386..e52c95d 100644 --- a/include/time.h +++ b/include/time.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -65,9 +67,17 @@ #include -#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_ diff --git a/include/timeconv.h b/include/timeconv.h index 5cdda68..2310e33 100644 --- a/include/timeconv.h +++ b/include/timeconv.h @@ -1,25 +1,3 @@ -/* - * 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. diff --git a/include/ttyent.h b/include/ttyent.h index 6f40d98..9e56ce7 100644 --- a/include/ttyent.h +++ b/include/ttyent.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/tzfile.h b/include/tzfile.h index 476c602..603b711 100644 --- a/include/tzfile.h +++ b/include/tzfile.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/ucontext.h b/include/ucontext.h index 5d03cdf..120ff0e 100644 --- a/include/ucontext.h +++ b/include/ucontext.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/ulimit.h b/include/ulimit.h index f183e0e..c6a451c 100644 --- a/include/ulimit.h +++ b/include/ulimit.h @@ -1,35 +1,41 @@ -/* - * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. +/*- + * Copyright (c) 2002 Kyle Martin + * 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 +#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_ */ diff --git a/include/unistd.h b/include/unistd.h index 88baf9c..456418c 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -70,17 +72,132 @@ #include #include -#include +#include /* 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 */ +#undef _POSIX_VERSION +#endif +#ifdef _POSIX2_VERSION /* XXX */ +#undef _POSIX2_VERSION +#endif +#ifdef _POSIX_CHOWN_RESTRICTED /* XXX */ +#undef _POSIX_CHOWN_RESTRICTED #endif +#ifdef _POSIX_NO_TRUNC /* XXX */ +#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 */ @@ -90,39 +207,162 @@ #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 */ +#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 @@ -157,6 +397,7 @@ pid_t getpid(void); 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); @@ -192,9 +433,7 @@ int async_daemon(void); 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); @@ -208,6 +447,7 @@ int gethostname(char *, 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); @@ -250,7 +490,7 @@ int seteuid(uid_t); 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() */ @@ -277,6 +517,16 @@ extern char *suboptarg; /* getsubopt(3) external variable */ 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); @@ -285,7 +535,7 @@ int getdirentriesattr(int,void*,void*,size_t,unsigned long*,unsigned long*,unsig 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 diff --git a/include/util.h b/include/util.h index 0f0ca6a..1da5789 100644 --- a/include/util.h +++ b/include/util.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/utime.h b/include/utime.h index 7036388..c2121ca 100644 --- a/include/utime.h +++ b/include/utime.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/utmp.h b/include/utmp.h index 29f0fb0..675ee29 100644 --- a/include/utmp.h +++ b/include/utmp.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/vis.h b/include/vis.h index 8c837e4..3b3519d 100644 --- a/include/vis.h +++ b/include/vis.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/include/wchar.h b/include/wchar.h index 917c303..45f5bd6 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -1,25 +1,3 @@ -/* - * 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. @@ -90,92 +68,102 @@ #define _WCHAR_H_ #include -#include +#include <_types.h> #include +#include +#include #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_); @@ -207,6 +195,8 @@ wchar_t *wcstok(wchar_t * __restrict, const wchar_t * __restrict, 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); @@ -216,7 +206,7 @@ int wprintf(const wchar_t * __restrict, ...); 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_); diff --git a/include/wctype.h b/include/wctype.h index 53bc524..ac35928 100644 --- a/include/wctype.h +++ b/include/wctype.h @@ -1,25 +1,3 @@ -/* - * 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. @@ -54,48 +32,43 @@ #define _WCTYPE_H_ #include -#include - +#include <_types.h> #include #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 diff --git a/include/wordexp.h b/include/wordexp.h new file mode 100644 index 0000000..b92131b --- /dev/null +++ b/include/wordexp.h @@ -0,0 +1,88 @@ +/* + * 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 +#include + +#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 */ diff --git a/internat/Makefile.inc b/internat/Makefile.inc index d3d5003..b9a0457 100644 --- a/internat/Makefile.inc +++ b/internat/Makefile.inc @@ -1,6 +1,6 @@ .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 diff --git a/internat/NXCType.c b/internat/NXCType.c index c0fe74c..fb9d839 100644 --- a/internat/NXCType.c +++ b/internat/NXCType.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXCType.h b/internat/NXCType.h index 5b379f0..970c684 100644 --- a/internat/NXCType.h +++ b/internat/NXCType.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsAlNum.c b/internat/NXIsAlNum.c index 6328a6a..dc911d1 100644 --- a/internat/NXIsAlNum.c +++ b/internat/NXIsAlNum.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsAlpha.c b/internat/NXIsAlpha.c index 9354194..0a5d5dc 100644 --- a/internat/NXIsAlpha.c +++ b/internat/NXIsAlpha.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsAscii.c b/internat/NXIsAscii.c index fc6f4bf..5acc0cb 100644 --- a/internat/NXIsAscii.c +++ b/internat/NXIsAscii.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsCntrl.c b/internat/NXIsCntrl.c index 96a2495..25ac943 100644 --- a/internat/NXIsCntrl.c +++ b/internat/NXIsCntrl.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsDigit.c b/internat/NXIsDigit.c index e363b1f..7ffa03f 100644 --- a/internat/NXIsDigit.c +++ b/internat/NXIsDigit.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsGraph.c b/internat/NXIsGraph.c index b65594d..42e9d72 100644 --- a/internat/NXIsGraph.c +++ b/internat/NXIsGraph.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsLower.c b/internat/NXIsLower.c index e796728..3fa8ca8 100644 --- a/internat/NXIsLower.c +++ b/internat/NXIsLower.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsPrint.c b/internat/NXIsPrint.c index b1f9d06..1863004 100644 --- a/internat/NXIsPrint.c +++ b/internat/NXIsPrint.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsPunct.c b/internat/NXIsPunct.c index af650d6..85667d1 100644 --- a/internat/NXIsPunct.c +++ b/internat/NXIsPunct.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsSpace.c b/internat/NXIsSpace.c index b26c5be..4317fd0 100644 --- a/internat/NXIsSpace.c +++ b/internat/NXIsSpace.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsUpper.c b/internat/NXIsUpper.c index 29afa98..13d761c 100644 --- a/internat/NXIsUpper.c +++ b/internat/NXIsUpper.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXIsXDigit.c b/internat/NXIsXDigit.c index 37886f1..114c5e0 100644 --- a/internat/NXIsXDigit.c +++ b/internat/NXIsXDigit.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXToAscii.c b/internat/NXToAscii.c index 8dc50e9..d215589 100644 --- a/internat/NXToAscii.c +++ b/internat/NXToAscii.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXToLower.c b/internat/NXToLower.c index 9b5939a..b66859f 100644 --- a/internat/NXToLower.c +++ b/internat/NXToLower.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/NXToUpper.c b/internat/NXToUpper.c index 49955e5..e57b11e 100644 --- a/internat/NXToUpper.c +++ b/internat/NXToUpper.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/_NXToLower.c b/internat/_NXToLower.c index 70b2d08..2f91ce2 100644 --- a/internat/_NXToLower.c +++ b/internat/_NXToLower.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/internat/_NXToUpper.c b/internat/_NXToUpper.c index f1f5f7a..6fe17e2 100644 --- a/internat/_NXToUpper.c +++ b/internat/_NXToUpper.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/locale/Makefile.inc b/locale/Makefile.inc index 6be6677..4e6ce9b 100644 --- a/locale/Makefile.inc +++ b/locale/Makefile.inc @@ -5,7 +5,7 @@ .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 \ @@ -18,14 +18,13 @@ FBSDSRCS= big5.c btowc.c collate.c collcmp.c euc.c fix_grouping.c frune.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 diff --git a/locale/lconv.c b/locale/lconv.c index e48aa34..f8b429d 100644 --- a/locale/lconv.c +++ b/locale/lconv.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/Makefile.inc b/mach/Makefile.inc index 353fc65..3a3942e 100644 --- a/mach/Makefile.inc +++ b/mach/Makefile.inc @@ -1,13 +1,13 @@ -.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 @@ -22,6 +22,7 @@ MIGDEFS += \ lock_set.defs \ mach_port.defs \ mach_host.defs \ + mach_vm.defs \ processor.defs \ processor_set.defs \ vm_map.defs @@ -33,7 +34,7 @@ MACH_INSTHDRS += ${MIGHDRS} # 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 \ diff --git a/mach/bootstrap_ports.c b/mach/bootstrap_ports.c index 1a278c2..9fad5f7 100644 --- a/mach/bootstrap_ports.c +++ b/mach/bootstrap_ports.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/clock.defs b/mach/clock.defs index 4334cee..4b78f55 100644 --- a/mach/clock.defs +++ b/mach/clock.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/clock_priv.defs b/mach/clock_priv.defs index d796ab1..ddf17f1 100644 --- a/mach/clock_priv.defs +++ b/mach/clock_priv.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/clock_reply.defs b/mach/clock_reply.defs index 19b5fe8..5bce14c 100644 --- a/mach/clock_reply.defs +++ b/mach/clock_reply.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/clock_sleep.c b/mach/clock_sleep.c index e6d1dcf..0d7916f 100644 --- a/mach/clock_sleep.c +++ b/mach/clock_sleep.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/error_codes.c b/mach/error_codes.c index 4b2461b..55856ee 100644 --- a/mach/error_codes.c +++ b/mach/error_codes.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/errorlib.h b/mach/errorlib.h index 2049010..9f06fcf 100644 --- a/mach/errorlib.h +++ b/mach/errorlib.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/exc.defs b/mach/exc.defs index 399e6a2..76e75ac 100644 --- a/mach/exc.defs +++ b/mach/exc.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/exc_catcher.c b/mach/exc_catcher.c index 2606e4f..f5ccbc4 100644 --- a/mach/exc_catcher.c +++ b/mach/exc_catcher.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/exc_catcher_state.c b/mach/exc_catcher_state.c index 0070cc8..f58c914 100644 --- a/mach/exc_catcher_state.c +++ b/mach/exc_catcher_state.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/exc_catcher_state_identity.c b/mach/exc_catcher_state_identity.c index ace77a3..dc12b56 100644 --- a/mach/exc_catcher_state_identity.c +++ b/mach/exc_catcher_state_identity.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/externs.h b/mach/externs.h index 3d013e7..a5482a9 100644 --- a/mach/externs.h +++ b/mach/externs.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/fprintf_stderr.c b/mach/fprintf_stderr.c index 5e4c883..322a6be 100644 --- a/mach/fprintf_stderr.c +++ b/mach/fprintf_stderr.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/headers/errorlib.h b/mach/headers/errorlib.h index d987c0c..d959f36 100644 --- a/mach/headers/errorlib.h +++ b/mach/headers/errorlib.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/headers/mach.h b/mach/headers/mach.h index 657ad6f..be81873 100644 --- a/mach/headers/mach.h +++ b/mach/headers/mach.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/headers/mach_error.h b/mach/headers/mach_error.h index 9443e7f..f101289 100644 --- a/mach/headers/mach_error.h +++ b/mach/headers/mach_error.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/headers/mach_init.h b/mach/headers/mach_init.h index c64c241..396b960 100644 --- a/mach/headers/mach_init.h +++ b/mach/headers/mach_init.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -100,6 +102,8 @@ extern mach_port_t service_port; */ 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)) diff --git a/mach/headers/mach_interface.h b/mach/headers/mach_interface.h index 0afa489..7a9f49e 100644 --- a/mach/headers/mach_interface.h +++ b/mach/headers/mach_interface.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/headers/port_obj.h b/mach/headers/port_obj.h index 2b30528..4c60f6f 100644 --- a/mach/headers/port_obj.h +++ b/mach/headers/port_obj.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/headers/sync.h b/mach/headers/sync.h index d948763..c588a0a 100644 --- a/mach/headers/sync.h +++ b/mach/headers/sync.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/headers/task.h b/mach/headers/task.h index d6eac79..2ab7201 100644 --- a/mach/headers/task.h +++ b/mach/headers/task.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,6 +26,8 @@ #include #elif defined(__ppc__) #include +#elif defined(__ppc64__) +#include #else #error unknown architecture #endif diff --git a/mach/headers/thread_act.h b/mach/headers/thread_act.h index ec40421..e933b90 100644 --- a/mach/headers/thread_act.h +++ b/mach/headers/thread_act.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,6 +26,8 @@ #include #elif defined(__ppc__) #include +#elif defined(__ppc64__) +#include #else #error unknown architecture #endif diff --git a/mach/headers/vm_task.h b/mach/headers/vm_task.h index a8ab751..afd6fa2 100644 --- a/mach/headers/vm_task.h +++ b/mach/headers/vm_task.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/host_priv.defs b/mach/host_priv.defs index e24592a..bfe8aae 100644 --- a/mach/host_priv.defs +++ b/mach/host_priv.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/host_security.defs b/mach/host_security.defs index 5c43238..39cc92a 100644 --- a/mach/host_security.defs +++ b/mach/host_security.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/ledger.defs b/mach/ledger.defs index 841ef8c..96e102e 100644 --- a/mach/ledger.defs +++ b/mach/ledger.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/lock_set.defs b/mach/lock_set.defs index 9c6693d..ed8a276 100644 --- a/mach/lock_set.defs +++ b/mach/lock_set.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/mach_error.c b/mach/mach_error.c index bfd034d..3d67b85 100644 --- a/mach/mach_error.c +++ b/mach/mach_error.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/mach_error_string.c b/mach/mach_error_string.c index 0975343..a3dd3f5 100644 --- a/mach/mach_error_string.c +++ b/mach/mach_error_string.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/mach_host.defs b/mach/mach_host.defs index 496ca14..b68dde5 100644 --- a/mach/mach_host.defs +++ b/mach/mach_host.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/mach_init.c b/mach/mach_init.c index 3b8a352..518c64a 100644 --- a/mach/mach_init.c +++ b/mach/mach_init.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -60,6 +62,8 @@ mach_port_t mach_host_self_ = MACH_PORT_NULL; __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 @@ -137,7 +141,25 @@ int mach_init_doit(int forkchild) * 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); diff --git a/mach/mach_init_ports.c b/mach/mach_init_ports.c index 5d4794e..c0b933a 100644 --- a/mach/mach_init_ports.c +++ b/mach/mach_init_ports.c @@ -1,8 +1,10 @@ /* - * 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 @@ -78,22 +80,6 @@ mach_init_ports(void) 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); @@ -105,6 +91,25 @@ mach_init_ports(void) 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 diff --git a/mach/mach_msg.c b/mach/mach_msg.c index 8d5251a..9af534c 100644 --- a/mach/mach_msg.c +++ b/mach/mach_msg.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/mach_port.defs b/mach/mach_port.defs index 11b50b8..4a6472b 100644 --- a/mach/mach_port.defs +++ b/mach/mach_port.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/mach_traps.s b/mach/mach_traps.s index 9071976..bd4c655 100644 --- a/mach/mach_traps.s +++ b/mach/mach_traps.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/mach_vm.defs b/mach/mach_vm.defs new file mode 100644 index 0000000..93b102e --- /dev/null +++ b/mach/mach_vm.defs @@ -0,0 +1,25 @@ +/* + * 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 diff --git a/mach/mig_allocate.c b/mach/mig_allocate.c index d42f6d3..74b41ba 100644 --- a/mach/mig_allocate.c +++ b/mach/mig_allocate.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/mig_deallocate.c b/mach/mig_deallocate.c index 67c2c9e..098b14c 100644 --- a/mach/mig_deallocate.c +++ b/mach/mig_deallocate.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/mig_reply_setup.c b/mach/mig_reply_setup.c index fd961a8..2faf015 100644 --- a/mach/mig_reply_setup.c +++ b/mach/mig_reply_setup.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/mig_strncpy.c b/mach/mig_strncpy.c index 44e0536..676eee0 100644 --- a/mach/mig_strncpy.c +++ b/mach/mig_strncpy.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/ms_thread_switch.c b/mach/ms_thread_switch.c index 32c5043..72fc09e 100644 --- a/mach/ms_thread_switch.c +++ b/mach/ms_thread_switch.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/notify.defs b/mach/notify.defs index 8821011..fc6581c 100644 --- a/mach/notify.defs +++ b/mach/notify.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/panic.c b/mach/panic.c index b6e91a2..dd6504d 100644 --- a/mach/panic.c +++ b/mach/panic.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/port_obj.c b/mach/port_obj.c index 9690eab..5c313d2 100644 --- a/mach/port_obj.c +++ b/mach/port_obj.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/processor.defs b/mach/processor.defs index c3a96ed..d740ea7 100644 --- a/mach/processor.defs +++ b/mach/processor.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/processor_set.defs b/mach/processor_set.defs index 2b9c480..22b37a4 100644 --- a/mach/processor_set.defs +++ b/mach/processor_set.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/sbrk.c b/mach/sbrk.c index 6f545cf..d03f1a6 100644 --- a/mach/sbrk.c +++ b/mach/sbrk.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/semaphore.c b/mach/semaphore.c index 988c618..114a802 100644 --- a/mach/semaphore.c +++ b/mach/semaphore.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/servers/Makefile.inc b/mach/servers/Makefile.inc index a9ac676..a48455f 100644 --- a/mach/servers/Makefile.inc +++ b/mach/servers/Makefile.inc @@ -10,7 +10,7 @@ SRVHDRS = bootstrap_defs.h netname_defs.h key_defs.h nm_defs.h ls_defs.h 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/} diff --git a/mach/servers/bootstrap_defs.h b/mach/servers/bootstrap_defs.h index 3d7ffe4..f6f74b2 100644 --- a/mach/servers/bootstrap_defs.h +++ b/mach/servers/bootstrap_defs.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/servers/key_defs.h b/mach/servers/key_defs.h index 074d4ee..3c6d661 100644 --- a/mach/servers/key_defs.h +++ b/mach/servers/key_defs.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/servers/ls_defs.h b/mach/servers/ls_defs.h index 64dc4f6..d52fa47 100644 --- a/mach/servers/ls_defs.h +++ b/mach/servers/ls_defs.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/servers/netname.defs b/mach/servers/netname.defs index 7a25618..06363f9 100644 --- a/mach/servers/netname.defs +++ b/mach/servers/netname.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/servers/netname_defs.h b/mach/servers/netname_defs.h index 3180b71..ac38ff1 100644 --- a/mach/servers/netname_defs.h +++ b/mach/servers/netname_defs.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/servers/nm_defs.h b/mach/servers/nm_defs.h index 96a513c..7c4c992 100644 --- a/mach/servers/nm_defs.h +++ b/mach/servers/nm_defs.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/servers/srvbootstrap.defs b/mach/servers/srvbootstrap.defs index d564916..e628cbe 100644 --- a/mach/servers/srvbootstrap.defs +++ b/mach/servers/srvbootstrap.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/slot_name.c b/mach/slot_name.c index 4d72ec0..af17981 100644 --- a/mach/slot_name.c +++ b/mach/slot_name.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/task.defs b/mach/task.defs index 0086d67..cf916bb 100644 --- a/mach/task.defs +++ b/mach/task.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/thread_act.defs b/mach/thread_act.defs index 6e1717d..61c7fc7 100644 --- a/mach/thread_act.defs +++ b/mach/thread_act.defs @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/mach/vm_map.defs b/mach/vm_map.defs index afa199c..7006b2a 100644 --- a/mach/vm_map.defs +++ b/mach/vm_map.defs @@ -1,8 +1,10 @@ /* - * 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 @@ -20,4 +22,16 @@ * * @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 +#else #include +#endif diff --git a/net/Makefile.inc b/net/Makefile.inc index 694bbe3..1267dc4 100644 --- a/net/Makefile.inc +++ b/net/Makefile.inc @@ -5,13 +5,13 @@ .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) diff --git a/nls/Makefile.inc b/nls/Makefile.inc index 94145cf..9c4ee6a 100644 --- a/nls/Makefile.inc +++ b/nls/Makefile.inc @@ -4,12 +4,12 @@ .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" diff --git a/posix1e/Makefile.inc b/posix1e/Makefile.inc index 42b2aa6..28b2840 100644 --- a/posix1e/Makefile.inc +++ b/posix1e/Makefile.inc @@ -4,7 +4,7 @@ MAINTAINER= rwatson@FreeBSD.org .PATH: ${.CURDIR}/../libc/posix1e -SRCS+= acl_calc_mask.c \ +MISRCS+= acl_calc_mask.c \ acl_copy.c \ acl_delete.c \ acl_delete_entry.c \ diff --git a/ppc/gen/Makefile.inc b/ppc/gen/Makefile.inc index 7223519..6f24ab3 100644 --- a/ppc/gen/Makefile.inc +++ b/ppc/gen/Makefile.inc @@ -1,12 +1,11 @@ +.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 diff --git a/ppc/gen/abs.s b/ppc/gen/abs.s index d9c94e1..2ee6d1f 100644 --- a/ppc/gen/abs.s +++ b/ppc/gen/abs.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/gen/assymdefs.c b/ppc/gen/assymdefs.c index 52e75f2..3ec0317 100644 --- a/ppc/gen/assymdefs.c +++ b/ppc/gen/assymdefs.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/gen/bcopy.s b/ppc/gen/bcopy.s deleted file mode 100644 index df9de1a..0000000 --- a/ppc/gen/bcopy.s +++ /dev/null @@ -1,43 +0,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@ - */ - -#define __APPLE_API_PRIVATE -#include -#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 - diff --git a/ppc/gen/bzero.s b/ppc/gen/bzero.s deleted file mode 100644 index 7d205fa..0000000 --- a/ppc/gen/bzero.s +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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 - -#include - - .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 diff --git a/ppc/gen/ecvt.c b/ppc/gen/ecvt.c index 4e1ec51..04e09ef 100644 --- a/ppc/gen/ecvt.c +++ b/ppc/gen/ecvt.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/gen/ffs.s b/ppc/gen/ffs.s index ece1d15..71ecbf8 100644 --- a/ppc/gen/ffs.s +++ b/ppc/gen/ffs.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/gen/fp.h b/ppc/gen/fp.h index 8464507..04620bc 100644 --- a/ppc/gen/fp.h +++ b/ppc/gen/fp.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/gen/genassym.c b/ppc/gen/genassym.c index ac6afca..4eb55e5 100644 --- a/ppc/gen/genassym.c +++ b/ppc/gen/genassym.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/gen/genassym.h b/ppc/gen/genassym.h index 4097703..fefb566 100644 --- a/ppc/gen/genassym.h +++ b/ppc/gen/genassym.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/gen/icacheinval.s b/ppc/gen/icacheinval.s index 82c5845..69ec1a9 100644 --- a/ppc/gen/icacheinval.s +++ b/ppc/gen/icacheinval.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/gen/isinf.c b/ppc/gen/isinf.c deleted file mode 100644 index 693bd84..0000000 --- a/ppc/gen/isinf.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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; -} diff --git a/ppc/gen/mcount.s b/ppc/gen/mcount.s index 6bc402c..6bc91fb 100644 --- a/ppc/gen/mcount.s +++ b/ppc/gen/mcount.s @@ -1,8 +1,10 @@ /* - * 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 @@ -26,19 +28,20 @@ ** */ -#include +/* 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 - .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 diff --git a/ppc/gen/setjmperr.c b/ppc/gen/setjmperr.c index 24403f2..4b9ec69 100644 --- a/ppc/gen/setjmperr.c +++ b/ppc/gen/setjmperr.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/mach/Makefile.inc b/ppc/mach/Makefile.inc index e35f6ab..64c76e4 100644 --- a/ppc/mach/Makefile.inc +++ b/ppc/mach/Makefile.inc @@ -1 +1,2 @@ -SRCS += mach_absolute_time.s +.PATH: ${.CURDIR}/ppc/mach +MDSRCS += mach_absolute_time.s diff --git a/ppc/mach/mach_absolute_time.s b/ppc/mach/mach_absolute_time.s index e28c1fe..52f3fbc 100644 --- a/ppc/mach/mach_absolute_time.s +++ b/ppc/mach/mach_absolute_time.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/pthreads/Makefile.inc b/ppc/pthreads/Makefile.inc index f4f5b0a..0b7a3fc 100644 --- a/ppc/pthreads/Makefile.inc +++ b/ppc/pthreads/Makefile.inc @@ -1,3 +1,4 @@ +.PATH: ${.CURDIR}/ppc/pthreads MDSRCS += \ init_cpu_capabilities.c \ get_cpu_capabilities.s \ diff --git a/ppc/pthreads/get_cpu_capabilities.s b/ppc/pthreads/get_cpu_capabilities.s index 2152993..6b795a7 100644 --- a/ppc/pthreads/get_cpu_capabilities.s +++ b/ppc/pthreads/get_cpu_capabilities.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/pthreads/init_cpu_capabilities.c b/ppc/pthreads/init_cpu_capabilities.c index 67b73bd..e9de34d 100644 --- a/ppc/pthreads/init_cpu_capabilities.c +++ b/ppc/pthreads/init_cpu_capabilities.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/pthreads/pthread_getspecific.s b/ppc/pthreads/pthread_getspecific.s index 41bb4f1..27af77c 100644 --- a/ppc/pthreads/pthread_getspecific.s +++ b/ppc/pthreads/pthread_getspecific.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/pthreads/pthread_self.s b/ppc/pthreads/pthread_self.s index a0c3748..a64ecf2 100644 --- a/ppc/pthreads/pthread_self.s +++ b/ppc/pthreads/pthread_self.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/pthreads/pthread_set_self.s b/ppc/pthreads/pthread_set_self.s index 1396201..b4f6dcb 100644 --- a/ppc/pthreads/pthread_set_self.s +++ b/ppc/pthreads/pthread_set_self.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/string/Makefile.inc b/ppc/string/Makefile.inc index 383a7ba..82f358a 100644 --- a/ppc/string/Makefile.inc +++ b/ppc/string/Makefile.inc @@ -2,7 +2,11 @@ # # PPC-optimised string functions. # +.PATH: ${.CURDIR}/ppc/string + MDSRCS += \ + bcopy.s \ + bzero.s \ memcmp.s \ strcat.s \ strcmp.s \ diff --git a/ppc/string/bcopy.s b/ppc/string/bcopy.s new file mode 100644 index 0000000..6630063 --- /dev/null +++ b/ppc/string/bcopy.s @@ -0,0 +1,45 @@ +/* + * 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 +#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 + diff --git a/ppc/string/bzero.s b/ppc/string/bzero.s new file mode 100644 index 0000000..08c547b --- /dev/null +++ b/ppc/string/bzero.s @@ -0,0 +1,159 @@ +/* + * 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 +#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 + + + .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 + diff --git a/ppc/string/memcmp.s b/ppc/string/memcmp.s index d2baaa4..d127043 100644 --- a/ppc/string/memcmp.s +++ b/ppc/string/memcmp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,6 +26,13 @@ #include #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 + + // *************** *********** // * M E M C M P * and * B C M P * // *************** *********** @@ -39,31 +48,33 @@ // 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 @@ -79,14 +90,14 @@ Lshortloop: 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. @@ -105,14 +116,14 @@ Lbyteloop: 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 @@ -121,40 +132,45 @@ Laligned: 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 diff --git a/ppc/string/strcat.s b/ppc/string/strcat.s index ae30377..f5897b5 100644 --- a/ppc/string/strcat.s +++ b/ppc/string/strcat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,6 +26,17 @@ #include #undef ASSEMBLER +#define __APPLE_API_PRIVATE +#include +#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 + + // *************** // * S T R C A T * // *************** @@ -33,7 +46,7 @@ // 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 @@ -44,75 +57,69 @@ // 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. @@ -133,31 +140,31 @@ Lbyteloop: 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 diff --git a/ppc/string/strcmp.s b/ppc/string/strcmp.s index 98c1824..8c97026 100644 --- a/ppc/string/strcmp.s +++ b/ppc/string/strcmp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,6 +26,17 @@ #include #undef ASSEMBLER +#define __APPLE_API_PRIVATE +#include +#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 + + // *************** // * S T R C M P * // *************** @@ -44,31 +57,36 @@ // 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? @@ -78,37 +96,38 @@ Lbyteloop: 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 @@ -117,7 +136,7 @@ Lunalignedloop: 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 @@ -132,8 +151,8 @@ Lunalignedloop: .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 @@ -147,18 +166,21 @@ Lalignedloop: // 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 diff --git a/ppc/string/strcpy.s b/ppc/string/strcpy.s index bc93346..54d6428 100644 --- a/ppc/string/strcpy.s +++ b/ppc/string/strcpy.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,6 +26,17 @@ #include #undef ASSEMBLER +#define __APPLE_API_PRIVATE +#include +#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 + + // *************** // * S T R C P Y * // *************** @@ -47,22 +60,27 @@ // // 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. @@ -83,31 +101,31 @@ Lbyteloop: 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 diff --git a/ppc/string/strlcat.s b/ppc/string/strlcat.s index 41f0014..d655538 100644 --- a/ppc/string/strlcat.s +++ b/ppc/string/strlcat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,6 +26,17 @@ #include #undef ASSEMBLER +#define __APPLE_API_PRIVATE +#include +#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 + + // ***************** // * S T R L C A T * // ***************** @@ -48,19 +61,24 @@ // // 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 @@ -73,12 +91,12 @@ LEXT(strlcat) // 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 @@ -86,10 +104,10 @@ L0words: 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 @@ -103,7 +121,7 @@ L0words: // 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: @@ -125,11 +143,11 @@ 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. @@ -141,7 +159,7 @@ L0found: // 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 @@ -154,42 +172,42 @@ Lbyteloop1: // entry when we know r5!=0 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 @@ -203,8 +221,8 @@ LwordloopEnter: // 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 @@ -218,18 +236,18 @@ L0stored: 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 diff --git a/ppc/string/strlcpy.s b/ppc/string/strlcpy.s index aeedf5f..1c71889 100644 --- a/ppc/string/strlcpy.s +++ b/ppc/string/strlcpy.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,6 +26,17 @@ #include #undef ASSEMBLER +#define __APPLE_API_PRIVATE +#include +#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 + + // ***************** // * S T R L C P Y * // ***************** @@ -44,22 +57,27 @@ // 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) @@ -82,40 +100,40 @@ Lbyteloop: 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 @@ -124,12 +142,12 @@ LwordloopEnter: 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 @@ -139,19 +157,19 @@ L0found: 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. diff --git a/ppc/string/strlen.s b/ppc/string/strlen.s index fcd8408..e32c0ce 100644 --- a/ppc/string/strlen.s +++ b/ppc/string/strlen.s @@ -1,8 +1,10 @@ /* - * 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 @@ -20,96 +22,82 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#define ASSEMBLER -#include -#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 -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 -; 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 +#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 diff --git a/ppc/string/strncat.s b/ppc/string/strncat.s index ab53914..65e418f 100644 --- a/ppc/string/strncat.s +++ b/ppc/string/strncat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,6 +26,17 @@ #include #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 + +#define __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE + + // ***************** // * S T R N C A T * // ***************** @@ -48,71 +61,70 @@ // 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) @@ -123,7 +135,7 @@ Lword0loop: // 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 @@ -135,40 +147,40 @@ Lbyteloop: 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 @@ -177,12 +189,12 @@ LwordloopEnter: 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 @@ -190,17 +202,17 @@ Lstorelastbytes: 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 diff --git a/ppc/string/strncmp.s b/ppc/string/strncmp.s index 0705cf8..dfd6003 100644 --- a/ppc/string/strncmp.s +++ b/ppc/string/strncmp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,6 +26,17 @@ #include #undef ASSEMBLER +#define __APPLE_API_PRIVATE +#include +#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 + + // ***************** // * S T R N C M P * // ***************** @@ -44,70 +57,76 @@ // 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? @@ -117,46 +136,46 @@ Lbyteloop: 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 @@ -171,14 +190,19 @@ Lwordloop: // 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 diff --git a/ppc/string/strncpy.s b/ppc/string/strncpy.s index 0b5777a..fda3976 100644 --- a/ppc/string/strncpy.s +++ b/ppc/string/strncpy.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,11 +26,22 @@ #include #undef ASSEMBLER +#define __APPLE_API_PRIVATE +#include +#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 + + // ***************** // * 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 @@ -44,23 +57,28 @@ // 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) @@ -72,148 +90,83 @@ LEXT(strncpy) // 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 - - - diff --git a/ppc/sys/ATPgetreq.s b/ppc/sys/ATPgetreq.s index b7c1af2..e5e9421 100644 --- a/ppc/sys/ATPgetreq.s +++ b/ppc/sys/ATPgetreq.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/ATPgetrsp.s b/ppc/sys/ATPgetrsp.s index 5d23b06..d76c6b0 100644 --- a/ppc/sys/ATPgetrsp.s +++ b/ppc/sys/ATPgetrsp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/ATPsndreq.s b/ppc/sys/ATPsndreq.s index 9c30a75..fc5e89f 100644 --- a/ppc/sys/ATPsndreq.s +++ b/ppc/sys/ATPsndreq.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/ATPsndrsp.s b/ppc/sys/ATPsndrsp.s index 0cead0e..95b5cc3 100644 --- a/ppc/sys/ATPsndrsp.s +++ b/ppc/sys/ATPsndrsp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/ATgetmsg.s b/ppc/sys/ATgetmsg.s index 043942d..c7a9d3c 100644 --- a/ppc/sys/ATgetmsg.s +++ b/ppc/sys/ATgetmsg.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/ATputmsg.s b/ppc/sys/ATputmsg.s index bf42d1c..bba995d 100644 --- a/ppc/sys/ATputmsg.s +++ b/ppc/sys/ATputmsg.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/ATsocket.s b/ppc/sys/ATsocket.s index 4aa08a7..b509411 100644 --- a/ppc/sys/ATsocket.s +++ b/ppc/sys/ATsocket.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/Makefile.inc b/ppc/sys/Makefile.inc index 0db3418..64853bc 100644 --- a/ppc/sys/Makefile.inc +++ b/ppc/sys/Makefile.inc @@ -1,10 +1,12 @@ -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 \ @@ -27,6 +29,7 @@ SRCS+= ATPgetreq.s \ audit.s \ auditctl.s \ auditon.s \ + auditsvc.s \ bind.s \ cerror.s \ chdir.s \ @@ -46,11 +49,15 @@ SRCS+= ATPgetreq.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 \ @@ -71,8 +78,8 @@ SRCS+= ATPgetreq.s \ getgroups.s \ getitimer.s \ getpeername.s \ - getpgrp.s \ getpgid.s \ + getpgrp.s \ getpid.s \ getppid.s \ getpriority.s \ @@ -81,8 +88,8 @@ SRCS+= ATPgetreq.s \ getsid.s \ getsockname.s \ getsockopt.s \ - ppc_gettimeofday.s \ getuid.s \ + getxattr.s \ ioctl.s \ issetugid.s \ kevent.s \ @@ -91,9 +98,11 @@ SRCS+= ATPgetreq.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 \ @@ -127,12 +136,13 @@ SRCS+= ATPgetreq.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 \ @@ -141,6 +151,7 @@ SRCS+= ATPgetreq.s \ reboot.s \ recvfrom.s \ recvmsg.s \ + removexattr.s \ rename.s \ reset_shared_file.s \ revoke.s \ @@ -180,6 +191,7 @@ SRCS+= ATPgetreq.s \ setsockopt.s \ settimeofday.s \ setuid.s \ + setxattr.s \ shmat.s \ shmctl.s \ shmdt.s \ @@ -211,3 +223,9 @@ SRCS+= ATPgetreq.s \ wait4.s \ write.s \ writev.s + +.for _src in fhopen.s getfh.s nfsclnt.s +CFLAGS-${_src} += -DNFSCLIENT +.endfor + +CFLAGS-nfssvc.s += -DNFSSERVER diff --git a/ppc/sys/OSAtomic.s b/ppc/sys/OSAtomic.s new file mode 100644 index 0000000..d268085 --- /dev/null +++ b/ppc/sys/OSAtomic.s @@ -0,0 +1,199 @@ +/* + * 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 +#undef __APPLE_API_PRIVATE + +#include + + +/* These are the functions in . + * 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 + diff --git a/ppc/sys/SYS.h b/ppc/sys/SYS.h index 9a8f440..602d97f 100644 --- a/ppc/sys/SYS.h +++ b/ppc/sys/SYS.h @@ -1,8 +1,10 @@ /* - * 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 @@ -41,13 +43,10 @@ * Created. */ -#define KERNEL_PRIVATE 1 /* * Header files. */ -#import -#import -#import +#include #import /* From rhapsody kernel mach/ppc/syscall_sw.h */ @@ -70,8 +69,7 @@ _##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) @@ -111,54 +109,34 @@ _##trap_name: @\ #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 - -#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 diff --git a/ppc/sys/_exit.s b/ppc/sys/_exit.s index ce75ddb..a3a5867 100644 --- a/ppc/sys/_exit.s +++ b/ppc/sys/_exit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/_getlogin.s b/ppc/sys/_getlogin.s index b37dee5..cdde9da 100644 --- a/ppc/sys/_getlogin.s +++ b/ppc/sys/_getlogin.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/_longjmp.s b/ppc/sys/_longjmp.s index fdb851b..35633c5 100644 --- a/ppc/sys/_longjmp.s +++ b/ppc/sys/_longjmp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -21,9 +23,6 @@ * @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. * @@ -36,190 +35,142 @@ * Created. Derived from longjmp.s */ -#include -#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 -/* 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 +#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 diff --git a/ppc/sys/_pthread_kill.s b/ppc/sys/_pthread_kill.s index bb863c0..5285149 100644 --- a/ppc/sys/_pthread_kill.s +++ b/ppc/sys/_pthread_kill.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/_setjmp.h b/ppc/sys/_setjmp.h index a1776a7..8d5da57 100644 --- a/ppc/sys/_setjmp.h +++ b/ppc/sys/_setjmp.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -35,8 +37,19 @@ * 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 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 @@ -60,11 +73,9 @@ #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 */ @@ -74,3 +85,46 @@ /* 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 diff --git a/ppc/sys/_setjmp.s b/ppc/sys/_setjmp.s index 86d4ecd..e934bcc 100644 --- a/ppc/sys/_setjmp.s +++ b/ppc/sys/_setjmp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -34,102 +36,55 @@ * 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 + +#define __APPLE_API_PRIVATE +#include +#undef __APPLE_API_PRIVATE -#include #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) @@ -148,8 +103,42 @@ LSaveFPRsIfNecessary: 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 diff --git a/ppc/sys/_setlogin.s b/ppc/sys/_setlogin.s index cc99282..10452c9 100644 --- a/ppc/sys/_setlogin.s +++ b/ppc/sys/_setlogin.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/_sysctl.s b/ppc/sys/_sysctl.s index 1322e52..cd04a03 100644 --- a/ppc/sys/_sysctl.s +++ b/ppc/sys/_sysctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/accept.s b/ppc/sys/accept.s index 320cf43..8eaf81a 100644 --- a/ppc/sys/accept.s +++ b/ppc/sys/accept.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/access.s b/ppc/sys/access.s index 49d0b3b..7b68e5c 100644 --- a/ppc/sys/access.s +++ b/ppc/sys/access.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/acct.s b/ppc/sys/acct.s index 1c0581d..641f682 100644 --- a/ppc/sys/acct.s +++ b/ppc/sys/acct.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/add_profil.s b/ppc/sys/add_profil.s index 8baa49a..de3191c 100644 --- a/ppc/sys/add_profil.s +++ b/ppc/sys/add_profil.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/adjtime.s b/ppc/sys/adjtime.s index 2b50258..88cfe36 100644 --- a/ppc/sys/adjtime.s +++ b/ppc/sys/adjtime.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/aio_cancel.s b/ppc/sys/aio_cancel.s index 918e1bf..45b2b91 100644 --- a/ppc/sys/aio_cancel.s +++ b/ppc/sys/aio_cancel.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/aio_error.s b/ppc/sys/aio_error.s index 6a559e4..1586c01 100644 --- a/ppc/sys/aio_error.s +++ b/ppc/sys/aio_error.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/aio_fsync.s b/ppc/sys/aio_fsync.s index becaad5..ad5e848 100644 --- a/ppc/sys/aio_fsync.s +++ b/ppc/sys/aio_fsync.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/aio_read.s b/ppc/sys/aio_read.s index 87f99a2..e275d1f 100644 --- a/ppc/sys/aio_read.s +++ b/ppc/sys/aio_read.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/aio_return.s b/ppc/sys/aio_return.s index a58039f..a82bd0a 100644 --- a/ppc/sys/aio_return.s +++ b/ppc/sys/aio_return.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/aio_suspend.s b/ppc/sys/aio_suspend.s index 9250c5f..80b8ae3 100644 --- a/ppc/sys/aio_suspend.s +++ b/ppc/sys/aio_suspend.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/aio_write.s b/ppc/sys/aio_write.s index 348e2ac..7de36b9 100644 --- a/ppc/sys/aio_write.s +++ b/ppc/sys/aio_write.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/assym.h b/ppc/sys/assym.h index c025721..26fd81a 100644 --- a/ppc/sys/assym.h +++ b/ppc/sys/assym.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/assymdefs.c b/ppc/sys/assymdefs.c index 407e9ea..c1569a6 100644 --- a/ppc/sys/assymdefs.c +++ b/ppc/sys/assymdefs.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/audit.s b/ppc/sys/audit.s index ec20e21..9116a19 100644 --- a/ppc/sys/audit.s +++ b/ppc/sys/audit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/auditctl.s b/ppc/sys/auditctl.s index 9f6a4e0..d3516f9 100644 --- a/ppc/sys/auditctl.s +++ b/ppc/sys/auditctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/auditon.s b/ppc/sys/auditon.s index a35ddc4..eba3dfe 100644 --- a/ppc/sys/auditon.s +++ b/ppc/sys/auditon.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/auditsvc.s b/ppc/sys/auditsvc.s new file mode 100644 index 0000000..fc4938c --- /dev/null +++ b/ppc/sys/auditsvc.s @@ -0,0 +1,28 @@ +/* + * 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) + diff --git a/ppc/sys/bind.s b/ppc/sys/bind.s index e685351..f3a0061 100644 --- a/ppc/sys/bind.s +++ b/ppc/sys/bind.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/cerror.s b/ppc/sys/cerror.s index 21ed018..47d7dad 100644 --- a/ppc/sys/cerror.s +++ b/ppc/sys/cerror.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -23,15 +25,20 @@ /* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ -#import -#import +/* 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 - .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 diff --git a/ppc/sys/chdir.s b/ppc/sys/chdir.s index b2e0d57..283b048 100644 --- a/ppc/sys/chdir.s +++ b/ppc/sys/chdir.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/checkuseraccess.s b/ppc/sys/checkuseraccess.s index c1ebd0f..6ca50f2 100644 --- a/ppc/sys/checkuseraccess.s +++ b/ppc/sys/checkuseraccess.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/chflags.s b/ppc/sys/chflags.s index 930eb4e..64c2df6 100644 --- a/ppc/sys/chflags.s +++ b/ppc/sys/chflags.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/chmod.s b/ppc/sys/chmod.s index 2a46c09..22c8b66 100644 --- a/ppc/sys/chmod.s +++ b/ppc/sys/chmod.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/chown.s b/ppc/sys/chown.s index 7008e88..073e2e5 100644 --- a/ppc/sys/chown.s +++ b/ppc/sys/chown.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/chroot.s b/ppc/sys/chroot.s index f3fd6c9..1f8fd40 100644 --- a/ppc/sys/chroot.s +++ b/ppc/sys/chroot.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/close.s b/ppc/sys/close.s index dc41a36..6233e25 100644 --- a/ppc/sys/close.s +++ b/ppc/sys/close.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/connect.s b/ppc/sys/connect.s index 4acc90c..97d0c71 100644 --- a/ppc/sys/connect.s +++ b/ppc/sys/connect.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/dup.s b/ppc/sys/dup.s index c68af1d..cd10ee7 100644 --- a/ppc/sys/dup.s +++ b/ppc/sys/dup.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/dup2.s b/ppc/sys/dup2.s index bcb5a38..682ab94 100644 --- a/ppc/sys/dup2.s +++ b/ppc/sys/dup2.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/exchangedata.s b/ppc/sys/exchangedata.s index 96b73f8..ea64f83 100644 --- a/ppc/sys/exchangedata.s +++ b/ppc/sys/exchangedata.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/execve.s b/ppc/sys/execve.s index 667b09f..6acbd68 100644 --- a/ppc/sys/execve.s +++ b/ppc/sys/execve.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fchdir.s b/ppc/sys/fchdir.s index 131d989..bf7829a 100644 --- a/ppc/sys/fchdir.s +++ b/ppc/sys/fchdir.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fchflags.s b/ppc/sys/fchflags.s index 3538f84..1ceb03c 100644 --- a/ppc/sys/fchflags.s +++ b/ppc/sys/fchflags.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fchmod.s b/ppc/sys/fchmod.s index dc8e29f..70e3e41 100644 --- a/ppc/sys/fchmod.s +++ b/ppc/sys/fchmod.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fchown.s b/ppc/sys/fchown.s index 919ccd4..b87d806 100644 --- a/ppc/sys/fchown.s +++ b/ppc/sys/fchown.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fcntl.s b/ppc/sys/fcntl.s index 25f6bca..1601e3a 100644 --- a/ppc/sys/fcntl.s +++ b/ppc/sys/fcntl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fgetxattr.s b/ppc/sys/fgetxattr.s new file mode 100644 index 0000000..c01ab45 --- /dev/null +++ b/ppc/sys/fgetxattr.s @@ -0,0 +1,28 @@ +/* + * 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) + diff --git a/ppc/sys/fhopen.s b/ppc/sys/fhopen.s index 3875be8..ba404ae 100644 --- a/ppc/sys/fhopen.s +++ b/ppc/sys/fhopen.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/flistxattr.s b/ppc/sys/flistxattr.s new file mode 100644 index 0000000..870f56a --- /dev/null +++ b/ppc/sys/flistxattr.s @@ -0,0 +1,28 @@ +/* + * 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) + diff --git a/ppc/sys/flock.s b/ppc/sys/flock.s index 67eafdf..3e035bf 100644 --- a/ppc/sys/flock.s +++ b/ppc/sys/flock.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fork.s b/ppc/sys/fork.s index ae1f825..03e7187 100644 --- a/ppc/sys/fork.s +++ b/ppc/sys/fork.s @@ -1,8 +1,10 @@ /* - * 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 @@ -32,134 +34,160 @@ * Created from M68K sources */ -#import -#import -#import -#import +/* 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 + +#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 diff --git a/ppc/sys/fpathconf.s b/ppc/sys/fpathconf.s index 8ac0e15..291069e 100644 --- a/ppc/sys/fpathconf.s +++ b/ppc/sys/fpathconf.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fremovexattr.s b/ppc/sys/fremovexattr.s new file mode 100644 index 0000000..12c01e1 --- /dev/null +++ b/ppc/sys/fremovexattr.s @@ -0,0 +1,28 @@ +/* + * 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) + diff --git a/ppc/sys/fsctl.s b/ppc/sys/fsctl.s index 2788c94..3e0302f 100644 --- a/ppc/sys/fsctl.s +++ b/ppc/sys/fsctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fsetxattr.s b/ppc/sys/fsetxattr.s new file mode 100644 index 0000000..1b945e4 --- /dev/null +++ b/ppc/sys/fsetxattr.s @@ -0,0 +1,28 @@ +/* + * 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) + diff --git a/ppc/sys/fstat.s b/ppc/sys/fstat.s index 6992c31..bd36610 100644 --- a/ppc/sys/fstat.s +++ b/ppc/sys/fstat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fstatfs.s b/ppc/sys/fstatfs.s index 8c1b15a..b0476f7 100644 --- a/ppc/sys/fstatfs.s +++ b/ppc/sys/fstatfs.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fstatv.s b/ppc/sys/fstatv.s index 07dc617..4f6dd04 100644 --- a/ppc/sys/fstatv.s +++ b/ppc/sys/fstatv.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/fsync.s b/ppc/sys/fsync.s index acfa327..c673e49 100644 --- a/ppc/sys/fsync.s +++ b/ppc/sys/fsync.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/ftruncate.s b/ppc/sys/ftruncate.s index 86c3ded..c9a77d4 100644 --- a/ppc/sys/ftruncate.s +++ b/ppc/sys/ftruncate.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/futimes.s b/ppc/sys/futimes.s index 84f001f..208726d 100644 --- a/ppc/sys/futimes.s +++ b/ppc/sys/futimes.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/genassym.c b/ppc/sys/genassym.c index ac6afca..4eb55e5 100644 --- a/ppc/sys/genassym.c +++ b/ppc/sys/genassym.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/genassym.h b/ppc/sys/genassym.h index 4097703..fefb566 100644 --- a/ppc/sys/genassym.h +++ b/ppc/sys/genassym.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getattrlist.s b/ppc/sys/getattrlist.s index 1f01edb..462adf3 100644 --- a/ppc/sys/getattrlist.s +++ b/ppc/sys/getattrlist.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getaudit.s b/ppc/sys/getaudit.s index 87cd358..40ffe13 100644 --- a/ppc/sys/getaudit.s +++ b/ppc/sys/getaudit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getaudit_addr.s b/ppc/sys/getaudit_addr.s index 091af6d..10ca54b 100644 --- a/ppc/sys/getaudit_addr.s +++ b/ppc/sys/getaudit_addr.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getauid.s b/ppc/sys/getauid.s index 1f3cd17..2fe23e4 100644 --- a/ppc/sys/getauid.s +++ b/ppc/sys/getauid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getdirentries.s b/ppc/sys/getdirentries.s index 4fc362f..c14ae25 100644 --- a/ppc/sys/getdirentries.s +++ b/ppc/sys/getdirentries.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getdirentriesattr.s b/ppc/sys/getdirentriesattr.s index 4f5e0bb..c31ee72 100644 --- a/ppc/sys/getdirentriesattr.s +++ b/ppc/sys/getdirentriesattr.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getegid.s b/ppc/sys/getegid.s index c7839ee..20d5b72 100644 --- a/ppc/sys/getegid.s +++ b/ppc/sys/getegid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -26,7 +28,5 @@ #import "SYS.h" -PSEUDO(getegid,getgid,0) - mr a0,a1 - blr +SYSCALL(getegid,0) diff --git a/ppc/sys/geteuid.s b/ppc/sys/geteuid.s index a997ace..34bb207 100644 --- a/ppc/sys/geteuid.s +++ b/ppc/sys/geteuid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -26,7 +28,4 @@ #import "SYS.h" -PSEUDO(geteuid,getuid,0) - mr a0,a1 - blr - +SYSCALL(geteuid,0) diff --git a/ppc/sys/getfh.s b/ppc/sys/getfh.s index 25312a8..3fdf12b 100644 --- a/ppc/sys/getfh.s +++ b/ppc/sys/getfh.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getfsstat.s b/ppc/sys/getfsstat.s index 58dc985..fe4a95c 100644 --- a/ppc/sys/getfsstat.s +++ b/ppc/sys/getfsstat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getgid.s b/ppc/sys/getgid.s index e9d1ca4..5c36fb8 100644 --- a/ppc/sys/getgid.s +++ b/ppc/sys/getgid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getgroups.s b/ppc/sys/getgroups.s index aeade81..fa977b1 100644 --- a/ppc/sys/getgroups.s +++ b/ppc/sys/getgroups.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getitimer.s b/ppc/sys/getitimer.s index a1b2c7c..84b9bad 100644 --- a/ppc/sys/getitimer.s +++ b/ppc/sys/getitimer.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getpeername.s b/ppc/sys/getpeername.s index dda54d4..d9180a8 100644 --- a/ppc/sys/getpeername.s +++ b/ppc/sys/getpeername.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getpgid.s b/ppc/sys/getpgid.s index 96b2861..716530d 100644 --- a/ppc/sys/getpgid.s +++ b/ppc/sys/getpgid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getpgrp.s b/ppc/sys/getpgrp.s index 11fc616..0ceb7ec 100644 --- a/ppc/sys/getpgrp.s +++ b/ppc/sys/getpgrp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getpid.s b/ppc/sys/getpid.s index 21dc1ba..f86505b 100644 --- a/ppc/sys/getpid.s +++ b/ppc/sys/getpid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -21,34 +23,39 @@ * @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 diff --git a/ppc/sys/getppid.s b/ppc/sys/getppid.s index b3cfc10..12316a2 100644 --- a/ppc/sys/getppid.s +++ b/ppc/sys/getppid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -26,7 +28,5 @@ #import "SYS.h" -PSEUDO(getppid,getpid,0) - mr a0,a1 - blr +SYSCALL(getppid,0) diff --git a/ppc/sys/getpriority.s b/ppc/sys/getpriority.s index 53783b3..d8d8644 100644 --- a/ppc/sys/getpriority.s +++ b/ppc/sys/getpriority.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getrlimit.s b/ppc/sys/getrlimit.s index 7b4ea0a..efe4583 100644 --- a/ppc/sys/getrlimit.s +++ b/ppc/sys/getrlimit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getrusage.s b/ppc/sys/getrusage.s index 7b66a4b..d1f3249 100644 --- a/ppc/sys/getrusage.s +++ b/ppc/sys/getrusage.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getsid.s b/ppc/sys/getsid.s index f9cfe99..5885484 100644 --- a/ppc/sys/getsid.s +++ b/ppc/sys/getsid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getsockname.s b/ppc/sys/getsockname.s index 8e3fb84..f368357 100644 --- a/ppc/sys/getsockname.s +++ b/ppc/sys/getsockname.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getsockopt.s b/ppc/sys/getsockopt.s index cd46a42..bfdd42f 100644 --- a/ppc/sys/getsockopt.s +++ b/ppc/sys/getsockopt.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getuid.s b/ppc/sys/getuid.s index f1f41fb..a0f8af8 100644 --- a/ppc/sys/getuid.s +++ b/ppc/sys/getuid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/getxattr.s b/ppc/sys/getxattr.s new file mode 100644 index 0000000..30d3843 --- /dev/null +++ b/ppc/sys/getxattr.s @@ -0,0 +1,28 @@ +/* + * 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) + diff --git a/ppc/sys/ioctl.s b/ppc/sys/ioctl.s index 5d19770..c24fe7a 100644 --- a/ppc/sys/ioctl.s +++ b/ppc/sys/ioctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/issetugid.s b/ppc/sys/issetugid.s index 65435f9..2353adc 100644 --- a/ppc/sys/issetugid.s +++ b/ppc/sys/issetugid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/kevent.s b/ppc/sys/kevent.s index a0471af..e770620 100644 --- a/ppc/sys/kevent.s +++ b/ppc/sys/kevent.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/kill.s b/ppc/sys/kill.s index 01628d1..b2dfe42 100644 --- a/ppc/sys/kill.s +++ b/ppc/sys/kill.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/kqueue.s b/ppc/sys/kqueue.s index dfde475..14be6b3 100644 --- a/ppc/sys/kqueue.s +++ b/ppc/sys/kqueue.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/kqueue_from_portset_np.s b/ppc/sys/kqueue_from_portset_np.s index 8e88cb2..fc2ddcc 100644 --- a/ppc/sys/kqueue_from_portset_np.s +++ b/ppc/sys/kqueue_from_portset_np.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/kqueue_portset_np.s b/ppc/sys/kqueue_portset_np.s index 4ab1c78..ce2c5c4 100644 --- a/ppc/sys/kqueue_portset_np.s +++ b/ppc/sys/kqueue_portset_np.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/ktrace.s b/ppc/sys/ktrace.s index c759ae6..ec8b0b5 100644 --- a/ppc/sys/ktrace.s +++ b/ppc/sys/ktrace.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/lchown.s b/ppc/sys/lchown.s new file mode 100644 index 0000000..980726e --- /dev/null +++ b/ppc/sys/lchown.s @@ -0,0 +1,28 @@ +/* + * 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) + diff --git a/ppc/sys/link.s b/ppc/sys/link.s index f37dabf..66213fc 100644 --- a/ppc/sys/link.s +++ b/ppc/sys/link.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/lio_listio.s b/ppc/sys/lio_listio.s index 819613e..211987b 100644 --- a/ppc/sys/lio_listio.s +++ b/ppc/sys/lio_listio.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/listen.s b/ppc/sys/listen.s index fa7ed22..98bfeee 100644 --- a/ppc/sys/listen.s +++ b/ppc/sys/listen.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/listxattr.s b/ppc/sys/listxattr.s new file mode 100644 index 0000000..7f01ec7 --- /dev/null +++ b/ppc/sys/listxattr.s @@ -0,0 +1,28 @@ +/* + * 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) + diff --git a/ppc/sys/load_shared_file.s b/ppc/sys/load_shared_file.s index 7f32fb1..14e3731 100644 --- a/ppc/sys/load_shared_file.s +++ b/ppc/sys/load_shared_file.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/longjmp.s b/ppc/sys/longjmp.s index 366f930..34f554e 100644 --- a/ppc/sys/longjmp.s +++ b/ppc/sys/longjmp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -34,8 +36,14 @@ * 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 + #include "SYS.h" -#include #include "_setjmp.h" /* @@ -44,21 +52,24 @@ /* 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) diff --git a/ppc/sys/lseek.s b/ppc/sys/lseek.s index ee09f5c..073f3da 100644 --- a/ppc/sys/lseek.s +++ b/ppc/sys/lseek.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/lstat.s b/ppc/sys/lstat.s index e02665e..0528b42 100644 --- a/ppc/sys/lstat.s +++ b/ppc/sys/lstat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/lstatv.s b/ppc/sys/lstatv.s index d9d2ea9..da5a26e 100644 --- a/ppc/sys/lstatv.s +++ b/ppc/sys/lstatv.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/madvise.s b/ppc/sys/madvise.s index ef7a6b9..5232b4b 100644 --- a/ppc/sys/madvise.s +++ b/ppc/sys/madvise.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/mincore.s b/ppc/sys/mincore.s index a2be47d..f1df7c9 100644 --- a/ppc/sys/mincore.s +++ b/ppc/sys/mincore.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/minherit.s b/ppc/sys/minherit.s index b733f5a..1586259 100644 --- a/ppc/sys/minherit.s +++ b/ppc/sys/minherit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/mkcomplex.s b/ppc/sys/mkcomplex.s index 3da9fa7..ba5b176 100644 --- a/ppc/sys/mkcomplex.s +++ b/ppc/sys/mkcomplex.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/mkdir.s b/ppc/sys/mkdir.s index 7e0e868..dbbfd00 100644 --- a/ppc/sys/mkdir.s +++ b/ppc/sys/mkdir.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/mkfifo.s b/ppc/sys/mkfifo.s index 0211ff6..135a6c6 100644 --- a/ppc/sys/mkfifo.s +++ b/ppc/sys/mkfifo.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/mknod.s b/ppc/sys/mknod.s index 52dabe5..df6054c 100644 --- a/ppc/sys/mknod.s +++ b/ppc/sys/mknod.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/mlock.s b/ppc/sys/mlock.s index 664ae6c..a4174d7 100644 --- a/ppc/sys/mlock.s +++ b/ppc/sys/mlock.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/mlockall.s b/ppc/sys/mlockall.s index aa2f01c..e61774a 100644 --- a/ppc/sys/mlockall.s +++ b/ppc/sys/mlockall.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/mmap.s b/ppc/sys/mmap.s index d4bf380..623dd7a 100644 --- a/ppc/sys/mmap.s +++ b/ppc/sys/mmap.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/mount.s b/ppc/sys/mount.s index e71e807..2ca8e96 100644 --- a/ppc/sys/mount.s +++ b/ppc/sys/mount.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -22,7 +24,6 @@ */ /* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved. */ -#import #import "SYS.h" SYSCALL(mount, 4) diff --git a/ppc/sys/mprotect.s b/ppc/sys/mprotect.s index 76b05c8..eab28c3 100644 --- a/ppc/sys/mprotect.s +++ b/ppc/sys/mprotect.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/msgctl.s b/ppc/sys/msgctl.s index b04f788..86b873f 100644 --- a/ppc/sys/msgctl.s +++ b/ppc/sys/msgctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/msgget.s b/ppc/sys/msgget.s index 1e5e544..b1c91b6 100644 --- a/ppc/sys/msgget.s +++ b/ppc/sys/msgget.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/msgrcv.s b/ppc/sys/msgrcv.s index db69ab6..411aebf 100644 --- a/ppc/sys/msgrcv.s +++ b/ppc/sys/msgrcv.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/msgsnd.s b/ppc/sys/msgsnd.s index bf4c21a..bc5c10e 100644 --- a/ppc/sys/msgsnd.s +++ b/ppc/sys/msgsnd.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/msgsys.s b/ppc/sys/msgsys.s index da09564..e2657d4 100644 --- a/ppc/sys/msgsys.s +++ b/ppc/sys/msgsys.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/msync.s b/ppc/sys/msync.s index 57f282d..8e683c8 100644 --- a/ppc/sys/msync.s +++ b/ppc/sys/msync.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/munlock.s b/ppc/sys/munlock.s index fd8c52d..1807a27 100644 --- a/ppc/sys/munlock.s +++ b/ppc/sys/munlock.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/munlockall.s b/ppc/sys/munlockall.s index fe5f9cf..8d8d350 100644 --- a/ppc/sys/munlockall.s +++ b/ppc/sys/munlockall.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/munmap.s b/ppc/sys/munmap.s index 9402cd9..426aa31 100644 --- a/ppc/sys/munmap.s +++ b/ppc/sys/munmap.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/new_system_shared_regions.s b/ppc/sys/new_system_shared_regions.s index 765ae1a..3277bfb 100644 --- a/ppc/sys/new_system_shared_regions.s +++ b/ppc/sys/new_system_shared_regions.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/nfsclnt.s b/ppc/sys/nfsclnt.s index f2a8297..ba7b380 100644 --- a/ppc/sys/nfsclnt.s +++ b/ppc/sys/nfsclnt.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/nfssvc.s b/ppc/sys/nfssvc.s index a03969d..ec06e6b 100644 --- a/ppc/sys/nfssvc.s +++ b/ppc/sys/nfssvc.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/open.s b/ppc/sys/open.s index 1af88bf..d19c77c 100644 --- a/ppc/sys/open.s +++ b/ppc/sys/open.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/pathconf.s b/ppc/sys/pathconf.s index 9150e0a..69d0509 100644 --- a/ppc/sys/pathconf.s +++ b/ppc/sys/pathconf.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/pipe.s b/ppc/sys/pipe.s index 4c0e142..73e9ff5 100644 --- a/ppc/sys/pipe.s +++ b/ppc/sys/pipe.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,11 +26,10 @@ #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 diff --git a/ppc/sys/posix_madvise.s b/ppc/sys/posix_madvise.s index 098f7f5..ab47329 100644 --- a/ppc/sys/posix_madvise.s +++ b/ppc/sys/posix_madvise.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/ppc_gettimeofday.s b/ppc/sys/ppc_gettimeofday.s index 9013f71..ae31d40 100644 --- a/ppc/sys/ppc_gettimeofday.s +++ b/ppc/sys/ppc_gettimeofday.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -28,23 +30,18 @@ #include #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 diff --git a/ppc/sys/pread.s b/ppc/sys/pread.s index 723f6d7..2fb578e 100644 --- a/ppc/sys/pread.s +++ b/ppc/sys/pread.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/processor_facilities.h b/ppc/sys/processor_facilities.h index 2fa6707..82a3abc 100644 --- a/ppc/sys/processor_facilities.h +++ b/ppc/sys/processor_facilities.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/processor_facilities.s b/ppc/sys/processor_facilities.s index 9001dbd..3eafae3 100644 --- a/ppc/sys/processor_facilities.s +++ b/ppc/sys/processor_facilities.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/profil.s b/ppc/sys/profil.s index 705995d..a5c262c 100644 --- a/ppc/sys/profil.s +++ b/ppc/sys/profil.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/pthread_sigmask.s b/ppc/sys/pthread_sigmask.s index 9defe25..31303fd 100644 --- a/ppc/sys/pthread_sigmask.s +++ b/ppc/sys/pthread_sigmask.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/ptrace.s b/ppc/sys/ptrace.s index 32ac334..3eea2dd 100644 --- a/ppc/sys/ptrace.s +++ b/ppc/sys/ptrace.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,8 +26,9 @@ #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 diff --git a/ppc/sys/pwrite.s b/ppc/sys/pwrite.s index 79fb8d0..14f3537 100644 --- a/ppc/sys/pwrite.s +++ b/ppc/sys/pwrite.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/quota.s b/ppc/sys/quota.s index 78ffe62..43911b5 100644 --- a/ppc/sys/quota.s +++ b/ppc/sys/quota.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/quotactl.s b/ppc/sys/quotactl.s index dfa5ee2..7903047 100644 --- a/ppc/sys/quotactl.s +++ b/ppc/sys/quotactl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/read.s b/ppc/sys/read.s index a880698..aa15c49 100644 --- a/ppc/sys/read.s +++ b/ppc/sys/read.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/readlink.s b/ppc/sys/readlink.s index 0c97e93..4e48856 100644 --- a/ppc/sys/readlink.s +++ b/ppc/sys/readlink.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/readv.s b/ppc/sys/readv.s index f2be2d4..5a2a211 100644 --- a/ppc/sys/readv.s +++ b/ppc/sys/readv.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/reboot.s b/ppc/sys/reboot.s index d7743ae..5842c5b 100644 --- a/ppc/sys/reboot.s +++ b/ppc/sys/reboot.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -25,4 +27,4 @@ #import "SYS.h" SYSCALL(reboot, 2) - BRANCH_EXTERN(_abort) + MI_BRANCH_EXTERNAL(_abort) diff --git a/ppc/sys/recvfrom.s b/ppc/sys/recvfrom.s index 71a1390..796191b 100644 --- a/ppc/sys/recvfrom.s +++ b/ppc/sys/recvfrom.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/recvmsg.s b/ppc/sys/recvmsg.s index 40c0837..7cc1ea4 100644 --- a/ppc/sys/recvmsg.s +++ b/ppc/sys/recvmsg.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/removexattr.s b/ppc/sys/removexattr.s new file mode 100644 index 0000000..697583b --- /dev/null +++ b/ppc/sys/removexattr.s @@ -0,0 +1,28 @@ +/* + * 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) + diff --git a/ppc/sys/rename.s b/ppc/sys/rename.s index a4d7a8b..631853b 100644 --- a/ppc/sys/rename.s +++ b/ppc/sys/rename.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/reset_shared_file.s b/ppc/sys/reset_shared_file.s index 2d6517a..5577bf8 100644 --- a/ppc/sys/reset_shared_file.s +++ b/ppc/sys/reset_shared_file.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/revoke.s b/ppc/sys/revoke.s index 6e4248b..49a8b58 100644 --- a/ppc/sys/revoke.s +++ b/ppc/sys/revoke.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/rmdir.s b/ppc/sys/rmdir.s index d06e70c..b38d788 100644 --- a/ppc/sys/rmdir.s +++ b/ppc/sys/rmdir.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/searchfs.s b/ppc/sys/searchfs.s index 523b832..7f8b789 100644 --- a/ppc/sys/searchfs.s +++ b/ppc/sys/searchfs.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/select.s b/ppc/sys/select.s index 171ee24..89a2d31 100644 --- a/ppc/sys/select.s +++ b/ppc/sys/select.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sem_close.s b/ppc/sys/sem_close.s index bafa743..3fb00fe 100644 --- a/ppc/sys/sem_close.s +++ b/ppc/sys/sem_close.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sem_destroy.s b/ppc/sys/sem_destroy.s index 89809ce..3fd2f13 100644 --- a/ppc/sys/sem_destroy.s +++ b/ppc/sys/sem_destroy.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sem_getvalue.s b/ppc/sys/sem_getvalue.s index fb42420..9551dd1 100644 --- a/ppc/sys/sem_getvalue.s +++ b/ppc/sys/sem_getvalue.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sem_init.s b/ppc/sys/sem_init.s index 1f243d5..218f0e9 100644 --- a/ppc/sys/sem_init.s +++ b/ppc/sys/sem_init.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sem_post.s b/ppc/sys/sem_post.s index 4f2829c..a9e585c 100644 --- a/ppc/sys/sem_post.s +++ b/ppc/sys/sem_post.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sem_trywait.s b/ppc/sys/sem_trywait.s index a1db0f0..1c8f5fe 100644 --- a/ppc/sys/sem_trywait.s +++ b/ppc/sys/sem_trywait.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sem_wait.s b/ppc/sys/sem_wait.s index 9e309e5..3593a08 100644 --- a/ppc/sys/sem_wait.s +++ b/ppc/sys/sem_wait.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/semconfig.s b/ppc/sys/semconfig.s index 3ea04d7..314e4ba 100644 --- a/ppc/sys/semconfig.s +++ b/ppc/sys/semconfig.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/semctl.s b/ppc/sys/semctl.s index 1fe89eb..c0e6d9f 100644 --- a/ppc/sys/semctl.s +++ b/ppc/sys/semctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/semget.s b/ppc/sys/semget.s index 66181f3..c86f9bc 100644 --- a/ppc/sys/semget.s +++ b/ppc/sys/semget.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/semop.s b/ppc/sys/semop.s index 0d55e79..b8b9738 100644 --- a/ppc/sys/semop.s +++ b/ppc/sys/semop.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/semsys.s b/ppc/sys/semsys.s index 98caf93..1882ec9 100644 --- a/ppc/sys/semsys.s +++ b/ppc/sys/semsys.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sendmsg.s b/ppc/sys/sendmsg.s index 9895f3d..0f9331c 100644 --- a/ppc/sys/sendmsg.s +++ b/ppc/sys/sendmsg.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sendto.s b/ppc/sys/sendto.s index 5c2daa3..c1093e8 100644 --- a/ppc/sys/sendto.s +++ b/ppc/sys/sendto.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setattrlist.s b/ppc/sys/setattrlist.s index 21a7260..c37ca78 100644 --- a/ppc/sys/setattrlist.s +++ b/ppc/sys/setattrlist.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setaudit.s b/ppc/sys/setaudit.s index 7d49366..b0d323b 100644 --- a/ppc/sys/setaudit.s +++ b/ppc/sys/setaudit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setaudit_addr.s b/ppc/sys/setaudit_addr.s index dd56b59..20fe96a 100644 --- a/ppc/sys/setaudit_addr.s +++ b/ppc/sys/setaudit_addr.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setauid.s b/ppc/sys/setauid.s index 9c48fb3..c1ec307 100644 --- a/ppc/sys/setauid.s +++ b/ppc/sys/setauid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setegid.s b/ppc/sys/setegid.s index ba3fe64..23a2d27 100644 --- a/ppc/sys/setegid.s +++ b/ppc/sys/setegid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/seteuid.s b/ppc/sys/seteuid.s index 00e0a3a..85af2d9 100644 --- a/ppc/sys/seteuid.s +++ b/ppc/sys/seteuid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setgid.s b/ppc/sys/setgid.s index 2bafccb..b883df5 100644 --- a/ppc/sys/setgid.s +++ b/ppc/sys/setgid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setgroups.s b/ppc/sys/setgroups.s index b86d5f3..226ba88 100644 --- a/ppc/sys/setgroups.s +++ b/ppc/sys/setgroups.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setitimer.s b/ppc/sys/setitimer.s index 5c94832..268153f 100644 --- a/ppc/sys/setitimer.s +++ b/ppc/sys/setitimer.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setjmp.s b/ppc/sys/setjmp.s index cae2564..4a6492c 100644 --- a/ppc/sys/setjmp.s +++ b/ppc/sys/setjmp.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -34,8 +36,14 @@ * 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 + #include "SYS.h" -#include #include "_setjmp.h" /* @@ -44,27 +52,26 @@ /* 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) diff --git a/ppc/sys/setpgid.s b/ppc/sys/setpgid.s index 3d58d06..4df01d8 100644 --- a/ppc/sys/setpgid.s +++ b/ppc/sys/setpgid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setpriority.s b/ppc/sys/setpriority.s index 87203b2..25a7a9e 100644 --- a/ppc/sys/setpriority.s +++ b/ppc/sys/setpriority.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setprivexec.s b/ppc/sys/setprivexec.s index 92053ed..7525455 100644 --- a/ppc/sys/setprivexec.s +++ b/ppc/sys/setprivexec.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setquota.s b/ppc/sys/setquota.s index 25560c8..727b9f5 100644 --- a/ppc/sys/setquota.s +++ b/ppc/sys/setquota.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setrlimit.s b/ppc/sys/setrlimit.s index fd51209..ba6ccde 100644 --- a/ppc/sys/setrlimit.s +++ b/ppc/sys/setrlimit.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setsid.s b/ppc/sys/setsid.s index aa4e8bc..c1d0d41 100644 --- a/ppc/sys/setsid.s +++ b/ppc/sys/setsid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setsockopt.s b/ppc/sys/setsockopt.s index 0dcfcd1..15898a6 100644 --- a/ppc/sys/setsockopt.s +++ b/ppc/sys/setsockopt.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/settimeofday.s b/ppc/sys/settimeofday.s index 0d70390..574c6a5 100644 --- a/ppc/sys/settimeofday.s +++ b/ppc/sys/settimeofday.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setuid.s b/ppc/sys/setuid.s index 225d68a..44b6f3f 100644 --- a/ppc/sys/setuid.s +++ b/ppc/sys/setuid.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/setxattr.s b/ppc/sys/setxattr.s new file mode 100644 index 0000000..82e4ee2 --- /dev/null +++ b/ppc/sys/setxattr.s @@ -0,0 +1,28 @@ +/* + * 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) + diff --git a/ppc/sys/shmat.s b/ppc/sys/shmat.s index ff6e1f1..5a8bbb6 100644 --- a/ppc/sys/shmat.s +++ b/ppc/sys/shmat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/shmctl.s b/ppc/sys/shmctl.s index b848410..f2f6e59 100644 --- a/ppc/sys/shmctl.s +++ b/ppc/sys/shmctl.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/shmdt.s b/ppc/sys/shmdt.s index 53df096..66c7c77 100644 --- a/ppc/sys/shmdt.s +++ b/ppc/sys/shmdt.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/shmget.s b/ppc/sys/shmget.s index 9be7cd8..e0cb88f 100644 --- a/ppc/sys/shmget.s +++ b/ppc/sys/shmget.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/shmsys.s b/ppc/sys/shmsys.s index 376f234..1f2ecb9 100644 --- a/ppc/sys/shmsys.s +++ b/ppc/sys/shmsys.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/shutdown.s b/ppc/sys/shutdown.s index 737ee0c..63ca4c2 100644 --- a/ppc/sys/shutdown.s +++ b/ppc/sys/shutdown.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sigaltstack.s b/ppc/sys/sigaltstack.s index 2cf3baf..a9c52e7 100644 --- a/ppc/sys/sigaltstack.s +++ b/ppc/sys/sigaltstack.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sigpending.s b/ppc/sys/sigpending.s index 336b836..f3a08cc 100644 --- a/ppc/sys/sigpending.s +++ b/ppc/sys/sigpending.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sigprocmask.s b/ppc/sys/sigprocmask.s index 90285aa..052588f 100644 --- a/ppc/sys/sigprocmask.s +++ b/ppc/sys/sigprocmask.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sigreturn.s b/ppc/sys/sigreturn.s index 290109b..85e45f2 100644 --- a/ppc/sys/sigreturn.s +++ b/ppc/sys/sigreturn.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -39,17 +41,15 @@ * 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) diff --git a/ppc/sys/sigwait.s b/ppc/sys/sigwait.s index 8c4c2d8..ef51ca4 100644 --- a/ppc/sys/sigwait.s +++ b/ppc/sys/sigwait.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/socket.s b/ppc/sys/socket.s index 5daadd1..d0d7a67 100644 --- a/ppc/sys/socket.s +++ b/ppc/sys/socket.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/socketpair.s b/ppc/sys/socketpair.s index 0edf7b2..814957c 100644 --- a/ppc/sys/socketpair.s +++ b/ppc/sys/socketpair.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/stat.s b/ppc/sys/stat.s index d9cab4c..0f75255 100644 --- a/ppc/sys/stat.s +++ b/ppc/sys/stat.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/statfs.s b/ppc/sys/statfs.s index 5a5694a..4395ab3 100644 --- a/ppc/sys/statfs.s +++ b/ppc/sys/statfs.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/statv.s b/ppc/sys/statv.s index 330bc73..40ddffd 100644 --- a/ppc/sys/statv.s +++ b/ppc/sys/statv.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/swapon.s b/ppc/sys/swapon.s index c0197d2..6d7a4e3 100644 --- a/ppc/sys/swapon.s +++ b/ppc/sys/swapon.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/symlink.s b/ppc/sys/symlink.s index 4304685..24b1c28 100644 --- a/ppc/sys/symlink.s +++ b/ppc/sys/symlink.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/sync.s b/ppc/sys/sync.s index efe002d..d377a71 100644 --- a/ppc/sys/sync.s +++ b/ppc/sys/sync.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/syscall.s b/ppc/sys/syscall.s index 8af52f5..205e205 100644 --- a/ppc/sys/syscall.s +++ b/ppc/sys/syscall.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/systable.s b/ppc/sys/systable.s index d3a6426..3f0d139 100644 --- a/ppc/sys/systable.s +++ b/ppc/sys/systable.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/truncate.s b/ppc/sys/truncate.s index c54d976..0df4841 100644 --- a/ppc/sys/truncate.s +++ b/ppc/sys/truncate.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/umask.s b/ppc/sys/umask.s index 30e9bf4..1efb115 100644 --- a/ppc/sys/umask.s +++ b/ppc/sys/umask.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/undelete.s b/ppc/sys/undelete.s index 1e7cdbb..6436458 100644 --- a/ppc/sys/undelete.s +++ b/ppc/sys/undelete.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/unlink.s b/ppc/sys/unlink.s index 8a21f70..6710a6b 100644 --- a/ppc/sys/unlink.s +++ b/ppc/sys/unlink.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/unmount.s b/ppc/sys/unmount.s index acbd04c..5540c16 100644 --- a/ppc/sys/unmount.s +++ b/ppc/sys/unmount.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/utimes.s b/ppc/sys/utimes.s index 8595d64..0cf697e 100644 --- a/ppc/sys/utimes.s +++ b/ppc/sys/utimes.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/vfork.s b/ppc/sys/vfork.s index 8bd3f2c..1d034fa 100644 --- a/ppc/sys/vfork.s +++ b/ppc/sys/vfork.s @@ -1,8 +1,10 @@ /* - * 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 @@ -29,184 +31,52 @@ * Created from fork.s * */ -#if 0 -#import -#import -#import -#import - -/* 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 -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) diff --git a/ppc/sys/wait4.s b/ppc/sys/wait4.s index 84c1be5..04dae84 100644 --- a/ppc/sys/wait4.s +++ b/ppc/sys/wait4.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/write.s b/ppc/sys/write.s index 3c74493..5f2f96e 100644 --- a/ppc/sys/write.s +++ b/ppc/sys/write.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc/sys/writev.s b/ppc/sys/writev.s index 64f059e..f0f3a84 100644 --- a/ppc/sys/writev.s +++ b/ppc/sys/writev.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/ppc64/gen/Makefile.inc b/ppc64/gen/Makefile.inc new file mode 100644 index 0000000..5f28a3a --- /dev/null +++ b/ppc64/gen/Makefile.inc @@ -0,0 +1,13 @@ +# 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 diff --git a/ppc64/mach/Makefile.inc b/ppc64/mach/Makefile.inc new file mode 100644 index 0000000..080e296 --- /dev/null +++ b/ppc64/mach/Makefile.inc @@ -0,0 +1,4 @@ +# searching ppc directory as a fallback to avoid unnecessary code duplication +.PATH: ${.CURDIR}/ppc/mach + +MDSRCS += mach_absolute_time.s diff --git a/ppc64/pthreads/Makefile.inc b/ppc64/pthreads/Makefile.inc new file mode 100644 index 0000000..b5f9cad --- /dev/null +++ b/ppc64/pthreads/Makefile.inc @@ -0,0 +1,9 @@ +# 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 diff --git a/ppc64/stdlib/gdtoa.mk b/ppc64/stdlib/gdtoa.mk new file mode 100644 index 0000000..3b3e39a --- /dev/null +++ b/ppc64/stdlib/gdtoa.mk @@ -0,0 +1,3 @@ +.PATH: ${.CURDIR}/ppc/stdlib +# Long double is just double precision. +FBSDSRCS+=machdep_ldisd.c diff --git a/ppc64/string/Makefile.inc b/ppc64/string/Makefile.inc new file mode 100644 index 0000000..5725d39 --- /dev/null +++ b/ppc64/string/Makefile.inc @@ -0,0 +1,20 @@ +# 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 + diff --git a/ppc64/sys/Makefile.inc b/ppc64/sys/Makefile.inc new file mode 100644 index 0000000..b1b0de3 --- /dev/null +++ b/ppc64/sys/Makefile.inc @@ -0,0 +1,232 @@ +# 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 diff --git a/pthreads/Makefile.inc b/pthreads/Makefile.inc index c876b73..586585a 100644 --- a/pthreads/Makefile.inc +++ b/pthreads/Makefile.inc @@ -1,10 +1,10 @@ -.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 diff --git a/pthreads/lock.s b/pthreads/lock.s index eb2a15a..8d1b277 100644 --- a/pthreads/lock.s +++ b/pthreads/lock.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -46,7 +48,7 @@ #include #undef __APPLE_API_PRIVATE -#if defined(__ppc__) +#if defined(__ppc__) || defined(__ppc64__) #import #import diff --git a/pthreads/mk_pthread_impl.c b/pthreads/mk_pthread_impl.c index d787c3a..adc5670 100644 --- a/pthreads/mk_pthread_impl.c +++ b/pthreads/mk_pthread_impl.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/pthreads/posix_sched.h b/pthreads/posix_sched.h index 8bbc4a5..b0cbad6 100644 --- a/pthreads/posix_sched.h +++ b/pthreads/posix_sched.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/pthreads/pthread.c b/pthreads/pthread.c index f591d30..f1548cd 100644 --- a/pthreads/pthread.c +++ b/pthreads/pthread.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -139,7 +141,7 @@ size_t _pthread_stack_size = 0; #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; @@ -1371,6 +1373,7 @@ pthread_init(void) int mib[2]; size_t len; int numcpus; + void *stackaddr; count = HOST_PRIORITY_INFO_COUNT; info = (host_info_t)&priority_info; @@ -1392,7 +1395,13 @@ pthread_init(void) 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. */ @@ -1434,6 +1443,20 @@ pthread_init(void) } #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; } diff --git a/pthreads/pthread.h b/pthreads/pthread.h index 598e7f0..863c6cc 100644 --- a/pthreads/pthread.h +++ b/pthreads/pthread.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -61,6 +63,7 @@ #include #include #include +#include /* temporary - need to fix correctly */ #ifndef _POSIX_C_SOURCE #include @@ -80,11 +83,6 @@ /* 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. diff --git a/pthreads/pthread_cond.c b/pthreads/pthread_cond.c index dbb2d91..9e3cc57 100644 --- a/pthreads/pthread_cond.c +++ b/pthreads/pthread_cond.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/pthreads/pthread_impl.h b/pthreads/pthread_impl.h index d778092..f5bc332 100644 --- a/pthreads/pthread_impl.h +++ b/pthreads/pthread_impl.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/pthreads/pthread_internals.h b/pthreads/pthread_internals.h index f44f574..705d0d2 100644 --- a/pthreads/pthread_internals.h +++ b/pthreads/pthread_internals.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -113,6 +115,9 @@ typedef struct _pthread 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 @@ -138,6 +143,9 @@ typedef struct 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 */ diff --git a/pthreads/pthread_machdep.h b/pthreads/pthread_machdep.h index 4fd292b..43e6dc0 100644 --- a/pthreads/pthread_machdep.h +++ b/pthreads/pthread_machdep.h @@ -1,8 +1,10 @@ /* - * 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 @@ -49,9 +51,14 @@ #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) diff --git a/pthreads/pthread_mutex.c b/pthreads/pthread_mutex.c index 1c85670..fce2d5c 100644 --- a/pthreads/pthread_mutex.c +++ b/pthreads/pthread_mutex.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/pthreads/pthread_rwlock.c b/pthreads/pthread_rwlock.c index e78cc3c..3ce5ef2 100644 --- a/pthreads/pthread_rwlock.c +++ b/pthreads/pthread_rwlock.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/pthreads/pthread_spinlock.h b/pthreads/pthread_spinlock.h index 40fa601..808a417 100644 --- a/pthreads/pthread_spinlock.h +++ b/pthreads/pthread_spinlock.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/pthreads/pthread_tsd.c b/pthreads/pthread_tsd.c index df1ee6f..3e90f37 100644 --- a/pthreads/pthread_tsd.c +++ b/pthreads/pthread_tsd.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/pthreads/sched.h b/pthreads/sched.h index 5c5693d..68cc30d 100644 --- a/pthreads/sched.h +++ b/pthreads/sched.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/pthreads/stack.s b/pthreads/stack.s index 37577a2..2628266 100644 --- a/pthreads/stack.s +++ b/pthreads/stack.s @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -47,7 +49,7 @@ .text -#if defined(__ppc__) +#if defined(__ppc__) || defined(__ppc64__) #import #import diff --git a/pthreads/thread_setup.c b/pthreads/thread_setup.c index 70aa4cd..53c68a4 100644 --- a/pthreads/thread_setup.c +++ b/pthreads/thread_setup.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -49,7 +51,7 @@ * Machine specific support for thread initialization */ -#if defined(__ppc__) +#if defined(__ppc__) || defined(__ppc64__) #include #endif @@ -66,7 +68,7 @@ _pthread_setup(pthread_t thread, { 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; diff --git a/quad/Makefile.inc b/quad/Makefile.inc index 679f6cc..a1335b9 100644 --- a/quad/Makefile.inc +++ b/quad/Makefile.inc @@ -6,11 +6,11 @@ .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 \ diff --git a/regex/Makefile.inc b/regex/Makefile.inc index 8eb7f04..352af9f 100644 --- a/regex/Makefile.inc +++ b/regex/Makefile.inc @@ -4,11 +4,10 @@ # 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" diff --git a/rpc/Makefile.inc b/rpc/Makefile.inc index 223003f..65e2712 100644 --- a/rpc/Makefile.inc +++ b/rpc/Makefile.inc @@ -2,7 +2,7 @@ # $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 \ @@ -12,24 +12,22 @@ SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.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 diff --git a/stdio/FreeBSD/fgets.3.patch b/stdio/FreeBSD/fgets.3.patch new file mode 100644 index 0000000..da1eeff --- /dev/null +++ b/stdio/FreeBSD/fgets.3.patch @@ -0,0 +1,14 @@ +--- 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 diff --git a/stdio/FreeBSD/findfp.c.patch b/stdio/FreeBSD/findfp.c.patch index b971a9c..f3ec96d 100644 --- a/stdio/FreeBSD/findfp.c.patch +++ b/stdio/FreeBSD/findfp.c.patch @@ -1,5 +1,5 @@ ---- 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 #include @@ -23,25 +23,7 @@ /* * 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; @@ -50,7 +32,7 @@ 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) */ diff --git a/stdio/FreeBSD/floatio.h b/stdio/FreeBSD/floatio.h index 8f7902f..83beec7 100644 --- a/stdio/FreeBSD/floatio.h +++ b/stdio/FreeBSD/floatio.h @@ -34,7 +34,7 @@ * 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 $ */ /* @@ -53,4 +53,6 @@ #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 **); diff --git a/stdio/FreeBSD/ftell.c.patch b/stdio/FreeBSD/ftell.c.patch new file mode 100644 index 0000000..9b82036 --- /dev/null +++ b/stdio/FreeBSD/ftell.c.patch @@ -0,0 +1,10 @@ +--- 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 { diff --git a/stdio/FreeBSD/mktemp.c.patch b/stdio/FreeBSD/mktemp.c.patch new file mode 100644 index 0000000..9d5f5be --- /dev/null +++ b/stdio/FreeBSD/mktemp.c.patch @@ -0,0 +1,79 @@ +--- 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 + #include ++#include + #include + #include + #include +@@ -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; + } + } diff --git a/stdio/FreeBSD/printf.3.patch b/stdio/FreeBSD/printf.3.patch index be68e2a..72158bd 100644 --- a/stdio/FreeBSD/printf.3.patch +++ b/stdio/FreeBSD/printf.3.patch @@ -1,12 +1,12 @@ ---- 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 @@ -50,3 +50,15 @@ .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 diff --git a/stdio/FreeBSD/sscanf.c.patch b/stdio/FreeBSD/sscanf.c.patch deleted file mode 100644 index 4d09cc9..0000000 --- a/stdio/FreeBSD/sscanf.c.patch +++ /dev/null @@ -1,20 +0,0 @@ -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; diff --git a/stdio/FreeBSD/tmpnam.3.patch b/stdio/FreeBSD/tmpnam.3.patch new file mode 100644 index 0000000..75a261b --- /dev/null +++ b/stdio/FreeBSD/tmpnam.3.patch @@ -0,0 +1,14 @@ +--- 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 diff --git a/stdio/FreeBSD/vfprintf.c b/stdio/FreeBSD/vfprintf.c index e615301..c879874 100644 --- a/stdio/FreeBSD/vfprintf.c +++ b/stdio/FreeBSD/vfprintf.c @@ -38,7 +38,7 @@ static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__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. @@ -66,9 +66,6 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfprintf.c,v 1.59 2003/04/19 23:53:19 das #include "local.h" #include "fvwrite.h" -/* Define FLOATING_POINT to get floating point. */ -#define FLOATING_POINT - union arg { int intarg; u_int uintarg; @@ -90,7 +87,7 @@ union arg { ptrdiff_t *pptrdiffarg; size_t *psizearg; intmax_t *pintmaxarg; -#ifdef FLOATING_POINT +#ifndef NO_FLOATING_POINT double doublearg; long double longdoublearg; #endif @@ -341,20 +338,21 @@ __ujtoa(uintmax_t val, char *endp, int base, int octzero, const char *xdigs, 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 || @@ -364,6 +362,7 @@ __wcsconv(wchar_t *wcsarg, int prec) } } else { p = wcsarg; + mbs = initial; nbytes = wcsrtombs(NULL, (const wchar_t **)&p, 0, &mbs); if (nbytes == (size_t)-1) return (NULL); @@ -377,7 +376,7 @@ __wcsconv(wchar_t *wcsarg, int prec) */ 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) @@ -408,7 +407,7 @@ vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) return (ret); } -#ifdef FLOATING_POINT +#ifndef NO_FLOATING_POINT #define dtoa __dtoa #define freedtoa __freedtoa @@ -422,7 +421,7 @@ vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap) 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 @@ -471,7 +470,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap) 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: @@ -638,7 +637,7 @@ __vfprintf(FILE *fp, const char *fmt0, va_list ap) thousands_sep = '\0'; grouping = NULL; convbuf = NULL; -#ifdef FLOATING_POINT +#ifndef NO_FLOATING_POINT dtoaresult = NULL; decimal_point = localeconv()->decimal_point; #endif @@ -759,7 +758,7 @@ reswitch: switch (ch) { } width = n; goto reswitch; -#ifdef FLOATING_POINT +#ifndef NO_FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; @@ -795,10 +794,11 @@ reswitch: switch (ch) { /*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) { @@ -832,8 +832,7 @@ reswitch: switch (ch) { } base = 10; goto number; -#ifdef FLOATING_POINT -#ifdef HEXFLOAT +#ifndef NO_FLOATING_POINT case 'a': case 'A': if (ch == 'a') { @@ -845,12 +844,12 @@ reswitch: switch (ch) { 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); @@ -860,8 +859,11 @@ reswitch: switch (ch) { __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; @@ -897,6 +899,7 @@ fp_begin: if (expt == 9999) expt = INT_MAX; } +fp_common: if (signflag) sign = '-'; if (expt == INT_MAX) { /* inf or nan */ @@ -962,7 +965,7 @@ fp_begin: lead = expt; } break; -#endif /* FLOATING_POINT */ +#endif /* !NO_FLOATING_POINT */ case 'n': /* * Assignment-like behavior is specified if the @@ -1137,7 +1140,7 @@ number: if ((dprec = prec) >= 0) realsz = dprec > size ? dprec : size; if (sign) realsz++; - else if (ox[1]) + if (ox[1]) realsz += 2; prsize = width > realsz ? width : realsz; @@ -1151,9 +1154,10 @@ number: if ((dprec = prec) >= 0) 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); } @@ -1166,7 +1170,7 @@ number: if ((dprec = prec) >= 0) 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 */ @@ -1229,7 +1233,7 @@ number: if ((dprec = prec) >= 0) done: FLUSH(); error: -#ifdef FLOATING_POINT +#ifndef NO_FLOATING_POINT if (dtoaresult != NULL) freedtoa(dtoaresult); #endif @@ -1311,7 +1315,8 @@ __find_arguments (const char *fmt0, va_list ap, union arg **argtable) 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). @@ -1362,7 +1367,7 @@ reswitch: switch (ch) { } width = n; goto reswitch; -#ifdef FLOATING_POINT +#ifndef NO_FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; @@ -1409,11 +1414,9 @@ reswitch: switch (ch) { case 'i': ADDSARG(); break; -#ifdef FLOATING_POINT -#ifdef HEXFLOAT +#ifndef NO_FLOATING_POINT case 'a': case 'A': -#endif case 'e': case 'E': case 'f': @@ -1424,7 +1427,7 @@ reswitch: switch (ch) { else ADDTYPE(T_DOUBLE); break; -#endif /* FLOATING_POINT */ +#endif /* !NO_FLOATING_POINT */ case 'n': if (flags & INTMAXT) ADDTYPE(TP_INTMAXT); @@ -1544,7 +1547,7 @@ done: 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; @@ -1580,26 +1583,28 @@ __grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) 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) @@ -1636,4 +1641,4 @@ exponent(char *p0, int exp, int fmtch) } return (p - p0); } -#endif /* FLOATING_POINT */ +#endif /* !NO_FLOATING_POINT */ diff --git a/stdio/FreeBSD/vfprintf.c.patch b/stdio/FreeBSD/vfprintf.c.patch index e0e299e..c84878a 100644 --- a/stdio/FreeBSD/vfprintf.c.patch +++ b/stdio/FreeBSD/vfprintf.c.patch @@ -1,5 +1,5 @@ ---- 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 #include @@ -8,37 +8,20 @@ #include #include "un-namespace.h" -@@ -66,9 +67,20 @@ +@@ -66,6 +67,12 @@ #include "local.h" #include "fvwrite.h" +#ifdef ALTIVEC +#include + -+#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; @@ -55,7 +38,7 @@ }; /* -@@ -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, @@ -67,7 +50,7 @@ }; 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 *); @@ -105,23 +88,7 @@ /* * 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 */ @@ -131,7 +98,7 @@ /* * 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 @@ -143,20 +110,7 @@ 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 @@ } /* @@ -172,7 +126,7 @@ * To extend shorts properly, we need both signed and unsigned * argument extraction methods. */ -@@ -634,7 +705,6 @@ +@@ -633,7 +684,6 @@ val = GETARG (int); \ } @@ -180,7 +134,7 @@ 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 */ @@ -192,7 +146,7 @@ /* 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; @@ -202,7 +156,7 @@ fmt++; /* skip over '%' */ flags = 0; -@@ -684,6 +759,9 @@ +@@ -683,6 +738,9 @@ prec = -1; sign = '\0'; ox[1] = '\0'; @@ -212,7 +166,7 @@ rflag: ch = *fmt++; reswitch: switch (ch) { -@@ -699,6 +777,11 @@ +@@ -698,6 +756,11 @@ case '#': flags |= ALT; goto rflag; @@ -224,20 +178,20 @@ 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': @@ -245,13 +199,13 @@ + 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 @@ -264,56 +218,8 @@ 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 @@ -326,7 +232,7 @@ 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': @@ -351,36 +257,7 @@ 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': @@ -388,12 +265,12 @@ + 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 */ @@ -406,7 +283,7 @@ 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': @@ -414,12 +291,12 @@ + 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: @@ -427,12 +304,12 @@ + 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; @@ -447,7 +324,7 @@ default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; -@@ -1120,6 +1309,186 @@ +@@ -1123,6 +1258,184 @@ break; } @@ -511,10 +388,12 @@ + * 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) { @@ -580,8 +459,7 @@ + VPRINT(vcnt, 0); + for (i = 1; i < vcnt; i++) { + /* Separator. */ -+ if (vsep) -+ PRINT(&vsep, 1); ++ PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vcnt, i); @@ -591,8 +469,7 @@ + VPRINT(vcnt, 0, prec); + for (i = 1; i < vcnt; i++) { + /* Separator. */ -+ if (vsep) -+ PRINT(&vsep, 1); ++ PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vcnt, i, prec); @@ -604,8 +481,7 @@ + VPRINT(vcnt, 0, width); + for (i = 1; i < vcnt; i++) { + /* Separator. */ -+ if (vsep) -+ PRINT(&vsep, 1); ++ PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vcnt, i, width); @@ -615,8 +491,7 @@ + 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); @@ -634,28 +509,7 @@ /* * 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 @@ -667,7 +521,7 @@ ADDTYPE(T_INT); break; case 'D': -@@ -1407,6 +1781,11 @@ +@@ -1412,6 +1730,11 @@ /*FALLTHROUGH*/ case 'd': case 'i': @@ -678,8 +532,8 @@ +#endif ADDSARG(); break; - #ifdef FLOATING_POINT -@@ -1419,6 +1798,11 @@ + #ifndef NO_FLOATING_POINT +@@ -1422,6 +1745,11 @@ case 'f': case 'g': case 'G': @@ -691,7 +545,7 @@ if (flags & LONGDBL) ADDTYPE(T_LONG_DOUBLE); else -@@ -1447,9 +1831,19 @@ +@@ -1450,9 +1778,19 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'o': @@ -711,7 +565,7 @@ ADDTYPE(TP_VOID); break; case 'S': -@@ -1467,6 +1861,11 @@ +@@ -1470,6 +1808,11 @@ case 'u': case 'X': case 'x': @@ -723,7 +577,7 @@ 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 diff --git a/stdio/FreeBSD/vfscanf.c.patch b/stdio/FreeBSD/vfscanf.c.patch new file mode 100644 index 0000000..75f89cc --- /dev/null +++ b/stdio/FreeBSD/vfscanf.c.patch @@ -0,0 +1,178 @@ +--- 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 diff --git a/stdio/FreeBSD/vfwprintf.c b/stdio/FreeBSD/vfwprintf.c index 02a5eff..f1934b1 100644 --- a/stdio/FreeBSD/vfwprintf.c +++ b/stdio/FreeBSD/vfwprintf.c @@ -34,14 +34,13 @@ * SUCH DAMAGE. */ -#include #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 +__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.20 2004/05/02 20:09:14 obrien Exp $"); /* * Actual wprintf innards. @@ -70,9 +69,6 @@ __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.14 2003/11/12 08:49:12 tj #include "local.h" #include "fvwrite.h" -/* Define FLOATING_POINT to get floating point. */ -#define FLOATING_POINT - union arg { int intarg; u_int uintarg; @@ -94,7 +90,7 @@ union arg { ptrdiff_t *pptrdiffarg; size_t *psizearg; intmax_t *pintmaxarg; -#ifdef FLOATING_POINT +#ifndef NO_FLOATING_POINT double doublearg; long double longdoublearg; #endif @@ -115,9 +111,9 @@ enum typeid { 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 **); @@ -163,16 +159,18 @@ __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap) 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); } @@ -198,7 +196,7 @@ __xfputwc(wchar_t wc, FILE *fp) * 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; @@ -276,7 +274,7 @@ __ultoa(u_long val, wchar_t *endp, int base, int octzero, const wchar_t *xdigs, /* 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; @@ -354,6 +352,8 @@ __ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero, 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; @@ -372,8 +372,9 @@ __mbsconv(char *mbsarg, int prec) */ 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; @@ -396,8 +397,9 @@ __mbsconv(char *mbsarg, int prec) 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++; @@ -428,7 +430,7 @@ vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) return (ret); } -#ifdef FLOATING_POINT +#ifndef NO_FLOATING_POINT #define dtoa __dtoa #define freedtoa __freedtoa @@ -442,7 +444,7 @@ vfwprintf(FILE * __restrict fp, const wchar_t * __restrict fmt0, va_list ap) 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 @@ -490,7 +492,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) 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: @@ -529,7 +531,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) 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 */ @@ -549,8 +551,8 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) 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 @@ -641,7 +643,7 @@ __vfwprintf(FILE *fp, const wchar_t *fmt0, va_list ap) thousands_sep = '\0'; grouping = NULL; -#ifdef FLOATING_POINT +#ifndef NO_FLOATING_POINT decimal_point = localeconv()->decimal_point; #endif convbuf = NULL; @@ -759,7 +761,7 @@ reswitch: switch (ch) { } width = n; goto reswitch; -#ifdef FLOATING_POINT +#ifndef NO_FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; @@ -821,8 +823,7 @@ reswitch: switch (ch) { } base = 10; goto number; -#ifdef FLOATING_POINT -#ifdef HEXFLOAT +#ifndef NO_FLOATING_POINT case 'a': case 'A': if (ch == 'a') { @@ -834,12 +835,10 @@ reswitch: switch (ch) { 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); @@ -849,12 +848,16 @@ reswitch: switch (ch) { __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; @@ -893,6 +896,7 @@ fp_begin: ndig = dtoaend - dtoaresult; cp = convbuf = __mbsconv(dtoaresult, -1); freedtoa(dtoaresult); +fp_common: if (signflag) sign = '-'; if (expt == INT_MAX) { /* inf or nan */ @@ -957,7 +961,7 @@ fp_begin: lead = expt; } break; -#endif /* FLOATING_POINT */ +#endif /* !NO_FLOATING_POINT */ case 'n': /* * Assignment-like behavior is specified if the @@ -1135,7 +1139,7 @@ number: if ((dprec = prec) >= 0) realsz = dprec > size ? dprec : size; if (sign) realsz++; - else if (ox[1]) + if (ox[1]) realsz += 2; prsize = width > realsz ? width : realsz; @@ -1149,9 +1153,10 @@ number: if ((dprec = prec) >= 0) 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); } @@ -1164,7 +1169,7 @@ number: if ((dprec = prec) >= 0) 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 */ @@ -1305,7 +1310,8 @@ __find_arguments (const wchar_t *fmt0, va_list ap, union arg **argtable) 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). @@ -1356,7 +1362,7 @@ reswitch: switch (ch) { } width = n; goto reswitch; -#ifdef FLOATING_POINT +#ifndef NO_FLOATING_POINT case 'L': flags |= LONGDBL; goto rflag; @@ -1403,11 +1409,9 @@ reswitch: switch (ch) { case 'i': ADDSARG(); break; -#ifdef FLOATING_POINT -#ifdef HEXFLOAT +#ifndef NO_FLOATING_POINT case 'a': case 'A': -#endif case 'e': case 'E': case 'f': @@ -1418,7 +1422,7 @@ reswitch: switch (ch) { else ADDTYPE(T_DOUBLE); break; -#endif /* FLOATING_POINT */ +#endif /* !NO_FLOATING_POINT */ case 'n': if (flags & INTMAXT) ADDTYPE(TP_INTMAXT); @@ -1538,7 +1542,7 @@ done: 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; @@ -1574,26 +1578,28 @@ __grow_type_table (int nextarg, enum typeid **typetable, int *tablesize) 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) @@ -1630,4 +1636,4 @@ exponent(wchar_t *p0, int exp, wchar_t fmtch) } return (p - p0); } -#endif /* FLOATING_POINT */ +#endif /* !NO_FLOATING_POINT */ diff --git a/stdio/FreeBSD/vfwprintf.c.patch b/stdio/FreeBSD/vfwprintf.c.patch index f818131..e59c64e 100644 --- a/stdio/FreeBSD/vfwprintf.c.patch +++ b/stdio/FreeBSD/vfwprintf.c.patch @@ -1,6 +1,6 @@ ---- 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 #include #include @@ -14,30 +14,13 @@ +#ifdef ALTIVEC +#include + -+#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; @@ -54,7 +37,7 @@ }; /* -@@ -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, @@ -66,7 +49,7 @@ }; 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 *); @@ -104,23 +87,7 @@ /* * 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 */ @@ -130,7 +97,7 @@ /* * 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 @@ -142,23 +109,7 @@ 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) /* @@ -174,15 +125,15 @@ * 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 */ @@ -194,7 +145,7 @@ /* 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; @@ -204,7 +155,7 @@ fmt++; /* skip over '%' */ flags = 0; -@@ -684,6 +762,9 @@ +@@ -686,6 +741,9 @@ prec = -1; sign = '\0'; ox[1] = '\0'; @@ -214,7 +165,7 @@ rflag: ch = *fmt++; reswitch: switch (ch) { -@@ -699,6 +780,11 @@ +@@ -701,6 +759,11 @@ case '#': flags |= ALT; goto rflag; @@ -226,26 +177,20 @@ 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': @@ -253,103 +198,12 @@ + 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': @@ -374,39 +228,7 @@ 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': @@ -414,12 +236,12 @@ + 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 */ @@ -432,7 +254,7 @@ 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': @@ -440,12 +262,12 @@ + 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: @@ -453,12 +275,12 @@ + 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; @@ -473,7 +295,7 @@ default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; -@@ -1118,6 +1317,185 @@ +@@ -1122,6 +1243,183 @@ break; } @@ -537,10 +359,12 @@ + * 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) { @@ -605,8 +429,7 @@ + VPRINT(vcnt, 0); + for (i = 1; i < vcnt; i++) { + /* Separator. */ -+ if (vsep) -+ PRINT(&vsep, 1); ++ PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vcnt, i); @@ -616,8 +439,7 @@ + VPRINT(vcnt, 0, prec); + for (i = 1; i < vcnt; i++) { + /* Separator. */ -+ if (vsep) -+ PRINT(&vsep, 1); ++ PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vcnt, i, prec); @@ -629,8 +451,7 @@ + VPRINT(vcnt, 0, width); + for (i = 1; i < vcnt; i++) { + /* Separator. */ -+ if (vsep) -+ PRINT(&vsep, 1); ++ PRINT(&vsep, 1); + + /* Element. */ + VPRINT(vcnt, i, width); @@ -640,8 +461,7 @@ + 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); @@ -659,28 +479,7 @@ /* * 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 @@ -692,7 +491,7 @@ ADDTYPE(T_INT); break; case 'D': -@@ -1413,6 +1796,11 @@ +@@ -1417,6 +1720,11 @@ case 'f': case 'g': case 'G': @@ -704,7 +503,7 @@ if (flags & LONGDBL) ADDTYPE(T_LONG_DOUBLE); else -@@ -1441,9 +1829,19 @@ +@@ -1445,9 +1753,19 @@ flags |= LONGINT; /*FALLTHROUGH*/ case 'o': @@ -724,7 +523,7 @@ ADDTYPE(TP_VOID); break; case 'S': -@@ -1461,6 +1859,11 @@ +@@ -1465,6 +1783,11 @@ case 'u': case 'X': case 'x': @@ -736,7 +535,7 @@ 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 diff --git a/stdio/FreeBSD/vfwscanf.c.patch b/stdio/FreeBSD/vfwscanf.c.patch new file mode 100644 index 0000000..e31161e --- /dev/null +++ b/stdio/FreeBSD/vfwscanf.c.patch @@ -0,0 +1,179 @@ +--- 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 diff --git a/stdio/FreeBSD/vswprintf.c.patch b/stdio/FreeBSD/vswprintf.c.patch new file mode 100644 index 0000000..159d765 --- /dev/null +++ b/stdio/FreeBSD/vswprintf.c.patch @@ -0,0 +1,26 @@ +--- 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); diff --git a/stdio/FreeBSD/wprintf.3.patch b/stdio/FreeBSD/wprintf.3.patch index b243b57..ef9fd10 100644 --- a/stdio/FreeBSD/wprintf.3.patch +++ b/stdio/FreeBSD/wprintf.3.patch @@ -4,9 +4,9 @@ .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 diff --git a/stdio/Makefile.inc b/stdio/Makefile.inc index d2e4300..3125b47 100644 --- a/stdio/Makefile.inc +++ b/stdio/Makefile.inc @@ -4,12 +4,8 @@ # 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 \ @@ -22,9 +18,13 @@ FBSDSRCS= _flock_stub.c asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.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 \ diff --git a/stdio/hexfloat.c b/stdio/hexfloat.c deleted file mode 100644 index 51881a9..0000000 --- a/stdio/hexfloat.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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 -#include -#include - -#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 */ diff --git a/stdlib/FreeBSD/atexit.c b/stdlib/FreeBSD/atexit.c index 51b195b..bd94bcd 100644 --- a/stdlib/FreeBSD/atexit.c +++ b/stdlib/FreeBSD/atexit.c @@ -38,7 +38,7 @@ static char sccsid[] = "@(#)atexit.c 8.2 (Berkeley) 7/3/94"; #endif /* LIBC_SCCS and not lint */ #include -__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 @@ -50,19 +50,38 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/atexit.c,v 1.6 2002/03/22 21:53:09 obrie #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; @@ -89,7 +108,82 @@ atexit(fn) 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); } diff --git a/stdlib/FreeBSD/atexit.c.patch b/stdlib/FreeBSD/atexit.c.patch new file mode 100644 index 0000000..04ddfe7 --- /dev/null +++ b/stdlib/FreeBSD/atexit.c.patch @@ -0,0 +1,24 @@ +--- atexit.c.orig Thu Mar 11 13:16:53 2004 ++++ atexit.c Mon Mar 15 12:47:39 2004 +@@ -45,6 +45,9 @@ + #include + #include + #include ++#if defined(__DYNAMIC__) ++#include ++#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); diff --git a/stdlib/FreeBSD/atexit.h b/stdlib/FreeBSD/atexit.h index b6aa183..cd30b3f 100644 --- a/stdlib/FreeBSD/atexit.h +++ b/stdlib/FreeBSD/atexit.h @@ -31,16 +31,10 @@ * 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); diff --git a/stdlib/FreeBSD/exit.c b/stdlib/FreeBSD/exit.c index 6fefb36..e71b3db 100644 --- a/stdlib/FreeBSD/exit.c +++ b/stdlib/FreeBSD/exit.c @@ -35,7 +35,7 @@ static char sccsid[] = "@(#)exit.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__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 @@ -61,17 +61,12 @@ void 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); diff --git a/stdlib/FreeBSD/exit.c.patch b/stdlib/FreeBSD/exit.c.patch index c7f7c9b..f1ac18e 100644 --- a/stdlib/FreeBSD/exit.c.patch +++ b/stdlib/FreeBSD/exit.c.patch @@ -1,6 +1,6 @@ ---- 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)(); /* @@ -16,15 +16,14 @@ * 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)(); diff --git a/stdlib/FreeBSD/realpath.c.patch b/stdlib/FreeBSD/realpath.c.patch new file mode 100644 index 0000000..603dc2b --- /dev/null +++ b/stdlib/FreeBSD/realpath.c.patch @@ -0,0 +1,115 @@ +--- realpath.c.orig Fri Aug 15 19:22:17 2003 ++++ realpath.c Tue Dec 9 14:36:32 2003 +@@ -40,8 +40,27 @@ + #include + #include + #include ++#include ++#include + #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. ++ */ + } + + /* diff --git a/stdlib/Makefile.inc b/stdlib/Makefile.inc index a9aa664..8fb6c96 100644 --- a/stdlib/Makefile.inc +++ b/stdlib/Makefile.inc @@ -1,8 +1,13 @@ # 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 @@ -15,14 +20,9 @@ FBSDMISRCS=_Exit_.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.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 diff --git a/stdlib/a64l.3 b/stdlib/a64l.3 index 0c15487..7876343 100644 --- a/stdlib/a64l.3 +++ b/stdlib/a64l.3 @@ -142,4 +142,3 @@ and .Fn l64a functions conform to .St -xpg4.2 . - diff --git a/stdlib/a64l.c b/stdlib/a64l.c index 8c2a9a3..53d671f 100644 --- a/stdlib/a64l.c +++ b/stdlib/a64l.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/stdlib/l64a.c b/stdlib/l64a.c index cc4b60a..93d50ff 100644 --- a/stdlib/l64a.c +++ b/stdlib/l64a.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/stdtime/FreeBSD/ftime.3 b/stdtime/FreeBSD/ftime.3 new file mode 100644 index 0000000..7cee2be --- /dev/null +++ b/stdtime/FreeBSD/ftime.3 @@ -0,0 +1,86 @@ +.\" 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 . diff --git a/stdtime/FreeBSD/ftime.3.patch b/stdtime/FreeBSD/ftime.3.patch new file mode 100644 index 0000000..c5d12ff --- /dev/null +++ b/stdtime/FreeBSD/ftime.3.patch @@ -0,0 +1,11 @@ +--- 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 diff --git a/stdtime/FreeBSD/ftime.c b/stdtime/FreeBSD/ftime.c new file mode 100644 index 0000000..6bb3f03 --- /dev/null +++ b/stdtime/FreeBSD/ftime.c @@ -0,0 +1,54 @@ +/* + * 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 +#include +#include + +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); +} diff --git a/stdtime/FreeBSD/localtime.c.patch b/stdtime/FreeBSD/localtime.c.patch index 11d2cc1..00406de 100644 --- a/stdtime/FreeBSD/localtime.c.patch +++ b/stdtime/FreeBSD/localtime.c.patch @@ -1,5 +1,5 @@ ---- 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 #include @@ -177,7 +177,7 @@ + *----------------------------------------------------------------*/ + 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; @@ -367,12 +367,13 @@ 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) @@ -392,7 +393,7 @@ _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; @@ -402,7 +403,7 @@ sp = lclptr; #ifdef ALL_STATE if (sp == NULL) { -@@ -1087,7 +1338,7 @@ +@@ -1087,7 +1339,7 @@ if (__isthreaded != 0) { _pthread_mutex_lock(&localtime_mutex); @@ -411,7 +412,7 @@ 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; { @@ -443,7 +444,7 @@ } _MUTEX_UNLOCK(&gmt_mutex); timesub(timep, offset, gmtptr, tmp); -@@ -1145,7 +1412,7 @@ +@@ -1145,7 +1413,7 @@ else { #ifdef ALL_STATE if (gmtptr == NULL) @@ -452,7 +453,7 @@ 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); diff --git a/stdtime/Makefile.inc b/stdtime/Makefile.inc index 7782481..4a71e90 100644 --- a/stdtime/Makefile.inc +++ b/stdtime/Makefile.inc @@ -3,22 +3,27 @@ .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 diff --git a/stdtime/getdate.3 b/stdtime/getdate.3 new file mode 100644 index 0000000..eb8c99f --- /dev/null +++ b/stdtime/getdate.3 @@ -0,0 +1,401 @@ +'\" 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 diff --git a/stdtime/getdate.c b/stdtime/getdate.c new file mode 100644 index 0000000..84a7b28 --- /dev/null +++ b/stdtime/getdate.c @@ -0,0 +1,266 @@ +/* + * 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 +#include +#include +#include +#include +#include + +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; +} diff --git a/stdtime/timegm.3 b/stdtime/timegm.3 new file mode 100644 index 0000000..e5f3fbc --- /dev/null +++ b/stdtime/timegm.3 @@ -0,0 +1,86 @@ +.\" Copyright (C) 2001 Andries Brouwer +.\" +.\" 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 +.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 +#include + +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) diff --git a/string/FreeBSD/bcopy.c b/string/FreeBSD/bcopy.c deleted file mode 100644 index 1b2bd0c..0000000 --- a/string/FreeBSD/bcopy.c +++ /dev/null @@ -1,139 +0,0 @@ -/*- - * 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 -__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 - -void * -#ifdef MEMCOPY -memcpy -#else -memmove -#endif -(void *dst0, const void *src0, size_t length) -#else -#include - -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 -} diff --git a/string/FreeBSD/bzero.c b/string/FreeBSD/bzero.c deleted file mode 100644 index 85bc5e8..0000000 --- a/string/FreeBSD/bzero.c +++ /dev/null @@ -1,5 +0,0 @@ -#include -__FBSDID("$FreeBSD: src/lib/libc/string/bzero.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); - -#define BZERO -#include "memset.c" diff --git a/string/FreeBSD/index.c.patch b/string/FreeBSD/index.c.patch new file mode 100644 index 0000000..739b1e0 --- /dev/null +++ b/string/FreeBSD/index.c.patch @@ -0,0 +1,13 @@ +--- 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); diff --git a/string/FreeBSD/memcpy.3.patch b/string/FreeBSD/memcpy.3.patch index f4f83f9..536697a 100644 --- a/string/FreeBSD/memcpy.3.patch +++ b/string/FreeBSD/memcpy.3.patch @@ -1,14 +1,29 @@ ---- 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 diff --git a/string/FreeBSD/memcpy.c b/string/FreeBSD/memcpy.c deleted file mode 100644 index dfc03ae..0000000 --- a/string/FreeBSD/memcpy.c +++ /dev/null @@ -1,5 +0,0 @@ -#include -__FBSDID("$FreeBSD: src/lib/libc/string/memcpy.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); - -#define MEMCOPY -#include "bcopy.c" diff --git a/string/FreeBSD/memmove.c b/string/FreeBSD/memmove.c deleted file mode 100644 index 8f44e82..0000000 --- a/string/FreeBSD/memmove.c +++ /dev/null @@ -1,5 +0,0 @@ -#include -__FBSDID("$FreeBSD: src/lib/libc/string/memmove.c,v 1.2 2002/03/22 21:53:19 obrien Exp $"); - -#define MEMMOVE -#include "bcopy.c" diff --git a/string/FreeBSD/rindex.c.patch b/string/FreeBSD/rindex.c.patch new file mode 100644 index 0000000..bc63904 --- /dev/null +++ b/string/FreeBSD/rindex.c.patch @@ -0,0 +1,14 @@ +--- 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); diff --git a/string/FreeBSD/strcat.3.patch b/string/FreeBSD/strcat.3.patch new file mode 100644 index 0000000..1824d98 --- /dev/null +++ b/string/FreeBSD/strcat.3.patch @@ -0,0 +1,23 @@ +--- 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 diff --git a/string/FreeBSD/strcmp.c b/string/FreeBSD/strcmp.c deleted file mode 100644 index 1befcbc..0000000 --- a/string/FreeBSD/strcmp.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * 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 -__FBSDID("$FreeBSD: src/lib/libc/string/strcmp.c,v 1.5 2002/03/21 18:44:54 obrien Exp $"); - -#include - -/* - * 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)); -} diff --git a/string/FreeBSD/strcpy.3.patch b/string/FreeBSD/strcpy.3.patch new file mode 100644 index 0000000..1860713 --- /dev/null +++ b/string/FreeBSD/strcpy.3.patch @@ -0,0 +1,19 @@ +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 diff --git a/string/Makefile.inc b/string/Makefile.inc index c28c20e..ac4318a 100644 --- a/string/Makefile.inc +++ b/string/Makefile.inc @@ -1,15 +1,20 @@ # @(#)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 \ @@ -21,11 +26,6 @@ FBSDMISRCS+=bcmp.c bcopy.c bzero.c ffs.c index.c memccpy.c memchr.c memcmp.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 \ diff --git a/sys/Makefile.inc b/sys/Makefile.inc index 9172bca..aed9ce4 100644 --- a/sys/Makefile.inc +++ b/sys/Makefile.inc @@ -1,13 +1,6 @@ # @(#)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. @@ -17,14 +10,24 @@ .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} @@ -64,6 +67,27 @@ MAN2+= pthread_kill.2 pthread_sigmask.2 \ 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 \ diff --git a/sys/SYSCALL-LIST b/sys/SYSCALL-LIST index f9234a1..5bc2cac 100644 --- a/sys/SYSCALL-LIST +++ b/sys/SYSCALL-LIST @@ -14,6 +14,7 @@ chmod fchmod chown fchown +lchown chroot close connect diff --git a/sys/atomic.3 b/sys/atomic.3 new file mode 100644 index 0000000..7ac2ce6 --- /dev/null +++ b/sys/atomic.3 @@ -0,0 +1,97 @@ +.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 diff --git a/sys/atomicqueue.3 b/sys/atomicqueue.3 new file mode 100644 index 0000000..ec96020 --- /dev/null +++ b/sys/atomicqueue.3 @@ -0,0 +1,65 @@ +.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 diff --git a/sys/barrier.3 b/sys/barrier.3 new file mode 100644 index 0000000..5e9cc9f --- /dev/null +++ b/sys/barrier.3 @@ -0,0 +1,25 @@ +.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 diff --git a/sys/crt_externs.c b/sys/crt_externs.c index c1c4546..ec6d7bb 100644 --- a/sys/crt_externs.c +++ b/sys/crt_externs.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/errno.c b/sys/errno.c index 1beeff9..bbede63 100644 --- a/sys/errno.c +++ b/sys/errno.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/fix-3375657.c b/sys/fix-3375657.c index d37d952..e60c9bb 100644 --- a/sys/fix-3375657.c +++ b/sys/fix-3375657.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/getdtablesize.c b/sys/getdtablesize.c index 8563f52..b6673e2 100644 --- a/sys/getdtablesize.c +++ b/sys/getdtablesize.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/gettimeofday.c b/sys/gettimeofday.c index c66563f..9b93989 100644 --- a/sys/gettimeofday.c +++ b/sys/gettimeofday.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -50,7 +52,7 @@ int gettimeofday (struct timeval *tp, struct timezone *tzp) tp = &localtv; } -#ifdef __ppc__ +#if defined(__ppc__) || defined(__ppc64__) { extern int __ppc_gettimeofday(struct timeval *, struct timezone *); extern int __commpage_gettimeofday(struct timeval *); diff --git a/sys/nanosleep.2 b/sys/nanosleep.2 index a0db6d6..ef75207 100644 --- a/sys/nanosleep.2 +++ b/sys/nanosleep.2 @@ -40,7 +40,7 @@ .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 @@ -49,7 +49,10 @@ .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. diff --git a/sys/pthread_kill.2 b/sys/pthread_kill.2 index 068b23e..c76f456 100644 --- a/sys/pthread_kill.2 +++ b/sys/pthread_kill.2 @@ -72,4 +72,3 @@ is an invalid or unsupported signal number. .Sh STANDARDS .Fn pthread_kill conforms to ISO/IEC 9945-1:1996 (``POSIX.1'') - diff --git a/sys/pthread_sigmask.2 b/sys/pthread_sigmask.2 index f961512..83dd291 100644 --- a/sys/pthread_sigmask.2 +++ b/sys/pthread_sigmask.2 @@ -91,4 +91,3 @@ is not one of the defined values. .Sh STANDARDS .Fn pthread_sigmask conforms to ISO/IEC 9945-1:1996 (``POSIX.1'') - diff --git a/sys/sem_open.c b/sys/sem_open.c index 8728234..e60ee61 100644 --- a/sys/sem_open.c +++ b/sys/sem_open.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/sem_unlink.2 b/sys/sem_unlink.2 index 213628a..6aea5ff 100644 --- a/sys/sem_unlink.2 +++ b/sys/sem_unlink.2 @@ -45,7 +45,7 @@ will refer to or create a new semaphore named .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. diff --git a/sys/sem_unlink.c b/sys/sem_unlink.c index 49c8cc8..10e0dd9 100644 --- a/sys/sem_unlink.c +++ b/sys/sem_unlink.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/shm_open.c b/sys/shm_open.c index 064ac1e..3ec0411 100644 --- a/sys/shm_open.c +++ b/sys/shm_open.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/shm_unlink.c b/sys/shm_unlink.c index dc813d9..07e1ad6 100644 --- a/sys/shm_unlink.c +++ b/sys/shm_unlink.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/sigaction.c b/sys/sigaction.c index dad8bc4..9b57cc4 100644 --- a/sys/sigaction.c +++ b/sys/sigaction.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/sigcatch.c b/sys/sigcatch.c index ba44c7e..2a17588 100644 --- a/sys/sigcatch.c +++ b/sys/sigcatch.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/sigcatch.h b/sys/sigcatch.h index 86f1e60..8114a0e 100644 --- a/sys/sigcatch.h +++ b/sys/sigcatch.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/sigsuspend.c b/sys/sigsuspend.c index f7fbfb0..a8536bd 100644 --- a/sys/sigsuspend.c +++ b/sys/sigsuspend.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/sys/sigtramp.c b/sys/sigtramp.c index e3e8834..abb488f 100644 --- a/sys/sigtramp.c +++ b/sys/sigtramp.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -24,8 +26,8 @@ * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ #import "sigcatch.h" +#import #import -#import #import /* @@ -41,7 +43,7 @@ int __in_sigtramp = 0; /* 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 @@ -61,10 +63,10 @@ int __in_sigtramp = 0; #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); @@ -144,11 +146,6 @@ restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle) 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); } @@ -163,7 +160,7 @@ _sigtramp( siginfo_t *sinfo, struct ucontext *uctx ) { -#ifdef __ppc__ +#if defined(__ppc__) || defined(__ppc64__) int ctxstyle = UC_FLAVOR; #endif mcontext_t mctx; @@ -172,10 +169,10 @@ _sigtramp( #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); @@ -186,7 +183,7 @@ _sigtramp( 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; @@ -203,12 +200,12 @@ _sigtramp( } } 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); */ @@ -216,6 +213,6 @@ _sigtramp( } #else sigreturn(uctx); -#endif /* __ppc__ */ +#endif /* __ppc__ || __ppc64__ */ } diff --git a/sys/spinlock.3 b/sys/spinlock.3 new file mode 100644 index 0000000..b11de26 --- /dev/null +++ b/sys/spinlock.3 @@ -0,0 +1,46 @@ +.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 diff --git a/threads/Makefile.inc b/threads/Makefile.inc index 0f81896..981911b 100644 --- a/threads/Makefile.inc +++ b/threads/Makefile.inc @@ -4,4 +4,4 @@ .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 diff --git a/threads/cprocs.c b/threads/cprocs.c index b45a962..99b52a6 100644 --- a/threads/cprocs.c +++ b/threads/cprocs.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -117,7 +119,8 @@ print_all_cprocs() * 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. @@ -135,15 +138,17 @@ void _cproc_fork_child() #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; } diff --git a/threads/cthread_internals.h b/threads/cthread_internals.h index 7bc550a..7370ee2 100644 --- a/threads/cthread_internals.h +++ b/threads/cthread_internals.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/threads/cthreads.c b/threads/cthreads.c index a96c83b..6fd75b5 100644 --- a/threads/cthreads.c +++ b/threads/cthreads.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/threads/cthreads.h b/threads/cthreads.h index e5207b8..037def2 100644 --- a/threads/cthreads.h +++ b/threads/cthreads.h @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/threads/lu_utils.c b/threads/lu_utils.c index 8508355..fce485a 100644 --- a/threads/lu_utils.c +++ b/threads/lu_utils.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/threads/mig_support.c b/threads/mig_support.c index 8cc775b..c744bc4 100644 --- a/threads/mig_support.c +++ b/threads/mig_support.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/util/Makefile.inc b/util/Makefile.inc index a8d0c80..a38699a 100644 --- a/util/Makefile.inc +++ b/util/Makefile.inc @@ -1,6 +1,6 @@ .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" diff --git a/util/fparseln.c b/util/fparseln.c index 3c02056..a740dd1 100644 --- a/util/fparseln.c +++ b/util/fparseln.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/util/login.c b/util/login.c index 9780bcd..9351abc 100644 --- a/util/login.c +++ b/util/login.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/util/login_tty.c b/util/login_tty.c index 46f09c2..2773d7c 100644 --- a/util/login_tty.c +++ b/util/login_tty.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/util/logout.c b/util/logout.c index fd8ac27..520a45e 100644 --- a/util/logout.c +++ b/util/logout.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/util/logwtmp.c b/util/logwtmp.c index b792b40..79ea648 100644 --- a/util/logwtmp.c +++ b/util/logwtmp.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/util/opendev.c b/util/opendev.c index 7f11a9c..64ccb07 100644 --- a/util/opendev.c +++ b/util/opendev.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/util/pty.c b/util/pty.c index a2f3e69..0491eea 100644 --- a/util/pty.c +++ b/util/pty.c @@ -3,6 +3,8 @@ * * @APPLE_LICENSE_HEADER_START@ * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in diff --git a/uuid/Makefile.inc b/uuid/Makefile.inc new file mode 100644 index 0000000..305fbfb --- /dev/null +++ b/uuid/Makefile.inc @@ -0,0 +1,31 @@ +# 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} diff --git a/uuid/uuid-config.h b/uuid/uuid-config.h new file mode 100644 index 0000000..070fd63 --- /dev/null +++ b/uuid/uuid-config.h @@ -0,0 +1,38 @@ +/* + * 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 diff --git a/uuid/uuidman.sed b/uuid/uuidman.sed new file mode 100644 index 0000000..9730238 --- /dev/null +++ b/uuid/uuidman.sed @@ -0,0 +1,3 @@ +s/@E2FSPROGS_MONTH@/April/g +s/@E2FSPROGS_YEAR@/2004/g +s/@E2FSPROGS_VERSION@/1.36/g diff --git a/uuid/uuidsrc/clear.c b/uuid/uuidsrc/clear.c new file mode 100644 index 0000000..f3a1005 --- /dev/null +++ b/uuid/uuidsrc/clear.c @@ -0,0 +1,43 @@ +/* + * 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); +} + diff --git a/uuid/uuidsrc/compare.c b/uuid/uuidsrc/compare.c new file mode 100644 index 0000000..a9c505c --- /dev/null +++ b/uuid/uuidsrc/compare.c @@ -0,0 +1,55 @@ +/* + * 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 + +#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); +} + diff --git a/uuid/uuidsrc/copy.c b/uuid/uuidsrc/copy.c new file mode 100644 index 0000000..963bc81 --- /dev/null +++ b/uuid/uuidsrc/copy.c @@ -0,0 +1,45 @@ +/* + * 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++; +} diff --git a/uuid/uuidsrc/gen_uuid.c b/uuid/uuidsrc/gen_uuid.c new file mode 100644 index 0000000..30d6202 --- /dev/null +++ b/uuid/uuidsrc/gen_uuid.c @@ -0,0 +1,316 @@ +/* + * 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 +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif +#ifdef HAVE_NET_IF_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_NET_IF_DL_H +#include +#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); +} diff --git a/uuid/uuidsrc/isnull.c b/uuid/uuidsrc/isnull.c new file mode 100644 index 0000000..54a8300 --- /dev/null +++ b/uuid/uuidsrc/isnull.c @@ -0,0 +1,48 @@ +/* + * 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; +} + diff --git a/uuid/uuidsrc/libuuid.3.in b/uuid/uuidsrc/libuuid.3.in new file mode 100644 index 0000000..a06d8e6 --- /dev/null +++ b/uuid/uuidsrc/libuuid.3.in @@ -0,0 +1,66 @@ +.\" 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 +.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) diff --git a/uuid/uuidsrc/pack.c b/uuid/uuidsrc/pack.c new file mode 100644 index 0000000..348d432 --- /dev/null +++ b/uuid/uuidsrc/pack.c @@ -0,0 +1,69 @@ +/* + * 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 +#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); +} + diff --git a/uuid/uuidsrc/parse.c b/uuid/uuidsrc/parse.c new file mode 100644 index 0000000..07b894d --- /dev/null +++ b/uuid/uuidsrc/parse.c @@ -0,0 +1,79 @@ +/* + * 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 +#include +#include +#include + +#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; +} diff --git a/uuid/uuidsrc/unpack.c b/uuid/uuidsrc/unpack.c new file mode 100644 index 0000000..9502fc2 --- /dev/null +++ b/uuid/uuidsrc/unpack.c @@ -0,0 +1,63 @@ +/* + * 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 +#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); +} + diff --git a/uuid/uuidsrc/unparse.c b/uuid/uuidsrc/unparse.c new file mode 100644 index 0000000..c0e08ef --- /dev/null +++ b/uuid/uuidsrc/unparse.c @@ -0,0 +1,76 @@ +/* + * 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 + +#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); +} diff --git a/uuid/uuidsrc/uuid.h b/uuid/uuidsrc/uuid.h new file mode 100644 index 0000000..0229e65 --- /dev/null +++ b/uuid/uuidsrc/uuid.h @@ -0,0 +1,69 @@ +/* + * 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} + +#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 */ diff --git a/uuid/uuidsrc/uuidP.h b/uuid/uuidsrc/uuidP.h new file mode 100644 index 0000000..21de696 --- /dev/null +++ b/uuid/uuidsrc/uuidP.h @@ -0,0 +1,78 @@ +/* + * 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 +#else +#include +#endif +#include +#include +#include + +#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); diff --git a/uuid/uuidsrc/uuid_clear.3.in b/uuid/uuidsrc/uuid_clear.3.in new file mode 100644 index 0000000..a853e68 --- /dev/null +++ b/uuid/uuidsrc/uuid_clear.3.in @@ -0,0 +1,60 @@ +.\" 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 +.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) diff --git a/uuid/uuidsrc/uuid_compare.3.in b/uuid/uuidsrc/uuid_compare.3.in new file mode 100644 index 0000000..642d970 --- /dev/null +++ b/uuid/uuidsrc/uuid_compare.3.in @@ -0,0 +1,66 @@ +.\" 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 +.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) diff --git a/uuid/uuidsrc/uuid_copy.3.in b/uuid/uuidsrc/uuid_copy.3.in new file mode 100644 index 0000000..efad12b --- /dev/null +++ b/uuid/uuidsrc/uuid_copy.3.in @@ -0,0 +1,62 @@ +.\" 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 +.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) diff --git a/uuid/uuidsrc/uuid_generate.3.in b/uuid/uuidsrc/uuid_generate.3.in new file mode 100644 index 0000000..7ec7762 --- /dev/null +++ b/uuid/uuidsrc/uuid_generate.3.in @@ -0,0 +1,103 @@ +.\" 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 +.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) diff --git a/uuid/uuidsrc/uuid_is_null.3.in b/uuid/uuidsrc/uuid_is_null.3.in new file mode 100644 index 0000000..5b9f5b5 --- /dev/null +++ b/uuid/uuidsrc/uuid_is_null.3.in @@ -0,0 +1,61 @@ +.\" 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 +.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) diff --git a/uuid/uuidsrc/uuid_parse.3.in b/uuid/uuidsrc/uuid_parse.3.in new file mode 100644 index 0000000..4584fa9 --- /dev/null +++ b/uuid/uuidsrc/uuid_parse.3.in @@ -0,0 +1,70 @@ +.\" 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 +.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) diff --git a/uuid/uuidsrc/uuid_unparse.3.in b/uuid/uuidsrc/uuid_unparse.3.in new file mode 100644 index 0000000..8616da9 --- /dev/null +++ b/uuid/uuidsrc/uuid_unparse.3.in @@ -0,0 +1,78 @@ +.\" 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 +.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) diff --git a/xdr/Makefile.inc b/xdr/Makefile.inc index 6ca6859..d75da0d 100644 --- a/xdr/Makefile.inc +++ b/xdr/Makefile.inc @@ -2,7 +2,7 @@ # $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" diff --git a/yp/Makefile.inc b/yp/Makefile.inc index 1f0668c..09c8b06 100644 --- a/yp/Makefile.inc +++ b/yp/Makefile.inc @@ -4,7 +4,7 @@ # 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